[vlc-devel] [PATCH 03/48] hls: Fix relative url

Hugo Beauzée-Luyssen beauze.h at gmail.com
Mon Jan 9 16:16:12 CET 2012


From: Luc Saillard <luc.saillard at sfr.com>

Don't add current directory, when the url is relative to the root server
---
 modules/stream_filter/httplive.c |  142 ++++++++++++++------------------------
 1 files changed, 53 insertions(+), 89 deletions(-)

diff --git a/modules/stream_filter/httplive.c b/modules/stream_filter/httplive.c
index 20e2821..f7aeab1 100644
--- a/modules/stream_filter/httplive.c
+++ b/modules/stream_filter/httplive.c
@@ -89,7 +89,7 @@ typedef struct hls_stream_s
 
 struct stream_sys_t
 {
-    vlc_url_t     m3u8;         /* M3U8 url */
+    char         *m3u8_playlist;/* M3U8 url */
     vlc_thread_t  reload;       /* HLS m3u8 reload thread */
     vlc_thread_t  thread;       /* HLS segment download thread */
 
@@ -139,8 +139,8 @@ static int  Read   (stream_t *, void *p_read, unsigned int i_read);
 static int  Peek   (stream_t *, const uint8_t **pp_peek, unsigned int i_peek);
 static int  Control(stream_t *, int i_query, va_list);
 
-static ssize_t read_M3U8_from_stream(stream_t *s, uint8_t **buffer);
-static ssize_t read_M3U8_from_url(stream_t *s, vlc_url_t *url, uint8_t **buffer);
+static ssize_t read_M3U8(stream_t *s, const char *psz_url, uint8_t **buffer);
+static ssize_t ReadM3U8(stream_t *s, uint8_t **buffer);
 static char *ReadLine(uint8_t *buffer, uint8_t **pos, size_t len);
 
 static int hls_Download(stream_t *s, segment_t *segment);
@@ -461,46 +461,52 @@ static char *parse_Attributes(const char *line, const char *attr)
     return NULL;
 }
 
-static char *relative_URI(stream_t *s, const char *uri, const char *path)
+/*
+ * Return an uri, that must be free with free().
+ */
+static char *relative_URI(const char *uri, const char *parent_uri)
 {
-    stream_sys_t *p_sys = s->p_sys;
+    char *p;
+    char *parent_uri_base;
+    char *new_uri;
 
-    char *p = strchr(uri, ':');
+    /* is address absolute (aka http://xxxx) ? */
+    p = strstr(uri, "://");
     if (p != NULL)
-        return NULL;
-
-    if (p_sys->m3u8.psz_path == NULL)
-        return NULL;
+      return strdup(uri);
 
-    char *psz_path = strdup(p_sys->m3u8.psz_path);
-    if (psz_path == NULL) return NULL;
-    p = strrchr(psz_path, '/');
-    if (p) *p = '\0';
-
-    char *psz_uri = NULL;
-    if (p_sys->m3u8.psz_password || p_sys->m3u8.psz_username)
+    if (*uri == '/')
     {
-        if (asprintf(&psz_uri, "%s://%s:%s@%s:%d%s/%s", p_sys->m3u8.psz_protocol,
-                     p_sys->m3u8.psz_username, p_sys->m3u8.psz_password,
-                     p_sys->m3u8.psz_host, p_sys->m3u8.i_port,
-                     path ? path : psz_path, uri) < 0)
-            goto fail;
+        /* This url is relative to the root of the server */
+        parent_uri_base = strdup(parent_uri);
+        p = strstr(parent_uri_base, "://");
+        if (p)
+        {
+            p = strchr(p+3, '/');
+            if (p)
+                *p = 0;
+        }
     }
     else
     {
-        if (asprintf(&psz_uri, "%s://%s:%d%s/%s", p_sys->m3u8.psz_protocol,
-                     p_sys->m3u8.psz_host, p_sys->m3u8.i_port,
-                     path ? path : psz_path, uri) < 0)
-           goto fail;
+        /* This url is relative to the current dir of the server */
+        parent_uri_base = strdup(parent_uri);
+        p = strrchr(parent_uri_base, '/');
+        if (p)
+            p[1] = 0;
     }
-    free(psz_path);
-    return psz_uri;
 
-fail:
-    free(psz_path);
-    return NULL;
+    if (asprintf(&new_uri, "%s%s", parent_uri_base, uri) < 0)
+    {
+        free(parent_uri_base);
+        return NULL;
+    }
+
+    free(parent_uri_base);
+    return new_uri;
 }
 
