mirror of
https://github.com/curl/curl.git
synced 2024-12-21 06:50:10 +08:00
url: fix connection reuse for HTTP/2 upgrades
Normally, when a connection's filters have all connected, the multiplex status is determined. However, HTTP/2 Upgrade: requests will only do this when the first server response has been received. The current connection reuse mechanism does not accomodate that and when the time between connect and response is large enough, connection reuse may not happen as desired. See test case 2405 failures, such as in https://github.com/curl/curl/actions/runs/10629497461/job/29467166451 Add 'conn->bits.asks_multiplex' as indicator that a connection is still being evaluated for mulitplexing, so that new transfers may wait on this to be cleared. Closes #14739
This commit is contained in:
parent
76212cbf3e
commit
00ef607326
@ -3439,6 +3439,7 @@ static CURLcode http_on_response(struct Curl_easy *data,
|
||||
/* Switching to HTTP/2, where we will get more responses */
|
||||
infof(data, "Received 101, Switching to HTTP/2");
|
||||
k->upgr101 = UPGR101_RECEIVED;
|
||||
data->conn->bits.asks_multiplex = FALSE;
|
||||
/* We expect more response from HTTP/2 later */
|
||||
k->header = TRUE;
|
||||
k->headerline = 0; /* restart the header line counter */
|
||||
@ -3485,6 +3486,7 @@ static CURLcode http_on_response(struct Curl_easy *data,
|
||||
if(k->upgr101 == UPGR101_H2) {
|
||||
/* A requested upgrade was denied, poke the multi handle to possibly
|
||||
allow a pending pipewait to continue */
|
||||
data->conn->bits.asks_multiplex = FALSE;
|
||||
Curl_multi_connchanged(data->multi);
|
||||
}
|
||||
|
||||
|
@ -1736,6 +1736,7 @@ CURLcode Curl_http2_request_upgrade(struct dynbuf *req,
|
||||
free(base64);
|
||||
|
||||
k->upgr101 = UPGR101_H2;
|
||||
data->conn->bits.asks_multiplex = TRUE;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -907,7 +907,10 @@ static bool url_match_conn(struct connectdata *conn, void *userdata)
|
||||
* connections that do not use this feature */
|
||||
return FALSE;
|
||||
|
||||
if(!Curl_conn_is_connected(conn, FIRSTSOCKET)) {
|
||||
if(!Curl_conn_is_connected(conn, FIRSTSOCKET) ||
|
||||
conn->bits.asks_multiplex) {
|
||||
/* Not yet connected, or not yet decided if it multiplexes. The later
|
||||
* happens for HTTP/2 Upgrade: requests that need a response. */
|
||||
if(match->may_multiplex) {
|
||||
match->seen_pending_conn = TRUE;
|
||||
/* Do not pick a connection that has not connected yet */
|
||||
|
@ -535,6 +535,7 @@ struct ConnectBits {
|
||||
#endif
|
||||
BIT(bound); /* set true if bind() has already been done on this socket/
|
||||
connection */
|
||||
BIT(asks_multiplex); /* connection asks for multiplexing, but is not yet */
|
||||
BIT(multiplex); /* connection is multiplexed */
|
||||
BIT(tcp_fastopen); /* use TCP Fast Open */
|
||||
BIT(tls_enable_alpn); /* TLS ALPN extension? */
|
||||
|
Loading…
Reference in New Issue
Block a user