@Override
    public void readFrame(ChannelHandlerContext ctx, ByteBuf input, Http2FrameListener listener)
            throws Http2Exception {
        if (readError) {
            input.skipBytes(input.readableBytes());
            return;
        }
        try {
            do {
                if (readingHeaders && !preProcessFrame(input)) {
                    return;
                }
                // The header is complete, fall into the next case to process the payload.
                // This is to ensure the proper handling of zero-length payloads. In this
                // case, we don't want to loop around because there may be no more data
                // available, causing us to exit the loop. Instead, we just want to perform
                // the first pass at payload processing now.
                // Wait until the entire payload has been read.
                if (input.readableBytes() < payloadLength) {
                    return;
                }
                // Slice to work only on the frame being read
                ByteBuf framePayload = input.readSlice(payloadLength);
                // We have consumed the data for this frame, next time we read,
                // we will be expecting to read a new frame header.
                readingHeaders = true;
                verifyFrameState();
                processPayloadState(ctx, framePayload, listener);
            } 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);
        }
    }
@Test
    public void failedWhenUnknownFrameInMiddleOfHeaderBlock() throws Http2Exception {
        final int streamId = 1;

        final 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);

            Http2Exception ex = assertThrows(Http2Exception.class, new Executable() {
                @Override
                public void execute() throws Throwable {
                    frameReader.readFrame(ctx, input, listener);
                }
            });
            assertFalse(ex instanceof Http2Exception.StreamException);
        } finally {
            input.release();
        }
    }