After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 725221 - Add GstUri object for URI handling
Add GstUri object for URI handling
Status: RESOLVED FIXED
Product: GStreamer
Classification: Platform
Component: gstreamer (core)
git master
Other Linux
: Normal enhancement
: 1.5.1
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2014-02-26 13:49 UTC by David Waring
Modified: 2015-02-19 13:55 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Add RFC3986 URL joining to dashdemux (28.30 KB, patch)
2014-02-26 13:49 UTC, David Waring
needs-work Details | Review
Add IETF RFC 3986 url joiner to uridownloader and use in dashdemux (27.08 KB, patch)
2014-02-27 15:14 UTC, David Waring
reviewed Details | Review
Patch to add GstUri class to libgstreamer (44.53 KB, patch)
2014-04-14 08:51 UTC, David Waring
reviewed Details | Review
Use new GstUri objects in dashdemux to join URLs. (8.33 KB, patch)
2014-04-14 08:53 UTC, David Waring
none Details | Review
Patch to add GstUri class to libgstreamer (ver.2) (84.56 KB, patch)
2014-08-01 12:01 UTC, David Waring
needs-work Details | Review
Use new GstUri objects in dashdemux to join URLs (ver.2) (8.21 KB, patch)
2014-08-01 12:02 UTC, David Waring
committed Details | Review
Patch to add GstUri class to libgstreamer (ver.3) (82.85 KB, patch)
2014-09-22 15:32 UTC, David Waring
none Details | Review
Patch to add GstUri class to libgstreamer (ver.4) (82.92 KB, patch)
2014-09-22 15:37 UTC, David Waring
none Details | Review
Patch to add GstUri class to libgstreamer (ver.5) (82.96 KB, patch)
2014-09-29 09:01 UTC, David Waring
committed Details | Review

Description David Waring 2014-02-26 13:49:26 UTC
Created attachment 270385 [details] [review]
Add RFC3986 URL joining to dashdemux

I have been trying to use dashdemux with various DASH sources and coming unstuck with mixtures of relative and absolute URLs throughout the MPD files.

I have therefore used a implementation I already had of RFC 3986 and placed it into a GObject called GUrl and have patched it into the dashdemux element. Git patch attached.

gurl.c and gurl.h should possibly live elsewhere as they form a generic
URL joining (RFC3986) object which could be useful elsewhere (e.g. in m3u8.c in uri_join). But since I only needed it to resolve issues in dashdemux, that's where I've placed it.
Comment 1 Sebastian Dröge (slomo) 2014-02-26 20:04:15 UTC
Thanks for the patch, this looks useful indeed :)

I think having something less heavy than a GObject for this would be beneficial, also it should be renamed to the GStreamer namespace and follow the general coding style (e.g. isWritable -> is_writable)

Would probably also make sense to just put it into gst-plugins-bad/gst-libs/gst/uridownloader until all this (dash, hls and smoothstreaming) is merged into a single plugin.
Comment 2 David Waring 2014-02-27 15:14:54 UTC
Created attachment 270481 [details] [review]
Add IETF RFC 3986 url joiner to uridownloader and use in dashdemux

Sebastian,

Thanks for the comments.

I've moved the GUrl class to uridownloader and changed it into a GstMiniObject called GstMiniUrl. ...makeWritable, ...isWritable and ...asString renamed to lower case with underscores to match the coding standard. I think that addresses everything.

Here's the new patch.
Comment 3 Sebastian Dröge (slomo) 2014-02-28 08:11:55 UTC
Review of attachment 270481 [details] [review]:

Thanks for the changes, I was more thinking of a simple C struct without refcounting. All the GObject/GstMiniObject code around that seems more lines of code than the actual logic :)
Comment 4 David Waring 2014-02-28 14:18:20 UTC
I figured that it may be useful to hold URLs in other structures/elements such as the MPD structure. This would mean that the URL is only parsed/split once and then combined multiple times with other URLs at later times. If this is the case then having ref counts for URL objects that may be passed around seemed like a sensible idea.
Comment 5 Nicolas Dufresne (ndufresne) 2014-02-28 15:25:19 UTC
Review of attachment 270481 [details] [review]:

