lib: clarify 'conn->httpversion'

The variable `conn->httpversion` was used for several purposes and it
was unclear at which time the value represents what.

- rename `conn->httpversion` to `conn->httpversion_seen`
  This makes clear that the variable only records the last
  HTTP version seen on the connection - if any. And that it
  no longer is an indication of what version to use.
- Change Alt-Svc handling to no longer modify `conn->httpversion`
  but set `data->state.httpwant` for influencing the HTTP version
  to use on a transfer.
- Add `data->req.httpversion_sent` to have a record of what
  HTTP version was sent in a request
- Add connection filter type CF_TYPE_HTTP
- Add filter query `CF_QUERY_HTTP_VERSION` to ask what HTTP
  filter version is in place
- Lookup filters HTTP version instead of using `conn->httpversion`

Test test_12_05 now switches to HTTP/1.1 correctly and the
expectations have been fixed.

Removed the connection fitler "is_httpN()" checks and using
the version query instead.

Closes #16073
This commit is contained in:
Stefan Eissing 2025-01-22 14:45:30 +01:00 committed by Daniel Stenberg
parent 7e814c8717
commit e83818cae1
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
21 changed files with 206 additions and 203 deletions

View file

@ -56,7 +56,7 @@ static bool hd_name_eq(const char *n1, size_t n1len,
}
static CURLcode dynhds_add_custom(struct Curl_easy *data,
bool is_connect,
bool is_connect, int httpversion,
struct dynhds *hds)
{
struct connectdata *conn = data->conn;
@ -169,9 +169,9 @@ static CURLcode dynhds_add_custom(struct Curl_easy *data,
Connection: */
hd_name_eq(name, namelen, STRCONST("Connection:")))
;
else if((conn->httpversion >= 20) &&
else if((httpversion >= 20) &&
hd_name_eq(name, namelen, STRCONST("Transfer-Encoding:")))
/* HTTP/2 does not support chunked requests */
/* HTTP/2 and HTTP/3 do not support chunked requests */
;
else if((hd_name_eq(name, namelen, STRCONST("Authorization:")) ||
hd_name_eq(name, namelen, STRCONST("Cookie:"))) &&
@ -221,11 +221,18 @@ CURLcode Curl_http_proxy_get_destination(struct Curl_cfilter *cf,
return CURLE_OK;
}
struct cf_proxy_ctx {
/* the protocol specific sub-filter we install during connect */
struct Curl_cfilter *cf_protocol;
int httpversion; /* HTTP version used to CONNECT */
};
CURLcode Curl_http_proxy_create_CONNECT(struct httpreq **preq,
struct Curl_cfilter *cf,
struct Curl_easy *data,
int http_version_major)
{
struct cf_proxy_ctx *ctx = cf->ctx;
const char *hostname = NULL;
char *authority = NULL;
int port;
@ -286,7 +293,7 @@ CURLcode Curl_http_proxy_create_CONNECT(struct httpreq **preq,
goto out;
}
result = dynhds_add_custom(data, TRUE, &req->headers);
result = dynhds_add_custom(data, TRUE, ctx->httpversion, &req->headers);
out:
if(result && req) {
@ -298,12 +305,6 @@ out:
return result;
}
struct cf_proxy_ctx {
/* the protocol specific sub-filter we install during connect */
struct Curl_cfilter *cf_protocol;
};
static CURLcode http_proxy_cf_connect(struct Curl_cfilter *cf,
struct Curl_easy *data,
bool blocking, bool *done)
@ -325,6 +326,7 @@ connect_sub:
*done = FALSE;
if(!ctx->cf_protocol) {
struct Curl_cfilter *cf_protocol = NULL;
int httpversion = 0;
int alpn = Curl_conn_cf_is_ssl(cf->next) ?
cf->conn->proxy_alpn : CURL_HTTP_VERSION_1_1;
@ -340,6 +342,7 @@ connect_sub:
if(result)
goto out;
cf_protocol = cf->next;
httpversion = (alpn == CURL_HTTP_VERSION_1_0) ? 10 : 11;
break;
#ifdef USE_NGHTTP2
case CURL_HTTP_VERSION_2:
@ -349,6 +352,7 @@ connect_sub:
if(result)
goto out;
cf_protocol = cf->next;
httpversion = 20;
break;
#endif
default:
@ -358,6 +362,7 @@ connect_sub:
}
ctx->cf_protocol = cf_protocol;
ctx->httpversion = httpversion;
/* after we installed the filter "below" us, we call connect
* on out sub-chain again.
*/