summaryrefslogtreecommitdiffstats
path: root/gst/rtsp
diff options
context:
space:
mode:
authorWim Taymans <wim.taymans@gmail.com>2007-12-31 13:27:32 +0000
committerWim Taymans <wim.taymans@gmail.com>2007-12-31 13:27:32 +0000
commiteb5e87944c1d2024463f96c475f5083af6522bce (patch)
tree680de4d56a12438e996e039e608f8adec7a9b251 /gst/rtsp
parent3761fb69e6a878b5bb1d06fcbdde9d0572827f51 (diff)
gst/rtsp/gstrtspsrc.*: Implement redirect for the DESCRIBE reply. Fixes #506025.
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.
Diffstat (limited to 'gst/rtsp')
-rw-r--r--gst/rtsp/gstrtspsrc.c62
-rw-r--r--gst/rtsp/gstrtspsrc.h1
2 files changed, 57 insertions, 6 deletions
diff --git a/gst/rtsp/gstrtspsrc.c b/gst/rtsp/gstrtspsrc.c
index 04df8abb..50ce4afe 100644
--- a/gst/rtsp/gstrtspsrc.c
+++ b/gst/rtsp/gstrtspsrc.c
@@ -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);
diff --git a/gst/rtsp/gstrtspsrc.h b/gst/rtsp/gstrtspsrc.h
index 77088b8a..58ec88fe 100644
--- a/gst/rtsp/gstrtspsrc.h
+++ b/gst/rtsp/gstrtspsrc.h
@@ -176,6 +176,7 @@ struct _GstRTSPSrc {
GstRTSPLowerTrans cur_protocols;
gboolean tried_url_auth;
gchar *addr;
+ gboolean need_redirect;
/* supported methods */
gint methods;