示例#1
0
        /* https://tools.ietf.org/html/rfc7540#section-6.2
         +-+-------------+-----------------------------------------------+
         |E|                 Stream Dependency? (31)                     |
         +-+-------------+-----------------------------------------------+
         |  Weight? (8)  |
         +-+-------------+-----------------------------------------------+
         |                   Header Block Fragment (*)                 ...
         +---------------------------------------------------------------+
         */
        public Task SendHeadersWithPriorityAsync(int streamId, IEnumerable <KeyValuePair <string, string> > headers, byte priority, int streamDependency, bool endStream)
        {
            var writableBuffer = _pair.Application.Output;
            var tcs            = new TaskCompletionSource <object>(TaskCreationOptions.RunContinuationsAsynchronously);

            var frame = new Http2Frame();

            frame.PrepareHeaders(Http2HeadersFrameFlags.END_HEADERS | Http2HeadersFrameFlags.PRIORITY, streamId);
            frame.HeadersPriorityWeight   = priority;
            frame.HeadersStreamDependency = streamDependency;

            var extendedHeaderLength = 5; // stream dependency + weight
            var buffer         = _headerEncodingBuffer.AsSpan();
            var extendedHeader = buffer.Slice(0, extendedHeaderLength);

            Bitshifter.WriteUInt31BigEndian(extendedHeader, (uint)streamDependency);
            extendedHeader[4] = priority;
            var payload = buffer.Slice(extendedHeaderLength);

            _hpackEncoder.BeginEncode(headers, payload, out var length);

            frame.PayloadLength = extendedHeaderLength + length;

            if (endStream)
            {
                frame.HeadersFlags |= Http2HeadersFrameFlags.END_STREAM;
            }

            Http2FrameWriter.WriteHeader(frame, writableBuffer);
            writableBuffer.Write(buffer.Slice(0, frame.PayloadLength));
            return(FlushAsync(writableBuffer));
        }
示例#2
0
        /* https://tools.ietf.org/html/rfc7540#section-6.2
         +---------------+
         |Pad Length? (8)|
         +-+-------------+-----------------------------------------------+
         |                   Header Block Fragment (*)                 ...
         +---------------------------------------------------------------+
         |                           Padding (*)                       ...
         +---------------------------------------------------------------+
         */
        public Task SendHeadersWithPaddingAsync(int streamId, IEnumerable <KeyValuePair <string, string> > headers, byte padLength, bool endStream)
        {
            var writableBuffer = _pair.Application.Output;
            var tcs            = new TaskCompletionSource <object>(TaskCreationOptions.RunContinuationsAsynchronously);

            var frame = new Http2Frame();

            frame.PrepareHeaders(Http2HeadersFrameFlags.END_HEADERS | Http2HeadersFrameFlags.PADDED, streamId);
            frame.HeadersPadLength = padLength;

            var extendedHeaderLength = 1; // Padding length field
            var buffer         = _headerEncodingBuffer.AsSpan();
            var extendedHeader = buffer.Slice(0, extendedHeaderLength);

            extendedHeader[0] = padLength;
            var payload = buffer.Slice(extendedHeaderLength, buffer.Length - padLength - extendedHeaderLength);

            _hpackEncoder.BeginEncode(headers, payload, out var length);
            var padding = buffer.Slice(extendedHeaderLength + length, padLength);

            padding.Fill(0);

            frame.PayloadLength = extendedHeaderLength + length + padLength;

            if (endStream)
            {
                frame.HeadersFlags |= Http2HeadersFrameFlags.END_STREAM;
            }

            WriteHeader(frame, writableBuffer);
            writableBuffer.Write(buffer.Slice(0, frame.PayloadLength));
            return(FlushAsync(writableBuffer));
        }
