mirror of
https://github.com/curl/curl.git
synced 2026-04-13 12:41:42 +08:00
vtls: set seen http version on successful ALPN
When a HTTP version has been negotiated via ALPN, set the member `conn->httpversion_seen` accordingly. This allows pending transfers to reuse multiplexed http connections before the response to the first transfer has arrived. Fixes #18177 Reported-by: IoannisGS on github Closes #18181
This commit is contained in:
parent
952117c032
commit
41fe621ae1
@ -2704,6 +2704,8 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
|
||||
if(result)
|
||||
goto fail;
|
||||
info_version = "HTTP/2";
|
||||
/* There is no ALPN here, but the connection is now definitely h2 */
|
||||
conn->httpversion_seen = 20;
|
||||
}
|
||||
else
|
||||
info_version = "HTTP/1.x";
|
||||
|
||||
@ -768,7 +768,7 @@ struct connectdata {
|
||||
and happy eyeballing. Use `Curl_conn_get_transport() for actual value
|
||||
once the connection is set up. */
|
||||
unsigned char ip_version; /* copied from the Curl_easy at creation time */
|
||||
/* HTTP version last responded with by the server.
|
||||
/* HTTP version last responded with by the server or negotiated via ALPN.
|
||||
* 0 at start, then one of 09, 10, 11, etc. */
|
||||
unsigned char httpversion_seen;
|
||||
unsigned char connect_only;
|
||||
|
||||
@ -1955,9 +1955,9 @@ static CURLcode h3_data_pause(struct Curl_cfilter *cf,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode cf_ngtcp2_data_event(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
int event, int arg1, void *arg2)
|
||||
static CURLcode cf_ngtcp2_cntrl(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
int event, int arg1, void *arg2)
|
||||
{
|
||||
struct cf_ngtcp2_ctx *ctx = cf->ctx;
|
||||
CURLcode result = CURLE_OK;
|
||||
@ -1995,6 +1995,10 @@ static CURLcode cf_ngtcp2_data_event(struct Curl_cfilter *cf,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CF_CTRL_CONN_INFO_UPDATE:
|
||||
if(!cf->sockindex && cf->connected)
|
||||
cf->conn->httpversion_seen = 30;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -2733,7 +2737,7 @@ struct Curl_cftype Curl_cft_http3 = {
|
||||
Curl_cf_def_data_pending,
|
||||
cf_ngtcp2_send,
|
||||
cf_ngtcp2_recv,
|
||||
cf_ngtcp2_data_event,
|
||||
cf_ngtcp2_cntrl,
|
||||
cf_ngtcp2_conn_is_alive,
|
||||
Curl_cf_def_conn_keep_alive,
|
||||
cf_ngtcp2_query,
|
||||
|
||||
@ -2168,9 +2168,9 @@ static bool cf_osslq_data_pending(struct Curl_cfilter *cf,
|
||||
return stream && !Curl_bufq_is_empty(&stream->recvbuf);
|
||||
}
|
||||
|
||||
static CURLcode cf_osslq_data_event(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
int event, int arg1, void *arg2)
|
||||
static CURLcode cf_osslq_cntrl(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
int event, int arg1, void *arg2)
|
||||
{
|
||||
struct cf_osslq_ctx *ctx = cf->ctx;
|
||||
CURLcode result = CURLE_OK;
|
||||
@ -2206,6 +2206,10 @@ static CURLcode cf_osslq_data_event(struct Curl_cfilter *cf,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CF_CTRL_CONN_INFO_UPDATE:
|
||||
if(!cf->sockindex && cf->connected)
|
||||
cf->conn->httpversion_seen = 30;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -2384,7 +2388,7 @@ struct Curl_cftype Curl_cft_http3 = {
|
||||
cf_osslq_data_pending,
|
||||
cf_osslq_send,
|
||||
cf_osslq_recv,
|
||||
cf_osslq_data_event,
|
||||
cf_osslq_cntrl,
|
||||
cf_osslq_conn_is_alive,
|
||||
Curl_cf_def_conn_keep_alive,
|
||||
cf_osslq_query,
|
||||
|
||||
@ -1197,9 +1197,9 @@ static CURLcode h3_data_pause(struct Curl_cfilter *cf,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode cf_quiche_data_event(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
int event, int arg1, void *arg2)
|
||||
static CURLcode cf_quiche_cntrl(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
int event, int arg1, void *arg2)
|
||||
{
|
||||
struct cf_quiche_ctx *ctx = cf->ctx;
|
||||
CURLcode result = CURLE_OK;
|
||||
@ -1238,6 +1238,10 @@ static CURLcode cf_quiche_data_event(struct Curl_cfilter *cf,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CF_CTRL_CONN_INFO_UPDATE:
|
||||
if(!cf->sockindex && cf->connected)
|
||||
cf->conn->httpversion_seen = 30;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -1621,7 +1625,7 @@ struct Curl_cftype Curl_cft_http3 = {
|
||||
cf_quiche_data_pending,
|
||||
cf_quiche_send,
|
||||
cf_quiche_recv,
|
||||
cf_quiche_data_event,
|
||||
cf_quiche_cntrl,
|
||||
cf_quiche_conn_is_alive,
|
||||
Curl_cf_def_conn_keep_alive,
|
||||
cf_quiche_query,
|
||||
|
||||
@ -1605,6 +1605,30 @@ static CURLcode ssl_cf_query(struct Curl_cfilter *cf,
|
||||
CURLE_UNKNOWN_OPTION;
|
||||
}
|
||||
|
||||
static CURLcode ssl_cf_cntrl(struct Curl_cfilter *cf,
|
||||
struct Curl_easy *data,
|
||||
int event, int arg1, void *arg2)
|
||||
{
|
||||
struct ssl_connect_data *connssl = cf->ctx;
|
||||
|
||||
(void)arg1;
|
||||
(void)arg2;
|
||||
(void)data;
|
||||
switch(event) {
|
||||
case CF_CTRL_CONN_INFO_UPDATE:
|
||||
if(connssl->negotiated.alpn && !cf->sockindex) {
|
||||
if(!strcmp("http/1.1", connssl->negotiated.alpn))
|
||||
cf->conn->httpversion_seen = 11;
|
||||
else if(!strcmp("h2", connssl->negotiated.alpn))
|
||||
cf->conn->httpversion_seen = 20;
|
||||
else if(!strcmp("h3", connssl->negotiated.alpn))
|
||||
cf->conn->httpversion_seen = 30;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static bool cf_ssl_is_alive(struct Curl_cfilter *cf, struct Curl_easy *data,
|
||||
bool *input_pending)
|
||||
{
|
||||
@ -1628,7 +1652,7 @@ struct Curl_cftype Curl_cft_ssl = {
|
||||
ssl_cf_data_pending,
|
||||
ssl_cf_send,
|
||||
ssl_cf_recv,
|
||||
Curl_cf_def_cntrl,
|
||||
ssl_cf_cntrl,
|
||||
cf_ssl_is_alive,
|
||||
Curl_cf_def_conn_keep_alive,
|
||||
ssl_cf_query,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user