summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2021-10-11 16:56:51 +0200
committerDaniel Stenberg <daniel@haxx.se>2021-10-11 17:00:14 +0200
commita5897ec138dd6067d781bf723a115d139533cae7 (patch)
tree3f9484ecaae858ea74d86fc6b04e5b50db2a5be9
parentab1671cafefcaf19ff6ac00a6cc7b36dfe16adcd (diff)
downloadcurl-bagder/http2-drained-remote-window.tar.gz
http2: make getsock not wait for write if there's no remote windowbagder/http2-drained-remote-window
While uploading, check for remote window availability in the getsock function so that we don't wait for a writable socket if no data can be sent. Reported-by: Steini2000 on github Fixes #7821
-rw-r--r--lib/http2.c26
1 files changed, 21 insertions, 5 deletions
diff --git a/lib/http2.c b/lib/http2.c
index 6d63f4363..992fbbb26 100644
--- a/lib/http2.c
+++ b/lib/http2.c
@@ -100,6 +100,7 @@ static int http2_getsock(struct Curl_easy *data,
const struct http_conn *c = &conn->proto.httpc;
struct SingleRequest *k = &data->req;
int bitmap = GETSOCK_BLANK;
+ struct HTTP *stream = data->req.p.http;
sock[0] = conn->sock[FIRSTSOCKET];
@@ -108,9 +109,13 @@ static int http2_getsock(struct Curl_easy *data,
frame so we should always be ready for one */
bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
- /* we're still uploading or the HTTP/2 layer wants to send data */
- if(((k->keepon & (KEEP_SEND|KEEP_SEND_PAUSE)) == KEEP_SEND) ||
- nghttp2_session_want_write(c->h2))
+ /* 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) ||
+ nghttp2_session_want_write(c->h2)) &&
+ (nghttp2_session_get_remote_window_size(c->h2) &&
+ nghttp2_session_get_stream_remote_window_size(c->h2,
+ stream->stream_id)))
bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
return bitmap;
@@ -1953,8 +1958,19 @@ static ssize_t http2_send(struct Curl_easy *data, int sockindex,
nghttp2_session_resume_data(h2, stream->stream_id);
}
- H2BUGF(infof(data, "http2_send returns %zu for stream %u", len,
- stream->stream_id));
+#ifdef DEBUG_HTTP2
+ if(!len) {
+ infof(data, "http2_send: easy %p (stream %u) win %u/%u",
+ data, stream->stream_id,
+ nghttp2_session_get_remote_window_size(httpc->h2),
+ nghttp2_session_get_stream_remote_window_size(httpc->h2,
+ stream->stream_id)
+ );
+
+ }
+ infof(data, "http2_send returns %zu for stream %u", len,
+ stream->stream_id);
+#endif
return len;
}