示例#3
0
        /* https://tools.ietf.org/html/rfc7540#section-6.2
         +---------------+
         |Pad Length? (8)|
         +-+-------------+-----------------------------------------------+
         |                   Header Block Fragment (*)                 ...
         +---------------------------------------------------------------+
         |                           Padding (*)                       ...
         +---------------------------------------------------------------+
         */
        public Task SendHeadersWithPaddingAsync(int streamId, IEnumerable <KeyValuePair <string, string> > headers, byte padLength, bool endStream)
        {
            var writableBuffer = _pair.Application.Output;

            var frame = new Http2Frame();

            frame.PrepareHeaders(Http2HeadersFrameFlags.END_HEADERS | Http2HeadersFrameFlags.PADDED, streamId);
            frame.HeadersPadLength = padLength;

            var extendedHeaderLength = 1; // Padding length field
            var buffer         = _headerEncodingBuffer.AsSpan();
            var extendedHeader = buffer.Slice(0, extendedHeaderLength);

            extendedHeader[0] = padLength;
            var payload = buffer.Slice(extendedHeaderLength, buffer.Length - padLength - extendedHeaderLength);

            HPackHeaderWriter.BeginEncodeHeaders(GetHeadersEnumerator(headers), payload, out var length);
            var padding = buffer.Slice(extendedHeaderLength + length, padLength);

            padding.Clear();

            frame.PayloadLength = extendedHeaderLength + length + padLength;

            if (endStream)
            {
                frame.HeadersFlags |= Http2HeadersFrameFlags.END_STREAM;
            }

            WriteHeader(frame, writableBuffer);
            writableBuffer.Write(buffer.Slice(0, frame.PayloadLength));
            return(FlushAsync(writableBuffer));
        }
示例#4
0
        protected Task SendHeadersAsync(int streamId, Http2HeadersFrameFlags flags, byte[] headerBlock)
        {
            var frame = new Http2Frame(Http2Limits.MinAllowedMaxFrameSize);

            frame.PrepareHeaders(flags, streamId);
            frame.PayloadLength = headerBlock.Length;
            headerBlock.CopyTo(frame.HeadersPayload);

            return(SendAsync(frame.Raw));
        }
        internal async Task SendHeadersAsync(int streamId, Http2HeadersFrameFlags flags, byte[] headerBlock)
        {
            var outputWriter = _pair.Application.Output;
            var frame        = new Http2Frame();

            frame.PrepareHeaders(flags, streamId);
            frame.PayloadLength = headerBlock.Length;

            WriteHeader(frame, outputWriter);
            await SendAsync(headerBlock);
        }
示例#6
0
        protected async Task <bool> SendHeadersAsync(int streamId, Http2HeadersFrameFlags flags, IEnumerable <KeyValuePair <string, string> > headers)
        {
            var frame = new Http2Frame(Http2Limits.MinAllowedMaxFrameSize);

            frame.PrepareHeaders(flags, streamId);
            var done = _hpackEncoder.BeginEncode(headers, frame.Payload, out var length);

            frame.PayloadLength = length;

            await SendAsync(frame.Raw);

            return(done);
        }
示例#7
0
        protected Task SendInvalidHeadersFrameAsync(int streamId, int payloadLength, byte padLength)
        {
            Assert.True(padLength >= payloadLength, $"{nameof(padLength)} must be greater than or equal to {nameof(payloadLength)} to create an invalid frame.");

            var frame = new Http2Frame(Http2Limits.MinAllowedMaxFrameSize);

            frame.PrepareHeaders(Http2HeadersFrameFlags.PADDED, streamId);
            frame.Payload[0] = padLength;

            // Set length last so .Payload can be written to
            frame.PayloadLength = payloadLength;

            return(SendAsync(frame.Raw));
        }
示例#8
0
        protected Task SendIncompleteHeadersFrameAsync(int streamId)
        {
            var frame = new Http2Frame(Http2Limits.MinAllowedMaxFrameSize);

            frame.PrepareHeaders(Http2HeadersFrameFlags.END_HEADERS, streamId);
            frame.PayloadLength = 3;

            // Set up an incomplete Literal Header Field w/ Incremental Indexing frame,
            // with an incomplete new name
            frame.Payload[0] = 0;
            frame.Payload[1] = 2;
            frame.Payload[2] = (byte)'a';

            return(SendAsync(frame.Raw));
        }