It's really annoying to see this being implemented again, see SoupURI, which is just a little more complete. I also agree that having an object is a bit overkill for such a small structure. For reference, see: https://git.gnome.org/browse/libsoup/tree/libsoup/soup-uri.c

::: ext/dash/gstdashdemux.c
@@ +1673,3 @@
+  gst_mini_url_unref(hdr_url);
+  gst_mini_url_unref(path_url);
+  gst_mini_url_unref(base_url);

An API like soup_uri_new_with_base() would be more conveniant then having to create two URI, combine in a third one and then unref.
Comment 6 Tim-Philipp Müller 2014-02-28 15:37:11 UTC
There was/is also some GURI or GURL branch for GLib, but don't think it ever landed unfortunately...
Comment 7 Sebastian Dröge (slomo) 2014-03-03 18:50:35 UTC
So yeah, either this should be simplified a lot or made into a GstUri object in a core or base library that implements generic URI handling like the GUri stuff or SoupUri. I think we need something like this in our stack.
Comment 8 David Waring 2014-03-14 09:32:52 UTC
I've been looking at putting the code into core, however I've noticed that there is already a gsturi.[ch] which holds the GstUriHandler class. Should I use gsturl.c and call my object GstUrl or should I rename gsturi.[ch] to gsturihandler.[ch] and put my new class in gsturi.[ch] as GstUri?
Comment 9 Sebastian Dröge (slomo) 2014-03-14 10:38:23 UTC
Just putting it into gsturi.[ch] should be fine.
Comment 10 David Waring 2014-04-14 08:51:43 UTC
Created attachment 274241 [details] [review]
Patch to add GstUri class to libgstreamer

This patch adds a GstUri mini object to libgstreamer and includes unit tests to check for correct working.
Comment 11 David Waring 2014-04-14 08:53:48 UTC
Created attachment 274242 [details] [review]
Use new GstUri objects in dashdemux to join URLs.

This patch uses the GstUri class, added to libgstreamer in gstreamer-add-gst-uri.patch, to join the URLs from the MPD in an IETF RFC 3986 complaint manner.

Requires the other patch to be present.
Comment 12 David Waring 2014-04-14 08:55:13 UTC
Sebastian,

Sorry for the delay in getting these new patches ready, I was given urgent work on another project for a couple of weeks. Hopefully these fulfil your requirements.
Comment 13 Sebastian Dröge (slomo) 2014-05-28 12:35:48 UTC
Review of attachment 274241 [details] [review]:

::: gst/gsturi.h
@@ +213,3 @@
+ */
+
+GstUri * gst_uri_new                       (const gchar * uri) G_GNUC_MALLOC;

I would prefer a component-based constructor here that automatically escapes the components... and then a gst_uri_from_string()

@@ +222,3 @@
+gboolean gst_uri_is_writable               (GstUri * uri);
+GstUri * gst_uri_make_writable             (GstUri * uri);
+gchar *  gst_uri_as_string                 (const GstUri * uri) G_GNUC_MALLOC;

gst_uri_to_string()

@@ +231,3 @@
+gchar *  gst_uri_escape_query              (const gchar * query);
+gchar *  gst_uri_escape_http_query_element (const gchar * element);
+gchar *  gst_uri_escape_fragment           (const gchar * fragment);

These escape functions should maybe be private

But additionally I think per-component setters would be useful (that automatically escape), and a gst_uri_get_parent() that walks the path components and a gst_uri_append_path() and things like that to make the path handling a bit simpler
Comment 14 Sebastian Dröge (slomo) 2014-05-28 12:39:23 UTC
https://developer.gnome.org/libsoup/2.44/SoupURI.html is an API from which we can take some inspiration :)
Comment 15 Tim-Philipp Müller 2014-05-28 12:51:22 UTC
For more inspiration also see bug #489862
Comment 16 David Waring 2014-06-05 15:50:19 UTC
Thanks for the feedback, I'm working on it, just taking a little longer than I hoped due to other interruptions.
Comment 17 David Waring 2014-08-01 12:01:37 UTC
Created attachment 282251 [details] [review]
Patch to add GstUri class to libgstreamer (ver.2)

