[tomcat] 02/03: Keep connection flow control window consistent with initial window size.

2019-09-05 Thread markt
This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch 8.5.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit 7e344a6f84d9e30340ac532d011c244293e2f15f
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.
---
 .../apache/coyote/http2/Http2UpgradeHandler.java   | 33 ++
 webapps/docs/changelog.xml |  6 
 2 files changed, 39 insertions(+)

diff --git a/java/org/apache/coyote/http2/Http2UpgradeHandler.java 
b/java/org/apache/coyote/http2/Http2UpgradeHandler.java
index d99e150..adeafa9 100644
--- a/java/org/apache/coyote/http2/Http2UpgradeHandler.java
+++ b/java/org/apache/coyote/http2/Http2UpgradeHandler.java
@@ -568,11 +568,21 @@ public class Http2UpgradeHandler extends AbstractStream 
implements InternalHttpU
 }
 
 
+/**
+ * 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).
+ */
 private 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);
@@ -584,6 +594,29 @@ public class Http2UpgradeHandler extends AbstractStream 
implements InternalHttpU
 }
 
 
+/**
+ * @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;
+}
+
+
 private 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 d6d889b..16c6b8c 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -64,6 +64,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 flow control window for the
+connection is consistent with the increased value. (markt)
+  
 
   
   


-
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org



[tomcat] 02/03: Keep connection flow control window consistent with initial window size.

2019-09-05 Thread markt
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