From b1ff540d28e22d7c400d0d05898c859cbf73f9f1 Mon Sep 17 00:00:00 2001 From: Aditya Mandaleeka Date: Thu, 24 Feb 2022 18:48:11 -0800 Subject: [PATCH 1/2] WIP - Fix incorrect h2 header decoding. --- .../Core/src/Internal/Http2/Http2Connection.cs | 2 +- .../src/Internal/Http2/Http2HeadersEnumerator.cs | 15 ++++++++++++++- .../Core/src/Internal/Http3/Http3Stream.cs | 2 +- .../Http2/Http2StreamTests.cs | 11 +++++++++-- .../Http2/Http2TestBase.cs | 12 ++++++++++++ 5 files changed, 37 insertions(+), 5 deletions(-) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.cs b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.cs index 88aed68720cf..5f05596a101e 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.cs @@ -1442,7 +1442,7 @@ private void OnHeaderCore(HeaderType headerType, int? staticTableIndex, ReadOnly { UpdateHeaderParsingState(value, GetPseudoHeaderField(staticTableIndex.GetValueOrDefault())); - _currentHeadersStream.OnHeader(staticTableIndex.GetValueOrDefault(), indexOnly: true, name, value); + _currentHeadersStream.OnHeader(staticTableIndex.GetValueOrDefault(), indexOnly: false, name, value); } else { diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2HeadersEnumerator.cs b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2HeadersEnumerator.cs index 2eaabd86d6dd..b2799dd5f214 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2HeadersEnumerator.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2HeadersEnumerator.cs @@ -90,11 +90,22 @@ public bool MoveNext() else { return _genericEnumerator!.MoveNext() - ? SetCurrent(_genericEnumerator.Current.Key, _genericEnumerator.Current.Value, default) + ? SetCurrent(_genericEnumerator.Current.Key, _genericEnumerator.Current.Value, ZZGetKnownHeaderType(_genericEnumerator.Current.Key)) : false; } } + private static KnownHeaderType ZZGetKnownHeaderType(string headerName) + { + switch (headerName) + { + case ":method": + return KnownHeaderType.Method; + default: + return default; + } + } + private bool MoveNextOnStringEnumerator(string key) { var result = _stringValuesEnumerator.MoveNext(); @@ -149,6 +160,8 @@ internal static int GetResponseHeaderStaticTableId(KnownHeaderType responseHeade // Removed from this test are request-only headers, e.g. cookie. switch (responseHeaderType) { + case KnownHeaderType.Method: + return H2StaticTable.MethodGet; case KnownHeaderType.CacheControl: return H2StaticTable.CacheControl; case KnownHeaderType.Date: diff --git a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3Stream.cs b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3Stream.cs index 4b4569b261a5..35a272cfcc4e 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http3/Http3Stream.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http3/Http3Stream.cs @@ -314,7 +314,7 @@ private void OnHeaderCore(HeaderType headerType, int? staticTableIndex, ReadOnly { UpdateHeaderParsingState(value, GetPseudoHeaderField(staticTableIndex.GetValueOrDefault())); - OnHeader(staticTableIndex.GetValueOrDefault(), indexOnly: true, name, value); + OnHeader(staticTableIndex.GetValueOrDefault(), indexOnly: false, name, value); } else { diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2StreamTests.cs b/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2StreamTests.cs index 2d50f1f32f86..ec86b8d41e55 100644 --- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2StreamTests.cs +++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2StreamTests.cs @@ -110,9 +110,16 @@ public async Task HEADERS_Received_KnownOrCustomMethods_Accepted(string method) withFlags: (byte)(Http2HeadersFrameFlags.END_HEADERS | Http2HeadersFrameFlags.END_STREAM), withStreamId: 1); - await StopConnectionAsync(expectedLastStreamId: 1, ignoreNonGoAwayFrames: false); + await StartStreamAsync(3, headers, endStream: true); - _hpackDecoder.Decode(headersFrame.PayloadSequence, endHeaders: false, handler: this); + // Can't check length this time because it will be different with compression. + var headersFrame2 = await ExpectAsync(Http2FrameType.HEADERS, + withFlags: (byte)(Http2HeadersFrameFlags.END_HEADERS | Http2HeadersFrameFlags.END_STREAM), + withStreamId: 3); + + await StopConnectionAsync(expectedLastStreamId: 3, ignoreNonGoAwayFrames: false); + + _hpackDecoder.Decode(headersFrame2.PayloadSequence, endHeaders: false, handler: this); Assert.Equal(4, _decodedHeaders.Count); Assert.Contains("date", _decodedHeaders.Keys, StringComparer.OrdinalIgnoreCase); diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2TestBase.cs b/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2TestBase.cs index b7d6b7a47535..526377145eed 100644 --- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2TestBase.cs +++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2TestBase.cs @@ -1183,6 +1183,18 @@ internal async Task ExpectAsync(Http2FrameType type, int return frame; } + + internal async Task ExpectAsync(Http2FrameType type, byte withFlags, int withStreamId) + { + var frame = await ReceiveFrameAsync(); + + Assert.Equal(type, frame.Type); + Assert.Equal(withFlags, frame.Flags); + Assert.Equal(withStreamId, frame.StreamId); + + return frame; + } + protected Task StopConnectionAsync(int expectedLastStreamId, bool ignoreNonGoAwayFrames) { _pair.Application.Output.Complete(); From d49e46f2aaaa5289565367d80512f02cc959ad8a Mon Sep 17 00:00:00 2001 From: James Newton-King Date: Fri, 25 Feb 2022 19:48:42 +1300 Subject: [PATCH 2/2] Fix test --- ...soft.AspNetCore.Server.Kestrel.Core.csproj | 2 + ...spNetCore.Server.Kestrel.Core.Tests.csproj | 4 +- ...oft.AspNetCore.Server.Kestrel.Tests.csproj | 2 +- ...Server.Kestrel.Transport.Quic.Tests.csproj | 7 ++- .../Http2/Http2ConnectionBenchmarkBase.cs | 1 + .../Http2/Http2HeadersEnumeratorBenchmark.cs | 1 + ...Core.Server.Kestrel.Microbenchmarks.csproj | 3 ++ .../Http2 => shared}/HPackHeaderWriter.cs | 6 +++ .../Http2HeadersEnumerator.cs | 44 ++++++++++++++++--- .../shared/test/Http3/Http3InMemory.cs | 8 ++-- .../test/PipeWriterHttp2FrameExtensions.cs | 2 + .../test/FunctionalTests/ResponseTests.cs | 1 - .../Http2/Http2StreamTests.cs | 16 ++++++- .../Http2/Http2TestBase.cs | 12 ----- .../InMemory.FunctionalTests.csproj | 4 +- .../Sockets.BindTests.csproj | 13 +++++- .../Sockets.FunctionalTests.csproj | 14 +++++- 17 files changed, 109 insertions(+), 31 deletions(-) rename src/Servers/Kestrel/{Core/src/Internal/Http2 => shared}/HPackHeaderWriter.cs (95%) rename src/Servers/Kestrel/{Core/src/Internal/Http2 => shared}/Http2HeadersEnumerator.cs (86%) diff --git a/src/Servers/Kestrel/Core/src/Microsoft.AspNetCore.Server.Kestrel.Core.csproj b/src/Servers/Kestrel/Core/src/Microsoft.AspNetCore.Server.Kestrel.Core.csproj index 530e06add285..ecbfa571142e 100644 --- a/src/Servers/Kestrel/Core/src/Microsoft.AspNetCore.Server.Kestrel.Core.csproj +++ b/src/Servers/Kestrel/Core/src/Microsoft.AspNetCore.Server.Kestrel.Core.csproj @@ -14,6 +14,8 @@ + + diff --git a/src/Servers/Kestrel/Core/test/Microsoft.AspNetCore.Server.Kestrel.Core.Tests.csproj b/src/Servers/Kestrel/Core/test/Microsoft.AspNetCore.Server.Kestrel.Core.Tests.csproj index d8c23b7f1802..ccfe2c28c585 100644 --- a/src/Servers/Kestrel/Core/test/Microsoft.AspNetCore.Server.Kestrel.Core.Tests.csproj +++ b/src/Servers/Kestrel/Core/test/Microsoft.AspNetCore.Server.Kestrel.Core.Tests.csproj @@ -3,7 +3,7 @@ $(DefaultNetCoreTargetFramework) true Kestrel.Core.Tests - $(DefineConstants);KESTREL + $(DefineConstants);KESTREL;IS_TESTS @@ -11,6 +11,8 @@ + + diff --git a/src/Servers/Kestrel/Kestrel/test/Microsoft.AspNetCore.Server.Kestrel.Tests.csproj b/src/Servers/Kestrel/Kestrel/test/Microsoft.AspNetCore.Server.Kestrel.Tests.csproj index 961f0710b306..89bf8657724d 100644 --- a/src/Servers/Kestrel/Kestrel/test/Microsoft.AspNetCore.Server.Kestrel.Tests.csproj +++ b/src/Servers/Kestrel/Kestrel/test/Microsoft.AspNetCore.Server.Kestrel.Tests.csproj @@ -6,7 +6,7 @@ - + diff --git a/src/Servers/Kestrel/Transport.Quic/test/Microsoft.AspNetCore.Server.Kestrel.Transport.Quic.Tests.csproj b/src/Servers/Kestrel/Transport.Quic/test/Microsoft.AspNetCore.Server.Kestrel.Transport.Quic.Tests.csproj index 3ff7e48078f0..0b3f8eb86baf 100644 --- a/src/Servers/Kestrel/Transport.Quic/test/Microsoft.AspNetCore.Server.Kestrel.Transport.Quic.Tests.csproj +++ b/src/Servers/Kestrel/Transport.Quic/test/Microsoft.AspNetCore.Server.Kestrel.Transport.Quic.Tests.csproj @@ -8,7 +8,12 @@ - + + + + + + diff --git a/src/Servers/Kestrel/perf/Microbenchmarks/Http2/Http2ConnectionBenchmarkBase.cs b/src/Servers/Kestrel/perf/Microbenchmarks/Http2/Http2ConnectionBenchmarkBase.cs index ca70054c0352..8c44390a9aeb 100644 --- a/src/Servers/Kestrel/perf/Microbenchmarks/Http2/Http2ConnectionBenchmarkBase.cs +++ b/src/Servers/Kestrel/perf/Microbenchmarks/Http2/Http2ConnectionBenchmarkBase.cs @@ -22,6 +22,7 @@ using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Primitives; using Microsoft.Net.Http.Headers; +using Http2HeadersEnumerator = Microsoft.AspNetCore.Server.Kestrel.Core.Tests.Http2HeadersEnumerator; namespace Microsoft.AspNetCore.Server.Kestrel.Microbenchmarks; diff --git a/src/Servers/Kestrel/perf/Microbenchmarks/Http2/Http2HeadersEnumeratorBenchmark.cs b/src/Servers/Kestrel/perf/Microbenchmarks/Http2/Http2HeadersEnumeratorBenchmark.cs index 69a2e5d5b9e4..d1b90dd056e2 100644 --- a/src/Servers/Kestrel/perf/Microbenchmarks/Http2/Http2HeadersEnumeratorBenchmark.cs +++ b/src/Servers/Kestrel/perf/Microbenchmarks/Http2/Http2HeadersEnumeratorBenchmark.cs @@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http; using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2; using Microsoft.Extensions.Primitives; +using Http2HeadersEnumerator = Microsoft.AspNetCore.Server.Kestrel.Core.Tests.Http2HeadersEnumerator; namespace Microsoft.AspNetCore.Server.Kestrel.Microbenchmarks; diff --git a/src/Servers/Kestrel/perf/Microbenchmarks/Microsoft.AspNetCore.Server.Kestrel.Microbenchmarks.csproj b/src/Servers/Kestrel/perf/Microbenchmarks/Microsoft.AspNetCore.Server.Kestrel.Microbenchmarks.csproj index e2c374f63b38..073496464d85 100644 --- a/src/Servers/Kestrel/perf/Microbenchmarks/Microsoft.AspNetCore.Server.Kestrel.Microbenchmarks.csproj +++ b/src/Servers/Kestrel/perf/Microbenchmarks/Microsoft.AspNetCore.Server.Kestrel.Microbenchmarks.csproj @@ -6,6 +6,7 @@ true true false + $(DefineConstants);IS_BENCHMARKS @@ -15,6 +16,8 @@ + + diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/HPackHeaderWriter.cs b/src/Servers/Kestrel/shared/HPackHeaderWriter.cs similarity index 95% rename from src/Servers/Kestrel/Core/src/Internal/Http2/HPackHeaderWriter.cs rename to src/Servers/Kestrel/shared/HPackHeaderWriter.cs index cbed00bc6d97..22cf2256cd53 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http2/HPackHeaderWriter.cs +++ b/src/Servers/Kestrel/shared/HPackHeaderWriter.cs @@ -4,8 +4,14 @@ using System.Net.Http; using System.Net.Http.HPack; +#if !(IS_TESTS || IS_BENCHMARKS) namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2; +#else +namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests; +#endif +// This file is used by Kestrel to write response headers and tests to write request headers. +// To avoid adding test code to Kestrel this file is shared. Test specifc code is excluded from Kestrel by ifdefs. internal static class HPackHeaderWriter { /// diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2HeadersEnumerator.cs b/src/Servers/Kestrel/shared/Http2HeadersEnumerator.cs similarity index 86% rename from src/Servers/Kestrel/Core/src/Internal/Http2/Http2HeadersEnumerator.cs rename to src/Servers/Kestrel/shared/Http2HeadersEnumerator.cs index b2799dd5f214..27688a1daae7 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2HeadersEnumerator.cs +++ b/src/Servers/Kestrel/shared/Http2HeadersEnumerator.cs @@ -7,20 +7,32 @@ using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http; using Microsoft.Extensions.Primitives; +#if !(IS_TESTS || IS_BENCHMARKS) namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2; +#else +namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests; +#endif +#nullable enable + +// This file is used by Kestrel to write response headers and tests to write request headers. +// To avoid adding test code to Kestrel this file is shared. Test specifc code is excluded from Kestrel by ifdefs. internal sealed class Http2HeadersEnumerator : IEnumerator> { private enum HeadersType : byte { Headers, Trailers, - Untyped +#if IS_TESTS || IS_BENCHMARKS + Untyped, +#endif } private HeadersType _headersType; private HttpResponseHeaders.Enumerator _headersEnumerator; private HttpResponseTrailers.Enumerator _trailersEnumerator; +#if IS_TESTS || IS_BENCHMARKS private IEnumerator>? _genericEnumerator; +#endif private StringValues.Enumerator _stringValuesEnumerator; private bool _hasMultipleValues; private KnownHeaderType _knownHeaderType; @@ -47,6 +59,7 @@ public void Initialize(HttpResponseTrailers headers) _hasMultipleValues = false; } +#if IS_TESTS || IS_BENCHMARKS public void Initialize(IDictionary headers) { switch (headers) @@ -67,6 +80,7 @@ public void Initialize(IDictionary headers) _hasMultipleValues = false; } +#endif public bool MoveNext() { @@ -89,13 +103,19 @@ public bool MoveNext() } else { +#if IS_TESTS || IS_BENCHMARKS return _genericEnumerator!.MoveNext() - ? SetCurrent(_genericEnumerator.Current.Key, _genericEnumerator.Current.Value, ZZGetKnownHeaderType(_genericEnumerator.Current.Key)) + ? SetCurrent(_genericEnumerator.Current.Key, _genericEnumerator.Current.Value, GetKnownRequestHeaderType(_genericEnumerator.Current.Key)) : false; +#else + ThrowUnexpectedHeadersType(); + return false; +#endif } } - private static KnownHeaderType ZZGetKnownHeaderType(string headerName) +#if IS_TESTS || IS_BENCHMARKS + private static KnownHeaderType GetKnownRequestHeaderType(string headerName) { switch (headerName) { @@ -105,6 +125,13 @@ private static KnownHeaderType ZZGetKnownHeaderType(string headerName) return default; } } +#else + [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)] + private static void ThrowUnexpectedHeadersType() + { + throw new InvalidOperationException("Unexpected headers collection type."); + } +#endif private bool MoveNextOnStringEnumerator(string key) { @@ -145,7 +172,11 @@ public void Reset() } else { +#if IS_TESTS || IS_BENCHMARKS _genericEnumerator!.Reset(); +#else + ThrowUnexpectedHeadersType(); +#endif } _stringValuesEnumerator = default; _knownHeaderType = default; @@ -160,8 +191,6 @@ internal static int GetResponseHeaderStaticTableId(KnownHeaderType responseHeade // Removed from this test are request-only headers, e.g. cookie. switch (responseHeaderType) { - case KnownHeaderType.Method: - return H2StaticTable.MethodGet; case KnownHeaderType.CacheControl: return H2StaticTable.CacheControl; case KnownHeaderType.Date: @@ -212,6 +241,11 @@ internal static int GetResponseHeaderStaticTableId(KnownHeaderType responseHeade return H2StaticTable.ContentLength; default: return -1; +#if IS_TESTS || IS_BENCHMARKS + // Include request headers for tests. + case KnownHeaderType.Method: + return H2StaticTable.MethodGet; +#endif } } } diff --git a/src/Servers/Kestrel/shared/test/Http3/Http3InMemory.cs b/src/Servers/Kestrel/shared/test/Http3/Http3InMemory.cs index 41db3fd52e68..38300b3aa1fb 100644 --- a/src/Servers/Kestrel/shared/test/Http3/Http3InMemory.cs +++ b/src/Servers/Kestrel/shared/test/Http3/Http3InMemory.cs @@ -107,7 +107,7 @@ internal async ValueTask GetInboundControlStream() if (_inboundControlStream == null) { var reader = MultiplexedConnectionContext.ToClientAcceptQueue.Reader; -#if IS_FUNCTIONAL_TESTS +#if IS_TESTS while (await reader.WaitToReadAsync().DefaultTimeout()) #else while (await reader.WaitToReadAsync()) @@ -147,7 +147,7 @@ internal async Task WaitForConnectionErrorAsync(bool ignoreNonGoAway AssertConnectionError(expectedErrorCode, matchExpectedErrorMessage, expectedErrorMessage); // Verify HttpConnection.ProcessRequestsAsync has exited. -#if IS_FUNCTIONAL_TESTS +#if IS_TESTS await _connectionTask.DefaultTimeout(); #else await _connectionTask; @@ -461,7 +461,7 @@ protected Task SendAsync(ReadOnlySpan span) protected static Task FlushAsync(PipeWriter writableBuffer) { var task = writableBuffer.FlushAsync(); -#if IS_FUNCTIONAL_TESTS +#if IS_TESTS return task.AsTask().DefaultTimeout(); #else return task.GetAsTask(); @@ -477,7 +477,7 @@ internal async Task ReceiveEndAsync() } } -#if IS_FUNCTIONAL_TESTS +#if IS_TESTS protected Task ReadApplicationInputAsync() { return Pair.Application.Input.ReadAsync().AsTask().DefaultTimeout(); diff --git a/src/Servers/Kestrel/shared/test/PipeWriterHttp2FrameExtensions.cs b/src/Servers/Kestrel/shared/test/PipeWriterHttp2FrameExtensions.cs index c57f1b4b43b7..b78da63662a2 100644 --- a/src/Servers/Kestrel/shared/test/PipeWriterHttp2FrameExtensions.cs +++ b/src/Servers/Kestrel/shared/test/PipeWriterHttp2FrameExtensions.cs @@ -8,6 +8,8 @@ using System.IO.Pipelines; using System.Net.Http.HPack; using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2; +using Http2HeadersEnumerator = Microsoft.AspNetCore.Server.Kestrel.Core.Tests.Http2HeadersEnumerator; +using HPackHeaderWriter = Microsoft.AspNetCore.Server.Kestrel.Core.Tests.HPackHeaderWriter; namespace Microsoft.AspNetCore.Testing; diff --git a/src/Servers/Kestrel/test/FunctionalTests/ResponseTests.cs b/src/Servers/Kestrel/test/FunctionalTests/ResponseTests.cs index 119c90a28234..17eb640826d9 100644 --- a/src/Servers/Kestrel/test/FunctionalTests/ResponseTests.cs +++ b/src/Servers/Kestrel/test/FunctionalTests/ResponseTests.cs @@ -22,7 +22,6 @@ using Microsoft.AspNetCore.Server.Kestrel.FunctionalTests; using Microsoft.AspNetCore.Server.Kestrel.Https; using Microsoft.AspNetCore.Server.Kestrel.Https.Internal; -using Microsoft.AspNetCore.Server.Kestrel.Tests; using Microsoft.AspNetCore.Testing; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2StreamTests.cs b/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2StreamTests.cs index ec86b8d41e55..fdeb2f7d47cf 100644 --- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2StreamTests.cs +++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2StreamTests.cs @@ -103,17 +103,28 @@ public async Task HEADERS_Received_KnownOrCustomMethods_Accepted(string method) }; await InitializeConnectionAsync(_echoMethodNoBody); + // First request await StartStreamAsync(1, headers, endStream: true); - var headersFrame = await ExpectAsync(Http2FrameType.HEADERS, + var headersFrame1 = await ExpectAsync(Http2FrameType.HEADERS, withLength: 45 + method.Length, withFlags: (byte)(Http2HeadersFrameFlags.END_HEADERS | Http2HeadersFrameFlags.END_STREAM), withStreamId: 1); + _hpackDecoder.Decode(headersFrame1.PayloadSequence, endHeaders: false, handler: this); + + Assert.Equal(4, _decodedHeaders.Count); + Assert.Contains("date", _decodedHeaders.Keys, StringComparer.OrdinalIgnoreCase); + Assert.Equal("200", _decodedHeaders[HeaderNames.Status]); + Assert.Equal("0", _decodedHeaders[HeaderNames.ContentLength]); + Assert.Equal(method, _decodedHeaders["Method"]); + _decodedHeaders.Clear(); + + // Second request (will use dynamic table indexes) await StartStreamAsync(3, headers, endStream: true); - // Can't check length this time because it will be different with compression. var headersFrame2 = await ExpectAsync(Http2FrameType.HEADERS, + withLength: 7, withFlags: (byte)(Http2HeadersFrameFlags.END_HEADERS | Http2HeadersFrameFlags.END_STREAM), withStreamId: 3); @@ -126,6 +137,7 @@ public async Task HEADERS_Received_KnownOrCustomMethods_Accepted(string method) Assert.Equal("200", _decodedHeaders[HeaderNames.Status]); Assert.Equal("0", _decodedHeaders[HeaderNames.ContentLength]); Assert.Equal(method, _decodedHeaders["Method"]); + _decodedHeaders.Clear(); } [Fact] diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2TestBase.cs b/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2TestBase.cs index 526377145eed..b7d6b7a47535 100644 --- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2TestBase.cs +++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2TestBase.cs @@ -1183,18 +1183,6 @@ internal async Task ExpectAsync(Http2FrameType type, int return frame; } - - internal async Task ExpectAsync(Http2FrameType type, byte withFlags, int withStreamId) - { - var frame = await ReceiveFrameAsync(); - - Assert.Equal(type, frame.Type); - Assert.Equal(withFlags, frame.Flags); - Assert.Equal(withStreamId, frame.StreamId); - - return frame; - } - protected Task StopConnectionAsync(int expectedLastStreamId, bool ignoreNonGoAwayFrames) { _pair.Application.Output.Complete(); diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/InMemory.FunctionalTests.csproj b/src/Servers/Kestrel/test/InMemory.FunctionalTests/InMemory.FunctionalTests.csproj index 04bfcda57908..16dc2c48315b 100644 --- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/InMemory.FunctionalTests.csproj +++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/InMemory.FunctionalTests.csproj @@ -4,7 +4,7 @@ true InMemory.FunctionalTests true - $(DefineConstants);IS_FUNCTIONAL_TESTS + $(DefineConstants);IS_TESTS @@ -12,6 +12,8 @@ + + diff --git a/src/Servers/Kestrel/test/Sockets.BindTests/Sockets.BindTests.csproj b/src/Servers/Kestrel/test/Sockets.BindTests/Sockets.BindTests.csproj index 0f7576c452d9..4338b1ea87f8 100644 --- a/src/Servers/Kestrel/test/Sockets.BindTests/Sockets.BindTests.csproj +++ b/src/Servers/Kestrel/test/Sockets.BindTests/Sockets.BindTests.csproj @@ -1,4 +1,4 @@ - + $(DefaultNetCoreTargetFramework) @@ -10,7 +10,16 @@ - + + + + + + + + + + diff --git a/src/Servers/Kestrel/test/Sockets.FunctionalTests/Sockets.FunctionalTests.csproj b/src/Servers/Kestrel/test/Sockets.FunctionalTests/Sockets.FunctionalTests.csproj index d42ac6b661f8..b128aa8aff69 100644 --- a/src/Servers/Kestrel/test/Sockets.FunctionalTests/Sockets.FunctionalTests.csproj +++ b/src/Servers/Kestrel/test/Sockets.FunctionalTests/Sockets.FunctionalTests.csproj @@ -11,7 +11,19 @@ - + + + + + + + + + + + + +