mirror of
https://github.com/curl/curl.git
synced 2025-01-18 14:04:30 +08:00
http2: Use KEEP_SEND_HOLD for flow control in HTTP/2
- use the defined, but so far not used, KEEP_SEND_HOLD bit for flow control based suspend of sending in transfers. Prior to this change KEEP_SEND_PAUSE bit was used instead, but that can interfere with pausing streams from the user side via curl_easy_pause. Fixes https://github.com/curl/curl/issues/10751 Closes https://github.com/curl/curl/pull/10753
This commit is contained in:
parent
7caaeca6f6
commit
06f65f771b
12
lib/http2.c
12
lib/http2.c
@ -958,12 +958,12 @@ static int on_frame_recv(nghttp2_session *session, const nghttp2_frame *frame,
|
||||
break;
|
||||
case NGHTTP2_WINDOW_UPDATE:
|
||||
DEBUGF(LOG_CF(data, cf, "[h2sid=%u] recv WINDOW_UPDATE", stream_id));
|
||||
if((data_s->req.keepon & KEEP_SEND_PAUSE) &&
|
||||
if((data_s->req.keepon & KEEP_SEND_HOLD) &&
|
||||
(data_s->req.keepon & KEEP_SEND)) {
|
||||
data_s->req.keepon &= ~KEEP_SEND_PAUSE;
|
||||
data_s->req.keepon &= ~KEEP_SEND_HOLD;
|
||||
drain_this(cf, data_s);
|
||||
Curl_expire(data_s, 0, EXPIRE_RUN_NOW);
|
||||
DEBUGF(LOG_CF(data, cf, "[h2sid=%u] unpausing after win update",
|
||||
DEBUGF(LOG_CF(data, cf, "[h2sid=%u] un-holding after win update",
|
||||
stream_id));
|
||||
}
|
||||
break;
|
||||
@ -2055,8 +2055,8 @@ static ssize_t cf_h2_send(struct Curl_cfilter *cf, struct Curl_easy *data,
|
||||
/* We cannot upload more as the stream's remote window size
|
||||
* is 0. We need to receive WIN_UPDATEs before we can continue.
|
||||
*/
|
||||
data->req.keepon |= KEEP_SEND_PAUSE;
|
||||
DEBUGF(LOG_CF(data, cf, "[h2sid=%u] pausing send as remote flow "
|
||||
data->req.keepon |= KEEP_SEND_HOLD;
|
||||
DEBUGF(LOG_CF(data, cf, "[h2sid=%u] holding send as remote flow "
|
||||
"window is exhausted", stream->stream_id));
|
||||
}
|
||||
}
|
||||
@ -2189,7 +2189,7 @@ static int cf_h2_get_select_socks(struct Curl_cfilter *cf,
|
||||
|
||||
/* we're (still uploading OR the HTTP/2 layer wants to send data) AND
|
||||
there's a window to send data in */
|
||||
if((((k->keepon & (KEEP_SEND|KEEP_SEND_PAUSE)) == KEEP_SEND) ||
|
||||
if((((k->keepon & KEEP_SENDBITS) == KEEP_SEND) ||
|
||||
nghttp2_session_want_write(ctx->h2)) &&
|
||||
(nghttp2_session_get_remote_window_size(ctx->h2) &&
|
||||
nghttp2_session_get_stream_remote_window_size(ctx->h2,
|
||||
|
@ -1234,8 +1234,7 @@ CURLcode Curl_readwrite(struct connectdata *conn,
|
||||
}
|
||||
|
||||
/* Now update the "done" boolean we return */
|
||||
*done = (0 == (k->keepon&(KEEP_RECV|KEEP_SEND|
|
||||
KEEP_RECV_PAUSE|KEEP_SEND_PAUSE))) ? TRUE : FALSE;
|
||||
*done = (0 == (k->keepon&(KEEP_RECVBITS|KEEP_SENDBITS))) ? TRUE : FALSE;
|
||||
result = CURLE_OK;
|
||||
out:
|
||||
if(result)
|
||||
|
@ -903,7 +903,7 @@ static int cf_ngtcp2_get_select_socks(struct Curl_cfilter *cf,
|
||||
rv |= GETSOCK_READSOCK(0);
|
||||
|
||||
/* we're still uploading or the HTTP/2 layer wants to send data */
|
||||
if((k->keepon & (KEEP_SEND|KEEP_SEND_PAUSE)) == KEEP_SEND &&
|
||||
if((k->keepon & KEEP_SENDBITS) == KEEP_SEND &&
|
||||
(!stream->h3out || stream->h3out->used < H3_SEND_SIZE) &&
|
||||
ngtcp2_conn_get_cwnd_left(ctx->qconn) &&
|
||||
ngtcp2_conn_get_max_data_left(ctx->qconn) &&
|
||||
|
@ -950,7 +950,7 @@ static int cf_quiche_get_select_socks(struct Curl_cfilter *cf,
|
||||
rv |= GETSOCK_READSOCK(0);
|
||||
|
||||
/* we're still uploading or the HTTP/3 layer wants to send data */
|
||||
if(((k->keepon & (KEEP_SEND|KEEP_SEND_PAUSE)) == KEEP_SEND)
|
||||
if(((k->keepon & KEEP_SENDBITS) == KEEP_SEND)
|
||||
&& stream_is_writeable(cf, data))
|
||||
rv |= GETSOCK_WRITESOCK(0);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user