Example #1
0
        private static (DynamicTable, HPackDecoder) CreateDecoderAndTable()
        {
            var dynamicTable = new DynamicTable(DynamicTableInitialMaxSize);
            var decoder      = new HPackDecoder(DynamicTableInitialMaxSize, MaxHeaderFieldSize, dynamicTable);

            return(dynamicTable, decoder);
        }
Example #2
0
 public void GlobalSetup()
 {
     _dynamicTable = new DynamicTable(maxSize: 4096);
     _dynamicTable.Insert(_headerNameBytes, _headerValueBytes);
     _decoder            = new HPackDecoder(maxDynamicTableSize: 4096, maxHeadersLength: 65536, _dynamicTable);
     _testHeadersHandler = new TestHeadersHandler();
 }
 public Http2Utilities(ConnectionContext clientConnectionContext, ILogger logger, CancellationToken stopToken)
 {
     _hpackDecoder = new HPackDecoder((int)_clientSettings.HeaderTableSize, MaxRequestHeaderFieldSize);
     _pair         = new DuplexPipe.DuplexPipePair(transport: null, application: clientConnectionContext.Transport);
     Logger        = logger;
     StopToken     = stopToken;
 }
Example #4
0
 public Http2Connection(Http2ConnectionContext context)
 {
     _context      = context;
     _frameWriter  = new Http2FrameWriter(context.Transport.Output, context.ConnectionContext, _outputFlowControl, this, context.ConnectionId, context.ServiceContext.Log);
     _hpackDecoder = new HPackDecoder((int)_serverSettings.HeaderTableSize);
     _serverSettings.MaxConcurrentStreams = (uint)context.ServiceContext.ServerOptions.Limits.Http2.MaxStreamsPerConnection;
 }
Example #5
0
        // adapted from header deserialization code in Http2Connection.cs
        private static HttpHeaders HPackDecode(Memory <byte> memory)
        {
            var header       = new HttpRequestHeaders();
            var hpackDecoder = new HPackDecoder(maxDynamicTableSize: 0, maxHeadersLength: HttpHandlerDefaults.DefaultMaxResponseHeadersLength * 1024);

            hpackDecoder.Decode(memory.Span, true, new HeaderHandler(header));

            return(header);
        }
Example #6
0
        public Http2Connection(HttpConnectionPool pool, SslStream stream)
        {
            _pool           = pool;
            _stream         = stream;
            _syncObject     = new object();
            _incomingBuffer = new ArrayBuffer(InitialBufferSize);
            _outgoingBuffer = new ArrayBuffer(InitialBufferSize);

            _hpackDecoder = new HPackDecoder();

            _httpStreams = new Dictionary <int, Http2Stream>();

            _writerLock = new SemaphoreSlim(1, 1);

            _nextStream = 1;
        }
Example #7
0
        public void DecodesStringLength_LimitConfigurable()
        {
            HPackDecoder decoder    = new HPackDecoder(DynamicTableInitialMaxSize, MaxHeaderFieldSize + 1);
            string       string8193 = new string('a', MaxHeaderFieldSize + 1);

            byte[] encoded = _literalHeaderFieldWithoutIndexingNewName
                             .Concat(new byte[] { 0x7f, 0x82, 0x3f }) // 8193 encoded with 7-bit prefix, no Huffman encoding
                             .Concat(Encoding.ASCII.GetBytes(string8193))
                             .Concat(new byte[] { 0x7f, 0x82, 0x3f }) // 8193 encoded with 7-bit prefix, no Huffman encoding
                             .Concat(Encoding.ASCII.GetBytes(string8193))
                             .ToArray();

            decoder.Decode(encoded, endHeaders: true, handler: _handler);

            Assert.Equal(string8193, _handler.DecodedHeaders[string8193]);
        }
Example #8
0
        public void DecodesStringLength_IndividualBytes()
        {
            HPackDecoder decoder    = new HPackDecoder(DynamicTableInitialMaxSize, MaxHeaderFieldSize + 1);
            string       string8193 = new string('a', MaxHeaderFieldSize + 1);

            byte[] encoded = _literalHeaderFieldWithoutIndexingNewName
                             .Concat(new byte[] { 0x7f, 0x82, 0x3f }) // 8193 encoded with 7-bit prefix, no Huffman encoding
                             .Concat(Encoding.ASCII.GetBytes(string8193))
                             .Concat(new byte[] { 0x7f, 0x82, 0x3f }) // 8193 encoded with 7-bit prefix, no Huffman encoding
                             .Concat(Encoding.ASCII.GetBytes(string8193))
                             .ToArray();

            for (int i = 0; i < encoded.Length; i++)
            {
                bool end = i + 1 == encoded.Length;

                decoder.Decode(new byte[] { encoded[i] }, endHeaders: end, handler: _handler);
            }

            Assert.Equal(string8193, _handler.DecodedHeaders[string8193]);
        }
