[vlc-commits] url: add vlc_uri_compose()

Rémi Denis-Courmont git at videolan.org
Sun Jul 17 16:13:56 CEST 2016


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sun Jul 17 16:00:11 2016 +0300| [ed7d9c7e72bd841eb7048a44207abbd8d96db245] | committer: Rémi Denis-Courmont

url: add vlc_uri_compose()

This builds a string from a vlc_url_t structure.

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=ed7d9c7e72bd841eb7048a44207abbd8d96db245
---

 include/vlc_url.h  |   14 ++++++++++++
 src/libvlccore.sym |    1 +
 src/text/url.c     |   61 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 76 insertions(+)

diff --git a/include/vlc_url.h b/include/vlc_url.h
index 8fdd959..a013e2c 100644
--- a/include/vlc_url.h
+++ b/include/vlc_url.h
@@ -101,6 +101,20 @@ VLC_API char *vlc_uri_decode_duplicate(const char *str) VLC_MALLOC;
 VLC_API char *vlc_uri_encode(const char *str) VLC_MALLOC;
 
 /**
+ * Composes an URI.
+ *
+ * Converts a decomposed/parsed URI structure (\ref vlc_url_t) into a
+ * nul-terminated URI literal string.
+ *
+ * See also IETF RFC3986 section 5.3 for details.
+ *
+ * \bug URI fragments (i.e. HTML anchors) are not handled
+ *
+ * \return a heap-allocated nul-terminated string or NULL if out of memory
+ */
+VLC_API char *vlc_uri_compose(const vlc_url_t *) VLC_MALLOC;
+
+/**
  * Fixes up a URI string.
  *
  * Attempts to convert a nul-terminated string into a syntactically valid URI.
diff --git a/src/libvlccore.sym b/src/libvlccore.sym
index 249bb50..5511e51 100644
--- a/src/libvlccore.sym
+++ b/src/libvlccore.sym
@@ -252,6 +252,7 @@ vlc_uri2path
 vlc_uri_decode
 vlc_uri_decode_duplicate
 vlc_uri_encode
+vlc_uri_compose
 vlc_uri_fixup
 mdate
 module_config_free
diff --git a/src/text/url.c b/src/text/url.c
index f5f7ba6..643bfd3 100644
--- a/src/text/url.c
+++ b/src/text/url.c
@@ -492,6 +492,67 @@ void vlc_UrlClean (vlc_url_t *restrict url)
     free (url->psz_buffer);
 }
 
+char *vlc_uri_compose(const vlc_url_t *uri)
+{
+    char *buf, *enc;
+    size_t len;
+    FILE *stream = open_memstream(&buf, &len);
+
+    if (stream == NULL)
+        return NULL;
+
+    if (uri->psz_protocol != NULL)
+        fprintf(stream, "%s:", uri->psz_protocol);
+
+    if (uri->psz_host != NULL)
+    {
+        fwrite("//", 1, 2, stream);
+
+        if (uri->psz_username != NULL)
+        {
+            enc = vlc_uri_encode(uri->psz_username);
+            if (enc == NULL)
+                goto error;
+
+            fputs(enc, stream);
+            free(enc);
+
+            if (uri->psz_password != NULL)
+            {
+                enc = vlc_uri_encode(uri->psz_password);
+                if (unlikely(enc == NULL))
+                    goto error;
+
+                fprintf(stream, ":%s", enc);
+            }
+            fputc('@', stream);
+        }
+
+        const char *fmt;
+
+        if (strchr(uri->psz_host, ':') != NULL)
+            fmt = (uri->i_port != 0) ? "[%s]:%d" : "[%s]";
+        else
+            fmt = (uri->i_port != 0) ? "%s:%d" : "%s";
+        /* No IDNA decoding here. Seems unnecessary, dangerous even. */
+        fprintf(stream, fmt, uri->psz_host, uri->i_port);
+    }
+
+    if (uri->psz_path != NULL)
+        fputs(uri->psz_path, stream);
+    if (uri->psz_option != NULL)
+        fprintf(stream, "?%s", uri->psz_option);
+    /* NOTE: fragment not handled currently */
+
+    fclose(stream);
+    return buf;
+
+error:
+    fclose(stream);
+    free(buf);
+    return NULL;
+}
+
 char *vlc_uri_fixup(const char *str)
 {
     /* Rule number one is do not change a (potentially) valid URI */



More information about the vlc-commits mailing list