mirror of
https://github.com/moparisthebest/curl
synced 2024-12-23 08:38:49 -05:00
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>
This commit is contained in:
parent
07e61abdac
commit
d997aa0e96
@ -2367,6 +2367,14 @@ void Curl_http2_cleanup_dependencies(struct Curl_easy *data)
|
|||||||
Curl_http2_remove_child(data->set.stream_depends_on, 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 */
|
#else /* !USE_NGHTTP2 */
|
||||||
|
|
||||||
/* Satisfy external references even if http2 is not compiled in. */
|
/* Satisfy external references even if http2 is not compiled in. */
|
||||||
|
@ -59,6 +59,9 @@ CURLcode Curl_http2_add_child(struct Curl_easy *parent,
|
|||||||
void Curl_http2_remove_child(struct Curl_easy *parent,
|
void Curl_http2_remove_child(struct Curl_easy *parent,
|
||||||
struct Curl_easy *child);
|
struct Curl_easy *child);
|
||||||
void Curl_http2_cleanup_dependencies(struct Curl_easy *data);
|
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 */
|
#else /* USE_NGHTTP2 */
|
||||||
#define Curl_http2_init(x) CURLE_UNSUPPORTED_PROTOCOL
|
#define Curl_http2_init(x) CURLE_UNSUPPORTED_PROTOCOL
|
||||||
#define Curl_http2_send_request(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_add_child(x, y, z)
|
||||||
#define Curl_http2_remove_child(x, y)
|
#define Curl_http2_remove_child(x, y)
|
||||||
#define Curl_http2_cleanup_dependencies(x)
|
#define Curl_http2_cleanup_dependencies(x)
|
||||||
|
#define Curl_h2_http_1_1_error(x) 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* HEADER_CURL_HTTP2_H */
|
#endif /* HEADER_CURL_HTTP2_H */
|
||||||
|
20
lib/multi.c
20
lib/multi.c
@ -46,6 +46,7 @@
|
|||||||
#include "vtls/vtls.h"
|
#include "vtls/vtls.h"
|
||||||
#include "connect.h"
|
#include "connect.h"
|
||||||
#include "http_proxy.h"
|
#include "http_proxy.h"
|
||||||
|
#include "http2.h"
|
||||||
/* The last 3 #include files should be in this order */
|
/* The last 3 #include files should be in this order */
|
||||||
#include "curl_printf.h"
|
#include "curl_printf.h"
|
||||||
#include "curl_memory.h"
|
#include "curl_memory.h"
|
||||||
@ -1955,6 +1956,25 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
|||||||
done = TRUE;
|
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) {
|
if(result) {
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user