Author: markt Date: Tue Jun 2 09:45:31 2015 New Revision: 1683064 URL: http://svn.apache.org/r1683064 Log: Copy (untested) priority frame support from Http2UpgradeHandler to Http2Parser
Modified: tomcat/trunk/java/org/apache/coyote/http2/Http2Parser.java tomcat/trunk/java/org/apache/coyote/http2/LocalStrings.properties Modified: tomcat/trunk/java/org/apache/coyote/http2/Http2Parser.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http2/Http2Parser.java?rev=1683064&r1=1683063&r2=1683064&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http2/Http2Parser.java (original) +++ tomcat/trunk/java/org/apache/coyote/http2/Http2Parser.java Tue Jun 2 09:45:31 2015 @@ -35,6 +35,7 @@ class Http2Parser implements HeaderEmitt private static final int FRAME_TYPE_DATA = 0; private static final int FRAME_TYPE_HEADERS = 1; + private static final int FRAME_TYPE_PRIORITY = 2; private static final int FRAME_TYPE_SETTINGS = 4; private final String connectionId; @@ -91,6 +92,9 @@ class Http2Parser implements HeaderEmitt case FRAME_TYPE_HEADERS: readHeadersFrame(streamId, flags, payloadSize); break; + case FRAME_TYPE_PRIORITY: + processFramePriority(streamId, flags, payloadSize); + break; case FRAME_TYPE_SETTINGS: readSettingsFrame(streamId, flags, payloadSize); break; @@ -148,45 +152,6 @@ class Http2Parser implements HeaderEmitt } - private void readSettingsFrame(int streamId, int flags, int payloadSize) throws IOException { - if (log.isDebugEnabled()) { - log.debug(sm.getString("http2Parser.processFrame", connectionId, - Integer.toString(streamId), Integer.toString(flags), - Integer.toString(payloadSize))); - } - - // Validate the frame - if (streamId != 0) { - throw new Http2Exception(sm.getString("http2Parser.processFrameSettings.invalidStream", - Integer.toString(streamId)), 0, Http2Exception.FRAME_SIZE_ERROR); - } - if (payloadSize % 6 != 0) { - throw new Http2Exception(sm.getString("http2Parser.processFrameSettings.invalidPayloadSize", - Integer.toString(payloadSize)), 0, Http2Exception.FRAME_SIZE_ERROR); - } - if (payloadSize > 0 && (flags & 0x1) != 0) { - throw new Http2Exception(sm.getString("http2Parser.processFrameSettings.ackWithNonZeroPayload"), - 0, Http2Exception.FRAME_SIZE_ERROR); - } - - if (payloadSize == 0) { - // Either an ACK or an empty settings frame - if ((flags & 0x1) != 0) { - output.settingsAck(); - } - } else { - // Process the settings - byte[] setting = new byte[6]; - for (int i = 0; i < payloadSize / 6; i++) { - input.fill(true, setting); - int id = ByteUtil.getTwoBytes(setting, 0); - long value = ByteUtil.getFourBytes(setting, 2); - output.setting(id, value); - } - } - } - - private void readHeadersFrame(int streamId, int flags, int payloadSize) throws IOException { if (log.isDebugEnabled()) { log.debug(sm.getString("http2Parser.processFrame", connectionId, @@ -266,6 +231,72 @@ class Http2Parser implements HeaderEmitt } + private void processFramePriority(int flags, int streamId, int payloadSize) throws IOException { + if (log.isDebugEnabled()) { + log.debug(sm.getString("http2Parser.processFrame", connectionId, + Integer.toString(streamId), Integer.toString(flags), + Integer.toString(payloadSize))); + } + // Validate the frame + if (streamId == 0) { + throw new Http2Exception(sm.getString("http2Parser.processFramePriority.invalidStream"), + 0, Http2Exception.PROTOCOL_ERROR); + } + if (payloadSize != 5) { + throw new Http2Exception(sm.getString("http2Parser.processFramePriority.invalidPayloadSize", + Integer.toString(payloadSize)), streamId, Http2Exception.FRAME_SIZE_ERROR); + } + + byte[] payload = new byte[5]; + input.fill(true, payload); + + boolean exclusive = ByteUtil.isBit7Set(payload[0]); + int parentStreamId = ByteUtil.get31Bits(payload, 0); + int weight = ByteUtil.getOneByte(payload, 4) + 1; + + output.reprioritise(streamId, parentStreamId, exclusive, weight); + } + + + private void readSettingsFrame(int streamId, int flags, int payloadSize) throws IOException { + if (log.isDebugEnabled()) { + log.debug(sm.getString("http2Parser.processFrame", connectionId, + Integer.toString(streamId), Integer.toString(flags), + Integer.toString(payloadSize))); + } + + // Validate the frame + if (streamId != 0) { + throw new Http2Exception(sm.getString("http2Parser.processFrameSettings.invalidStream", + Integer.toString(streamId)), 0, Http2Exception.FRAME_SIZE_ERROR); + } + if (payloadSize % 6 != 0) { + throw new Http2Exception(sm.getString("http2Parser.processFrameSettings.invalidPayloadSize", + Integer.toString(payloadSize)), 0, Http2Exception.FRAME_SIZE_ERROR); + } + if (payloadSize > 0 && (flags & 0x1) != 0) { + throw new Http2Exception(sm.getString("http2Parser.processFrameSettings.ackWithNonZeroPayload"), + 0, Http2Exception.FRAME_SIZE_ERROR); + } + + if (payloadSize == 0) { + // Either an ACK or an empty settings frame + if ((flags & 0x1) != 0) { + output.settingsAck(); + } + } else { + // Process the settings + byte[] setting = new byte[6]; + for (int i = 0; i < payloadSize / 6; i++) { + input.fill(true, setting); + int id = ByteUtil.getTwoBytes(setting, 0); + long value = ByteUtil.getFourBytes(setting, 2); + output.setting(id, value); + } + } + } + + private void readUnknownFrame(int streamId, int frameType, int flags, int payloadSize) throws IOException { output.swallow(streamId, frameType, flags, payloadSize); 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=1683064&r1=1683063&r2=1683064&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http2/LocalStrings.properties (original) +++ tomcat/trunk/java/org/apache/coyote/http2/LocalStrings.properties Tue Jun 2 09:45:31 2015 @@ -40,6 +40,8 @@ http2Parser.processFrameData.invalidStre http2Parser.processFrameHeaders.invalidStream=Headers frame received for stream [0] http2Parser.processFrameHeaders.decodingFailed=There was an error during the HPACK decoding of HTTP headers http2Parser.processFrameHeaders.decodingDataLeft=Data left over after HPACK decoding - it should have been consumed +http2Parser.processFramePriority.invalidPayloadSize=Priority frame received with an invalid payload size of [{0}] (should be 5) +http2Parser.processFramePriority.invalidStream=Priority frame received for stream [0] http2Parser.processFrameSettings.ackWithNonZeroPayload=Settings frame received with the ACK flag set and payload present http2Parser.processFrameSettings.invalidPayloadSize=Settings frame received with a payload size of [{0}] which is not a multiple of 6 http2Parser.processFrameSettings.invalidStream=Settings frame received for stream [{0}] --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org