Revision of GstUri mini-object class to provides methods closer to Soup API. I think this addresses previous comments. (needs ver.2 of the gst-plugins-bad patch too)
Comment 18 David Waring 2014-08-01 12:02:25 UTC
Created attachment 282252 [details] [review]
Use new GstUri objects in dashdemux to join URLs (ver.2)
Comment 19 Sebastian Dröge (slomo) 2014-09-05 08:57:50 UTC
Review of attachment 282251 [details] [review]:

Looks very good in general, just some minor comments

::: gst/gsturi.c
@@ +909,3 @@
+ * using the algorithm described in RFC3986.
+ *
+ * Last reviewed on never ()

Remove that part :)

@@ +929,3 @@
+ * fragment NULL.
+ *
+ * Returns: A new GstUri object. [transfer full]

No need to add gtk-doc documentation for private functions

@@ +1458,3 @@
+ * escaped except where indicated.
+ *
+ * Returns: (transfer full): A new #GstUri object.

Add Since: 1.6 at the end of the gtk-doc comments of every public function

@@ +1778,3 @@
+{
+  const gchar *r_scheme;
+  GstUri *t;

Add guards to *all* public functions, e.g. here

g_return_val_if_fail (base_uri != NULL, NULL);
g_return_val_if_fail (ref_uri != NULL, NULL);

@@ +2433,3 @@
+ * gst_uri_set_query_table:
+ * @uri: (transfer none)(nullable): The #GstUri to modify.
+ * @query_table: (transfer none)(nullable): The new query table to use.

Not sure if a GHashTable is ideal for this. Are the GI annotations to tell about the key and value types?

Maybe we need a GstUriQueryElement struct, and then here use a GList of GPtrArray of them?

@@ +2560,3 @@
+ * Get a list of the query keys from the URI.
+ *
+ * Returns: (transfer full)(element-type gchar*): A list of keys from

This is "transfer container" as the gchar* don't have to be freed

::: gst/gsturi.h
@@ +173,3 @@
+ */
+typedef struct _GstUri GstUri;
+struct _GstUri

Make this struct private and put it into the .c file. If any direct accesses are needed, add getters (and setters?) for them
Comment 20 Sebastian Dröge (slomo) 2014-09-05 09:01:42 UTC
Comment on attachment 282252 [details] [review]
Use new GstUri objects in dashdemux to join URLs (ver.2)

Looks good to me :)
Comment 21 David Waring 2014-09-22 15:32:54 UTC
Created attachment 286820 [details] [review]
Patch to add GstUri class to libgstreamer (ver.3)

Required for patch 282252
Comment 22 David Waring 2014-09-22 15:37:45 UTC
Created attachment 286821 [details] [review]
Patch to add GstUri class to libgstreamer (ver.4)

Missed a few "Since: 1.6" when a few methods were moved from gsturi.h file.

Required for patch 282252.
Comment 23 David Waring 2014-09-22 15:46:32 UTC
(In reply to comment #19)
> Review of attachment 282251 [details] [review]:
> 
> Looks very good in general, just some minor comments
> 
> ::: gst/gsturi.c
> @@ +909,3 @@
> + * using the algorithm described in RFC3986.
> + *
> + * Last reviewed on never ()
> 
> Remove that part :)
> 
Done.

> @@ +929,3 @@
> + * fragment NULL.
> + *
> + * Returns: A new GstUri object. [transfer full]
> 
> No need to add gtk-doc documentation for private functions
> 
Removed those although did leave in an explanation of one function as a simple comment.

> @@ +1458,3 @@
> + * escaped except where indicated.
> + *
> + * Returns: (transfer full): A new #GstUri object.
> 
> Add Since: 1.6 at the end of the gtk-doc comments of every public function
> 
Done.