示例#9
0
    public static void WriteStartStream(this PipeWriter writer, int streamId, Span <byte> headerData, bool endStream, Http2Frame frame = null)
    {
        frame ??= new Http2Frame();
        frame.PrepareHeaders(Http2HeadersFrameFlags.NONE, streamId);
        frame.PayloadLength = headerData.Length;
        frame.HeadersFlags  = Http2HeadersFrameFlags.END_HEADERS;

        if (endStream)
        {
            frame.HeadersFlags |= Http2HeadersFrameFlags.END_STREAM;
        }

        Http2FrameWriter.WriteHeader(frame, writer);
        writer.Write(headerData);
    }
        internal async Task <bool> SendHeadersAsync(int streamId, Http2HeadersFrameFlags flags, IEnumerable <KeyValuePair <string, string> > headers)
        {
            var outputWriter = _pair.Application.Output;
            var frame        = new Http2Frame();

            frame.PrepareHeaders(flags, streamId);
            var buffer = _headerEncodingBuffer.AsMemory();
            var done   = _hpackEncoder.BeginEncode(headers, buffer.Span, out var length);

            frame.PayloadLength = length;

            WriteHeader(frame, outputWriter);
            await SendAsync(buffer.Span.Slice(0, length));

            return(done);
        }
示例#11
0
        protected Task StartStreamAsync(int streamId, IEnumerable <KeyValuePair <string, string> > headers, bool endStream)
        {
            var writableBuffer = _pair.Application.Output;
            var tcs            = new TaskCompletionSource <object>(TaskCreationOptions.RunContinuationsAsynchronously);

            _runningStreams[streamId] = tcs;

            var frame = new Http2Frame();

            frame.PrepareHeaders(Http2HeadersFrameFlags.NONE, streamId);

            var buffer = _headerEncodingBuffer.AsSpan();
            var done   = _hpackEncoder.BeginEncode(headers, buffer, out var length);

            frame.PayloadLength = length;

            if (done)
            {
                frame.HeadersFlags = Http2HeadersFrameFlags.END_HEADERS;
            }

            if (endStream)
            {
                frame.HeadersFlags |= Http2HeadersFrameFlags.END_STREAM;
            }

            Http2FrameWriter.WriteHeader(frame, writableBuffer);
            writableBuffer.Write(buffer.Slice(0, length));

            while (!done)
            {
                frame.PrepareContinuation(Http2ContinuationFrameFlags.NONE, streamId);

                done = _hpackEncoder.Encode(buffer, out length);
                frame.PayloadLength = length;

                if (done)
                {
                    frame.ContinuationFlags = Http2ContinuationFrameFlags.END_HEADERS;
                }

                Http2FrameWriter.WriteHeader(frame, writableBuffer);
                writableBuffer.Write(buffer.Slice(0, length));
            }

            return(FlushAsync(writableBuffer));
        }
