mirror of
https://github.com/curl/curl.git
synced 2024-12-15 06:40:09 +08:00
urldata: don't touch data->set.httpversion at run-time
Rename it to 'httpwant' and make a cloned field in the state struct as well for run-time updates. Also: refuse non-supported HTTP versions. Verified with test 129. Closes #6585
This commit is contained in:
parent
bd6b54ba1f
commit
88dd1a8a11
@ -741,7 +741,7 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
|
||||
goto error;
|
||||
}
|
||||
|
||||
if(data->set.httpversion == CURL_HTTP_VERSION_1_0) {
|
||||
if(data->state.httpwant == CURL_HTTP_VERSION_1_0) {
|
||||
if(HYPERE_OK != hyper_request_set_version(req,
|
||||
HYPER_HTTP_VERSION_1_0)) {
|
||||
failf(data, "error setting HTTP version");
|
||||
|
37
lib/http.c
37
lib/http.c
@ -183,7 +183,7 @@ static CURLcode http_setup_conn(struct Curl_easy *data,
|
||||
Curl_mime_initpart(&http->form, data);
|
||||
data->req.p.http = http;
|
||||
|
||||
if(data->set.httpversion == CURL_HTTP_VERSION_3) {
|
||||
if(data->state.httpwant == CURL_HTTP_VERSION_3) {
|
||||
if(conn->handler->flags & PROTOPT_SSL)
|
||||
/* Only go HTTP/3 directly on HTTPS URLs. It needs a UDP socket and does
|
||||
the QUIC dance. */
|
||||
@ -595,7 +595,7 @@ CURLcode Curl_http_auth_act(struct Curl_easy *data)
|
||||
conn->httpversion > 11) {
|
||||
infof(data, "Forcing HTTP/1.1 for NTLM");
|
||||
connclose(conn, "Force HTTP/1.1 connection");
|
||||
data->set.httpversion = CURL_HTTP_VERSION_1_1;
|
||||
data->state.httpwant = CURL_HTTP_VERSION_1_1;
|
||||
}
|
||||
}
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
@ -1625,11 +1625,11 @@ static bool use_http_1_1plus(const struct Curl_easy *data,
|
||||
{
|
||||
if((data->state.httpversion == 10) || (conn->httpversion == 10))
|
||||
return FALSE;
|
||||
if((data->set.httpversion == CURL_HTTP_VERSION_1_0) &&
|
||||
if((data->state.httpwant == CURL_HTTP_VERSION_1_0) &&
|
||||
(conn->httpversion <= 10))
|
||||
return FALSE;
|
||||
return ((data->set.httpversion == CURL_HTTP_VERSION_NONE) ||
|
||||
(data->set.httpversion >= CURL_HTTP_VERSION_1_1));
|
||||
return ((data->state.httpwant == CURL_HTTP_VERSION_NONE) ||
|
||||
(data->state.httpwant >= CURL_HTTP_VERSION_1_1));
|
||||
}
|
||||
|
||||
#ifndef USE_HYPER
|
||||
@ -1637,7 +1637,7 @@ static const char *get_http_string(const struct Curl_easy *data,
|
||||
const struct connectdata *conn)
|
||||
{
|
||||
#ifdef ENABLE_QUIC
|
||||
if((data->set.httpversion == CURL_HTTP_VERSION_3) ||
|
||||
if((data->state.httpwant == CURL_HTTP_VERSION_3) ||
|
||||
(conn->httpversion == 30))
|
||||
return "3";
|
||||
#endif
|
||||
@ -2950,7 +2950,7 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
|
||||
default:
|
||||
/* Check if user wants to use HTTP/2 with clear TCP*/
|
||||
#ifdef USE_NGHTTP2
|
||||
if(data->set.httpversion == CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE) {
|
||||
if(data->state.httpwant == CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE) {
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
if(conn->bits.httpproxy && !conn->bits.tunnel_proxy) {
|
||||
/* We don't support HTTP/2 proxies yet. Also it's debatable
|
||||
@ -3156,7 +3156,7 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
|
||||
|
||||
if(!(conn->handler->flags&PROTOPT_SSL) &&
|
||||
conn->httpversion != 20 &&
|
||||
(data->set.httpversion == CURL_HTTP_VERSION_2)) {
|
||||
(data->state.httpwant == CURL_HTTP_VERSION_2)) {
|
||||
/* append HTTP2 upgrade magic stuff to the HTTP request if it isn't done
|
||||
over SSL */
|
||||
result = Curl_http2_request_upgrade(&req, conn);
|
||||
@ -4148,10 +4148,11 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
||||
*/
|
||||
char separator;
|
||||
char twoorthree[2];
|
||||
int httpversion = 0;
|
||||
nc = sscanf(HEADER1,
|
||||
" HTTP/%1d.%1d%c%3d",
|
||||
&httpversion_major,
|
||||
&conn->httpversion,
|
||||
&httpversion,
|
||||
&separator,
|
||||
&k->httpcode);
|
||||
|
||||
@ -4163,7 +4164,23 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
||||
}
|
||||
|
||||
if((nc == 4) && (' ' == separator)) {
|
||||
conn->httpversion += 10 * httpversion_major;
|
||||
httpversion += 10 * httpversion_major;
|
||||
switch(httpversion) {
|
||||
case 10:
|
||||
case 11:
|
||||
#if defined(USE_NGHTTP2) || defined(USE_HYPER)
|
||||
case 20:
|
||||
#endif
|
||||
#if defined(ENABLE_QUIC)
|
||||
case 30:
|
||||
#endif
|
||||
conn->httpversion = (unsigned char)httpversion;
|
||||
break;
|
||||
default:
|
||||
failf(data, "Unsupported HTTP version (%u.%d) in response",
|
||||
httpversion/10, httpversion%10);
|
||||
return CURLE_UNSUPPORTED_PROTOCOL;
|
||||
}
|
||||
|
||||
if(k->upgr101 == UPGR101_RECEIVED) {
|
||||
/* supposedly upgraded to http2 now */
|
||||
|
@ -2173,7 +2173,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi,
|
||||
|
||||
if(!ret) {
|
||||
infof(data, "Downgrades to HTTP/1.1!\n");
|
||||
data->set.httpversion = CURL_HTTP_VERSION_1_1;
|
||||
data->state.httpwant = CURL_HTTP_VERSION_1_1;
|
||||
/* clear the error message bit too as we ignore the one we got */
|
||||
data->state.errorbuf = FALSE;
|
||||
if(!newurl)
|
||||
|
@ -888,7 +888,7 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
|
||||
if(arg == CURL_HTTP_VERSION_NONE)
|
||||
arg = CURL_HTTP_VERSION_2TLS;
|
||||
#endif
|
||||
data->set.httpversion = arg;
|
||||
data->set.httpwant = (unsigned char)arg;
|
||||
break;
|
||||
|
||||
case CURLOPT_EXPECT_100_TIMEOUT_MS:
|
||||
|
@ -1431,8 +1431,8 @@ CURLcode Curl_pretransfer(struct Curl_easy *data)
|
||||
data->state.followlocation = 0; /* reset the location-follow counter */
|
||||
data->state.this_is_a_follow = FALSE; /* reset this */
|
||||
data->state.errorbuf = FALSE; /* no error has occurred */
|
||||
data->state.httpversion = 0; /* don't assume any particular server version */
|
||||
|
||||
data->state.httpwant = data->set.httpwant;
|
||||
data->state.httpversion = 0;
|
||||
data->state.authproblem = FALSE;
|
||||
data->state.authhost.want = data->set.httpauth;
|
||||
data->state.authproxy.want = data->set.proxyauth;
|
||||
|
@ -609,7 +609,7 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data)
|
||||
set->maxconnects = DEFAULT_CONNCACHE_SIZE; /* for easy handles */
|
||||
set->maxage_conn = 118;
|
||||
set->http09_allowed = FALSE;
|
||||
set->httpversion =
|
||||
set->httpwant =
|
||||
#ifdef USE_NGHTTP2
|
||||
CURL_HTTP_VERSION_2TLS
|
||||
#else
|
||||
@ -887,7 +887,7 @@ static int IsMultiplexingPossible(const struct Curl_easy *handle,
|
||||
(!conn->bits.protoconnstart || !conn->bits.close)) {
|
||||
|
||||
if(Curl_multiplex_wanted(handle->multi) &&
|
||||
(handle->set.httpversion >= CURL_HTTP_VERSION_2))
|
||||
(handle->state.httpwant >= CURL_HTTP_VERSION_2))
|
||||
/* allows HTTP/2 */
|
||||
avail |= CURLPIPE_MULTIPLEX;
|
||||
}
|
||||
|
@ -991,7 +991,7 @@ struct connectdata {
|
||||
char *passwd; /* password string, allocated */
|
||||
char *options; /* options string, allocated */
|
||||
char *sasl_authzid; /* authorisation identity string, allocated */
|
||||
int httpversion; /* the HTTP version*10 reported by the server */
|
||||
unsigned char httpversion; /* the HTTP version*10 reported by the server */
|
||||
struct curltime now; /* "current" time */
|
||||
struct curltime created; /* creation time */
|
||||
struct curltime lastused; /* when returned to the connection cache */
|
||||
@ -1375,9 +1375,10 @@ struct UrlState {
|
||||
|
||||
/* a place to store the most recently set FTP entrypath */
|
||||
char *most_recent_ftp_entrypath;
|
||||
|
||||
int httpversion; /* the lowest HTTP version*10 reported by any server
|
||||
involved in this request */
|
||||
unsigned char httpwant; /* when non-zero, a specific HTTP version requested
|
||||
to be used in the library's request(s) */
|
||||
unsigned char httpversion; /* the lowest HTTP version*10 reported by any
|
||||
server involved in this request */
|
||||
|
||||
#if !defined(WIN32) && !defined(MSDOS) && !defined(__EMX__)
|
||||
/* do FTP line-end conversions on most platforms */
|
||||
@ -1718,8 +1719,8 @@ struct UserDefined {
|
||||
curl_proxytype proxytype; /* what kind of proxy that is in use */
|
||||
time_t timevalue; /* what time to compare with */
|
||||
Curl_HttpReq method; /* what kind of HTTP request (if any) is this */
|
||||
long httpversion; /* when non-zero, a specific HTTP version requested to
|
||||
be used in the library's request(s) */
|
||||
unsigned char httpwant; /* when non-zero, a specific HTTP version requested
|
||||
to be used in the library's request(s) */
|
||||
struct ssl_config_data ssl; /* user defined SSL stuff */
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
struct ssl_config_data proxy_ssl; /* user defined SSL stuff for proxy */
|
||||
|
@ -390,7 +390,7 @@ static CURLcode bearssl_connect_step1(struct Curl_easy *data,
|
||||
*/
|
||||
|
||||
#ifdef USE_NGHTTP2
|
||||
if(data->set.httpversion >= CURL_HTTP_VERSION_2
|
||||
if(data->state.httpversion >= CURL_HTTP_VERSION_2
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
&& (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy)
|
||||
#endif
|
||||
|
@ -618,7 +618,7 @@ gtls_connect_step1(struct Curl_easy *data,
|
||||
gnutls_datum_t protocols[2];
|
||||
|
||||
#ifdef USE_NGHTTP2
|
||||
if(data->set.httpversion >= CURL_HTTP_VERSION_2
|
||||
if(data->state.httpversion >= CURL_HTTP_VERSION_2
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
&& (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy)
|
||||
#endif
|
||||
|
@ -495,7 +495,7 @@ mbed_connect_step1(struct Curl_easy *data, struct connectdata *conn,
|
||||
if(conn->bits.tls_enable_alpn) {
|
||||
const char **p = &backend->protocols[0];
|
||||
#ifdef USE_NGHTTP2
|
||||
if(data->set.httpversion >= CURL_HTTP_VERSION_2)
|
||||
if(data->state.httpversion >= CURL_HTTP_VERSION_2)
|
||||
*p++ = NGHTTP2_PROTO_VERSION_ID;
|
||||
#endif
|
||||
*p++ = ALPN_HTTP_1_1;
|
||||
|
@ -2080,7 +2080,7 @@ static CURLcode nss_setup_connect(struct Curl_easy *data,
|
||||
unsigned char protocols[128];
|
||||
|
||||
#ifdef USE_NGHTTP2
|
||||
if(data->set.httpversion >= CURL_HTTP_VERSION_2
|
||||
if(data->state.httpversion >= CURL_HTTP_VERSION_2
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
&& (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy)
|
||||
#endif
|
||||
|
@ -2222,7 +2222,7 @@ select_next_proto_cb(SSL *ssl,
|
||||
(void)ssl;
|
||||
|
||||
#ifdef USE_NGHTTP2
|
||||
if(data->set.httpversion >= CURL_HTTP_VERSION_2 &&
|
||||
if(data->state.httpwant >= CURL_HTTP_VERSION_2 &&
|
||||
!select_next_protocol(out, outlen, in, inlen, NGHTTP2_PROTO_VERSION_ID,
|
||||
NGHTTP2_PROTO_VERSION_ID_LEN)) {
|
||||
infof(data, "NPN, negotiated HTTP2 (%s)\n",
|
||||
@ -2749,7 +2749,7 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data,
|
||||
unsigned char protocols[128];
|
||||
|
||||
#ifdef USE_NGHTTP2
|
||||
if(data->set.httpversion >= CURL_HTTP_VERSION_2
|
||||
if(data->state.httpwant >= CURL_HTTP_VERSION_2
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
&& (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy)
|
||||
#endif
|
||||
|
@ -861,7 +861,7 @@ schannel_connect_step1(struct Curl_easy *data, struct connectdata *conn,
|
||||
list_start_index = cur;
|
||||
|
||||
#ifdef USE_NGHTTP2
|
||||
if(data->set.httpversion >= CURL_HTTP_VERSION_2) {
|
||||
if(data->state.httpversion >= CURL_HTTP_VERSION_2) {
|
||||
memcpy(&alpn_buffer[cur], NGHTTP2_PROTO_ALPN, NGHTTP2_PROTO_ALPN_LEN);
|
||||
cur += NGHTTP2_PROTO_ALPN_LEN;
|
||||
infof(data, "schannel: ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID);
|
||||
|
@ -1611,7 +1611,7 @@ static CURLcode sectransp_connect_step1(struct Curl_easy *data,
|
||||
&kCFTypeArrayCallBacks);
|
||||
|
||||
#ifdef USE_NGHTTP2
|
||||
if(data->set.httpversion >= CURL_HTTP_VERSION_2
|
||||
if(data->state.httpversion >= CURL_HTTP_VERSION_2
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
&& (!SSL_IS_PROXY() || !conn->bits.tunnel_proxy)
|
||||
#endif
|
||||
|
@ -475,7 +475,7 @@ wolfssl_connect_step1(struct Curl_easy *data, struct connectdata *conn,
|
||||
protocols in descending order of preference, eg: "h2,http/1.1" */
|
||||
|
||||
#ifdef USE_NGHTTP2
|
||||
if(data->set.httpversion >= CURL_HTTP_VERSION_2) {
|
||||
if(data->state.httpversion >= CURL_HTTP_VERSION_2) {
|
||||
strcpy(protocols + strlen(protocols), NGHTTP2_PROTO_VERSION_ID ",");
|
||||
infof(data, "ALPN, offering %s\n", NGHTTP2_PROTO_VERSION_ID);
|
||||
}
|
||||
@ -724,7 +724,7 @@ wolfssl_connect_step2(struct Curl_easy *data, struct connectdata *conn,
|
||||
!memcmp(protocol, ALPN_HTTP_1_1, ALPN_HTTP_1_1_LENGTH))
|
||||
conn->negnpn = CURL_HTTP_VERSION_1_1;
|
||||
#ifdef USE_NGHTTP2
|
||||
else if(data->set.httpversion >= CURL_HTTP_VERSION_2 &&
|
||||
else if(data->state.httpversion >= CURL_HTTP_VERSION_2 &&
|
||||
protocol_len == NGHTTP2_PROTO_VERSION_ID_LEN &&
|
||||
!memcmp(protocol, NGHTTP2_PROTO_VERSION_ID,
|
||||
NGHTTP2_PROTO_VERSION_ID_LEN))
|
||||
|
@ -34,7 +34,7 @@ test90 test91 test92 test93 test94 test95 test96 test97 test98 test99 \
|
||||
test100 test101 test102 test103 test104 test105 test106 test107 test108 \
|
||||
test109 test110 test111 test112 test113 test114 test115 test116 test117 \
|
||||
test118 test119 test120 test121 test122 test123 test124 test125 test126 \
|
||||
test127 test128 test130 test131 test132 test133 test134 test135 \
|
||||
test127 test128 test129 test130 test131 test132 test133 test134 test135 \
|
||||
test136 test137 test138 test139 test140 test141 test142 test143 test144 \
|
||||
test145 test146 test147 test148 test149 test150 test151 test152 test153 \
|
||||
test154 test155 test156 test157 test158 test159 test160 test161 test162 \
|
||||
|
57
tests/data/test129
Normal file
57
tests/data/test129
Normal file
@ -0,0 +1,57 @@
|
||||
<testcase>
|
||||
<info>
|
||||
<keywords>
|
||||
HTTP
|
||||
HTTP GET
|
||||
</keywords>
|
||||
</info>
|
||||
|
||||
#
|
||||
# Server-side
|
||||
<reply>
|
||||
<data nocheck="yes">
|
||||
HTTP/1.2 200 OK
|
||||
Date: Tue, 09 Nov 2010 14:49:00 GMT
|
||||
Server: test-server/fake
|
||||
Last-Modified: Tue, 13 Jun 2000 12:10:00 GMT
|
||||
ETag: "21025-dc7-39462498"
|
||||
Accept-Ranges: bytes
|
||||
Content-Length: 6
|
||||
Connection: close
|
||||
Content-Type: text/html
|
||||
Funny-head: yesyes
|
||||
|
||||
-foo-
|
||||
</data>
|
||||
</reply>
|
||||
|
||||
#
|
||||
# Client-side
|
||||
<client>
|
||||
<server>
|
||||
http
|
||||
</server>
|
||||
<name>
|
||||
HTTP/1.2 is rejected
|
||||
</name>
|
||||
<command>
|
||||
http://%HOSTIP:%HTTPPORT/129
|
||||
</command>
|
||||
</client>
|
||||
|
||||
#
|
||||
# Verify data after the test has been "shot"
|
||||
<verify>
|
||||
<protocol>
|
||||
GET /129 HTTP/1.1
|
||||
Host: %HOSTIP:%HTTPPORT
|
||||
User-Agent: curl/%VERSION
|
||||
Accept: */*
|
||||
|
||||
</protocol>
|
||||
# CURLE_UNSUPPORTED_PROTOCOL
|
||||
<errorcode>
|
||||
1
|
||||
</errorcode>
|
||||
</verify>
|
||||
</testcase>
|
Loading…
Reference in New Issue
Block a user