예제 #1
0
        internal async Task <bool> SendContinuationAsync(int streamId, Http2ContinuationFrameFlags flags, IEnumerator <KeyValuePair <string, string> > headersEnumerator)
        {
            var outputWriter = _pair.Application.Output;
            var frame        = new Http2Frame();

            frame.PrepareContinuation(flags, streamId);
            var buffer = _headerEncodingBuffer.AsMemory();
            var done   = HPackHeaderWriter.ContinueEncodeHeaders(headersEnumerator, buffer.Span, out var length);

            frame.PayloadLength = length;

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

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

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