DefaultHttp2FrameReader implements Http2FrameReader, Http2FrameSizePolicy, Configuration { @Override public void readFrame(ChannelHandlerContext ctx, ByteBuf input, Http2FrameListener listener) throws Http2Exception { if (readError) { input.skipBytes(input.readableBytes()); return; } try { do { if (readingHeaders) { processHeaderState(input); if (readingHeaders) { return; } } processPayloadState(ctx, input, listener); if (!readingHeaders) { return; } } while (input.isReadable()); } catch (Http2Exception e) { readError = !Http2Exception.isStreamError(e); throw e; } catch (RuntimeException e) { readError = true; throw e; } catch (Throwable cause) { readError = true; PlatformDependent.throwException(cause); } } DefaultHttp2FrameReader();  DefaultHttp2FrameReader(boolean validateHeaders);  DefaultHttp2FrameReader(Http2HeadersDecoder headersDecoder); @Override Http2HeadersDecoder.Configuration headersConfiguration(); @Override Configuration configuration(); @Override Http2FrameSizePolicy frameSizePolicy(); @Override void maxFrameSize(int max); @Override int maxFrameSize(); @Override void close(); @Override void readFrame(ChannelHandlerContext ctx, ByteBuf input, Http2FrameListener listener);  }
@Test public void readHeaderFrame() throws Http2Exception { final int streamId = 1; ByteBuf input = Unpooled.buffer(); try { Http2Headers headers = new DefaultHttp2Headers() .authority("foo") .method("get") .path("/") .scheme("https"); Http2Flags flags = new Http2Flags().endOfHeaders(true).endOfStream(true); writeHeaderFrame(input, streamId, headers, flags); frameReader.readFrame(ctx, input, listener); verify(listener).onHeadersRead(ctx, 1, headers, 0, true); } finally { input.release(); } }
@Test public void readHeaderFrameAndContinuationFrame() throws Http2Exception { final int streamId = 1; ByteBuf input = Unpooled.buffer(); try { Http2Headers headers = new DefaultHttp2Headers() .authority("foo") .method("get") .path("/") .scheme("https"); writeHeaderFrame(input, streamId, headers, new Http2Flags().endOfHeaders(false).endOfStream(true)); writeContinuationFrame(input, streamId, new DefaultHttp2Headers().add("foo", "bar"), new Http2Flags().endOfHeaders(true)); frameReader.readFrame(ctx, input, listener); verify(listener).onHeadersRead(ctx, 1, headers.add("foo", "bar"), 0, true); } finally { input.release(); } }
@Test(expected = Http2Exception.class) public void failedWhenUnknownFrameInMiddleOfHeaderBlock() throws Http2Exception { final int streamId = 1; ByteBuf input = Unpooled.buffer(); try { Http2Headers headers = new DefaultHttp2Headers() .authority("foo") .method("get") .path("/") .scheme("https"); Http2Flags flags = new Http2Flags().endOfHeaders(false).endOfStream(true); writeHeaderFrame(input, streamId, headers, flags); writeFrameHeader(input, 0, (byte) 0xff, new Http2Flags(), streamId); frameReader.readFrame(ctx, input, listener); } finally { input.release(); } }
@Test(expected = Http2Exception.class) public void failedWhenContinuationFrameStreamIdMismatch() throws Http2Exception { ByteBuf input = Unpooled.buffer(); try { Http2Headers headers = new DefaultHttp2Headers() .authority("foo") .method("get") .path("/") .scheme("https"); writeHeaderFrame(input, 1, headers, new Http2Flags().endOfHeaders(false).endOfStream(true)); writeContinuationFrame(input, 3, new DefaultHttp2Headers().add("foo", "bar"), new Http2Flags().endOfHeaders(true)); frameReader.readFrame(ctx, input, listener); } finally { input.release(); } }
@Test(expected = Http2Exception.class) public void failedWhenContinuationFrameNotFollowHeaderFrame() throws Http2Exception { ByteBuf input = Unpooled.buffer(); try { writeContinuationFrame(input, 1, new DefaultHttp2Headers().add("foo", "bar"), new Http2Flags().endOfHeaders(true)); frameReader.readFrame(ctx, input, listener); } finally { input.release(); } }
@Test(expected = Http2Exception.class) public void failedWhenHeaderFrameDependsOnItself() throws Http2Exception { ByteBuf input = Unpooled.buffer(); try { Http2Headers headers = new DefaultHttp2Headers() .authority("foo") .method("get") .path("/") .scheme("https"); writeHeaderFramePriorityPresent( input, 1, headers, new Http2Flags().endOfHeaders(true).endOfStream(true).priorityPresent(true), 1, 10); frameReader.readFrame(ctx, input, listener); } finally { input.release(); } }
@Test public void readHeaderAndData() throws Http2Exception { ByteBuf input = Unpooled.buffer(); ByteBuf dataPayload = Unpooled.buffer(); try { Http2Headers headers = new DefaultHttp2Headers() .authority("foo") .method("get") .path("/") .scheme("https"); dataPayload.writeByte(1); writeHeaderFrameWithData(input, 1, headers, dataPayload); frameReader.readFrame(ctx, input, listener); verify(listener).onHeadersRead(ctx, 1, headers, 0, false); verify(listener).onDataRead(ctx, 1, dataPayload.slice(0, 1), 0, true); } finally { input.release(); dataPayload.release(); } }
@Test(expected = Http2Exception.class) public void failedWhenDataFrameNotAssociateWithStream() throws Http2Exception { ByteBuf input = Unpooled.buffer(); ByteBuf payload = Unpooled.buffer(); try { payload.writeByte(1); writeFrameHeader(input, payload.readableBytes(), DATA, new Http2Flags().endOfStream(true), 0); input.writeBytes(payload); frameReader.readFrame(ctx, input, listener); } finally { payload.release(); input.release(); } }
@Test(expected = Http2Exception.class) public void failedWhenPriorityFrameDependsOnItself() throws Http2Exception { ByteBuf input = Unpooled.buffer(); try { writePriorityFrame(input, 1, 1, 10); frameReader.readFrame(ctx, input, listener); } finally { input.release(); } }
@Test(expected = Http2Exception.class) public void failedWhenWindowUpdateFrameWithZeroDelta() throws Http2Exception { ByteBuf input = Unpooled.buffer(); try { writeFrameHeader(input, 4, WINDOW_UPDATE, new Http2Flags(), 0); input.writeInt(0); frameReader.readFrame(ctx, input, listener); } finally { input.release(); } }
@Test public void readAckSettingsFrame() throws Http2Exception { ByteBuf input = Unpooled.buffer(); try { writeFrameHeader(input, 0, SETTINGS, new Http2Flags().ack(true), 0); frameReader.readFrame(ctx, input, listener); listener.onSettingsAckRead(ctx); } finally { input.release(); } }
@Test(expected = Http2Exception.class) public void failedWhenSettingsFrameOnNonZeroStream() throws Http2Exception { ByteBuf input = Unpooled.buffer(); try { writeFrameHeader(input, 6, SETTINGS, new Http2Flags(), 1); input.writeShort(SETTINGS_MAX_HEADER_LIST_SIZE); input.writeInt(1024); frameReader.readFrame(ctx, input, listener); } finally { input.release(); } }
@Test(expected = Http2Exception.class) public void failedWhenAckSettingsFrameWithPayload() throws Http2Exception { ByteBuf input = Unpooled.buffer(); try { writeFrameHeader(input, 1, SETTINGS, new Http2Flags().ack(true), 0); input.writeByte(1); frameReader.readFrame(ctx, input, listener); } finally { input.release(); } }
@Test(expected = Http2Exception.class) public void failedWhenSettingsFrameWithWrongPayloadLength() throws Http2Exception { ByteBuf input = Unpooled.buffer(); try { writeFrameHeader(input, 8, SETTINGS, new Http2Flags(), 0); input.writeInt(SETTINGS_MAX_HEADER_LIST_SIZE); input.writeInt(1024); frameReader.readFrame(ctx, input, listener); } finally { input.release(); } }