gst/rtsp/gstrtspsrc.*: Implement redirect for the DESCRIBE reply. Fixes #506025.
authorWim Taymans <wim.taymans@gmail.com>
Mon, 31 Dec 2007 13:27:32 +0000 (13:27 +0000)
committerWim Taymans <wim.taymans@gmail.com>
Mon, 31 Dec 2007 13:27:32 +0000 (13:27 +0000)
Original commit message from CVS:
* gst/rtsp/gstrtspsrc.c: (gst_rtspsrc_send), (gst_rtspsrc_open):
* gst/rtsp/gstrtspsrc.h:
Implement redirect for the DESCRIBE reply. Fixes #506025.

ChangeLog
gst/rtsp/gstrtspsrc.c
gst/rtsp/gstrtspsrc.h

index 376c47f1879d3ae3d45cda0af7a4fe124d218add..018428beb008d19a30041e48dc247db1e7482437 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2007-12-31  Wim Taymans  <wim.taymans@collabora.co.uk>
+
+       * gst/rtsp/gstrtspsrc.c: (gst_rtspsrc_send), (gst_rtspsrc_open):
+       * gst/rtsp/gstrtspsrc.h:
+       Implement redirect for the DESCRIBE reply. Fixes #506025.
+
 2007-12-29  Sebastian Dröge  <slomo@circular-chaos.org>
 
        * ext/flac/gstflacdec.c: (gst_flac_dec_write):
index 04df8abbc6ab1922440551284c42fc8c5950a6c6..50ce4afe23ba6abb20b06556bab4cf85ff1ebaed 100644 (file)
@@ -3216,24 +3216,34 @@ gst_rtspsrc_send (GstRTSPSrc * src, GstRTSPMessage * request,
 {
   GstRTSPStatusCode int_code = GST_RTSP_STS_OK;
   GstRTSPResult res;
+  gint count;
   gboolean retry;
   GstRTSPMethod method;
 
+  count = 0;
   do {
     retry = FALSE;
 
+    /* make sure we don't loop forever */
+    if (count++ > 8)
+      break;
+
     /* save method so we can disable it when the server complains */
     method = request->type_data.request.method;
 
     if ((res = gst_rtspsrc_try_send (src, request, response, &int_code)) < 0)
       goto error;
 
-    if (int_code == GST_RTSP_STS_UNAUTHORIZED) {
-      if (gst_rtspsrc_setup_auth (src, response)) {
-        /* Try the request/response again after configuring the auth info
-         * and loop again */
-        retry = TRUE;
-      }
+    switch (int_code) {
+      case GST_RTSP_STS_UNAUTHORIZED:
+        if (gst_rtspsrc_setup_auth (src, response)) {
+          /* Try the request/response again after configuring the auth info
+           * and loop again */
+          retry = TRUE;
+        }
+        break;
+      default:
+        break;
     }
   } while (retry == TRUE);
 
@@ -3261,6 +3271,29 @@ error_response:
         GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, (NULL), ("%s",
                 response->type_data.response.reason));
         break;
+      case GST_RTSP_STS_MOVED_PERMANENTLY:
+      case GST_RTSP_STS_MOVE_TEMPORARILY:
+      {
+        gchar *new_location;
+
+        GST_DEBUG_OBJECT (src, "got redirection");
+        /* if we don't have a Location Header, we must error */
+        if (gst_rtsp_message_get_header (response, GST_RTSP_HDR_LOCATION,
+                &new_location, 0) < 0)
+          break;
+
+        /* When we receive a redirect result, we go back to the INIT state after
+         * parsing the new URI. The caller should do the needed steps to issue
+         * a new setup when it detects this state change. */
+        GST_DEBUG_OBJECT (src, "redirection to %s", new_location);
+
+        gst_rtspsrc_uri_set_uri (GST_URI_HANDLER (src), new_location);
+
+        src->need_redirect = TRUE;
+        src->state = GST_RTSP_STATE_INIT;
+        res = GST_RTSP_OK;
+        break;
+      }
       case GST_RTSP_STS_NOT_ACCEPTABLE:
       case GST_RTSP_STS_NOT_IMPLEMENTED:
       case GST_RTSP_STS_METHOD_NOT_ALLOWED:
@@ -3816,9 +3849,11 @@ gst_rtspsrc_open (GstRTSPSrc * src)
 
   GST_RTSP_STATE_LOCK (src);
 
+restart:
   /* reset our state */
   gst_segment_init (&src->segment, GST_FORMAT_TIME);
   src->need_range = TRUE;
+  src->need_redirect = FALSE;
 
   /* can't continue without a valid url */
   if (G_UNLIKELY (src->url == NULL))
@@ -3876,6 +3911,21 @@ gst_rtspsrc_open (GstRTSPSrc * src)
   if ((res = gst_rtspsrc_send (src, &request, &response, NULL)) < 0)
     goto send_error;
 
+  /* we only perform redirect for the describe, currently */
+  if (src->need_redirect) {
+    /* close connection, we don't have to send a TEARDOWN yet, ignore the
+     * result. */
+    gst_rtsp_connection_close (src->connection);
+    gst_rtsp_connection_free (src->connection);
+    src->connection = NULL;
+
+    gst_rtsp_message_unset (&request);
+    gst_rtsp_message_unset (&response);
+
+    /* and now retry */
+    goto restart;
+  }
+
   /* check if reply is SDP */
   gst_rtsp_message_get_header (&response, GST_RTSP_HDR_CONTENT_TYPE, &respcont,
       0);
index 77088b8a63fa250d94adf53f1534b5253fd0ad62..58ec88fec60d3df98606c0ef5076fbfe8b19b7f3 100644 (file)
@@ -176,6 +176,7 @@ struct _GstRTSPSrc {
   GstRTSPLowerTrans  cur_protocols;
   gboolean           tried_url_auth;
   gchar             *addr;
+  gboolean           need_redirect;
 
   /* supported methods */
   gint               methods;