Ejemplo n.º 1
0
        private PushPromise DecodePushPromise(DecodingContext context, int payloadLength, byte flags,
                                              int streamIdentifier)
        {
            if (streamIdentifier != 0)
            {
                throw new DecoderException(Http2ErrorCode.ProtocolError,
                                           "PUSH_PROMISE frame must have a stream identifier.");
            }

            var paddingSize      = GetPaddingSize(context, flags);
            var promisedStreamId = BitConverter.ToInt32(context.Buffer, context.Offset) & ~Bit32;

            context.Offset             += 4;
            context.BytesLeftToProcess -= 4;

            var frame = new PushPromise
            {
                FrameFlags       = flags,
                StreamIdentifier = streamIdentifier,
                PromisedStreamId = promisedStreamId
            };


            _headerReceiver = args => frame.Add(args.Name, args.Value, args.IsIndexingAllowed);
            _headerDecoder.Decode(context.Buffer, ref context.Offset, ref context.BytesLeftToProcess);
            _headerReceiver = null;

            // skip padding
            context.BytesLeftToProcess -= paddingSize;
            context.Offset             += paddingSize;

            return(frame);
        }
Ejemplo n.º 2
0
        private HeaderFrame DecodeHeaderFrame(DecodingContext context, int payloadLength, byte flags,
                                              int streamIdentifier)
        {
            var paddingSize = GetPaddingSize(context, flags);
            var isPriority  = (flags & 0x20) == 0x20;

            if (isPriority)
            {
                var isExclusive        = (context.Buffer[context.Offset] & Bit32) == Bit32;
                var streamDependencyId = BitConverter.ToInt32(context.Buffer, context.Offset) & ~Bit32;
                context.Offset += 4;
                var weight = context.Buffer[context.Offset++];
                context.BytesLeftToProcess -= 5;
            }


            _headerFrame = new HeaderFrame
            {
                FrameFlags       = flags,
                StreamIdentifier = streamIdentifier
            };
            _headerReceiver = args => _headerFrame.Add(args.Name, args.Value, args.IsIndexingAllowed);
            _headerDecoder.Decode(context.Buffer, ref context.Offset, ref context.BytesLeftToProcess);
            _headerReceiver = null;

            // skip padding
            context.BytesLeftToProcess -= paddingSize;
            context.Offset             += paddingSize;

            // A HEADERS frame without the END_HEADERS flag set MUST be followed by a CONTINUATION frame for the same stream
            if ((flags & 0x4) == 0x4)
            {
                _continuationHandlers[streamIdentifier] = ResumeHeaderFrame;
                return(null);
            }

            var frame = _headerFrame;

            _headerFrame = null;
            return(frame);
        }
Ejemplo n.º 3
0
        /// <summary>
        ///     CONTINUATION frame for the HEADERS frame
        /// </summary>
        private HttpFrame ResumeHeaderFrame(DecodingContext context, int contentlength, byte flags, int streamIdentifier)
        {
            if (streamIdentifier == 0)
            {
                throw new DecoderException(Http2ErrorCode.ProtocolError,
                                           "CONTINUATION frames require a stream identifier.");
            }

            _headerReceiver = args => _headerFrame.Add(args.Name, args.Value, args.IsIndexingAllowed);
            _headerDecoder.Decode(context.Buffer, ref context.Offset, ref context.BytesLeftToProcess);
            _headerReceiver = null;

            // A HEADERS frame without the END_HEADERS flag set MUST be followed by a CONTINUATION frame for the same stream
            if ((flags & 0x4) == 0x4)
            {
                _continuationHandlers[streamIdentifier] = ResumeHeaderFrame;
                return(null);
            }

            var frame = _headerFrame;

            _headerFrame = null;
            return(frame);
        }