summaryrefslogtreecommitdiff
path: root/libavformat/http.c
diff options
context:
space:
mode:
Diffstat (limited to 'libavformat/http.c')
-rw-r--r--libavformat/http.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/libavformat/http.c b/libavformat/http.c
index 91650be47a..4415a26f2c 100644
--- a/libavformat/http.c
+++ b/libavformat/http.c
@@ -69,7 +69,9 @@ typedef struct HTTPContext {
uint64_t chunksize;
int chunkend;
uint64_t off, end_off, filesize;
+ char *uri;
char *location;
+ int cache_redirect;
HTTPAuthState auth_state;
HTTPAuthState proxy_auth_state;
char *http_proxy;
@@ -169,6 +171,7 @@ static const AVOption options[] = {
{ "resource", "The resource requested by a client", OFFSET(resource), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, E },
{ "reply_code", "The http status code to return to a client", OFFSET(reply_code), AV_OPT_TYPE_INT, { .i64 = 200}, INT_MIN, 599, E},
{ "short_seek_size", "Threshold to favor readahead over seek.", OFFSET(short_seek_size), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, D },
+ { "cache_redirect", "Save redirected URL for subsequent seek operations", OFFSET(cache_redirect), AV_OPT_TYPE_BOOL, { .i64 = FF_HTTP_CACHE_REDIRECT_DEFAULT }, 0, 1, D },
{ NULL }
};
@@ -432,11 +435,17 @@ int ff_http_do_new_request2(URLContext *h, const char *uri, AVDictionary **opts)
s->chunkend = 0;
s->off = 0;
s->icy_data_read = 0;
+
av_free(s->location);
s->location = av_strdup(uri);
if (!s->location)
return AVERROR(ENOMEM);
+ av_free(s->uri);
+ s->uri = av_strdup(uri);
+ if (!s->uri)
+ return AVERROR(ENOMEM);
+
if ((ret = av_opt_set_dict(s, opts)) < 0)
return ret;
@@ -623,9 +632,15 @@ static int http_open(URLContext *h, const char *uri, int flags,
h->is_streamed = 1;
s->filesize = UINT64_MAX;
+
s->location = av_strdup(uri);
if (!s->location)
return AVERROR(ENOMEM);
+
+ s->uri = av_strdup(uri);
+ if (!s->uri)
+ return AVERROR(ENOMEM);
+
if (options)
av_dict_copy(&s->chained_options, *options, 0);
@@ -651,6 +666,7 @@ bail_out:
if (ret < 0) {
av_dict_free(&s->chained_options);
av_dict_free(&s->cookie_dict);
+ av_freep(&s->uri);
}
return ret;
}
@@ -1769,6 +1785,7 @@ static int http_close(URLContext *h)
ffurl_closep(&s->hd);
av_dict_free(&s->chained_options);
av_dict_free(&s->cookie_dict);
+ av_freep(&s->uri);
return ret;
}
@@ -1810,6 +1827,16 @@ static int64_t http_seek_internal(URLContext *h, int64_t off, int whence, int fo
return s->off;
}
+ /* if redirect caching is disabled, revert to the original uri */
+ if (!s->cache_redirect && strcmp(s->uri, s->location)) {
+ char *new_uri;
+ new_uri = av_strdup(s->uri);
+ if (!new_uri)
+ return AVERROR(ENOMEM);
+ av_free(s->location);
+ s->location = new_uri;
+ }
+
/* we save the old context in case the seek fails */
old_buf_size = s->buf_end - s->buf_ptr;
memcpy(old_buf, s->buf_ptr, old_buf_size);