diff options
author | Johannes Schindelin <johannes.schindelin@gmx.de> | 2018-12-07 17:04:39 +0100 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2018-12-08 10:59:23 +0100 |
commit | d997aa0e963c5be5de100dccdc5208d39bd3d62b (patch) | |
tree | f8b002f3eefc58c89bd176c17ef39fc7270565ac | |
parent | 07e61abdac949dda7ff8ab152ed6eb8854db8484 (diff) | |
download | curl-d997aa0e963c5be5de100dccdc5208d39bd3d62b.tar.gz |
Upon HTTP_1_1_REQUIRED, retry the request with HTTP/1.1
This is a companion patch to cbea2fd2c (NTLM: force the connection to
HTTP/1.1, 2018-12-06): with NTLM, we can switch to HTTP/1.1
preemptively. However, with other (Negotiate) authentication it is not
clear to this developer whether there is a way to make it work with
HTTP/2, so let's try HTTP/2 first and fall back in case we encounter the
error HTTP_1_1_REQUIRED.
Note: we will still keep the NTLM workaround, as it avoids an extra
round trip.
Daniel Stenberg helped a lot with this patch, in particular by
suggesting to introduce the Curl_h2_http_1_1_error() function.
Closes #3349
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
-rw-r--r-- | lib/http2.c | 8 | ||||
-rw-r--r-- | lib/http2.h | 4 | ||||
-rw-r--r-- | lib/multi.c | 20 |
3 files changed, 32 insertions, 0 deletions
diff --git a/lib/http2.c b/lib/http2.c index c33bee3eb..a61d8c240 100644 --- a/lib/http2.c +++ b/lib/http2.c @@ -2367,6 +2367,14 @@ void Curl_http2_cleanup_dependencies(struct Curl_easy *data) Curl_http2_remove_child(data->set.stream_depends_on, data); } +/* Only call this function for a transfer that already got a HTTP/2 + CURLE_HTTP2_STREAM error! */ +bool Curl_h2_http_1_1_error(struct connectdata *conn) +{ + struct http_conn *httpc = &conn->proto.httpc; + return (httpc->error_code == NGHTTP2_HTTP_1_1_REQUIRED); +} + #else /* !USE_NGHTTP2 */ /* Satisfy external references even if http2 is not compiled in. */ diff --git a/lib/http2.h b/lib/http2.h index 4492ec211..67db3dffb 100644 --- a/lib/http2.h +++ b/lib/http2.h @@ -59,6 +59,9 @@ CURLcode Curl_http2_add_child(struct Curl_easy *parent, void Curl_http2_remove_child(struct Curl_easy *parent, struct Curl_easy *child); void Curl_http2_cleanup_dependencies(struct Curl_easy *data); + +/* returns true if the HTTP/2 stream error was HTTP_1_1_REQUIRED */ +bool Curl_h2_http_1_1_error(struct connectdata *conn); #else /* USE_NGHTTP2 */ #define Curl_http2_init(x) CURLE_UNSUPPORTED_PROTOCOL #define Curl_http2_send_request(x) CURLE_UNSUPPORTED_PROTOCOL @@ -74,6 +77,7 @@ void Curl_http2_cleanup_dependencies(struct Curl_easy *data); #define Curl_http2_add_child(x, y, z) #define Curl_http2_remove_child(x, y) #define Curl_http2_cleanup_dependencies(x) +#define Curl_h2_http_1_1_error(x) 0 #endif #endif /* HEADER_CURL_HTTP2_H */ diff --git a/lib/multi.c b/lib/multi.c index cca138005..4ba22c46e 100644 --- a/lib/multi.c +++ b/lib/multi.c @@ -46,6 +46,7 @@ #include "vtls/vtls.h" #include "connect.h" #include "http_proxy.h" +#include "http2.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" #include "curl_memory.h" @@ -1955,6 +1956,25 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, done = TRUE; } } + else if((CURLE_HTTP2_STREAM == result) && + Curl_h2_http_1_1_error(data->easy_conn)) { + CURLcode ret = Curl_retry_request(data->easy_conn, &newurl); + + infof(data, "Forcing HTTP/1.1 for NTLM"); + data->set.httpversion = CURL_HTTP_VERSION_1_1; + + if(!ret) + retry = (newurl)?TRUE:FALSE; + else + result = ret; + + if(retry) { + /* if we are to retry, set the result to OK and consider the + request as done */ + result = CURLE_OK; + done = TRUE; + } + } if(result) { /* |