This is an automated email from the ASF dual-hosted git repository.
markt pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit 69d7c0435c17444d5314da2d237e7468538e869a
Author: Mark Thomas
AuthorDate: Thu Sep 5 14:48:46 2019 +0100
Keep connection flow control window consistent with initial window size.
If the HTTP/2 connection requires an initial window size larger than the
default, send a WINDOW_UPDATE to increase the flow control window for
the connection so that the initial size of the flow control window for
the connection is consistent with the increased value.
---
.../coyote/http2/Http2AsyncUpgradeHandler.java | 4 +--
.../apache/coyote/http2/Http2UpgradeHandler.java | 33 ++
webapps/docs/changelog.xml | 6
3 files changed, 41 insertions(+), 2 deletions(-)
diff --git a/java/org/apache/coyote/http2/Http2AsyncUpgradeHandler.java
b/java/org/apache/coyote/http2/Http2AsyncUpgradeHandler.java
index 92ad29c..545292f 100644
--- a/java/org/apache/coyote/http2/Http2AsyncUpgradeHandler.java
+++ b/java/org/apache/coyote/http2/Http2AsyncUpgradeHandler.java
@@ -105,10 +105,10 @@ public class Http2AsyncUpgradeHandler extends
Http2UpgradeHandler {
@Override
protected void writeSettings() {
-// Send the initial settings frame
socketWrapper.write(BlockingMode.SEMI_BLOCK,
protocol.getWriteTimeout(),
TimeUnit.MILLISECONDS, null, SocketWrapperBase.COMPLETE_WRITE,
errorCompletion,
-ByteBuffer.wrap(localSettings.getSettingsFrameForPending()));
+ByteBuffer.wrap(localSettings.getSettingsFrameForPending()),
+ByteBuffer.wrap(createWindowUpdateForSettings()));
if (error != null) {
String msg = sm.getString("upgradeHandler.sendPrefaceFail",
connectionId);
if (log.isDebugEnabled()) {
diff --git a/java/org/apache/coyote/http2/Http2UpgradeHandler.java
b/java/org/apache/coyote/http2/Http2UpgradeHandler.java
index f395d10..9753ebc 100644
--- a/java/org/apache/coyote/http2/Http2UpgradeHandler.java
+++ b/java/org/apache/coyote/http2/Http2UpgradeHandler.java
@@ -560,11 +560,21 @@ class Http2UpgradeHandler extends AbstractStream
implements InternalHttpUpgradeH
}
+/**
+ * Write the initial settings frame and any necessary supporting frames. If
+ * the initial settings increase the initial window size, it will also be
+ * necessary to send a WINDOW_UPDATE frame to increase the size of the flow
+ * control window for the connection (stream 0).
+ */
protected void writeSettings() {
// Send the initial settings frame
try {
byte[] settings = localSettings.getSettingsFrameForPending();
socketWrapper.write(true, settings, 0, settings.length);
+byte[] windowUpdateFrame = createWindowUpdateForSettings();
+if (windowUpdateFrame.length > 0) {
+socketWrapper.write(true, windowUpdateFrame, 0 ,
windowUpdateFrame.length);
+}
socketWrapper.flush(true);
} catch (IOException ioe) {
String msg = sm.getString("upgradeHandler.sendPrefaceFail",
connectionId);
@@ -576,6 +586,29 @@ class Http2UpgradeHandler extends AbstractStream
implements InternalHttpUpgradeH
}
+/**
+ * @return The WINDOW_UPDATE frame if one is required or an empty array if
+ * no WINDOW_UPDATE is required.
+ */
+protected byte[] createWindowUpdateForSettings() {
+// Build a WINDOW_UPDATE frame if one is required. If not, create an
+// empty byte array.
+byte[] windowUpdateFrame;
+int increment = protocol.getInitialWindowSize() -
ConnectionSettingsBase.DEFAULT_INITIAL_WINDOW_SIZE;
+if (increment > 0) {
+// Build window update frame for stream 0
+windowUpdateFrame = new byte[13];
+ByteUtil.setThreeBytes(windowUpdateFrame, 0, 4);
+windowUpdateFrame[3] = FrameType.WINDOW_UPDATE.getIdByte();
+ByteUtil.set31Bits(windowUpdateFrame, 9, increment);
+} else {
+windowUpdateFrame = new byte[0];
+}
+
+return windowUpdateFrame;
+}
+
+
protected void writeGoAwayFrame(int maxStreamId, long errorCode, byte[]
debugMsg)
throws IOException {
byte[] fixedPayload = new byte[8];
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 6e907c9..b91c956 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -68,6 +68,12 @@
overheadDataThreshold and
overheadWindowUpdateThreshold. (markt)
+
+If the HTTP/2 connection requires an initial window size larger than
the
+default, send a WINDOW_UPDATE to increase the flow control window for
the
+connection so that the initial size of the flo