]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
http2: enlarge the connection window
authorStefan Eissing <stefan@eissing.org>
Thu, 27 Apr 2023 13:18:22 +0000 (15:18 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Thu, 27 Apr 2023 15:44:55 +0000 (17:44 +0200)
- fixes stalled connections

- Make the connection window large enough, so that there is
  some room left should 99/100 streams be PAUSED by the application

Reported-by: Paweł Wegner
Fixes #10988
Closes #11043

lib/http2.c

index cdabb6f6c04cafaa4fab8c9dbe646acbbabb65ba..0e361ab487e0ead29f9bf00ea6027a002cdcfb29 100644 (file)
 /* spare chunks we keep for a full window */
 #define H2_STREAM_POOL_SPARES   (H2_STREAM_WINDOW_SIZE / H2_CHUNK_SIZE)
 
-#define HTTP2_HUGE_WINDOW_SIZE (16 * H2_STREAM_WINDOW_SIZE)
+/* We need to accomodate the max number of streams with their window
+ * sizes on the overall connection. Streams might become PAUSED which
+ * will block their received QUOTA in the connection window. And if we
+ * run out of space, the server is blocked from sending us any data.
+ * See #10988 for an issue with this. */
+#define HTTP2_HUGE_WINDOW_SIZE (100 * H2_STREAM_WINDOW_SIZE)
 
 #define H2_SETTINGS_IV_LEN  3
 #define H2_BINSETTINGS_LEN 80
@@ -1018,7 +1023,7 @@ static CURLcode on_stream_frame(struct Curl_cfilter *cf,
     }
     break;
   case NGHTTP2_RST_STREAM:
-    DEBUGF(LOG_CF(data, cf, "[h2sid=%d] FARME[RST]", stream_id));
+    DEBUGF(LOG_CF(data, cf, "[h2sid=%d] FRAME[RST]", stream_id));
     stream->closed = TRUE;
     stream->reset = TRUE;
     drain_stream(cf, data, stream);
@@ -1813,13 +1818,15 @@ out:
     nread = -1;
   }
   DEBUGF(LOG_CF(data, cf, "[h2sid=%d] cf_recv(len=%zu) -> %zd %d, "
-                "buffered=%zu, window=%d/%d",
+                "buffered=%zu, window=%d/%d, connection %d/%d",
                 stream->id, len, nread, *err,
                 Curl_bufq_len(&stream->recvbuf),
                 nghttp2_session_get_stream_effective_recv_data_length(
                   ctx->h2, stream->id),
                 nghttp2_session_get_stream_effective_local_window_size(
-                  ctx->h2, stream->id)));
+                  ctx->h2, stream->id),
+                nghttp2_session_get_effective_local_window_size(ctx->h2),
+                HTTP2_HUGE_WINDOW_SIZE));
 
   CF_DATA_RESTORE(cf, save);
   return nread;