rtspsrc: Retry connection if tunneling needs authentication

Leverage response from gst_rtsp_connection_connect_with_response to
determine if the connection should be retried using authentication.  If
so, add the appropriate authentication headers based upon the response
and retry the connection.

https://bugzilla.gnome.org/show_bug.cgi?id=749596
This commit is contained in:
Evan Callaway 2015-12-14 09:05:06 -05:00 committed by Sebastian Dröge
parent 4735d2a9a5
commit 4718870959

View file

@ -342,6 +342,8 @@ static gboolean gst_rtspsrc_stream_push_event (GstRTSPSrc * src,
GstRTSPStream * stream, GstEvent * event);
static gboolean gst_rtspsrc_push_event (GstRTSPSrc * src, GstEvent * event);
static void gst_rtspsrc_connection_flush (GstRTSPSrc * src, gboolean flush);
static GstRTSPResult gst_rtsp_conninfo_close (GstRTSPSrc * src,
GstRTSPConnInfo * info, gboolean free);
typedef struct
{
@ -4491,68 +4493,90 @@ gst_rtsp_conninfo_connect (GstRTSPSrc * src, GstRTSPConnInfo * info,
gboolean async)
{
GstRTSPResult res;
GstRTSPMessage response;
gboolean retry = FALSE;
memset (&response, 0, sizeof (response));
gst_rtsp_message_init (&response);
do {
if (info->connection == NULL) {
if (info->url == NULL) {
GST_DEBUG_OBJECT (src, "parsing uri (%s)...", info->location);
if ((res = gst_rtsp_url_parse (info->location, &info->url)) < 0)
goto parse_error;
}
/* create connection */
GST_DEBUG_OBJECT (src, "creating connection (%s)...", info->location);
if ((res = gst_rtsp_connection_create (info->url, &info->connection)) < 0)
goto could_not_create;
if (info->connection == NULL) {
if (info->url == NULL) {
GST_DEBUG_OBJECT (src, "parsing uri (%s)...", info->location);
if ((res = gst_rtsp_url_parse (info->location, &info->url)) < 0)
goto parse_error;
if (retry) {
gst_rtspsrc_setup_auth (src, &response);
}
g_free (info->url_str);
info->url_str = gst_rtsp_url_get_request_uri (info->url);
GST_DEBUG_OBJECT (src, "sanitized uri %s", info->url_str);
if (info->url->transports & GST_RTSP_LOWER_TRANS_TLS) {
if (!gst_rtsp_connection_set_tls_validation_flags (info->connection,
src->tls_validation_flags))
GST_WARNING_OBJECT (src, "Unable to set TLS validation flags");
if (src->tls_database)
gst_rtsp_connection_set_tls_database (info->connection,
src->tls_database);
if (src->tls_interaction)
gst_rtsp_connection_set_tls_interaction (info->connection,
src->tls_interaction);
}
if (info->url->transports & GST_RTSP_LOWER_TRANS_HTTP)
gst_rtsp_connection_set_tunneled (info->connection, TRUE);
if (src->proxy_host) {
GST_DEBUG_OBJECT (src, "setting proxy %s:%d", src->proxy_host,
src->proxy_port);
gst_rtsp_connection_set_proxy (info->connection, src->proxy_host,
src->proxy_port);
}
}
/* create connection */
GST_DEBUG_OBJECT (src, "creating connection (%s)...", info->location);
if ((res = gst_rtsp_connection_create (info->url, &info->connection)) < 0)
goto could_not_create;
if (!info->connected) {
/* connect */
if (async)
GST_ELEMENT_PROGRESS (src, CONTINUE, "connect",
("Connecting to %s", info->location));
GST_DEBUG_OBJECT (src, "connecting (%s)...", info->location);
res = gst_rtsp_connection_connect_with_response (info->connection,
src->ptcp_timeout, &response);
g_free (info->url_str);
info->url_str = gst_rtsp_url_get_request_uri (info->url);
if (response.type == GST_RTSP_MESSAGE_HTTP_RESPONSE &&
response.type_data.response.code == GST_RTSP_STS_UNAUTHORIZED) {
gst_rtsp_conninfo_close (src, info, TRUE);
if (!retry)
retry = TRUE;
else
retry = FALSE; // we should not retry more than once
} else {
retry = FALSE;
}
GST_DEBUG_OBJECT (src, "sanitized uri %s", info->url_str);
if (info->url->transports & GST_RTSP_LOWER_TRANS_TLS) {
if (!gst_rtsp_connection_set_tls_validation_flags (info->connection,
src->tls_validation_flags))
GST_WARNING_OBJECT (src, "Unable to set TLS validation flags");
if (src->tls_database)
gst_rtsp_connection_set_tls_database (info->connection,
src->tls_database);
if (src->tls_interaction)
gst_rtsp_connection_set_tls_interaction (info->connection,
src->tls_interaction);
if (res == GST_RTSP_OK)
info->connected = TRUE;
else if (!retry)
goto could_not_connect;
}
if (info->url->transports & GST_RTSP_LOWER_TRANS_HTTP)
gst_rtsp_connection_set_tunneled (info->connection, TRUE);
if (src->proxy_host) {
GST_DEBUG_OBJECT (src, "setting proxy %s:%d", src->proxy_host,
src->proxy_port);
gst_rtsp_connection_set_proxy (info->connection, src->proxy_host,
src->proxy_port);
}
}
if (!info->connected) {
/* connect */
if (async)
GST_ELEMENT_PROGRESS (src, CONTINUE, "connect",
("Connecting to %s", info->location));
GST_DEBUG_OBJECT (src, "connecting (%s)...", info->location);
if ((res =
gst_rtsp_connection_connect (info->connection,
src->ptcp_timeout)) < 0)
goto could_not_connect;
info->connected = TRUE;
}
} while (!info->connected && retry);
gst_rtsp_message_unset (&response);
return GST_RTSP_OK;
/* ERRORS */
parse_error:
{
GST_ERROR_OBJECT (src, "No valid RTSP URL was provided");
gst_rtsp_message_unset (&response);
return res;
}
could_not_create:
@ -4560,6 +4584,7 @@ could_not_create:
gchar *str = gst_rtsp_strresult (res);
GST_ERROR_OBJECT (src, "Could not create connection. (%s)", str);
g_free (str);
gst_rtsp_message_unset (&response);
return res;
}
could_not_connect:
@ -4567,6 +4592,7 @@ could_not_connect:
gchar *str = gst_rtsp_strresult (res);
GST_ERROR_OBJECT (src, "Could not connect to server. (%s)", str);
g_free (str);
gst_rtsp_message_unset (&response);
return res;
}
}