rtsp: Added support for parsing IPv6 addresses in RTSP URLs.

This commit is contained in:
Peter Kjellerstedt 2009-06-09 19:06:57 +02:00
parent 95a606a0bb
commit ddbeb44f14

View file

@ -85,7 +85,11 @@ gst_rtsp_url_get_type (void)
#define RTSPH_PROTO "rtsph://" #define RTSPH_PROTO "rtsph://"
#define RTSPH_PROTO_LEN 8 #define RTSPH_PROTO_LEN 8
/* format is rtsp[u]://[user:passwd@]host[:port]/abspath[?query] */ /* format is rtsp[u]://[user:passwd@]host[:port]/abspath[?query] where host
* is a host name, an IPv4 dotted decimal address ("aaa.bbb.ccc.ddd") or an
* [IPv6] address ("[aabb:ccdd:eeff:gghh::sstt]" note the brackets around the
* address to allow the distinction between ':' as an IPv6 hexgroup separator
* and as a host/port separator) */
/** /**
* gst_rtsp_url_parse: * gst_rtsp_url_parse:
@ -102,6 +106,7 @@ gst_rtsp_url_parse (const gchar * urlstr, GstRTSPUrl ** url)
{ {
GstRTSPUrl *res; GstRTSPUrl *res;
gchar *p, *delim, *at, *col; gchar *p, *delim, *at, *col;
gchar *host_end = NULL;
g_return_val_if_fail (urlstr != NULL, GST_RTSP_EINVAL); g_return_val_if_fail (urlstr != NULL, GST_RTSP_EINVAL);
g_return_val_if_fail (url != NULL, GST_RTSP_EINVAL); g_return_val_if_fail (url != NULL, GST_RTSP_EINVAL);
@ -147,39 +152,52 @@ gst_rtsp_url_parse (const gchar * urlstr, GstRTSPUrl ** url)
p = at + 1; p = at + 1;
} }
col = strchr (p, ':'); if (*p == '[') {
/* we have a ':' and a delimiter but the ':' is after the delimiter, it's res->family = GST_RTSP_FAM_INET6;
* not really part of the hostname */
if (col && delim && col >= delim)
col = NULL;
if (col) { /* we have an IPv6 address in the URL, find the ending ] which must be
res->host = g_strndup (p, col - p); * before any delimiter */
p = col + 1; host_end = strchr (++p, ']');
res->port = strtoul (p, (char **) &p, 10); if (!host_end || (delim && host_end >= delim))
if (delim) goto invalid;
p = delim;
/* a port specifier must follow the address immediately */
col = host_end[1] == ':' ? host_end + 1 : NULL;
} else { } else {
/* no port specified, set to 0. _get_port() will return the default port. */ res->family = GST_RTSP_FAM_INET;
res->port = 0;
if (!delim) { col = strchr (p, ':');
res->host = g_strdup (p);
p = NULL; /* we have a ':' and a delimiter but the ':' is after the delimiter, it's
* not really part of the hostname */
if (col && delim && col >= delim)
col = NULL;
host_end = col ? col : delim;
}
if (!host_end)
res->host = g_strdup (p);
else {
res->host = g_strndup (p, host_end - p);
if (col) {
res->port = strtoul (col + 1, NULL, 10);
} else { } else {
res->host = g_strndup (p, delim - p); /* no port specified, set to 0. gst_rtsp_url_get_port() will return the
p = delim; * default port */
res->port = 0;
} }
} }
p = delim;
if (p && *p == '/') { if (p && *p == '/') {
delim = strchr (p, '?'); delim = strchr (p, '?');
if (!delim) { if (!delim)
res->abspath = g_strdup (p); res->abspath = g_strdup (p);
p = NULL; else
} else {
res->abspath = g_strndup (p, delim - p); res->abspath = g_strndup (p, delim - p);
p = delim; p = delim;
}
} else { } else {
res->abspath = g_strdup ("/"); res->abspath = g_strdup ("/");
} }
@ -305,15 +323,24 @@ gchar *
gst_rtsp_url_get_request_uri (const GstRTSPUrl * url) gst_rtsp_url_get_request_uri (const GstRTSPUrl * url)
{ {
gchar *uri; gchar *uri;
gchar *pre_host;
gchar *post_host;
gchar *pre_query;
gchar *query;
g_return_val_if_fail (url != NULL, NULL); g_return_val_if_fail (url != NULL, NULL);
pre_host = url->family == GST_RTSP_FAM_INET6 ? "[" : "";
post_host = url->family == GST_RTSP_FAM_INET6 ? "]" : "";
pre_query = url->query ? "?" : "";
query = url->query ? url->query : "";
if (url->port != 0) { if (url->port != 0) {
uri = g_strdup_printf ("rtsp://%s:%u%s%s%s", url->host, url->port, uri = g_strdup_printf ("rtsp://%s%s%s:%u%s%s%s", pre_host, url->host,
url->abspath, url->query ? "?" : "", url->query ? url->query : ""); post_host, url->port, url->abspath, pre_query, query);
} else { } else {
uri = g_strdup_printf ("rtsp://%s%s%s%s", url->host, url->abspath, uri = g_strdup_printf ("rtsp://%s%s%s%s%s%s", pre_host, url->host,
url->query ? "?" : "", url->query ? url->query : ""); post_host, url->abspath, pre_query, query);
} }
return uri; return uri;