private void readPushPromiseFrame( final ChannelHandlerContext ctx, ByteBuf payload, Http2FrameObserver observer) throws Http2Exception { final int pushPromiseStreamId = streamId; int padding = flags.readPaddingLength(payload); final int promisedStreamId = readUnsignedInt(payload); // Create a handler that invokes the observer when the header block is complete. headersContinuation = new HeadersContinuation() { @Override public int getStreamId() { return pushPromiseStreamId; } @Override public void processFragment( boolean endOfHeaders, ByteBuf fragment, int padding, Http2FrameObserver observer) throws Http2Exception { builder().addFragment(fragment, ctx.alloc(), endOfHeaders); if (endOfHeaders) { Http2Headers headers = builder().buildHeaders(); observer.onPushPromiseRead( ctx, pushPromiseStreamId, promisedStreamId, headers, padding); close(); } } }; // Process the initial fragment, invoking the observer's callback if end of headers. final ByteBuf fragment = payload.readSlice(payload.readableBytes() - padding); headersContinuation.processFragment(flags.endOfHeaders(), fragment, padding, observer); }
private void readContinuationFrame(ByteBuf payload, Http2FrameObserver observer) throws Http2Exception { int padding = flags.readPaddingLength(payload); // Process the initial fragment, invoking the observer's callback if end of headers. final ByteBuf continuationFragment = payload.readSlice(payload.readableBytes() - padding); headersContinuation.processFragment( flags.endOfHeaders(), continuationFragment, padding, observer); }
private void verifyContinuationFrame() throws Http2Exception { verifyPayloadLength(payloadLength); if (headersContinuation == null) { throw protocolError("Received %s frame but not currently processing headers.", frameType); } if (streamId != headersContinuation.getStreamId()) { throw protocolError( "Continuation stream ID does not match pending headers. " + "Expected %d, but received %d.", headersContinuation.getStreamId(), streamId); } if (!flags.isPaddingLengthValid()) { throw protocolError("Pad high is set but pad low is not"); } if (payloadLength < flags.getNumPaddingLengthBytes()) { throw protocolError("Frame length %d too small for padding.", payloadLength); } }
@Override public void close() { if (headersContinuation != null) { headersContinuation.close(); } }
private void readHeadersFrame( final ChannelHandlerContext ctx, ByteBuf payload, Http2FrameObserver observer) throws Http2Exception { final int headersStreamId = streamId; final Http2Flags headersFlags = flags; int padding = flags.readPaddingLength(payload); // The callback that is invoked is different depending on whether priority information // is present in the headers frame. if (flags.priorityPresent()) { long word1 = payload.readUnsignedInt(); final boolean exclusive = (word1 & 0x80000000L) > 0; final int streamDependency = (int) (word1 & 0x7FFFFFFFL); final short weight = (short) (payload.readUnsignedByte() + 1); final ByteBuf fragment = payload.readSlice(payload.readableBytes() - padding); // Create a handler that invokes the observer when the header block is complete. headersContinuation = new HeadersContinuation() { @Override public int getStreamId() { return headersStreamId; } @Override public void processFragment( boolean endOfHeaders, ByteBuf fragment, int padding, Http2FrameObserver observer) throws Http2Exception { builder().addFragment(fragment, ctx.alloc(), endOfHeaders); if (endOfHeaders) { Http2Headers headers = builder().buildHeaders(); observer.onHeadersRead( ctx, headersStreamId, headers, streamDependency, weight, exclusive, padding, headersFlags.endOfStream(), headersFlags.endOfSegment()); close(); } } }; // Process the initial fragment, invoking the observer's callback if end of headers. headersContinuation.processFragment(flags.endOfHeaders(), fragment, padding, observer); return; } // The priority fields are not present in the frame. Prepare a continuation that invokes // the observer callback without priority information. headersContinuation = new HeadersContinuation() { @Override public int getStreamId() { return headersStreamId; } @Override public void processFragment( boolean endOfHeaders, ByteBuf fragment, int padding, Http2FrameObserver observer) throws Http2Exception { builder().addFragment(fragment, ctx.alloc(), endOfHeaders); if (endOfHeaders) { Http2Headers headers = builder().buildHeaders(); observer.onHeadersRead( ctx, headersStreamId, headers, padding, headersFlags.endOfStream(), headersFlags.endOfSegment()); close(); } } }; // Process the initial fragment, invoking the observer's callback if end of headers. final ByteBuf fragment = payload.readSlice(payload.readableBytes() - padding); headersContinuation.processFragment(flags.endOfHeaders(), fragment, padding, observer); }