From b5bf0a1a87c4fc572a899234d63e1db3e2b0dafa Mon Sep 17 00:00:00 2001 From: Niklas Haas Date: Tue, 23 Jun 2026 18:36:59 +0200 Subject: [PATCH] avformat/hls: check if http protocol is native or not When using -prefer_libcurl, http might be served by libcurl instead of the native HTTP backend; in this case we shouldn't use `ff_http_do_new_request2` and instead create a new request. I added a few assertions to safeguard some of the assumptions this code clearly relies on. Sponsored-by: nxtedition AB Signed-off-by: Niklas Haas --- libavformat/hls.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/libavformat/hls.c b/libavformat/hls.c index 0e1a1ba49c..b4f4f035a9 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -661,6 +661,16 @@ static int ensure_playlist(HLSContext *c, struct playlist **pls, const char *url return 0; } +static int is_native_http(AVIOContext *pb) +{ +#if !CONFIG_HTTP_PROTOCOL + return 0; +#else + URLContext *uc = ffio_geturlcontext(pb); + return uc && !strncmp(uc->prot->name, "http", 4); +#endif +} + static int open_url_keepalive(AVFormatContext *s, AVIOContext **pb, const char *url, AVDictionary **options) { @@ -730,7 +740,7 @@ static int open_url(AVFormatContext *s, AVIOContext **pb, const char *url, av_dict_copy(&tmp, *opts, 0); av_dict_copy(&tmp, opts2, 0); - if (is_http && c->http_persistent && *pb) { + if (is_http && c->http_persistent && is_native_http(*pb)) { ret = open_url_keepalive(c->ctx, pb, url, &tmp); if (ret == AVERROR_EXIT) { av_dict_free(&tmp); @@ -745,6 +755,7 @@ static int open_url(AVFormatContext *s, AVIOContext **pb, const char *url, ret = s->io_open(s, pb, url, AVIO_FLAG_READ, &tmp); } } else { + av_assert0(!*pb); ret = s->io_open(s, pb, url, AVIO_FLAG_READ, &tmp); } if (ret >= 0) { @@ -862,7 +873,7 @@ static int parse_playlist(HLSContext *c, const char *url, if (ret < 0) return ret; - if (is_http && c->http_persistent) + if (is_http && c->http_persistent && is_native_http(in)) c->playlist_pb = in; else close_in = 1; @@ -1754,6 +1765,7 @@ static int read_data_continuous(void *opaque, uint8_t *buf, int buf_size) struct segment *seg; if (c->http_persistent && v->input_read_done) { + av_assert0(v->input); ret = reload_playlist(v, c); if (ret < 0) return ret; @@ -1855,7 +1867,7 @@ restart: * join the ranges. */ v->input_reuse = 1; v->input_read_done = 1; - } else if (c->http_persistent && + } else if (c->http_persistent && is_native_http(v->input) && seg->key_type == KEY_NONE && av_strstart(seg->url, "http", NULL)) { v->input_read_done = 1; } else {