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
/* 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 */
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);
}
free(base64);
k->upgr101 = UPGR101_H2;
+ data->conn->bits.asks_multiplex = TRUE;
return result;
}
* 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 */
#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? */