mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-23 06:26:23 +00:00
rtsp: Rewrote setup_tunneling().
Rewrote setup_tunneling() to use normal GstRTSPMessages instead of hard coded strings and duplicates of the message parsing code.
This commit is contained in:
parent
c18e2eec88
commit
db66ff4a62
1 changed files with 92 additions and 152 deletions
|
@ -624,16 +624,17 @@ setup_tunneling (GstRTSPConnection * conn, GTimeVal * timeout)
|
||||||
{
|
{
|
||||||
gint i;
|
gint i;
|
||||||
GstRTSPResult res;
|
GstRTSPResult res;
|
||||||
gchar *str;
|
gchar *ip;
|
||||||
guint idx, line;
|
gchar *uri;
|
||||||
gint retval;
|
gchar *value;
|
||||||
GstClockTime to;
|
|
||||||
gchar *ip, *url_port_str;
|
|
||||||
guint16 port, url_port;
|
guint16 port, url_port;
|
||||||
gchar codestr[4], *resultstr;
|
|
||||||
gint code;
|
|
||||||
GstRTSPUrl *url;
|
GstRTSPUrl *url;
|
||||||
gchar *hostparam;
|
gchar *hostparam;
|
||||||
|
GstRTSPMessage *msg;
|
||||||
|
GstRTSPMessage response;
|
||||||
|
|
||||||
|
memset (&response, 0, sizeof (response));
|
||||||
|
gst_rtsp_message_init (&response);
|
||||||
|
|
||||||
/* create a random sessionid */
|
/* create a random sessionid */
|
||||||
for (i = 0; i < TUNNELID_LEN; i++)
|
for (i = 0; i < TUNNELID_LEN; i++)
|
||||||
|
@ -645,115 +646,64 @@ setup_tunneling (GstRTSPConnection * conn, GTimeVal * timeout)
|
||||||
gst_rtsp_url_get_port (url, &url_port);
|
gst_rtsp_url_get_port (url, &url_port);
|
||||||
|
|
||||||
if (conn->proxy_host) {
|
if (conn->proxy_host) {
|
||||||
hostparam = g_strdup_printf ("Host: %s:%d\r\n", url->host, url_port);
|
uri = g_strdup_printf ("http://%s:%d%s%s%s", url->host, url_port,
|
||||||
url_port_str = g_strdup_printf (":%d", url_port);
|
url->abspath, url->query ? "?" : "", url->query ? url->query : "");
|
||||||
|
hostparam = g_strdup_printf ("%s:%d", url->host, url_port);
|
||||||
ip = conn->proxy_host;
|
ip = conn->proxy_host;
|
||||||
port = conn->proxy_port;
|
port = conn->proxy_port;
|
||||||
} else {
|
} else {
|
||||||
|
uri = g_strdup_printf ("%s%s%s", url->abspath, url->query ? "?" : "",
|
||||||
|
url->query ? url->query : "");
|
||||||
hostparam = NULL;
|
hostparam = NULL;
|
||||||
url_port_str = NULL;
|
|
||||||
ip = conn->ip;
|
ip = conn->ip;
|
||||||
port = url_port;
|
port = url_port;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* */
|
/* create the GET request for the read connection */
|
||||||
str = g_strdup_printf ("GET %s%s%s%s%s%s HTTP/1.0\r\n"
|
GST_RTSP_CHECK (gst_rtsp_message_new_request (&msg, GST_RTSP_GET, uri),
|
||||||
"%s"
|
no_message);
|
||||||
"x-sessioncookie: %s\r\n"
|
msg->type = GST_RTSP_MESSAGE_HTTP_REQUEST;
|
||||||
"Accept: application/x-rtsp-tunnelled\r\n"
|
|
||||||
"Pragma: no-cache\r\n"
|
if (hostparam != NULL)
|
||||||
"Cache-Control: no-cache\r\n" "\r\n",
|
gst_rtsp_message_add_header (msg, GST_RTSP_HDR_HOST, hostparam);
|
||||||
conn->proxy_host ? "http://" : "",
|
gst_rtsp_message_add_header (msg, GST_RTSP_HDR_X_SESSIONCOOKIE,
|
||||||
conn->proxy_host ? url->host : "",
|
conn->tunnelid);
|
||||||
conn->proxy_host ? url_port_str : "",
|
gst_rtsp_message_add_header (msg, GST_RTSP_HDR_ACCEPT,
|
||||||
url->abspath, url->query ? "?" : "", url->query ? url->query : "",
|
"application/x-rtsp-tunnelled");
|
||||||
hostparam ? hostparam : "", conn->tunnelid);
|
gst_rtsp_message_add_header (msg, GST_RTSP_HDR_CACHE_CONTROL, "no-cache");
|
||||||
|
gst_rtsp_message_add_header (msg, GST_RTSP_HDR_PRAGMA, "no-cache");
|
||||||
|
|
||||||
/* we start by writing to this fd */
|
/* we start by writing to this fd */
|
||||||
conn->writefd = &conn->fd0;
|
conn->writefd = &conn->fd0;
|
||||||
|
|
||||||
res = gst_rtsp_connection_write (conn, (guint8 *) str, strlen (str), timeout);
|
/* we need to temporarily set conn->tunneled to FALSE to prevent the HTTP
|
||||||
g_free (str);
|
* request from being base64 encoded */
|
||||||
if (res != GST_RTSP_OK)
|
conn->tunneled = FALSE;
|
||||||
goto write_failed;
|
GST_RTSP_CHECK (gst_rtsp_connection_send (conn, msg, timeout), write_failed);
|
||||||
|
gst_rtsp_message_free (msg);
|
||||||
|
conn->tunneled = TRUE;
|
||||||
|
|
||||||
gst_poll_fd_ctl_write (conn->fdset, &conn->fd0, FALSE);
|
/* receive the response to the GET request */
|
||||||
gst_poll_fd_ctl_read (conn->fdset, &conn->fd0, TRUE);
|
/* we need to temporarily set manual_http to TRUE since
|
||||||
|
* gst_rtsp_connection_receive() will treat the HTTP response as a parsing
|
||||||
|
* failure otherwise */
|
||||||
|
conn->manual_http = TRUE;
|
||||||
|
GST_RTSP_CHECK (gst_rtsp_connection_receive (conn, &response, timeout),
|
||||||
|
read_failed);
|
||||||
|
conn->manual_http = FALSE;
|
||||||
|
|
||||||
to = timeout ? GST_TIMEVAL_TO_TIME (*timeout) : GST_CLOCK_TIME_NONE;
|
if (response.type != GST_RTSP_MESSAGE_HTTP_RESPONSE ||
|
||||||
|
response.type_data.response.code != GST_RTSP_STS_OK)
|
||||||
line = 0;
|
|
||||||
while (TRUE) {
|
|
||||||
guint8 buffer[4096];
|
|
||||||
|
|
||||||
idx = 0;
|
|
||||||
while (TRUE) {
|
|
||||||
res = read_line (conn, buffer, &idx, sizeof (buffer));
|
|
||||||
if (res == GST_RTSP_EEOF)
|
|
||||||
goto eof;
|
|
||||||
if (res == GST_RTSP_OK)
|
|
||||||
break;
|
|
||||||
if (res != GST_RTSP_EINTR)
|
|
||||||
goto read_error;
|
|
||||||
|
|
||||||
do {
|
|
||||||
retval = gst_poll_wait (conn->fdset, to);
|
|
||||||
} while (retval == -1 && (errno == EINTR || errno == EAGAIN));
|
|
||||||
|
|
||||||
/* check for timeout */
|
|
||||||
if (retval == 0)
|
|
||||||
goto timeout;
|
|
||||||
|
|
||||||
if (retval == -1) {
|
|
||||||
if (errno == EBUSY)
|
|
||||||
goto stopped;
|
|
||||||
else
|
|
||||||
goto select_error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check for last line */
|
|
||||||
if (buffer[0] == '\r')
|
|
||||||
buffer[0] = '\0';
|
|
||||||
if (buffer[0] == '\0')
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (line == 0) {
|
|
||||||
/* first line, parse response */
|
|
||||||
gchar versionstr[20];
|
|
||||||
gchar *bptr;
|
|
||||||
|
|
||||||
bptr = (gchar *) buffer;
|
|
||||||
|
|
||||||
parse_string (versionstr, sizeof (versionstr), &bptr);
|
|
||||||
parse_string (codestr, sizeof (codestr), &bptr);
|
|
||||||
code = atoi (codestr);
|
|
||||||
|
|
||||||
while (g_ascii_isspace (*bptr))
|
|
||||||
bptr++;
|
|
||||||
|
|
||||||
resultstr = bptr;
|
|
||||||
|
|
||||||
if (code != GST_RTSP_STS_OK)
|
|
||||||
goto wrong_result;
|
goto wrong_result;
|
||||||
} else {
|
|
||||||
gchar key[32];
|
|
||||||
gchar *value;
|
|
||||||
|
|
||||||
/* other lines, parse key/value */
|
if (gst_rtsp_message_get_header (&response, GST_RTSP_HDR_X_SERVER_IP_ADDRESS,
|
||||||
res = parse_key_value (buffer, key, sizeof (key), &value);
|
&value, 0) != GST_RTSP_OK) {
|
||||||
if (res == GST_RTSP_OK) {
|
|
||||||
/* we got a new ip address */
|
|
||||||
if (g_ascii_strcasecmp (key, "x-server-ip-address") == 0) {
|
|
||||||
if (conn->proxy_host) {
|
if (conn->proxy_host) {
|
||||||
/* if we use a proxy we need to change the destination url */
|
/* if we use a proxy we need to change the destination url */
|
||||||
g_free (url->host);
|
g_free (url->host);
|
||||||
url->host = g_strdup (value);
|
url->host = g_strdup (value);
|
||||||
g_free (hostparam);
|
g_free (hostparam);
|
||||||
g_free (url_port_str);
|
hostparam = g_strdup_printf ("%s:%d", url->host, url_port);
|
||||||
hostparam =
|
|
||||||
g_strdup_printf ("Host: %s:%d\r\n", url->host, url_port);
|
|
||||||
url_port_str = g_strdup_printf (":%d", url_port);
|
|
||||||
} else {
|
} else {
|
||||||
/* and resolve the new ip address */
|
/* and resolve the new ip address */
|
||||||
if (!(ip = do_resolve (conn->ip)))
|
if (!(ip = do_resolve (conn->ip)))
|
||||||
|
@ -762,10 +712,6 @@ setup_tunneling (GstRTSPConnection * conn, GTimeVal * timeout)
|
||||||
conn->ip = ip;
|
conn->ip = ip;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
line++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* connect to the host/port */
|
/* connect to the host/port */
|
||||||
res = do_connect (ip, port, &conn->fd1, conn->fdset, timeout);
|
res = do_connect (ip, port, &conn->fd1, conn->fdset, timeout);
|
||||||
|
@ -775,66 +721,60 @@ setup_tunneling (GstRTSPConnection * conn, GTimeVal * timeout)
|
||||||
/* this is now our writing socket */
|
/* this is now our writing socket */
|
||||||
conn->writefd = &conn->fd1;
|
conn->writefd = &conn->fd1;
|
||||||
|
|
||||||
/* */
|
/* create the POST request for the write connection */
|
||||||
str = g_strdup_printf ("POST %s%s%s%s%s%s HTTP/1.0\r\n"
|
GST_RTSP_CHECK (gst_rtsp_message_new_request (&msg, GST_RTSP_POST, uri),
|
||||||
"%s"
|
no_message);
|
||||||
"x-sessioncookie: %s\r\n"
|
msg->type = GST_RTSP_MESSAGE_HTTP_REQUEST;
|
||||||
"Content-Type: application/x-rtsp-tunnelled\r\n"
|
|
||||||
"Pragma: no-cache\r\n"
|
|
||||||
"Cache-Control: no-cache\r\n"
|
|
||||||
"Content-Length: 32767\r\n"
|
|
||||||
"Expires: Sun, 9 Jan 1972 00:00:00 GMT\r\n"
|
|
||||||
"\r\n",
|
|
||||||
conn->proxy_host ? "http://" : "",
|
|
||||||
conn->proxy_host ? url->host : "",
|
|
||||||
conn->proxy_host ? url_port_str : "",
|
|
||||||
url->abspath, url->query ? "?" : "", url->query ? url->query : "",
|
|
||||||
hostparam ? hostparam : "", conn->tunnelid);
|
|
||||||
|
|
||||||
res = gst_rtsp_connection_write (conn, (guint8 *) str, strlen (str), timeout);
|
if (hostparam != NULL)
|
||||||
g_free (str);
|
gst_rtsp_message_add_header (msg, GST_RTSP_HDR_HOST, hostparam);
|
||||||
if (res != GST_RTSP_OK)
|
gst_rtsp_message_add_header (msg, GST_RTSP_HDR_X_SESSIONCOOKIE,
|
||||||
goto write_failed;
|
conn->tunnelid);
|
||||||
|
gst_rtsp_message_add_header (msg, GST_RTSP_HDR_ACCEPT,
|
||||||
|
"application/x-rtsp-tunnelled");
|
||||||
|
gst_rtsp_message_add_header (msg, GST_RTSP_HDR_CACHE_CONTROL, "no-cache");
|
||||||
|
gst_rtsp_message_add_header (msg, GST_RTSP_HDR_PRAGMA, "no-cache");
|
||||||
|
gst_rtsp_message_add_header (msg, GST_RTSP_HDR_EXPIRES,
|
||||||
|
"Sun, 9 Jan 1972 00:00:00 GMT");
|
||||||
|
gst_rtsp_message_add_header (msg, GST_RTSP_HDR_CONTENT_LENGTH, "32767");
|
||||||
|
|
||||||
|
/* we need to temporarily set conn->tunneled to FALSE to prevent the HTTP
|
||||||
|
* request from being base64 encoded */
|
||||||
|
conn->tunneled = FALSE;
|
||||||
|
GST_RTSP_CHECK (gst_rtsp_connection_send (conn, msg, timeout), write_failed);
|
||||||
|
gst_rtsp_message_free (msg);
|
||||||
|
conn->tunneled = TRUE;
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
|
gst_rtsp_message_unset (&response);
|
||||||
g_free (hostparam);
|
g_free (hostparam);
|
||||||
g_free (url_port_str);
|
g_free (uri);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
/* ERRORS */
|
/* ERRORS */
|
||||||
|
no_message:
|
||||||
|
{
|
||||||
|
GST_ERROR ("failed to create request (%d)", res);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
write_failed:
|
write_failed:
|
||||||
{
|
{
|
||||||
GST_ERROR ("write failed (%d)", res);
|
GST_ERROR ("write failed (%d)", res);
|
||||||
|
gst_rtsp_message_free (msg);
|
||||||
|
conn->tunneled = TRUE;
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
eof:
|
read_failed:
|
||||||
{
|
{
|
||||||
res = GST_RTSP_EEOF;
|
GST_ERROR ("read failed (%d)", res);
|
||||||
goto exit;
|
conn->manual_http = FALSE;
|
||||||
}
|
|
||||||
read_error:
|
|
||||||
{
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
timeout:
|
|
||||||
{
|
|
||||||
res = GST_RTSP_ETIMEOUT;
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
select_error:
|
|
||||||
{
|
|
||||||
res = GST_RTSP_ESYS;
|
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
stopped:
|
|
||||||
{
|
|
||||||
res = GST_RTSP_EINTR;
|
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
wrong_result:
|
wrong_result:
|
||||||
{
|
{
|
||||||
GST_ERROR ("got failure response %d %s", code, resultstr);
|
GST_ERROR ("got failure response %d %s", response.type_data.response.code,
|
||||||
|
response.type_data.response.reason);
|
||||||
res = GST_RTSP_ERROR;
|
res = GST_RTSP_ERROR;
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue