Author: markt Date: Mon May 23 12:52:06 2016 New Revision: 1745177 URL: http://svn.apache.org/viewvc?rev=1745177&view=rev Log: Further improvements to the handling of reset streams
Modified: tomcat/trunk/java/org/apache/coyote/http2/Stream.java tomcat/trunk/test/org/apache/coyote/http2/TestHttp2Section_5_1.java 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=1745177&r1=1745176&r2=1745177&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http2/Stream.java (original) +++ tomcat/trunk/java/org/apache/coyote/http2/Stream.java Mon May 23 12:52:06 2016 @@ -122,7 +122,16 @@ public class Stream extends AbstractStre log.debug(sm.getString("stream.reset.debug", getConnectionId(), getIdentifier(), Long.toString(errorCode))); } + // Set the new state first since read and write both check this state.receiveReset(); + // Reads wait internally so need to call a method to break the wait() + if (inputBuffer != null) { + inputBuffer.receiveReset(); + } + // Writes wait on Stream so we can notify directly + synchronized (this) { + this.notifyAll(); + } } @@ -603,6 +612,7 @@ public class Stream extends AbstractStre // 'write mode'. private volatile ByteBuffer inBuffer; private volatile boolean readInterest; + private boolean reset = false; @Override public int doRead(ByteChunk chunk) throws IOException { @@ -620,6 +630,10 @@ public class Stream extends AbstractStre log.debug(sm.getString("stream.inputBuffer.empty")); } inBuffer.wait(); + if (reset) { + // TODO: i18n + throw new IOException("HTTP/2 Stream reset"); + } } catch (InterruptedException e) { // Possible shutdown / rst or similar. Use an // IOException to signal to the client that further I/O @@ -729,5 +743,15 @@ public class Stream extends AbstractStre } } } + + + protected void receiveReset() { + if (inBuffer != null) { + synchronized (inBuffer) { + reset = true; + inBuffer.notifyAll(); + } + } + } } } Modified: tomcat/trunk/test/org/apache/coyote/http2/TestHttp2Section_5_1.java URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/coyote/http2/TestHttp2Section_5_1.java?rev=1745177&r1=1745176&r2=1745177&view=diff ============================================================================== --- tomcat/trunk/test/org/apache/coyote/http2/TestHttp2Section_5_1.java (original) +++ tomcat/trunk/test/org/apache/coyote/http2/TestHttp2Section_5_1.java Mon May 23 12:52:06 2016 @@ -250,4 +250,60 @@ public class TestHttp2Section_5_1 extend parser.readFrame(true); } } + + + @Test + public void testErrorOnWaitingStream() throws Exception { + // http2Connect() - modified + enableHttp2(1); + configureAndStartWebApplication(); + openClientConnection(); + doHttpUpgrade(); + sendClientPreface(); + + // validateHttp2InitialResponse() - modified + parser.readFrame(true); + parser.readFrame(true); + parser.readFrame(true); + parser.readFrame(true); + parser.readFrame(true); + + Assert.assertEquals("0-Settings-[3]-[1]\n" + + "0-Settings-End\n" + + "0-Settings-Ack\n" + + "0-Ping-[0,0,0,0,0,0,0,1]\n" + + getSimpleResponseTrace(1) + , output.getTrace()); + output.clearTrace(); + + sendLargeGetRequest(3); + + sendSimpleGetRequest(5); + + // Default connection window size is 64k-1. + // Initial request will have used 8k leaving 56k-1. + // Stream window will be 64k-1. + // Expecting + // 1 * headers + // 56k-1 of body (7 * ~8k) + // 1 * error (could be in any order) + for (int i = 0; i < 8; i++) { + parser.readFrame(true); + } + parser.readFrame(true); + + Assert.assertTrue(output.getTrace(), + output.getTrace().contains("5-RST-[" + + Http2Error.REFUSED_STREAM.getCode() + "]")); + output.clearTrace(); + + // Connection window is zero. + // Stream window is 8k + + // Expand the stream window too much to trigger an error + // Allow for the 8k still in the stream window + sendWindowUpdate(3, (1 << 31) - 1); + + parser.readFrame(true); + } } --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org