예제 #1
0
        public async Task TakeMessageHeadersDoesNotCountAlreadyConsumedBytesTowardsSizeLimit()
        {
            const string startLine = "GET / HTTP/1.1\r\n";

            // This doesn't actually need to be larger than the start line to cause the regression,
            // but doing so gives us a nice HeadersExceedMaxTotalSize error rather than an invalid slice
            // when we do see the regression.
            const string headerLine = "Header: makethislargerthanthestartline\r\n";

            _serviceContext.ServerOptions.Limits.MaxRequestHeadersTotalSize = headerLine.Length;
            _http1Connection.Reset();

            // Don't send header initially because the regression is only caught if TakeMessageHeaders
            // is called multiple times. The first call overcounted the header bytes consumed, and the
            // subsequent calls overslice the buffer due to the overcounting.
            await _application.Output.WriteAsync(Encoding.ASCII.GetBytes($"{startLine}"));

            var readableBuffer = (await _transport.Input.ReadAsync()).Buffer;

            SequencePosition TakeStartLineAndMessageHeaders()
            {
                var reader = new SequenceReader <byte>(readableBuffer);

                Assert.True(_http1Connection.TakeStartLine(ref reader));
                Assert.False(_http1Connection.TakeMessageHeaders(ref reader, trailers: false));
                return(reader.Position);
            }

            _transport.Input.AdvanceTo(TakeStartLineAndMessageHeaders());

            Assert.Equal(0, _http1Connection.RequestHeaders.Count);

            await _application.Output.WriteAsync(Encoding.ASCII.GetBytes($"{headerLine}\r\n"));

            readableBuffer = (await _transport.Input.ReadAsync()).Buffer;

            SequencePosition TakeMessageHeaders()
            {
                var reader = new SequenceReader <byte>(readableBuffer);

                Assert.True(_http1Connection.TakeMessageHeaders(ref reader, trailers: false));
                return(reader.Position);
            }

            _transport.Input.AdvanceTo(TakeMessageHeaders());

            Assert.Equal(1, _http1Connection.RequestHeaders.Count);
            Assert.Equal("makethislargerthanthestartline", _http1Connection.RequestHeaders["Header"]);
        }
예제 #2
0
        public async Task TakeMessageHeadersThrowsWhenHeadersExceedTotalSizeLimit()
        {
            const string headerLine = "Header: value\r\n";

            _serviceContext.ServerOptions.Limits.MaxRequestHeadersTotalSize = headerLine.Length - 1;
            _http1Connection.Reset();

            await _application.Output.WriteAsync(Encoding.ASCII.GetBytes($"{headerLine}\r\n"));

            var readableBuffer = (await _transport.Input.ReadAsync()).Buffer;

            var exception = Assert.Throws <BadHttpRequestException>(() => _http1Connection.TakeMessageHeaders(readableBuffer, out _consumed, out _examined));

            _transport.Input.Advance(_consumed, _examined);

            Assert.Equal(CoreStrings.BadRequest_HeadersExceedMaxTotalSize, exception.Message);
            Assert.Equal(StatusCodes.Status431RequestHeaderFieldsTooLarge, exception.StatusCode);
        }
예제 #3
0
        public async Task TakeMessageHeadersSucceedsWhenHeaderValueContainsUTF8()
        {
            var headerName       = "Header";
            var headerValueBytes = new byte[] { 0x46, 0x72, 0x61, 0x6e, 0xc3, 0xa7, 0x6f, 0x69, 0x73 };
            var headerValue      = Encoding.UTF8.GetString(headerValueBytes);

            _http1Connection.Reset();

            await _application.Output.WriteAsync(Encoding.UTF8.GetBytes($"{headerName}: "));

            await _application.Output.WriteAsync(headerValueBytes);

            await _application.Output.WriteAsync(Encoding.UTF8.GetBytes("\r\n\r\n"));

            var readableBuffer = (await _transport.Input.ReadAsync()).Buffer;

            _http1Connection.TakeMessageHeaders(readableBuffer, trailers: false, out _consumed, out _examined);
            _transport.Input.AdvanceTo(_consumed, _examined);

            Assert.Equal(headerValue, _http1Connection.RequestHeaders[headerName]);
        }