diff --git a/doc/protocols.texi b/doc/protocols.texi index f0fd344ce9..e1caa049a5 100644 --- a/doc/protocols.texi +++ b/doc/protocols.texi @@ -385,6 +385,11 @@ ffmpeg -i somefile.ogg -chunked_post 0 -c copy -f ogg http://@var{server}:@var{p wget --post-file=somefile.ogg http://@var{server}:@var{port} @end example +@item send_expect_100 +Send an Expect: 100-continue header for POST. If set to 1 it will send, if set +to 0 it won't, if set to -1 it will try to send if it is applicable. Default +value is -1. + @end table @subsection HTTP Cookies diff --git a/libavformat/http.c b/libavformat/http.c index 74d743850d..5a937994cf 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -113,6 +113,7 @@ typedef struct HTTPContext { uint8_t *inflate_buffer; #endif /* CONFIG_ZLIB */ AVDictionary *chained_options; + /* -1 = try to send if applicable, 0 = always disabled, 1 = always enabled */ int send_expect_100; char *method; int reconnect; @@ -155,7 +156,7 @@ static const AVOption options[] = { { "auth_type", "HTTP authentication type", OFFSET(auth_state.auth_type), AV_OPT_TYPE_INT, { .i64 = HTTP_AUTH_NONE }, HTTP_AUTH_NONE, HTTP_AUTH_BASIC, D | E, "auth_type"}, { "none", "No auth method set, autodetect", 0, AV_OPT_TYPE_CONST, { .i64 = HTTP_AUTH_NONE }, 0, 0, D | E, "auth_type"}, { "basic", "HTTP basic authentication", 0, AV_OPT_TYPE_CONST, { .i64 = HTTP_AUTH_BASIC }, 0, 0, D | E, "auth_type"}, - { "send_expect_100", "Force sending an Expect: 100-continue header for POST", OFFSET(send_expect_100), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E }, + { "send_expect_100", "Force sending an Expect: 100-continue header for POST", OFFSET(send_expect_100), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, E }, { "location", "The actual location of the data received", OFFSET(location), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, D | E }, { "offset", "initial byte offset", OFFSET(off), AV_OPT_TYPE_INT64, { .i64 = 0 }, 0, INT64_MAX, D }, { "end_offset", "try to limit the request to bytes preceding this offset", OFFSET(end_off), AV_OPT_TYPE_INT64, { .i64 = 0 }, 0, INT64_MAX, D }, @@ -1179,16 +1180,21 @@ static int http_connect(URLContext *h, const char *path, const char *local_path, local_path, method); proxyauthstr = ff_http_auth_create_response(&s->proxy_auth_state, proxyauth, local_path, method); - if (post && !s->post_data) { - send_expect_100 = s->send_expect_100; - /* The user has supplied authentication but we don't know the auth type, - * send Expect: 100-continue to get the 401 response including the - * WWW-Authenticate header, or an 100 continue if no auth actually - * is needed. */ - if (auth && *auth && - s->auth_state.auth_type == HTTP_AUTH_NONE && - s->http_code != 401) - send_expect_100 = 1; + + if (post && !s->post_data) { + if (s->send_expect_100 != -1) { + send_expect_100 = s->send_expect_100; + } else { + send_expect_100 = 0; + /* The user has supplied authentication but we don't know the auth type, + * send Expect: 100-continue to get the 401 response including the + * WWW-Authenticate header, or an 100 continue if no auth actually + * is needed. */ + if (auth && *auth && + s->auth_state.auth_type == HTTP_AUTH_NONE && + s->http_code != 401) + send_expect_100 = 1; + } } #if FF_API_HTTP_USER_AGENT diff --git a/libavformat/icecast.c b/libavformat/icecast.c index c93b06b553..d2198b78ec 100644 --- a/libavformat/icecast.c +++ b/libavformat/icecast.c @@ -115,7 +115,7 @@ static int icecast_open(URLContext *h, const char *uri, int flags) av_dict_set(&opt_dict, "auth_type", "basic", 0); av_dict_set(&opt_dict, "headers", headers, 0); av_dict_set(&opt_dict, "chunked_post", "0", 0); - av_dict_set(&opt_dict, "send_expect_100", s->legacy_icecast ? "0" : "1", 0); + av_dict_set(&opt_dict, "send_expect_100", s->legacy_icecast ? "-1" : "1", 0); if (NOT_EMPTY(s->content_type)) av_dict_set(&opt_dict, "content_type", s->content_type, 0); else diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c index 4661654967..033095905d 100644 --- a/libavformat/rtsp.c +++ b/libavformat/rtsp.c @@ -1797,6 +1797,7 @@ redirect: sessioncookie); av_opt_set(rt->rtsp_hd_out->priv_data, "headers", headers, 0); av_opt_set(rt->rtsp_hd_out->priv_data, "chunked_post", "0", 0); + av_opt_set(rt->rtsp_hd_out->priv_data, "send_expect_100", "0", 0); /* Initialize the authentication state for the POST session. The HTTP * protocol implementation doesn't properly handle multi-pass