Skip to content

Commit

Permalink
Ensure that a Stream is only reset once. Second and subsequent resets
Browse files Browse the repository at this point in the history
are NO-OPs.
Ensure that a Stream is not reset when it is closed. Resetting a closed
stream is a NO-OP.
Ensure that IDLE streams are not reset. Resetting an IDLE stream
triggers an ISE.

git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@1708465 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information
markt-asf committed Oct 13, 2015
1 parent e808894 commit 687c71f
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 20 deletions.
34 changes: 16 additions & 18 deletions java/org/apache/coyote/http2/Http2UpgradeHandler.java
Expand Up @@ -410,25 +410,23 @@ void resetStream(StreamException se) throws ConnectionException, IOException {
} }


Stream stream = getStream(se.getStreamId(), false); Stream stream = getStream(se.getStreamId(), false);
if (stream != null) { if (stream != null && stream.sendReset()) {
stream.sendRst(); // Write a RST frame
} byte[] rstFrame = new byte[13];
// Length
ByteUtil.setThreeBytes(rstFrame, 0, 4);
// Type
rstFrame[3] = FrameType.RST.getIdByte();
// No flags
// Stream ID
ByteUtil.set31Bits(rstFrame, 5, se.getStreamId());
// Payload
ByteUtil.setFourBytes(rstFrame, 9, se.getError().getCode());


// Write a RST frame synchronized (socketWrapper) {
byte[] rstFrame = new byte[13]; socketWrapper.write(true, rstFrame, 0, rstFrame.length);
// Length socketWrapper.flush(true);
ByteUtil.setThreeBytes(rstFrame, 0, 4); }
// Type
rstFrame[3] = FrameType.RST.getIdByte();
// No flags
// Stream ID
ByteUtil.set31Bits(rstFrame, 5, se.getStreamId());
// Payload
ByteUtil.setFourBytes(rstFrame, 9, se.getError().getCode());

synchronized (socketWrapper) {
socketWrapper.write(true, rstFrame, 0, rstFrame.length);
socketWrapper.flush(true);
} }
} }


Expand Down
17 changes: 15 additions & 2 deletions java/org/apache/coyote/http2/Stream.java
Expand Up @@ -314,8 +314,21 @@ StreamOutputBuffer getOutputBuffer() {
} }




void sendRst() { /**
state.sendReset(); * 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>
*
* @return <code>true</code> if a reset frame needs to be sent to the peer,
* otherwise <code>false</code>
*
* @throws IllegalStateException If the stream is in a state that does not
* permit resets
*/
boolean sendReset() {
return state.sendReset();
} }




Expand Down

0 comments on commit 687c71f

Please sign in to comment.