summaryrefslogtreecommitdiff
path: root/lib/http2.c
diff options
context:
space:
mode:
authorStefan Eissing <stefan@eissing.org>2023-04-28 11:27:25 +0200
committerDaniel Stenberg <daniel@haxx.se>2023-04-28 13:55:39 +0200
commita9b7f72bc999f2e3c40607edd6974fd240966a08 (patch)
treead4b7d05869c1ee627176578493ed33b1c08bb2b /lib/http2.c
parentb0edf0b7dae44d9e66f270a257cf654b35d5263d (diff)
downloadcurl-a9b7f72bc999f2e3c40607edd6974fd240966a08.tar.gz
http2: do flow window accounting for cancelled streams
- nghttp2 does not free connection level window flow for aborted streams - when closing transfers, make sure that any buffered response data is "given back" to the flow control window - add tests test_02_22 and test_02_23 to reproduce Closes #11052
Diffstat (limited to 'lib/http2.c')
-rw-r--r--lib/http2.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/lib/http2.c b/lib/http2.c
index 0e361ab48..539b1fc81 100644
--- a/lib/http2.c
+++ b/lib/http2.c
@@ -160,6 +160,9 @@ static void cf_h2_ctx_free(struct cf_h2_ctx *ctx)
}
}
+static CURLcode h2_progress_egress(struct Curl_cfilter *cf,
+ struct Curl_easy *data);
+
/**
* All about the H3 internals of a stream
*/
@@ -272,6 +275,16 @@ static void http2_data_done(struct Curl_cfilter *cf,
stream->id, NGHTTP2_STREAM_CLOSED))
(void)nghttp2_session_send(ctx->h2);
}
+ if(!Curl_bufq_is_empty(&stream->recvbuf)) {
+ /* Anything in the recvbuf is still being counted
+ * in stream and connection window flow control. Need
+ * to free that space or the connection window might get
+ * exhausted eventually. */
+ nghttp2_session_consume(ctx->h2, stream->id,
+ Curl_bufq_len(&stream->recvbuf));
+ /* give WINDOW_UPATE a chance to be sent */
+ h2_progress_egress(cf, data);
+ }
/* -1 means unassigned and 0 means cleared */
if(nghttp2_session_get_stream_user_data(ctx->h2, stream->id)) {
@@ -1825,7 +1838,7 @@ out:
ctx->h2, stream->id),
nghttp2_session_get_stream_effective_local_window_size(
ctx->h2, stream->id),
- nghttp2_session_get_effective_local_window_size(ctx->h2),
+ nghttp2_session_get_local_window_size(ctx->h2),
HTTP2_HUGE_WINDOW_SIZE));
CF_DATA_RESTORE(cf, save);