Пример #1
0
        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());
        }