[vlc-devel] [PATCH 03/48] hls: Fix relative url
Jean-Paul Saman
jpsaman at videolan.org
Tue Jan 10 11:16:54 CET 2012
Please provide a test sample that needs this patch to work.
Kind regards,
Jean-Paul Saman
On Mon, Jan 9, 2012 at 4:16 PM, Hugo Beauzée-Luyssen <beauze.h at gmail.com> wrote:
> 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
>
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> http://mailman.videolan.org/listinfo/vlc-devel
More information about the vlc-devel
mailing list