http: Pass options through to the nested protocol
authorMartin Storsjö <martin@martin.st>
Mon, 7 Nov 2011 09:06:50 +0000 (11:06 +0200)
committerMartin Storsjö <martin@martin.st>
Thu, 26 Sep 2013 20:13:16 +0000 (23:13 +0300)
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>
libavformat/http.c

index 10fcc50..57b9569 100644 (file)
@@ -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,