示例#12
0
    public Task StartStreamAsync(int streamId, IEnumerable <KeyValuePair <string, string> > headers, bool endStream)
    {
        var writableBuffer = _pair.Application.Output;

        var frame = new Http2Frame();

        frame.PrepareHeaders(Http2HeadersFrameFlags.NONE, streamId);

        var buffer            = _headerEncodingBuffer.AsSpan();
        var headersEnumerator = GetHeadersEnumerator(headers);
        var done = HPackHeaderWriter.BeginEncodeHeaders(headersEnumerator, buffer, out var length);

        frame.PayloadLength = length;

        if (done)
        {
            frame.HeadersFlags = Http2HeadersFrameFlags.END_HEADERS;
        }

        if (endStream)
        {
            frame.HeadersFlags |= Http2HeadersFrameFlags.END_STREAM;
        }

        WriteHeader(frame, writableBuffer);
        writableBuffer.Write(buffer.Slice(0, length));

        while (!done)
        {
            frame.PrepareContinuation(Http2ContinuationFrameFlags.NONE, streamId);

            done = HPackHeaderWriter.ContinueEncodeHeaders(headersEnumerator, buffer, out length);
            frame.PayloadLength = length;

            if (done)
            {
                frame.ContinuationFlags = Http2ContinuationFrameFlags.END_HEADERS;
            }

            WriteHeader(frame, writableBuffer);
            writableBuffer.Write(buffer.Slice(0, length));
        }

        return(FlushAsync(writableBuffer));
    }
        public async Task SendIncompleteHeadersFrameAsync(int streamId)
        {
            var outputWriter = _pair.Application.Output;
            var frame        = new Http2Frame();

            frame.PrepareHeaders(Http2HeadersFrameFlags.END_HEADERS, streamId);
            frame.PayloadLength = 3;
            var payload = new byte[3];

            // Set up an incomplete Literal Header Field w/ Incremental Indexing frame,
            // with an incomplete new name
            payload[0] = 0;
            payload[1] = 2;
            payload[2] = (byte)'a';

            WriteHeader(frame, outputWriter);
            await SendAsync(payload);
        }
        public async Task SendInvalidHeadersFrameAsync(int streamId, int payloadLength, byte padLength)
        {
            Assert.True(padLength >= payloadLength, $"{nameof(padLength)} must be greater than or equal to {nameof(payloadLength)} to create an invalid frame.");

            var outputWriter = _pair.Application.Output;
            var frame        = new Http2Frame();

            frame.PrepareHeaders(Http2HeadersFrameFlags.PADDED, streamId);
            frame.PayloadLength = payloadLength;
            var payload = new byte[payloadLength];

            if (payloadLength > 0)
            {
                payload[0] = padLength;
            }

            WriteHeader(frame, outputWriter);
            await SendAsync(payload);
        }
        public static void WriteStartStream(this PipeWriter writer, int streamId, Http2HeadersEnumerator headers, HPackEncoder hpackEncoder, byte[] headerEncodingBuffer, bool endStream)
        {
            var frame = new Http2Frame();

            frame.PrepareHeaders(Http2HeadersFrameFlags.NONE, streamId);

            var buffer = headerEncodingBuffer.AsSpan();
            var done   = hpackEncoder.BeginEncode(headers, buffer, out var length);

            frame.PayloadLength = length;

            if (done)
            {
                frame.HeadersFlags = Http2HeadersFrameFlags.END_HEADERS;
            }

            if (endStream)
            {
                frame.HeadersFlags |= Http2HeadersFrameFlags.END_STREAM;
            }

            Http2FrameWriter.WriteHeader(frame, writer);
            writer.Write(buffer.Slice(0, length));

            while (!done)
            {
                frame.PrepareContinuation(Http2ContinuationFrameFlags.NONE, streamId);

                done = hpackEncoder.Encode(buffer, out length);
                frame.PayloadLength = length;

                if (done)
                {
                    frame.ContinuationFlags = Http2ContinuationFrameFlags.END_HEADERS;
                }

                Http2FrameWriter.WriteHeader(frame, writer);
                writer.Write(buffer.Slice(0, length));
            }
        }
示例#16
0
        protected async Task StartStreamAsync(int streamId, IEnumerable <KeyValuePair <string, string> > headers, bool endStream)
        {
            var tcs = new TaskCompletionSource <object>(TaskCreationOptions.RunContinuationsAsynchronously);

            _runningStreams[streamId] = tcs;

            var frame = new Http2Frame(Http2Limits.MinAllowedMaxFrameSize);

            frame.PrepareHeaders(Http2HeadersFrameFlags.NONE, streamId);
            var done = _hpackEncoder.BeginEncode(headers, frame.HeadersPayload, out var length);

            frame.PayloadLength = length;

            if (done)
            {
                frame.HeadersFlags = Http2HeadersFrameFlags.END_HEADERS;
            }

            if (endStream)
            {
                frame.HeadersFlags |= Http2HeadersFrameFlags.END_STREAM;
            }

            await SendAsync(frame.Raw);

            while (!done)
            {
                frame.PrepareContinuation(Http2ContinuationFrameFlags.NONE, streamId);
                done = _hpackEncoder.Encode(frame.HeadersPayload, out length);
                frame.PayloadLength = length;

                if (done)
                {
                    frame.ContinuationFlags = Http2ContinuationFrameFlags.END_HEADERS;
                }

                await SendAsync(frame.Raw);
            }
        }