> @@ +1778,3 @@
> +{
> +  const gchar *r_scheme;
> +  GstUri *t;
> 
> Add guards to *all* public functions, e.g. here
> 
> g_return_val_if_fail (base_uri != NULL, NULL);
> g_return_val_if_fail (ref_uri != NULL, NULL);
> 
Done.

> @@ +2433,3 @@
> + * gst_uri_set_query_table:
> + * @uri: (transfer none)(nullable): The #GstUri to modify.
> + * @query_table: (transfer none)(nullable): The new query table to use.
> 
> Not sure if a GHashTable is ideal for this. Are the GI annotations to tell
> about the key and value types?
> 
Yes, those detail the key and value types.

> Maybe we need a GstUriQueryElement struct, and then here use a GList of
> GPtrArray of them?
> 
I've left this as a GHashTable for now as I didn't want to reinvent a key/value pair type. I thought the hash table would be the best fit here as most of the time you'd want to lookup a query value string by it's key name, or insert key/value pairs. I couldn't see a situation where this structure wouldn't fit, so it seemed best. It maybe worth revisiting later.

> @@ +2560,3 @@
> + * Get a list of the query keys from the URI.
> + *
> + * Returns: (transfer full)(element-type gchar*): A list of keys from
> 
> This is "transfer container" as the gchar* don't have to be freed
> 
Done.

> ::: gst/gsturi.h
> @@ +173,3 @@
> + */
> +typedef struct _GstUri GstUri;
> +struct _GstUri
> 
> Make this struct private and put it into the .c file. If any direct accesses
> are needed, add getters (and setters?) for them

Moved this to the .c file along with a few inline functions which no longer have access directly to the internal parts of the structure.
Comment 24 Sebastian Dröge (slomo) 2014-09-22 20:32:41 UTC
Thanks for the patch update :)

(In reply to comment #23)

> > @@ +929,3 @@
> > + * fragment NULL.
> > + *
> > + * Returns: A new GstUri object. [transfer full]
> > 
> > No need to add gtk-doc documentation for private functions
> > 
> Removed those although did leave in an explanation of one function as a simple
> comment.

That's ok (and good :) )

> > @@ +2433,3 @@
> > + * gst_uri_set_query_table:
> > + * @uri: (transfer none)(nullable): The #GstUri to modify.
> > + * @query_table: (transfer none)(nullable): The new query table to use.
> > 
> > Not sure if a GHashTable is ideal for this. Are the GI annotations to tell
> > about the key and value types?
> > 
> Yes, those detail the key and value types.

Ah yes, there's apparently "(element-type KTYPE VTYPE)". But you didn't add those. Can you add them? Otherwise I'll add that when merging :)

> > Maybe we need a GstUriQueryElement struct, and then here use a GList of
> > GPtrArray of them?
> > 
> I've left this as a GHashTable for now as I didn't want to reinvent a key/value
> pair type. I thought the hash table would be the best fit here as most of the
> time you'd want to lookup a query value string by it's key name, or insert
> key/value pairs. I couldn't see a situation where this structure wouldn't fit,
> so it seemed best. It maybe worth revisiting later.

Conceptionally it makes sense, yes. I was just worried about the bindings friendliness here :)
Comment 25 David Waring 2014-09-29 09:01:02 UTC
Created attachment 287328 [details] [review]
Patch to add GstUri class to libgstreamer (ver.5)

Fixed missing element-type annotation.
Comment 26 Sebastian Dröge (slomo) 2014-09-29 09:21:11 UTC
Thanks, merged :)

commit b9bf5d5ff22446cf00e0a9916772887095662543
Author: Sebastian Dröge <sebastian@centricular.com>
Date:   Mon Sep 29 12:19:35 2014 +0300

    uri: Fix memory leak in gst_uri_join()
    
    The merged path segments are a deep-copied list and we need to free the
    contained strings too instead of just the list nodes themselves.

commit 54c5f1855cfe87189ef2c32d74ffa9b3c40ed66d
Author: David Waring <david.waring@rd.bbc.co.uk>
Date:   Thu Jul 31 22:18:53 2014 +0100

    GstUri: Add GstUri miniobject to handle URIs in an RFC 3986 compliant fashion
    
    https://bugzilla.gnome.org/show_bug.cgi?id=725221
Comment 27 Marc-Andre Lureau 2015-02-19 13:44:47 UTC
I am looking at GUri branch proposed in bug 489862 compared to GstUri:

I wonder about usefulness of {get,set}_path_segments() and append_path*(), as well as all the query functions. Imho, g_uri_parse_params() was more flexible because it can be configured, and then you just manipulate the hashtable as usual.

(apparently, gst_uri_set_path() == gst_uri_set_path_string(), but I guess this is for consistency reasons
Comment 28 Sebastian Dröge (slomo) 2015-02-19 13:55:31 UTC
What's the timeline for GUri? Maybe it makes sense to make GstUri a renamed copy of GUri for consistency, and then at a later point once we depend on new enough glib just make it a wrapper around GUri.