diff options
author | Martin Storsjö <martin@martin.st> | 2011-11-07 11:06:50 +0200 |
---|---|---|
committer | Martin Storsjö <martin@martin.st> | 2013-09-26 23:13:16 +0300 |
commit | 5c53bf7aaf03748464cbf978bffe7ffdb71112b1 (patch) | |
tree | 235dc26fd08f1eaa032aed83a4a25799f74599d2 | |
parent | 8b09d917e7dc7d7f2ace31419f802d4ff518236c (diff) | |
download | ffmpeg-5c53bf7aaf03748464cbf978bffe7ffdb71112b1.tar.gz |
http: Pass options through to the nested protocol
When passing a dict to the nested protocol, it will consume
the used options from it, so a separate copy needs to be used
when reopening the connection multiple times.
Signed-off-by: Martin Storsjö <martin@martin.st>
-rw-r--r-- | libavformat/http.c | 34 |
1 files changed, 26 insertions, 8 deletions
diff --git a/libavformat/http.c b/libavformat/http.c index 10fcc50d12..57b9569863 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -67,6 +67,7 @@ typedef struct { z_stream inflate_stream; uint8_t *inflate_buffer; #endif + AVDictionary *chained_options; } HTTPContext; #define OFFSET(x) offsetof(HTTPContext, x) @@ -104,7 +105,7 @@ void ff_http_init_auth_state(URLContext *dest, const URLContext *src) } /* return non zero if error */ -static int http_open_cnx(URLContext *h) +static int http_open_cnx(URLContext *h, AVDictionary **options) { const char *path, *proxy_path, *lower_proto = "tcp", *local_path; char hostname[1024], hoststr[1024], proto[10]; @@ -155,7 +156,7 @@ static int http_open_cnx(URLContext *h) if (!s->hd) { err = ffurl_open(&s->hd, buf, AVIO_FLAG_READ_WRITE, - &h->interrupt_callback, NULL); + &h->interrupt_callback, options); if (err < 0) goto fail; } @@ -208,21 +209,30 @@ static int http_open_cnx(URLContext *h) int ff_http_do_new_request(URLContext *h, const char *uri) { HTTPContext *s = h->priv_data; + AVDictionary *options = NULL; + int ret; s->off = 0; av_strlcpy(s->location, uri, sizeof(s->location)); - return http_open_cnx(h); + av_dict_copy(&options, s->chained_options, 0); + ret = http_open_cnx(h, &options); + av_dict_free(&options); + return ret; } -static int http_open(URLContext *h, const char *uri, int flags) +static int http_open(URLContext *h, const char *uri, int flags, + AVDictionary **options) { HTTPContext *s = h->priv_data; + int ret; h->is_streamed = 1; s->filesize = -1; av_strlcpy(s->location, uri, sizeof(s->location)); + if (options) + av_dict_copy(&s->chained_options, *options, 0); if (s->headers) { int len = strlen(s->headers); @@ -230,7 +240,10 @@ static int http_open(URLContext *h, const char *uri, int flags) av_log(h, AV_LOG_WARNING, "No trailing CRLF found in HTTP header.\n"); } - return http_open_cnx(h); + ret = http_open_cnx(h, options); + if (ret < 0) + av_dict_free(&s->chained_options); + return ret; } static int http_getc(HTTPContext *s) { @@ -676,6 +689,7 @@ static int http_close(URLContext *h) if (s->hd) ffurl_close(s->hd); + av_dict_free(&s->chained_options); return ret; } @@ -686,6 +700,7 @@ static int64_t http_seek(URLContext *h, int64_t off, int whence) int64_t old_off = s->off; uint8_t old_buf[BUFFER_SIZE]; int old_buf_size; + AVDictionary *options = NULL; if (whence == AVSEEK_SIZE) return s->filesize; @@ -703,7 +718,9 @@ static int64_t http_seek(URLContext *h, int64_t off, int whence) s->off = off; /* if it fails, continue on old connection */ - if (http_open_cnx(h) < 0) { + av_dict_copy(&options, s->chained_options, 0); + if (http_open_cnx(h, &options) < 0) { + av_dict_free(&options); memcpy(s->buffer, old_buf, old_buf_size); s->buf_ptr = s->buffer; s->buf_end = s->buffer + old_buf_size; @@ -711,6 +728,7 @@ static int64_t http_seek(URLContext *h, int64_t off, int whence) s->off = old_off; return -1; } + av_dict_free(&options); ffurl_close(old_hd); return off; } @@ -725,7 +743,7 @@ http_get_file_handle(URLContext *h) #if CONFIG_HTTP_PROTOCOL URLProtocol ff_http_protocol = { .name = "http", - .url_open = http_open, + .url_open2 = http_open, .url_read = http_read, .url_write = http_write, .url_seek = http_seek, @@ -740,7 +758,7 @@ URLProtocol ff_http_protocol = { #if CONFIG_HTTPS_PROTOCOL URLProtocol ff_https_protocol = { .name = "https", - .url_open = http_open, + .url_open2 = http_open, .url_read = http_read, .url_write = http_write, .url_seek = http_seek, |