+
 static char *ConstructUrl(vlc_url_t *url)
 {
     if ((url->psz_protocol == NULL) ||
@@ -586,18 +592,7 @@ static int parse_AddSegment(stream_t *s, hls_stream_t *hls, const int duration,
     assert(hls);
     assert(uri);
 
-    /* Store segment information */
-    char *psz_path = NULL;
-    if (hls->url.psz_path != NULL)
-    {
-        psz_path = strdup(hls->url.psz_path);
-        if (psz_path == NULL)
-            return VLC_ENOMEM;
-        char *p = strrchr(psz_path, '/');
-        if (p) *p = '\0';
-    }
-    char *psz_uri = relative_URI(s, uri, psz_path);
-    free(psz_path);
+    char *psz_uri = relative_URI(uri, hls->uri);
 
     vlc_mutex_lock(&hls->lock);
     segment_t *segment = segment_New(hls, duration, psz_uri ? psz_uri : uri);
@@ -661,7 +656,7 @@ static int parse_StreamInformation(stream_t *s, vlc_array_t **hls_stream,
 
     msg_Info(s, "bandwidth adaptation detected (program-id=%d, bandwidth=%"PRIu64").", id, bw);
 
-    char *psz_uri = relative_URI(s, uri, NULL);
+    char *psz_uri = relative_URI(uri, s->p_sys->m3u8_playlist);
 
     *hls = hls_New(*hls_stream, id, bw, psz_uri ? psz_uri : uri);
 
@@ -893,7 +888,7 @@ static int parse_M3U8(stream_t *s, vlc_array_t *streams, uint8_t *buffer, const
 
                     /* Download playlist file from server */
                     uint8_t *buf = NULL;
-                    ssize_t len = read_M3U8_from_url(s, &hls->url, &buf);
+                    ssize_t len = read_M3U8(s, hls->url, &buf);
                     if (len < 0)
                         err = VLC_EGENERIC;
                     else
@@ -1007,43 +1002,17 @@ static int get_HTTPLiveMetaPlaylist(stream_t *s, vlc_array_t **streams)
 {
     stream_sys_t *p_sys = s->p_sys;
     assert(*streams);
-    int err = VLC_EGENERIC;
-
-    /* Duplicate HLS stream META information */
-    for (int i = 0; i < vlc_array_count(p_sys->hls_stream); i++)
-    {
-        hls_stream_t *src, *dst;
-        src = (hls_stream_t *)vlc_array_item_at_index(p_sys->hls_stream, i);
-        if (src == NULL)
-            return VLC_EGENERIC;
-
-        dst = hls_Copy(src, false);
-        if (dst == NULL)
-            return VLC_ENOMEM;
-
-        vlc_array_append(*streams, dst);
-    }
+    int     err = VLC_SUCCESS;
 
     /* Download new playlist file from server */
-    for (int i = 0; i < vlc_array_count(*streams); i++)
-    {
-        hls_stream_t *hls;
-        hls = (hls_stream_t *)vlc_array_item_at_index(*streams, i);
-        if (hls == NULL)
-            return VLC_EGENERIC;
+    uint8_t *buffer = NULL;
+    ssize_t len = read_M3U8(s, p_sys->m3u8_playlist, &buffer);
+    if (len < 0)
+        return VLC_EGENERIC;
+
+    err = parse_M3U8(s, *streams, buffer, len);
+    free(buffer);
 
-        /* Download playlist file from server */
-        uint8_t *buf = NULL;
-        ssize_t len = read_M3U8_from_url(s, &hls->url, &buf);
-        if (len < 0)
-            err = VLC_EGENERIC;
-        else
-        {
-            /* Parse HLS m3u8 content. */
-            err = parse_M3U8(s, *streams, buf, len);
-            free(buf);
-        }
-    }
     return err;
 }
 
@@ -1530,7 +1499,6 @@ static int hls_Download(stream_t *s, segment_t *segment)
     return VLC_SUCCESS;
 }
 
-/* Read M3U8 file */
 static ssize_t read_M3U8_from_stream(stream_t *s, uint8_t **buffer)
 {
     int64_t total_bytes = 0;
@@ -1642,14 +1610,12 @@ static int Open(vlc_object_t *p_this)
     if (p_sys == NULL)
         return VLC_ENOMEM;
 
-    char *psz_uri = NULL;
-    if (asprintf(&psz_uri,"%s://%s", s->psz_access, s->psz_path) < 0)
+    p_sys->m3u8_playlist = NULL;
+    if (asprintf(&p_sys->m3u8_playlist,"%s://%s", s->psz_access, s->psz_path) < 0)
     {
         free(p_sys);
         return VLC_ENOMEM;
     }
-    vlc_UrlParse(&p_sys->m3u8, psz_uri, 0);
-    free(psz_uri);
 
     p_sys->bandwidth = 0;
     p_sys->b_live = true;
@@ -1659,7 +1625,7 @@ static int Open(vlc_object_t *p_this)
     p_sys->hls_stream = vlc_array_new();
     if (p_sys->hls_stream == NULL)
     {
-        vlc_UrlClean(&p_sys->m3u8);
+        free(p_sys->m3u8_playlist);
         free(p_sys);
         return VLC_ENOMEM;
     }
@@ -1742,7 +1708,7 @@ fail:
     vlc_array_destroy(p_sys->hls_stream);
 
     /* */
-    vlc_UrlClean(&p_sys->m3u8);
+    free(p_sys->m3u8_playlist);
     free(p_sys);
     return VLC_EGENERIC;
 }
@@ -1779,9 +1745,7 @@ static void Close(vlc_object_t *p_this)
     vlc_array_destroy(p_sys->hls_stream);
 
     /* */
-    vlc_UrlClean(&p_sys->m3u8);
-    if (p_sys->peeked)
-        block_Release (p_sys->peeked);
+    free(p_sys->m3u8_playlist);
     free(p_sys);
 }
 
-- 
1.7.8.3




More information about the vlc-devel mailing list