示例#17
0
        protected async Task SendHeadersWithPriorityAsync(int streamId, IEnumerable <KeyValuePair <string, string> > headers, byte priority, int streamDependency, bool endStream)
        {
            var tcs = new TaskCompletionSource <object>(TaskCreationOptions.RunContinuationsAsynchronously);

            _runningStreams[streamId] = tcs;

            var frame = new Http2Frame(Http2Limits.MinAllowedMaxFrameSize);

            frame.PrepareHeaders(Http2HeadersFrameFlags.END_HEADERS | Http2HeadersFrameFlags.PRIORITY, streamId);
            frame.HeadersPriorityWeight   = priority;
            frame.HeadersStreamDependency = streamDependency;

            _hpackEncoder.BeginEncode(headers, frame.HeadersPayload, out var length);

            frame.PayloadLength = 5 + length;

            if (endStream)
            {
                frame.HeadersFlags |= Http2HeadersFrameFlags.END_STREAM;
            }

            await SendAsync(frame.Raw);
        }
示例#18
0
        protected async Task SendHeadersWithPaddingAsync(int streamId, IEnumerable <KeyValuePair <string, string> > headers, byte padLength, bool endStream)
        {
            var tcs = new TaskCompletionSource <object>(TaskCreationOptions.RunContinuationsAsynchronously);

            _runningStreams[streamId] = tcs;

            var frame = new Http2Frame(Http2Limits.MinAllowedMaxFrameSize);

            frame.PrepareHeaders(Http2HeadersFrameFlags.END_HEADERS | Http2HeadersFrameFlags.PADDED, streamId);
            frame.HeadersPadLength = padLength;

            _hpackEncoder.BeginEncode(headers, frame.HeadersPayload, out var length);

            frame.PayloadLength = 1 + length + padLength;
            frame.Payload.Slice(1 + length).Fill(0);

            if (endStream)
            {
                frame.HeadersFlags |= Http2HeadersFrameFlags.END_STREAM;
            }

            await SendAsync(frame.Raw);
        }
示例#19
0
    /* https://tools.ietf.org/html/rfc7540#section-6.2
     +---------------+
     |Pad Length? (8)|
     +-+-------------+-----------------------------------------------+
     |E|                 Stream Dependency? (31)                     |
     +-+-------------+-----------------------------------------------+
     |  Weight? (8)  |
     +-+-------------+-----------------------------------------------+
     |                   Header Block Fragment (*)                 ...
     +---------------------------------------------------------------+
     |                           Padding (*)                       ...
     +---------------------------------------------------------------+
     */
    public Task SendHeadersWithPaddingAndPriorityAsync(int streamId, IEnumerable <KeyValuePair <string, string> > headers, byte padLength, byte priority, int streamDependency, bool endStream)
    {
        var writableBuffer = _pair.Application.Output;

        var frame = new Http2Frame();

        frame.PrepareHeaders(Http2HeadersFrameFlags.END_HEADERS | Http2HeadersFrameFlags.PADDED | Http2HeadersFrameFlags.PRIORITY, streamId);
        frame.HeadersPadLength        = padLength;
        frame.HeadersPriorityWeight   = priority;
        frame.HeadersStreamDependency = streamDependency;

        var extendedHeaderLength = 6; // pad length + stream dependency + weight
        var buffer         = _headerEncodingBuffer.AsSpan();
        var extendedHeader = buffer.Slice(0, extendedHeaderLength);

        extendedHeader[0] = padLength;
        Bitshifter.WriteUInt31BigEndian(extendedHeader.Slice(1), (uint)streamDependency);
        extendedHeader[5] = priority;
        var payload = buffer.Slice(extendedHeaderLength, buffer.Length - padLength - extendedHeaderLength);

        HPackHeaderWriter.BeginEncodeHeaders(GetHeadersEnumerator(headers), payload, out var length);
        var padding = buffer.Slice(extendedHeaderLength + length, padLength);

        padding.Clear();

        frame.PayloadLength = extendedHeaderLength + length + padLength;

        if (endStream)
        {
            frame.HeadersFlags |= Http2HeadersFrameFlags.END_STREAM;
        }

        WriteHeader(frame, writableBuffer);
        writableBuffer.Write(buffer.Slice(0, frame.PayloadLength));
        return(FlushAsync(writableBuffer));
    }