char *http_proxy;
char *headers;
char *mime_type;
+ char *http_version;
char *user_agent;
#if FF_API_HTTP_USER_AGENT
char *user_agent_deprecated;
{ "multiple_requests", "use persistent connections", OFFSET(multiple_requests), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, D | E },
{ "post_data", "set custom HTTP post data", OFFSET(post_data), AV_OPT_TYPE_BINARY, .flags = D | E },
{ "mime_type", "export the MIME type", OFFSET(mime_type), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, AV_OPT_FLAG_EXPORT | AV_OPT_FLAG_READONLY },
+ { "http_version", "export the http response version", OFFSET(http_version), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, AV_OPT_FLAG_EXPORT | AV_OPT_FLAG_READONLY },
{ "cookies", "set cookies to be sent in applicable future requests, use newline delimited Set-Cookie HTTP field value syntax", OFFSET(cookies), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, D },
{ "icy", "request ICY metadata", OFFSET(icy), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, D },
{ "icy_metadata_headers", "return ICY metadata headers", OFFSET(icy_metadata_headers), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, AV_OPT_FLAG_EXPORT },
const char *hoststr, const char *auth,
const char *proxyauth, int *new_location);
static int http_read_header(URLContext *h, int *new_location);
+static int http_shutdown(URLContext *h, int flags);
void ff_http_init_auth_state(URLContext *dest, const URLContext *src)
{
HTTPContext *s = h->priv_data;
AVDictionary *options = NULL;
int ret;
+ char hostname1[1024], hostname2[1024], proto1[10], proto2[10];
+ int port1, port2;
+ if (!h->prot ||
+ !(!strcmp(h->prot->name, "http") ||
+ !strcmp(h->prot->name, "https")))
+ return AVERROR(EINVAL);
+
+ av_url_split(proto1, sizeof(proto1), NULL, 0,
+ hostname1, sizeof(hostname1), &port1,
+ NULL, 0, s->location);
+ av_url_split(proto2, sizeof(proto2), NULL, 0,
+ hostname2, sizeof(hostname2), &port2,
+ NULL, 0, uri);
+ if (port1 != port2 || strncmp(hostname1, hostname2, sizeof(hostname2)) != 0) {
+ av_log(h, AV_LOG_ERROR, "Cannot reuse HTTP connection for different host: %s:%d != %s:%d\n",
+ hostname1, port1,
+ hostname2, port2
+ );
+ return AVERROR(EINVAL);
+ }
+
+ if (!s->end_chunked_post) {
+ ret = http_shutdown(h, h->flags);
+ if (ret < 0)
+ return ret;
+ }
+
+ if (s->willclose)
+ return AVERROR_EOF;
+
+ s->end_chunked_post = 0;
s->chunkend = 0;
s->off = 0;
s->icy_data_read = 0;
if (!s->location)
return AVERROR(ENOMEM);
+ av_log(s, AV_LOG_INFO, "Opening \'%s\' for %s\n", uri, h->flags & AVIO_FLAG_WRITE ? "writing" : "reading");
ret = http_open_cnx(h, &options);
av_dict_free(&options);
return ret;
}
av_log(h, AV_LOG_TRACE, "HTTP version string: %s\n", version);
} else {
+ if (av_strncasecmp(p, "HTTP/1.0", 8) == 0)
+ s->willclose = 1;
+ while (*p != '/' && *p != '\0')
+ p++;
+ while (*p == '/')
+ p++;
+ av_freep(&s->http_version);
+ s->http_version = av_strndup(p, 3);
while (!av_isspace(*p) && *p != '\0')
p++;
while (av_isspace(*p))