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); }
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); }
/// <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); }