Example #9
0
        public Http2Connection(HttpConnectionPool pool, SslStream stream)
        {
            _pool           = pool;
            _stream         = stream;
            _syncObject     = new object();
            _incomingBuffer = new ArrayBuffer(InitialConnectionBufferSize);
            _outgoingBuffer = new ArrayBuffer(InitialConnectionBufferSize);
            _headerBuffer   = new ArrayBuffer(InitialConnectionBufferSize);

            _hpackDecoder = new HPackDecoder();

            _httpStreams = new Dictionary <int, Http2Stream>();

            _writerLock        = new SemaphoreSlim(1, 1);
            _connectionWindow  = new CreditManager(DefaultInitialWindowSize);
            _concurrentStreams = new CreditManager(int.MaxValue);

            _nextStream           = 1;
            _initialWindowSize    = DefaultInitialWindowSize;
            _maxConcurrentStreams = int.MaxValue;
        }
Example #10
0
        // adapted from header deserialization code in Http2Connection.cs
        private static HttpHeaders HPackDecode(Memory <byte> memory)
        {
            var header       = new HttpRequestHeaders();
            var hpackDecoder = new HPackDecoder(maxDynamicTableSize: 0, maxResponseHeadersLength: HttpHandlerDefaults.DefaultMaxResponseHeadersLength * 1024);

            hpackDecoder.Decode(memory.Span, true, ((_, name, value) => HeaderHandler(name, value)), null);

            return(header);

            void HeaderHandler(ReadOnlySpan <byte> name, ReadOnlySpan <byte> value)
            {
                if (!HeaderDescriptor.TryGet(name, out HeaderDescriptor descriptor))
                {
                    throw new HttpRequestException(SR.Format(SR.net_http_invalid_response_header_name, Encoding.ASCII.GetString(name)));
                }

                string headerValue = descriptor.GetHeaderValue(value);

                header.TryAddWithoutValidation(descriptor, headerValue.Split(',').Select(x => x.Trim()));
            }
        }
Example #11
0
        public void DecodesHeaderNameAndValue_SeparateSegments()
        {
            HPackDecoder decoder    = new HPackDecoder(DynamicTableInitialMaxSize, MaxHeaderFieldSize + 1);
            string       string8193 = new string('a', MaxHeaderFieldSize + 1);

            byte[][] segments = new byte[][]
            {
                _literalHeaderFieldWithoutIndexingNewName,
                new byte[] { 0x7f, 0x82, 0x3f }, // 8193 encoded with 7-bit prefix, no Huffman encoding
                Encoding.ASCII.GetBytes(string8193),
                new byte[] { 0x7f, 0x82, 0x3f }, // 8193 encoded with 7-bit prefix, no Huffman encoding
                Encoding.ASCII.GetBytes(string8193)
            };

            for (int i = 0; i < segments.Length; i++)
            {
                bool end = i + 1 == segments.Length;

                decoder.Decode(segments[i], endHeaders: end, handler: _handler);
            }

            Assert.Equal(string8193, _handler.DecodedHeaders[string8193]);
        }
 public Http2Connection(Http2ConnectionContext context)
 {
     _context      = context;
     _frameWriter  = new Http2FrameWriter(context.Transport.Output, context.Application.Input, _outputFlowControl, this);
     _hpackDecoder = new HPackDecoder((int)_serverSettings.HeaderTableSize);
 }
Example #13
0
 public HPackDecoderTests()
 {
     _dynamicTable = new DynamicTable(DynamicTableInitialMaxSize);
     _decoder      = new HPackDecoder(DynamicTableInitialMaxSize, MaxRequestHeaderFieldSize, _dynamicTable);
 }
 public HPackDecoderTest()
 {
     _dynamicTable = new DynamicTable(DynamicTableInitialMaxSize);
     _decoder      = new HPackDecoder(DynamicTableInitialMaxSize, maxResponseHeadersLength: 4096, dynamicTable: _dynamicTable);
 }
Example #15
0
 public Http2Utilities(ConnectionContext clientConnectionContext)
 {
     _hpackDecoder = new HPackDecoder((int)_clientSettings.HeaderTableSize, MaxRequestHeaderFieldSize);
     _pair         = new DuplexPipe.DuplexPipePair(transport: null, application: clientConnectionContext.Transport);
 }
