/* Switching Protocols */
if(k->upgr101 == UPGR101_H2) {
/* Switching to HTTP/2 */
+ DEBUGASSERT(conn->httpversion < 20);
infof(data, "Received 101, Switching to HTTP/2");
k->upgr101 = UPGR101_RECEIVED;
}
}
else {
+ if(k->upgr101 == UPGR101_H2) {
+ /* A requested upgrade was denied, poke the multi handle to possibly
+ allow a pending pipewait to continue */
+ Curl_multi_connchanged(data->multi);
+ }
k->header = FALSE; /* no more header to parse! */
if((k->size == -1) && !k->chunk && !conn->bits.close &&
static int error_callback(nghttp2_session *session, const char *msg,
size_t len, void *userp);
-/*
- * multi_connchanged() is called to tell that there is a connection in
- * this multi handle that has changed state (multiplexing become possible, the
- * number of allowed streams changed or similar), and a subsequent use of this
- * multi handle should move CONNECT_PEND handles back to CONNECT to have them
- * retry.
- */
-static void multi_connchanged(struct Curl_multi *multi)
-{
- multi->recheckstate = TRUE;
-}
-
/*
* Initialize the cfilter context
*/
/* only signal change if the value actually changed */
DEBUGF(LOG_CF(data, cf, "MAX_CONCURRENT_STREAMS now %u",
ctx->max_concurrent_streams));
- multi_connchanged(data->multi);
+ Curl_multi_connchanged(data->multi);
}
/* Since the initial stream window is 64K, a request might be on HOLD,
* due to exhaustion. The (initial) SETTINGS may announce a much larger
ctx->goaway_error, ctx->last_stream_id));
infof(data, "received GOAWAY, error=%d, last_stream=%u",
ctx->goaway_error, ctx->last_stream_id);
- multi_connchanged(data->multi);
+ Curl_multi_connchanged(data->multi);
}
break;
case NGHTTP2_WINDOW_UPDATE:
ssize_t nread = -1;
CURLcode result;
struct cf_call_data save;
-
+ DEBUGASSERT(stream);
CF_DATA_SAVE(save, cf, data);
nread = stream_recv(cf, data, buf, len, err);
conn->httpversion = 20; /* we know we're on HTTP/2 now */
conn->bits.multiplex = TRUE; /* at least potentially multiplexed */
conn->bundle->multiuse = BUNDLE_MULTIPLEX;
- multi_connchanged(data->multi);
+ Curl_multi_connchanged(data->multi);
if(cf->next) {
bool done;
cf->conn->httpversion = 20; /* we know we're on HTTP/2 now */
cf->conn->bits.multiplex = TRUE; /* at least potentially multiplexed */
cf->conn->bundle->multiuse = BUNDLE_MULTIPLEX;
- multi_connchanged(data->multi);
+ Curl_multi_connchanged(data->multi);
if(cf_h2->next) {
bool done;
conn->httpversion = 20; /* we know we're on HTTP/2 now */
conn->bits.multiplex = TRUE; /* at least potentially multiplexed */
conn->bundle->multiuse = BUNDLE_MULTIPLEX;
- multi_connchanged(data->multi);
+ Curl_multi_connchanged(data->multi);
if(cf->next) {
bool done;
return retval;
}
+/*
+ * Curl_multi_connchanged() is called to tell that there is a connection in
+ * this multi handle that has changed state (multiplexing become possible, the
+ * number of allowed streams changed or similar), and a subsequent use of this
+ * multi handle should move CONNECT_PEND handles back to CONNECT to have them
+ * retry.
+ */
+void Curl_multi_connchanged(struct Curl_multi *multi)
+{
+ multi->recheckstate = TRUE;
+}
+
CURLMcode Curl_multi_add_perform(struct Curl_multi *multi,
struct Curl_easy *data,
struct connectdata *conn)
bool Curl_is_in_callback(struct Curl_easy *easy);
CURLcode Curl_preconnect(struct Curl_easy *data);
+void Curl_multi_connchanged(struct Curl_multi *multi);
+
/* Internal version of curl_multi_init() accepts size parameters for the
socket, connection and dns hashes */
struct Curl_multi *Curl_multi_handle(int hashsize, int chashsize,
bool wantProxyNTLMhttp = FALSE;
#endif
#endif
+ /* plain HTTP with upgrade */
+ bool h2upgrade = (data->state.httpwant == CURL_HTTP_VERSION_2_0) &&
+ (needle->handler->protocol & CURLPROTO_HTTP);
*force_reuse = FALSE;
*waitpipe = FALSE;
}
if(data->set.ipver != CURL_IPRESOLVE_WHATEVER
- && data->set.ipver != check->ip_version) {
+ && data->set.ipver != check->ip_version) {
/* skip because the connection is not via the requested IP version */
continue;
}
}
#endif
+ if(h2upgrade && !check->httpversion && canmultiplex) {
+ if(data->set.pipewait) {
+ infof(data, "Server upgrade doesn't support multiplex yet, wait");
+ *waitpipe = TRUE;
+ CONNCACHE_UNLOCK(data);
+ return FALSE; /* no re-use */
+ }
+ infof(data, "Server upgrade cannot be used");
+ continue; /* can't be used atm */
+ }
+
if(!canmultiplex && CONN_INUSE(check))
/* this request can't be multiplexed but the checked connection is
already in use so we skip it */
(((check->httpversion >= 20) &&
(data->state.httpwant < CURL_HTTP_VERSION_2_0))
|| ((check->httpversion >= 30) &&
- (data->state.httpwant < CURL_HTTP_VERSION_3))))
+ (data->state.httpwant < CURL_HTTP_VERSION_3))))
continue;
#ifdef USE_SSH
else if(get_protocol_family(needle->handler) & PROTO_FAMILY_SSH) {