mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +00:00
Make a mount point of "/" work correctly.
As far as I can tell, this is neither explicitly allowed nor forbidden by RFC 7826. Meanwhile, URLs such as rtsp://<IP>:554 or rtsp://<IP>:554/ are in use in the wild (presumably with non-GStreamer servers). GStreamer's prior behavior was confusing, in that gst_rtsp_mount_points_add_factory() would appear to accept a mount path of "" or "/", but later connection attempts would fail with a "media not found" error. This commit makes a mount path of "/" work for either form of URL, while an empty mount path ("") is rejected and logs a warning. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-rtsp-server/-/merge_requests/168>
This commit is contained in:
parent
9f42f941d7
commit
c4762da9b7
3 changed files with 31 additions and 9 deletions
|
@ -1320,10 +1320,12 @@ default_make_path_from_uri (GstRTSPClient * client, const GstRTSPUrl * uri)
|
||||||
{
|
{
|
||||||
gchar *path;
|
gchar *path;
|
||||||
|
|
||||||
if (uri->query)
|
if (uri->query) {
|
||||||
path = g_strconcat (uri->abspath, "?", uri->query, NULL);
|
path = g_strconcat (uri->abspath, "?", uri->query, NULL);
|
||||||
else
|
} else {
|
||||||
path = g_strdup (uri->abspath);
|
/* normalize rtsp://<IP>:<PORT> to rtsp://<IP>:<PORT>/ */
|
||||||
|
path = g_strdup (uri->abspath[0] ? uri->abspath : "/");
|
||||||
|
}
|
||||||
|
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
@ -2763,9 +2765,15 @@ handle_setup_request (GstRTSPClient * client, GstRTSPContext * ctx)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* path is what matched. */
|
/* path is what matched. */
|
||||||
path[matched] = '\0';
|
gchar *newpath = g_strndup (path, matched);
|
||||||
/* control is remainder */
|
/* control is remainder */
|
||||||
control = &path[matched + 1];
|
if (matched == 1 && path[0] == '/')
|
||||||
|
control = g_strdup (&path[1]);
|
||||||
|
else
|
||||||
|
control = g_strdup (&path[matched + 1]);
|
||||||
|
|
||||||
|
g_free (path);
|
||||||
|
path = newpath;
|
||||||
|
|
||||||
/* find the stream now using the control part */
|
/* find the stream now using the control part */
|
||||||
stream = gst_rtsp_media_find_stream (media, control);
|
stream = gst_rtsp_media_find_stream (media, control);
|
||||||
|
@ -2977,6 +2985,7 @@ handle_setup_request (GstRTSPClient * client, GstRTSPContext * ctx)
|
||||||
g_object_unref (media);
|
g_object_unref (media);
|
||||||
g_object_unref (session);
|
g_object_unref (session);
|
||||||
g_free (path);
|
g_free (path);
|
||||||
|
g_free (control);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
|
@ -3109,6 +3118,7 @@ keymgmt_error:
|
||||||
g_object_unref (session);
|
g_object_unref (session);
|
||||||
cleanup_path:
|
cleanup_path:
|
||||||
g_free (path);
|
g_free (path);
|
||||||
|
g_free (control);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -171,7 +171,8 @@ gst_rtsp_mount_points_new (void)
|
||||||
static gchar *
|
static gchar *
|
||||||
default_make_path (GstRTSPMountPoints * mounts, const GstRTSPUrl * url)
|
default_make_path (GstRTSPMountPoints * mounts, const GstRTSPUrl * url)
|
||||||
{
|
{
|
||||||
return g_strdup (url->abspath);
|
/* normalize rtsp://<IP>:<PORT> to rtsp://<IP>:<PORT>/ */
|
||||||
|
return g_strdup (url->abspath[0] ? url->abspath : "/");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -210,6 +211,10 @@ has_prefix (DataItem * str, DataItem * prefix)
|
||||||
if (str->len < prefix->len)
|
if (str->len < prefix->len)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
/* special case when "/" is the entire prefix */
|
||||||
|
if (prefix->len == 1 && prefix->path[0] == '/' && str->path[0] == '/')
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
/* if str is larger, it there should be a / following the prefix */
|
/* if str is larger, it there should be a / following the prefix */
|
||||||
if (str->len > prefix->len && str->path[prefix->len] != '/')
|
if (str->len > prefix->len && str->path[prefix->len] != '/')
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -331,7 +336,8 @@ gst_rtsp_mount_points_remove_factory_unlocked (GstRTSPMountPoints * mounts,
|
||||||
*
|
*
|
||||||
* Attach @factory to the mount point @path in @mounts.
|
* Attach @factory to the mount point @path in @mounts.
|
||||||
*
|
*
|
||||||
* @path is of the form (/node)+. Any previous mount point will be freed.
|
* @path is either of the form (/node)+ or the root path '/'. (An empty path is
|
||||||
|
* not allowed.) Any previous mount point will be freed.
|
||||||
*
|
*
|
||||||
* Ownership is taken of the reference on @factory so that @factory should not be
|
* Ownership is taken of the reference on @factory so that @factory should not be
|
||||||
* used after calling this function.
|
* used after calling this function.
|
||||||
|
@ -345,7 +351,7 @@ gst_rtsp_mount_points_add_factory (GstRTSPMountPoints * mounts,
|
||||||
|
|
||||||
g_return_if_fail (GST_IS_RTSP_MOUNT_POINTS (mounts));
|
g_return_if_fail (GST_IS_RTSP_MOUNT_POINTS (mounts));
|
||||||
g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
|
g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory));
|
||||||
g_return_if_fail (path != NULL);
|
g_return_if_fail (path != NULL && path[0] == '/');
|
||||||
|
|
||||||
priv = mounts->priv;
|
priv = mounts->priv;
|
||||||
|
|
||||||
|
@ -374,7 +380,7 @@ gst_rtsp_mount_points_remove_factory (GstRTSPMountPoints * mounts,
|
||||||
GstRTSPMountPointsPrivate *priv;
|
GstRTSPMountPointsPrivate *priv;
|
||||||
|
|
||||||
g_return_if_fail (GST_IS_RTSP_MOUNT_POINTS (mounts));
|
g_return_if_fail (GST_IS_RTSP_MOUNT_POINTS (mounts));
|
||||||
g_return_if_fail (path != NULL);
|
g_return_if_fail (path != NULL && path[0] == '/');
|
||||||
|
|
||||||
priv = mounts->priv;
|
priv = mounts->priv;
|
||||||
|
|
||||||
|
|
|
@ -194,6 +194,12 @@ gst_rtsp_session_media_matches (GstRTSPSessionMedia * media,
|
||||||
if (len < priv->path_len)
|
if (len < priv->path_len)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
/* special case when "/" is the entire path */
|
||||||
|
if (priv->path_len == 1 && priv->path[0] == '/' && path[0] == '/') {
|
||||||
|
*matched = 1;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/* if media path is larger, it there should be a / following the path */
|
/* if media path is larger, it there should be a / following the path */
|
||||||
if (len > priv->path_len && path[priv->path_len] != '/')
|
if (len > priv->path_len && path[priv->path_len] != '/')
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
Loading…
Reference in a new issue