Author: markt Date: Wed Oct 26 17:58:06 2016 New Revision: 1766714 URL: http://svn.apache.org/viewvc?rev=1766714&view=rev Log: Don't call receiveReset when sending a reset. Restore the sendReset() method on the state machine and use it as intended
Modified: tomcat/trunk/java/org/apache/coyote/http2/LocalStrings.properties tomcat/trunk/java/org/apache/coyote/http2/Stream.java tomcat/trunk/java/org/apache/coyote/http2/StreamStateMachine.java Modified: tomcat/trunk/java/org/apache/coyote/http2/LocalStrings.properties URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http2/LocalStrings.properties?rev=1766714&r1=1766713&r2=1766714&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http2/LocalStrings.properties (original) +++ tomcat/trunk/java/org/apache/coyote/http2/LocalStrings.properties Wed Oct 26 17:58:06 2016 @@ -75,8 +75,9 @@ stream.header.unexpectedPseudoHeader=Con stream.header.unknownPseudoHeader=Connection [{0}], Stream [{1}], Unknown pseduo header [{2}] received stream.notWritable=Connection [{0}], Stream [{1}], This stream is not writable stream.reprioritisation.debug=Connection [{0}], Stream [{1}], Exclusive [{2}], Parent [{3}], Weight [{4}] -stream.reset.debug=Connection [{0}], Stream [{1}], Reset due to [{2}] stream.reset.fail=Connection [{0}], Stream [{1}], Failed to reset stream +stream.reset.receive=Connection [{0}], Stream [{1}], Reset received due to [{2}] +stream.reset.send=Connection [{0}], Stream [{1}], Reset sent due to [{2}] stream.trialerHeader.noEndOfStream=Connection [{0}], Stream [{1}], The trailer headers did not include the end of stream flag stream.write=Connection [{0}], Stream [{1}] 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=1766714&r1=1766713&r2=1766714&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http2/Stream.java (original) +++ tomcat/trunk/java/org/apache/coyote/http2/Stream.java Wed Oct 26 17:58:06 2016 @@ -130,7 +130,7 @@ class Stream extends AbstractStream impl final void receiveReset(long errorCode) { if (log.isDebugEnabled()) { - log.debug(sm.getString("stream.reset.debug", getConnectionId(), getIdentifier(), + log.debug(sm.getString("stream.reset.receive", getConnectionId(), getIdentifier(), Long.toString(errorCode))); } // Set the new state first since read and write both check this @@ -434,7 +434,11 @@ class Stream extends AbstractStream impl if (http2Exception instanceof StreamException) { try { StreamException se = (StreamException) http2Exception; - receiveReset(se.getError().getCode()); + if (log.isDebugEnabled()) { + log.debug(sm.getString("stream.reset.send", getConnectionId(), getIdentifier(), + Long.toString(se.getError().getCode()))); + } + state.sendReset(); handler.sendStreamReset(se); } catch (IOException ioe) { ConnectionException ce = new ConnectionException( Modified: tomcat/trunk/java/org/apache/coyote/http2/StreamStateMachine.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http2/StreamStateMachine.java?rev=1766714&r1=1766713&r2=1766714&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http2/StreamStateMachine.java (original) +++ tomcat/trunk/java/org/apache/coyote/http2/StreamStateMachine.java Wed Oct 26 17:58:06 2016 @@ -71,6 +71,28 @@ class StreamStateMachine { } + /** + * Marks the stream as reset. This method will not change the stream state + * if: + * <ul> + * <li>The stream is already reset</li> + * <li>The stream is already closed</li> + * </ul> + * + * @throws IllegalStateException If the stream is in a state that does not + * permit resets + */ + public synchronized void sendReset() { + if (state == State.IDLE) { + throw new IllegalStateException(sm.getString("streamStateMachine.debug.change", + stream.getConnectionId(), stream.getIdentifier(), state)); + } + if (state.canReset()) { + stateChange(state, State.CLOSED_RST_TX); + } + } + + final synchronized void receivedReset() { stateChange(state, State.CLOSED_RST_RX); } @@ -129,52 +151,66 @@ class StreamStateMachine { private enum State { - IDLE (false, false, true, Http2Error.PROTOCOL_ERROR, FrameType.HEADERS, - FrameType.PRIORITY), - OPEN (true, true, true, Http2Error.PROTOCOL_ERROR, FrameType.DATA, - FrameType.HEADERS, - FrameType.PRIORITY, - FrameType.RST, - FrameType.PUSH_PROMISE, - FrameType.WINDOW_UPDATE), - RESERVED_LOCAL (false, false, true, Http2Error.PROTOCOL_ERROR, FrameType.PRIORITY, - FrameType.RST, - FrameType.WINDOW_UPDATE), - RESERVED_REMOTE (false, false, true, Http2Error.PROTOCOL_ERROR, FrameType.HEADERS, - FrameType.PRIORITY, - FrameType.RST), - HALF_CLOSED_LOCAL (true, false, true, Http2Error.PROTOCOL_ERROR, FrameType.DATA, - FrameType.HEADERS, - FrameType.PRIORITY, - FrameType.RST, - FrameType.PUSH_PROMISE, - FrameType.WINDOW_UPDATE), - HALF_CLOSED_REMOTE (false, true, true, Http2Error.STREAM_CLOSED, FrameType.PRIORITY, - FrameType.RST, - FrameType.WINDOW_UPDATE), - CLOSED_RX (false, false, true, Http2Error.STREAM_CLOSED, FrameType.PRIORITY), - CLOSED_TX (false, false, true, Http2Error.STREAM_CLOSED, FrameType.PRIORITY, - FrameType.RST, - FrameType.WINDOW_UPDATE), - CLOSED_RST_RX (false, false, false, Http2Error.STREAM_CLOSED, FrameType.PRIORITY), - CLOSED_RST_TX (false, false, false, Http2Error.STREAM_CLOSED, FrameType.DATA, - FrameType.HEADERS, - FrameType.PRIORITY, - FrameType.RST, - FrameType.PUSH_PROMISE, - FrameType.WINDOW_UPDATE), - CLOSED_FINAL (false, false, true, Http2Error.PROTOCOL_ERROR, FrameType.PRIORITY); + IDLE (false, false, false, true, + Http2Error.PROTOCOL_ERROR, FrameType.HEADERS, + FrameType.PRIORITY), + OPEN (true, true, true, true, + Http2Error.PROTOCOL_ERROR, FrameType.DATA, + FrameType.HEADERS, + FrameType.PRIORITY, + FrameType.RST, + FrameType.PUSH_PROMISE, + FrameType.WINDOW_UPDATE), + RESERVED_LOCAL (false, false, true, true, + Http2Error.PROTOCOL_ERROR, FrameType.PRIORITY, + FrameType.RST, + FrameType.WINDOW_UPDATE), + RESERVED_REMOTE (false, false, true, true, + Http2Error.PROTOCOL_ERROR, FrameType.HEADERS, + FrameType.PRIORITY, + FrameType.RST), + HALF_CLOSED_LOCAL (true, false, true, true, + Http2Error.PROTOCOL_ERROR, FrameType.DATA, + FrameType.HEADERS, + FrameType.PRIORITY, + FrameType.RST, + FrameType.PUSH_PROMISE, + FrameType.WINDOW_UPDATE), + HALF_CLOSED_REMOTE (false, true, true, true, + Http2Error.STREAM_CLOSED, FrameType.PRIORITY, + FrameType.RST, + FrameType.WINDOW_UPDATE), + CLOSED_RX (false, false, false, true, + Http2Error.STREAM_CLOSED, FrameType.PRIORITY), + CLOSED_TX (false, false, false, true, + Http2Error.STREAM_CLOSED, FrameType.PRIORITY, + FrameType.RST, + FrameType.WINDOW_UPDATE), + CLOSED_RST_RX (false, false, false, false, + Http2Error.STREAM_CLOSED, FrameType.PRIORITY), + CLOSED_RST_TX (false, false, false, false, + Http2Error.STREAM_CLOSED, FrameType.DATA, + FrameType.HEADERS, + FrameType.PRIORITY, + FrameType.RST, + FrameType.PUSH_PROMISE, + FrameType.WINDOW_UPDATE), + CLOSED_FINAL (false, false, false, true, + Http2Error.PROTOCOL_ERROR, FrameType.PRIORITY); private final boolean canRead; private final boolean canWrite; + private final boolean canReset; private final boolean connectionErrorForInvalidFrame; private final Http2Error errorCodeForInvalidFrame; private final Set<FrameType> frameTypesPermitted = new HashSet<>(); - private State(boolean canRead, boolean canWrite, boolean connectionErrorForInvalidFrame, - Http2Error errorCode, FrameType... frameTypes) { + private State(boolean canRead, boolean canWrite, boolean canReset, + boolean connectionErrorForInvalidFrame, Http2Error errorCode, + FrameType... frameTypes) { this.canRead = canRead; this.canWrite = canWrite; + this.canReset = canReset; this.connectionErrorForInvalidFrame = connectionErrorForInvalidFrame; this.errorCodeForInvalidFrame = errorCode; for (FrameType frameType : frameTypes) { @@ -190,6 +226,10 @@ class StreamStateMachine { return canWrite; } + public boolean canReset() { + return canReset; + } + public boolean isFrameTypePermitted(FrameType frameType) { return frameTypesPermitted.contains(frameType); } --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org