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 <ma...@apache.org> 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 @@ <code>overheadDataThreshold</code> and <code>overheadWindowUpdateThreshold</code>. (markt) </fix> + <fix> + 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) + </fix> </changelog> </subsection> <subsection name="Web applications"> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org