Commit e744cca5 authored by Jean-Paul Saman's avatar Jean-Paul Saman Committed by Jean-Baptiste Kempf

stream_filter/httplive.c: Rewrite relativeURL (fix #4268)

The relativeURL function missed various checks to determine the correct
location for the next download. Checking not only the meta playlist locations,
but also the HLS playlist locations itself should fix #4268.
(cherry picked from commit 5de5d154)
Signed-off-by: default avatarJean-Baptiste Kempf <jb@videolan.org>
parent 1e39f64c
...@@ -460,44 +460,90 @@ static char *parse_Attributes(const char *line, const char *attr) ...@@ -460,44 +460,90 @@ static char *parse_Attributes(const char *line, const char *attr)
return NULL; return NULL;
} }
static char *relative_URI(stream_t *s, const char *uri, const char *path) static char *relative_URI(stream_t *s, const char *uri, const vlc_url_t *url)
{ {
stream_sys_t *p_sys = s->p_sys; stream_sys_t *p_sys = s->p_sys;
char *psz_password = NULL;
char *psz_username = NULL;
char *psz_protocol = NULL;
char *psz_path = NULL;
char *psz_host = NULL;
char *psz_uri = NULL;
int i_port = -1;
char *p = strchr(uri, ':'); char *p = strchr(uri, ':');
if (p != NULL) if (p != NULL)
return NULL; return NULL;
if (p_sys->m3u8.psz_path == NULL) /* Determine protocol to use */
return NULL; if (url && url->psz_protocol)
{
psz_protocol = strdup(url->psz_protocol);
i_port = url->i_port;
}
else if (p_sys->m3u8.psz_protocol)
{
psz_protocol = strdup(p_sys->m3u8.psz_protocol);
i_port = p_sys->m3u8.i_port;
}
/* Determine host to use */
if (url && url->psz_host)
psz_host = strdup(url->psz_host);
else if (p_sys->m3u8.psz_host)
psz_host = strdup(p_sys->m3u8.psz_host);
/* Determine path to use */
if (url && url->psz_path != NULL)
psz_path = strdup(url->psz_path);
else if (p_sys->m3u8.psz_path != NULL)
psz_path = strdup(p_sys->m3u8.psz_path);
if ((psz_protocol == NULL) ||
(psz_path == NULL) ||
(psz_host == NULL))
goto fail;
char *psz_path = strdup(p_sys->m3u8.psz_path);
if (psz_path == NULL) return NULL;
p = strrchr(psz_path, '/'); p = strrchr(psz_path, '/');
if (p) *p = '\0'; if (p) *p = '\0';
char *psz_uri = NULL; /* Determine credentials to use */
if (p_sys->m3u8.psz_password || p_sys->m3u8.psz_username) if (url && url->psz_username)
{ psz_username = strdup(url->psz_username);
if (asprintf(&psz_uri, "%s://%s:%s@%s:%d%s/%s", p_sys->m3u8.psz_protocol, else if (p_sys->m3u8.psz_username)
p_sys->m3u8.psz_username, p_sys->m3u8.psz_password, psz_username = strdup(p_sys->m3u8.psz_username);
p_sys->m3u8.psz_host, p_sys->m3u8.i_port,
path ? path : psz_path, uri) < 0) if (url && url->psz_password)
psz_password = strdup(url->psz_password);
else if (p_sys->m3u8.psz_password)
psz_password = strdup(p_sys->m3u8.psz_password);
/* */
if (psz_password || psz_username)
{
if (asprintf(&psz_uri, "%s://%s:%s@%s:%d%s/%s",
psz_protocol,
psz_username ? psz_username : "",
psz_password ? psz_password : "",
psz_host, i_port,
psz_path, uri) < 0)
goto fail; goto fail;
} }
else else
{ {
if (asprintf(&psz_uri, "%s://%s:%d%s/%s", p_sys->m3u8.psz_protocol, if (asprintf(&psz_uri, "%s://%s:%d%s/%s",
p_sys->m3u8.psz_host, p_sys->m3u8.i_port, psz_protocol, psz_host, i_port,
path ? path : psz_path, uri) < 0) psz_path, uri) < 0)
goto fail; goto fail;
} }
free(psz_path);
return psz_uri;
fail: fail:
free(psz_password);
free(psz_username);
free(psz_protocol);
free(psz_path); free(psz_path);
return NULL; free(psz_host);
return psz_uri;
} }
static char *ConstructUrl(vlc_url_t *url) static char *ConstructUrl(vlc_url_t *url)
...@@ -586,25 +632,17 @@ static int parse_AddSegment(stream_t *s, hls_stream_t *hls, const int duration, ...@@ -586,25 +632,17 @@ static int parse_AddSegment(stream_t *s, hls_stream_t *hls, const int duration,
assert(uri); assert(uri);
/* Store segment information */ /* 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);
vlc_mutex_lock(&hls->lock); vlc_mutex_lock(&hls->lock);
char *psz_uri = relative_URI(s, uri, &hls->url);
segment_t *segment = segment_New(hls, duration, psz_uri ? psz_uri : uri); segment_t *segment = segment_New(hls, duration, psz_uri ? psz_uri : uri);
if (segment) if (segment)
segment->sequence = hls->sequence + vlc_array_count(hls->segments) - 1; segment->sequence = hls->sequence + vlc_array_count(hls->segments) - 1;
free(psz_uri);
vlc_mutex_unlock(&hls->lock); vlc_mutex_unlock(&hls->lock);
free(psz_uri);
return segment ? VLC_SUCCESS : VLC_ENOMEM; return segment ? VLC_SUCCESS : VLC_ENOMEM;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment