mirror of
https://github.com/curl/curl.git
synced 2026-07-02 21:57:18 +03: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
6 changed files with 52 additions and 14 deletions
|
|
@ -2704,6 +2704,8 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
|
||||||
if(result)
|
if(result)
|
||||||
goto fail;
|
goto fail;
|
||||||
info_version = "HTTP/2";
|
info_version = "HTTP/2";
|
||||||
|
/* There is no ALPN here, but the connection is now definitely h2 */
|
||||||
|
conn->httpversion_seen = 20;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
info_version = "HTTP/1.x";
|
info_version = "HTTP/1.x";
|
||||||
|
|
|
||||||
|
|
@ -768,7 +768,7 @@ struct connectdata {
|
||||||
and happy eyeballing. Use `Curl_conn_get_transport() for actual value
|
and happy eyeballing. Use `Curl_conn_get_transport() for actual value
|
||||||
once the connection is set up. */
|
once the connection is set up. */
|
||||||
unsigned char ip_version; /* copied from the Curl_easy at creation time */
|
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. */
|
* 0 at start, then one of 09, 10, 11, etc. */
|
||||||
unsigned char httpversion_seen;
|
unsigned char httpversion_seen;
|
||||||
unsigned char connect_only;
|
unsigned char connect_only;
|
||||||
|
|
|
||||||
|
|
@ -1955,9 +1955,9 @@ static CURLcode h3_data_pause(struct Curl_cfilter *cf,
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CURLcode cf_ngtcp2_data_event(struct Curl_cfilter *cf,
|
static CURLcode cf_ngtcp2_cntrl(struct Curl_cfilter *cf,
|
||||||
struct Curl_easy *data,
|
struct Curl_easy *data,
|
||||||
int event, int arg1, void *arg2)
|
int event, int arg1, void *arg2)
|
||||||
{
|
{
|
||||||
struct cf_ngtcp2_ctx *ctx = cf->ctx;
|
struct cf_ngtcp2_ctx *ctx = cf->ctx;
|
||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
|
|
@ -1995,6 +1995,10 @@ static CURLcode cf_ngtcp2_data_event(struct Curl_cfilter *cf,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case CF_CTRL_CONN_INFO_UPDATE:
|
||||||
|
if(!cf->sockindex && cf->connected)
|
||||||
|
cf->conn->httpversion_seen = 30;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -2733,7 +2737,7 @@ struct Curl_cftype Curl_cft_http3 = {
|
||||||
Curl_cf_def_data_pending,
|
Curl_cf_def_data_pending,
|
||||||
cf_ngtcp2_send,
|
cf_ngtcp2_send,
|
||||||
cf_ngtcp2_recv,
|
cf_ngtcp2_recv,
|
||||||
cf_ngtcp2_data_event,
|
cf_ngtcp2_cntrl,
|
||||||
cf_ngtcp2_conn_is_alive,
|
cf_ngtcp2_conn_is_alive,
|
||||||
Curl_cf_def_conn_keep_alive,
|
Curl_cf_def_conn_keep_alive,
|
||||||
cf_ngtcp2_query,
|
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);
|
return stream && !Curl_bufq_is_empty(&stream->recvbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static CURLcode cf_osslq_data_event(struct Curl_cfilter *cf,
|
static CURLcode cf_osslq_cntrl(struct Curl_cfilter *cf,
|
||||||
struct Curl_easy *data,
|
struct Curl_easy *data,
|
||||||
int event, int arg1, void *arg2)
|
int event, int arg1, void *arg2)
|
||||||
{
|
{
|
||||||
struct cf_osslq_ctx *ctx = cf->ctx;
|
struct cf_osslq_ctx *ctx = cf->ctx;
|
||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
|
|
@ -2206,6 +2206,10 @@ static CURLcode cf_osslq_data_event(struct Curl_cfilter *cf,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case CF_CTRL_CONN_INFO_UPDATE:
|
||||||
|
if(!cf->sockindex && cf->connected)
|
||||||
|
cf->conn->httpversion_seen = 30;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -2384,7 +2388,7 @@ struct Curl_cftype Curl_cft_http3 = {
|
||||||
cf_osslq_data_pending,
|
cf_osslq_data_pending,
|
||||||
cf_osslq_send,
|
cf_osslq_send,
|
||||||
cf_osslq_recv,
|
cf_osslq_recv,
|
||||||
cf_osslq_data_event,
|
cf_osslq_cntrl,
|
||||||
cf_osslq_conn_is_alive,
|
cf_osslq_conn_is_alive,
|
||||||
Curl_cf_def_conn_keep_alive,
|
Curl_cf_def_conn_keep_alive,
|
||||||
cf_osslq_query,
|
cf_osslq_query,
|
||||||
|
|
|
||||||
|
|
@ -1197,9 +1197,9 @@ static CURLcode h3_data_pause(struct Curl_cfilter *cf,
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CURLcode cf_quiche_data_event(struct Curl_cfilter *cf,
|
static CURLcode cf_quiche_cntrl(struct Curl_cfilter *cf,
|
||||||
struct Curl_easy *data,
|
struct Curl_easy *data,
|
||||||
int event, int arg1, void *arg2)
|
int event, int arg1, void *arg2)
|
||||||
{
|
{
|
||||||
struct cf_quiche_ctx *ctx = cf->ctx;
|
struct cf_quiche_ctx *ctx = cf->ctx;
|
||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
|
|
@ -1238,6 +1238,10 @@ static CURLcode cf_quiche_data_event(struct Curl_cfilter *cf,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case CF_CTRL_CONN_INFO_UPDATE:
|
||||||
|
if(!cf->sockindex && cf->connected)
|
||||||
|
cf->conn->httpversion_seen = 30;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -1621,7 +1625,7 @@ struct Curl_cftype Curl_cft_http3 = {
|
||||||
cf_quiche_data_pending,
|
cf_quiche_data_pending,
|
||||||
cf_quiche_send,
|
cf_quiche_send,
|
||||||
cf_quiche_recv,
|
cf_quiche_recv,
|
||||||
cf_quiche_data_event,
|
cf_quiche_cntrl,
|
||||||
cf_quiche_conn_is_alive,
|
cf_quiche_conn_is_alive,
|
||||||
Curl_cf_def_conn_keep_alive,
|
Curl_cf_def_conn_keep_alive,
|
||||||
cf_quiche_query,
|
cf_quiche_query,
|
||||||
|
|
|
||||||
|
|
@ -1605,6 +1605,30 @@ static CURLcode ssl_cf_query(struct Curl_cfilter *cf,
|
||||||
CURLE_UNKNOWN_OPTION;
|
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,
|
static bool cf_ssl_is_alive(struct Curl_cfilter *cf, struct Curl_easy *data,
|
||||||
bool *input_pending)
|
bool *input_pending)
|
||||||
{
|
{
|
||||||
|
|
@ -1628,7 +1652,7 @@ struct Curl_cftype Curl_cft_ssl = {
|
||||||
ssl_cf_data_pending,
|
ssl_cf_data_pending,
|
||||||
ssl_cf_send,
|
ssl_cf_send,
|
||||||
ssl_cf_recv,
|
ssl_cf_recv,
|
||||||
Curl_cf_def_cntrl,
|
ssl_cf_cntrl,
|
||||||
cf_ssl_is_alive,
|
cf_ssl_is_alive,
|
||||||
Curl_cf_def_conn_keep_alive,
|
Curl_cf_def_conn_keep_alive,
|
||||||
ssl_cf_query,
|
ssl_cf_query,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue