Author: remm Date: Mon Feb 12 20:48:40 2018 New Revision: 1824066 URL: http://svn.apache.org/viewvc?rev=1824066&view=rev Log: Loop over already read data rather than using unRead and reading the same data again.
Modified: tomcat/trunk/java/org/apache/coyote/http2/Http2AsyncParser.java Modified: tomcat/trunk/java/org/apache/coyote/http2/Http2AsyncParser.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http2/Http2AsyncParser.java?rev=1824066&r1=1824065&r2=1824066&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http2/Http2AsyncParser.java (original) +++ tomcat/trunk/java/org/apache/coyote/http2/Http2AsyncParser.java Mon Feb 12 20:48:40 2018 @@ -49,7 +49,7 @@ class Http2AsyncParser extends Http2Pars return super.readFrame(block, expected); } handleAsyncException(); - // TODO: examine if it could be possible to reuse byte buffers or loop over frame readings (= less unRead abuse) + // TODO: examine if it could be possible to reuse byte buffers ByteBuffer header = ByteBuffer.allocate(9); ByteBuffer framePaylod = ByteBuffer.allocate(input.getMaxFrameSize()); FrameCompletionHandler handler = new FrameCompletionHandler(expected, header, framePaylod); @@ -195,44 +195,71 @@ class Http2AsyncParser extends Http2Pars ByteBuffer payload = buffers[1]; payload.flip(); try { - if (streamException) { - swallow(streamId, payloadSize, false, payload); - } else { - switch (frameType) { - case DATA: - readDataFrame(streamId, flags, payloadSize, payload); - break; - case HEADERS: - readHeadersFrame(streamId, flags, payloadSize, payload); - break; - case PRIORITY: - readPriorityFrame(streamId, payload); - break; - case RST: - readRstFrame(streamId, payload); - break; - case SETTINGS: - readSettingsFrame(flags, payloadSize, payload); - break; - case PUSH_PROMISE: - readPushPromiseFrame(streamId, payload); - break; - case PING: - readPingFrame(flags, payload); - break; - case GOAWAY: - readGoawayFrame(payloadSize, payload); - break; - case WINDOW_UPDATE: - readWindowUpdateFrame(streamId, payload); - break; - case CONTINUATION: - readContinuationFrame(streamId, flags, payloadSize, payload); - break; - case UNKNOWN: - readUnknownFrame(streamId, frameType, flags, payloadSize, payload); + boolean continueParsing; + do { + continueParsing = false; + if (streamException) { + swallow(streamId, payloadSize, false, payload); + } else { + switch (frameType) { + case DATA: + readDataFrame(streamId, flags, payloadSize, payload); + break; + case HEADERS: + readHeadersFrame(streamId, flags, payloadSize, payload); + break; + case PRIORITY: + readPriorityFrame(streamId, payload); + break; + case RST: + readRstFrame(streamId, payload); + break; + case SETTINGS: + readSettingsFrame(flags, payloadSize, payload); + break; + case PUSH_PROMISE: + readPushPromiseFrame(streamId, payload); + break; + case PING: + readPingFrame(flags, payload); + break; + case GOAWAY: + readGoawayFrame(payloadSize, payload); + break; + case WINDOW_UPDATE: + readWindowUpdateFrame(streamId, payload); + break; + case CONTINUATION: + readContinuationFrame(streamId, flags, payloadSize, payload); + break; + case UNKNOWN: + readUnknownFrame(streamId, frameType, flags, payloadSize, payload); + } } - } + // See if there is a new 9 byte header and continue parsing if possible + if (payload.remaining() >= 9) { + int position = payload.position(); + payloadSize = ByteUtil.getThreeBytes(payload, position); + frameType = FrameType.valueOf(ByteUtil.getOneByte(payload, position + 3)); + flags = ByteUtil.getOneByte(payload, position + 4); + streamId = ByteUtil.get31Bits(payload, position + 5); + streamException = false; + if (payload.remaining() - 9 >= payloadSize) { + continueParsing = true; + // Now go over frame header + payload.position(payload.position() + 9); + try { + validateFrame(null, frameType, streamId, flags, payloadSize); + } catch (StreamException e) { + error = e; + streamException = true; + } catch (Http2Exception e) { + error = e; + continueParsing = false; + } + } + } + } while (continueParsing); } catch (Exception e) { error = e; } --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org