void ReadHeadersFrame(IChannelHandlerContext ctx, IByteBuffer payload, int payloadEndIndex, IHttp2FrameListener listener) { int headersStreamId = _streamId; Http2Flags headersFlags = _flags; int padding = ReadPadding(payload); VerifyPadding(padding); // The callback that is invoked is different depending on whether priority information // is present in the headers frame. if (headersFlags.PriorityPresent()) { long word1 = payload.ReadUnsignedInt(); bool exclusive = (word1 & 0x80000000L) != 0; int streamDependency = (int)(uint)(word1 & 0x7FFFFFFFL); if (streamDependency == headersStreamId) { ThrowHelper.ThrowStreamError_AStreamCannotDependOnItself(headersStreamId); } short weight = (short)(payload.ReadByte() + 1); int lenToRead = LengthWithoutTrailingPadding(payloadEndIndex - payload.ReaderIndex, padding); // Create a handler that invokes the listener when the header block is complete. _headersContinuation = new PriorityHeadersFrameHeadersContinuation(this, ctx, headersStreamId, padding, streamDependency, weight, exclusive, headersFlags); // Process the initial fragment, invoking the listener's callback if end of headers. _headersContinuation.ProcessFragment(headersFlags.EndOfHeaders(), payload, lenToRead, listener); ResetHeadersContinuationIfEnd(headersFlags.EndOfHeaders()); return; } // The priority fields are not present in the frame. Prepare a continuation that invokes // the listener callback without priority information. _headersContinuation = new HeadersFrameHeadersContinuation(this, ctx, headersStreamId, padding, headersFlags); // Process the initial fragment, invoking the listener's callback if end of headers. int dataLength = LengthWithoutTrailingPadding(payloadEndIndex - payload.ReaderIndex, padding); _headersContinuation.ProcessFragment(headersFlags.EndOfHeaders(), payload, dataLength, listener); ResetHeadersContinuationIfEnd(headersFlags.EndOfHeaders()); }