Example #16
0
        public Http2TestBase()
        {
            // Always dispatch test code back to the ThreadPool. This prevents deadlocks caused by continuing
            // Http2Connection.ProcessRequestsAsync() loop with writer locks acquired. Run product code inline to make
            // it easier to verify request frames are processed correctly immediately after sending the them.
            var inputPipeOptions = new PipeOptions(
                pool: _memoryPool,
                readerScheduler: PipeScheduler.Inline,
                writerScheduler: PipeScheduler.ThreadPool,
                useSynchronizationContext: false
                );
            var outputPipeOptions = new PipeOptions(
                pool: _memoryPool,
                readerScheduler: PipeScheduler.ThreadPool,
                writerScheduler: PipeScheduler.Inline,
                useSynchronizationContext: false
                );

            _pair         = DuplexPipe.CreateConnectionPair(inputPipeOptions, outputPipeOptions);
            _hpackDecoder = new HPackDecoder((int)_clientSettings.HeaderTableSize);

            _noopApplication = context => Task.CompletedTask;

            _readHeadersApplication = context =>
            {
                foreach (var header in context.Request.Headers)
                {
                    _receivedHeaders[header.Key] = header.Value.ToString();
                }

                return(Task.CompletedTask);
            };

            _readTrailersApplication = async context =>
            {
                using (var ms = new MemoryStream())
                {
                    // Consuming the entire request body guarantees trailers will be available
                    await context.Request.Body.CopyToAsync(ms);
                }

                foreach (var header in context.Request.Headers)
                {
                    _receivedHeaders[header.Key] = header.Value.ToString();
                }
            };

            _bufferingApplication = async context =>
            {
                var data     = new List <byte>();
                var buffer   = new byte[1024];
                var received = 0;

                while ((received = await context.Request.Body.ReadAsync(buffer, 0, buffer.Length)) > 0)
                {
                    data.AddRange(new ArraySegment <byte>(buffer, 0, received));
                }

                await context.Response.Body.WriteAsync(data.ToArray(), 0, data.Count);
            };

            _echoApplication = async context =>
            {
                var buffer   = new byte[Http2Limits.MinAllowedMaxFrameSize];
                var received = 0;

                while ((received = await context.Request.Body.ReadAsync(buffer, 0, buffer.Length)) > 0)
                {
                    await context.Response.Body.WriteAsync(buffer, 0, received);
                }
            };

            _echoWaitForAbortApplication = async context =>
            {
                var buffer   = new byte[Http2Limits.MinAllowedMaxFrameSize];
                var received = 0;

                while ((received = await context.Request.Body.ReadAsync(buffer, 0, buffer.Length)) > 0)
                {
                    await context.Response.Body.WriteAsync(buffer, 0, received);
                }

                var sem = new SemaphoreSlim(0);

                context.RequestAborted.Register(() =>
                {
                    sem.Release();
                });

                await sem.WaitAsync().DefaultTimeout();
            };

            _largeHeadersApplication = context =>
            {
                foreach (var name in new[] { "a", "b", "c", "d", "e", "f", "g", "h" })
                {
                    context.Response.Headers[name] = _4kHeaderValue;
                }

                return(Task.CompletedTask);
            };

            _waitForAbortApplication = async context =>
            {
                var streamIdFeature = context.Features.Get <IHttp2StreamIdFeature>();
                var sem             = new SemaphoreSlim(0);

                context.RequestAborted.Register(() =>
                {
                    lock (_abortedStreamIdsLock)
                    {
                        _abortedStreamIds.Add(streamIdFeature.StreamId);
                    }

                    sem.Release();
                });

                await sem.WaitAsync().DefaultTimeout();

                _runningStreams[streamIdFeature.StreamId].TrySetResult(null);
            };

            _waitForAbortFlushingApplication = async context =>
            {
                var streamIdFeature = context.Features.Get <IHttp2StreamIdFeature>();
                var sem             = new SemaphoreSlim(0);

                context.RequestAborted.Register(() =>
                {
                    lock (_abortedStreamIdsLock)
                    {
                        _abortedStreamIds.Add(streamIdFeature.StreamId);
                    }

                    sem.Release();
                });

                await sem.WaitAsync().DefaultTimeout();

                await context.Response.Body.FlushAsync();

                _runningStreams[streamIdFeature.StreamId].TrySetResult(null);
            };

            _waitForAbortWithDataApplication = async context =>
            {
                var streamIdFeature = context.Features.Get <IHttp2StreamIdFeature>();
                var sem             = new SemaphoreSlim(0);

                context.RequestAborted.Register(() =>
                {
                    lock (_abortedStreamIdsLock)
                    {
                        _abortedStreamIds.Add(streamIdFeature.StreamId);
                    }

                    sem.Release();
                });

                await sem.WaitAsync().DefaultTimeout();

                await context.Response.Body.WriteAsync(new byte[10], 0, 10);

                _runningStreams[streamIdFeature.StreamId].TrySetResult(null);
            };

            _echoMethod = context =>
            {
                context.Response.Headers["Method"] = context.Request.Method;

                return(Task.CompletedTask);
            };

            _echoHost = context =>
            {
                context.Response.Headers[HeaderNames.Host] = context.Request.Headers[HeaderNames.Host];

                return(Task.CompletedTask);
            };

            _echoPath = context =>
            {
                context.Response.Headers["path"]      = context.Request.Path.ToString();
                context.Response.Headers["rawtarget"] = context.Features.Get <IHttpRequestFeature>().RawTarget;

                return(Task.CompletedTask);
            };
        }
Example #17
0
 public HPackDecoderTest()
 {
     _dynamicTable = new DynamicTable(DynamicTableInitialMaxSize);
     _decoder      = new HPackDecoder(DynamicTableInitialMaxSize, _dynamicTable);
 }
Example #18
0
        private int _initialStreamWindowSize     = 1024 * 96;  // Larger than the default 64kb

        public Http2Protocol(ConnectionContext connection)
        {
            _connection      = connection;
            _httpFrameWriter = new Http2FrameWriter(connection, _outputFlowControl, NullLogger.Instance);
            _hpackDecoder    = new HPackDecoder(_headerTableSize, _maxRequestHeaderFieldSize);
        }