Author: markt Date: Thu Mar 15 14:10:17 2018 New Revision: 1826817 URL: http://svn.apache.org/viewvc?rev=1826817&view=rev Log: Fix https://bz.apache.org/bugzilla/show_bug.cgi?id=62177 Correct two protocol errors with HTTP/2 PUSH_PROMISE frames. Firstly, the HTTP/2 protocol only permits pushes to be sent on peer initiated requests. Secondly, pushes must be sent in order of increasing stream ID. These restriction were not being enforced leading to protocol errors at the client.
Modified: tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java tomcat/trunk/java/org/apache/coyote/http2/Stream.java tomcat/trunk/webapps/docs/changelog.xml Modified: tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java?rev=1826817&r1=1826816&r2=1826817&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java (original) +++ tomcat/trunk/java/org/apache/coyote/http2/Http2UpgradeHandler.java Thu Mar 15 14:10:17 2018 @@ -1122,11 +1122,18 @@ class Http2UpgradeHandler extends Abstra void push(Request request, Stream associatedStream) throws IOException { - Stream pushStream = createLocalStream(request); + Stream pushStream; - // TODO: Is 1k the optimal value? - writeHeaders(associatedStream, pushStream.getIdentifier().intValue(), - request.getMimeHeaders(), false, 1024); + // Synchronized since PUSH_PROMISE frames have to be sent in order. Once + // the stream has been created we need to ensure that the PUSH_PROMISE + // is sent before the next stream is created for a PUSH_PROMISE. + synchronized (socketWrapper) { + pushStream = createLocalStream(request); + + // TODO: Is 1k the optimal value? + writeHeaders(associatedStream, pushStream.getIdentifier().intValue(), + request.getMimeHeaders(), false, 1024); + } pushStream.sentPushPromise(); Modified: tomcat/trunk/java/org/apache/coyote/http2/Stream.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http2/Stream.java?rev=1826817&r1=1826816&r2=1826817&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http2/Stream.java (original) +++ tomcat/trunk/java/org/apache/coyote/http2/Stream.java Thu Mar 15 14:10:17 2018 @@ -624,7 +624,8 @@ class Stream extends AbstractStream impl final void push(Request request) throws IOException { - if (!isPushSupported()) { + // Can only push when supported and from a peer initiated stream + if (!isPushSupported() || getIdentifier().intValue() % 2 == 0) { return; } // Set the special HTTP/2 headers Modified: tomcat/trunk/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1826817&r1=1826816&r2=1826817&view=diff ============================================================================== --- tomcat/trunk/webapps/docs/changelog.xml (original) +++ tomcat/trunk/webapps/docs/changelog.xml Thu Mar 15 14:10:17 2018 @@ -85,6 +85,13 @@ <fix> The OpenSSL engine SSL session will now ignore invalid accesses. (remm) </fix> + <fix> + <bug>62177</bug>: Correct two protocol errors with HTTP/2 + <code>PUSH_PROMISE</code> frames. Firstly, the HTTP/2 protocol only + permits pushes to be sent on peer initiated requests. Secondly, pushes + must be sent in order of increasing stream ID. These restriction were + not being enforced leading to protocol errors at the client. (markt) + </fix> </changelog> </subsection> <subsection name="jdbc-pool"> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org