diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/HttpHeaders.Generated.cs b/src/Servers/Kestrel/Core/src/Internal/Http/HttpHeaders.Generated.cs index fa499588ba0e..b335d7837694 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/HttpHeaders.Generated.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/HttpHeaders.Generated.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Buffers; using System.IO.Pipelines; using System.Numerics; @@ -14261,481 +14262,350 @@ internal void ClearInvalidH2H3Headers() } internal unsafe void CopyToFast(ref BufferWriter output) { - var tempBits = (ulong)_bits | (_contentLength.HasValue ? 0x8000000000000000L : 0); - var next = 0; - var keyStart = 0; - var keyLength = 0; - ref readonly StringValues values = ref Unsafe.AsRef(null); + var tempBits = (ulong)_bits; + // Set exact next + var next = BitOperations.TrailingZeroCount(tempBits); + + // Output Content-Length now as it isn't contained in the bit flags. + if (_contentLength.HasValue) + { + output.Write(HeaderBytes.Slice(640, 18)); + output.WriteNumeric((ulong)ContentLength.GetValueOrDefault()); + } + if (tempBits == 0) + { + return; + } + ref readonly StringValues values = ref Unsafe.AsRef(null); do { + int keyStart; + int keyLength; switch (next) { case 0: // Header: "Connection" - if ((tempBits & 0x1L) != 0) + Debug.Assert((tempBits & 0x1L) != 0); + if (_headers._rawConnection != null) { + // Clear and set next as not using common output. tempBits ^= 0x1L; - if (_headers._rawConnection != null) - { - output.Write(_headers._rawConnection); - } - else - { - values = ref _headers._Connection; - keyStart = 0; - keyLength = 14; - next = 1; - break; // OutputHeader - } - } - goto case 1; - case 1: // Header: "Content-Type" - if ((tempBits & 0x2L) != 0) + next = BitOperations.TrailingZeroCount(tempBits); + output.Write(_headers._rawConnection); + continue; // Jump to next, already output header + } + else { - tempBits ^= 0x2L; - values = ref _headers._ContentType; - keyStart = 14; - keyLength = 16; - next = 2; - break; // OutputHeader + values = ref _headers._Connection; + keyStart = 0; + keyLength = 14; } - goto case 2; + break; // OutputHeader + + case 1: // Header: "Content-Type" + Debug.Assert((tempBits & 0x2L) != 0); + values = ref _headers._ContentType; + keyStart = 14; + keyLength = 16; + break; // OutputHeader + case 2: // Header: "Date" - if ((tempBits & 0x4L) != 0) + Debug.Assert((tempBits & 0x4L) != 0); + if (_headers._rawDate != null) { + // Clear and set next as not using common output. tempBits ^= 0x4L; - if (_headers._rawDate != null) - { - output.Write(_headers._rawDate); - } - else - { - values = ref _headers._Date; - keyStart = 30; - keyLength = 8; - next = 3; - break; // OutputHeader - } - } - goto case 3; - case 3: // Header: "Server" - if ((tempBits & 0x8L) != 0) + next = BitOperations.TrailingZeroCount(tempBits); + output.Write(_headers._rawDate); + continue; // Jump to next, already output header + } + else { - tempBits ^= 0x8L; - if (_headers._rawServer != null) - { - output.Write(_headers._rawServer); - } - else - { - values = ref _headers._Server; - keyStart = 38; - keyLength = 10; - next = 4; - break; // OutputHeader - } - } - goto case 4; - case 4: // Header: "Content-Length" - if ((tempBits & 0x8000000000000000L) != 0) - { - tempBits ^= 0x8000000000000000L; - output.Write(HeaderBytes.Slice(640, 18)); - output.WriteNumeric((ulong)ContentLength.GetValueOrDefault()); - if (tempBits == 0) - { - return; - } - } - goto case 5; - case 5: // Header: "Accept-Ranges" - if ((tempBits & 0x10L) != 0) - { - tempBits ^= 0x10L; - values = ref _headers._AcceptRanges; - keyStart = 48; - keyLength = 17; - next = 6; - break; // OutputHeader - } - goto case 6; - case 6: // Header: "Access-Control-Allow-Credentials" - if ((tempBits & 0x20L) != 0) - { - tempBits ^= 0x20L; - values = ref _headers._AccessControlAllowCredentials; - keyStart = 65; - keyLength = 36; - next = 7; - break; // OutputHeader - } - goto case 7; - case 7: // Header: "Access-Control-Allow-Headers" - if ((tempBits & 0x40L) != 0) - { - tempBits ^= 0x40L; - values = ref _headers._AccessControlAllowHeaders; - keyStart = 101; - keyLength = 32; - next = 8; - break; // OutputHeader - } - goto case 8; - case 8: // Header: "Access-Control-Allow-Methods" - if ((tempBits & 0x80L) != 0) - { - tempBits ^= 0x80L; - values = ref _headers._AccessControlAllowMethods; - keyStart = 133; - keyLength = 32; - next = 9; - break; // OutputHeader - } - goto case 9; - case 9: // Header: "Access-Control-Allow-Origin" - if ((tempBits & 0x100L) != 0) - { - tempBits ^= 0x100L; - values = ref _headers._AccessControlAllowOrigin; - keyStart = 165; - keyLength = 31; - next = 10; - break; // OutputHeader - } - goto case 10; - case 10: // Header: "Access-Control-Expose-Headers" - if ((tempBits & 0x200L) != 0) - { - tempBits ^= 0x200L; - values = ref _headers._AccessControlExposeHeaders; - keyStart = 196; - keyLength = 33; - next = 11; - break; // OutputHeader - } - goto case 11; - case 11: // Header: "Access-Control-Max-Age" - if ((tempBits & 0x400L) != 0) - { - tempBits ^= 0x400L; - values = ref _headers._AccessControlMaxAge; - keyStart = 229; - keyLength = 26; - next = 12; - break; // OutputHeader - } - goto case 12; - case 12: // Header: "Age" - if ((tempBits & 0x800L) != 0) - { - tempBits ^= 0x800L; - values = ref _headers._Age; - keyStart = 255; - keyLength = 7; - next = 13; - break; // OutputHeader - } - goto case 13; - case 13: // Header: "Allow" - if ((tempBits & 0x1000L) != 0) - { - tempBits ^= 0x1000L; - values = ref _headers._Allow; - keyStart = 262; - keyLength = 9; - next = 14; - break; // OutputHeader - } - goto case 14; - case 14: // Header: "Alt-Svc" - if ((tempBits & 0x2000L) != 0) - { - tempBits ^= 0x2000L; - values = ref _headers._AltSvc; - keyStart = 271; - keyLength = 11; - next = 15; - break; // OutputHeader - } - goto case 15; - case 15: // Header: "Cache-Control" - if ((tempBits & 0x4000L) != 0) - { - tempBits ^= 0x4000L; - values = ref _headers._CacheControl; - keyStart = 282; - keyLength = 17; - next = 16; - break; // OutputHeader - } - goto case 16; - case 16: // Header: "Content-Encoding" - if ((tempBits & 0x8000L) != 0) - { - tempBits ^= 0x8000L; - values = ref _headers._ContentEncoding; - keyStart = 299; - keyLength = 20; - next = 17; - break; // OutputHeader - } - goto case 17; - case 17: // Header: "Content-Language" - if ((tempBits & 0x10000L) != 0) - { - tempBits ^= 0x10000L; - values = ref _headers._ContentLanguage; - keyStart = 319; - keyLength = 20; - next = 18; - break; // OutputHeader - } - goto case 18; - case 18: // Header: "Content-Location" - if ((tempBits & 0x20000L) != 0) - { - tempBits ^= 0x20000L; - values = ref _headers._ContentLocation; - keyStart = 339; - keyLength = 20; - next = 19; - break; // OutputHeader - } - goto case 19; - case 19: // Header: "Content-MD5" - if ((tempBits & 0x40000L) != 0) - { - tempBits ^= 0x40000L; - values = ref _headers._ContentMD5; - keyStart = 359; - keyLength = 15; - next = 20; - break; // OutputHeader - } - goto case 20; - case 20: // Header: "Content-Range" - if ((tempBits & 0x80000L) != 0) - { - tempBits ^= 0x80000L; - values = ref _headers._ContentRange; - keyStart = 374; - keyLength = 17; - next = 21; - break; // OutputHeader - } - goto case 21; - case 21: // Header: "ETag" - if ((tempBits & 0x100000L) != 0) - { - tempBits ^= 0x100000L; - values = ref _headers._ETag; - keyStart = 391; + values = ref _headers._Date; + keyStart = 30; keyLength = 8; - next = 22; - break; // OutputHeader - } - goto case 22; - case 22: // Header: "Expires" - if ((tempBits & 0x200000L) != 0) - { - tempBits ^= 0x200000L; - values = ref _headers._Expires; - keyStart = 399; - keyLength = 11; - next = 23; - break; // OutputHeader - } - goto case 23; - case 23: // Header: "Grpc-Encoding" - if ((tempBits & 0x400000L) != 0) - { - tempBits ^= 0x400000L; - values = ref _headers._GrpcEncoding; - keyStart = 410; - keyLength = 17; - next = 24; - break; // OutputHeader - } - goto case 24; - case 24: // Header: "Keep-Alive" - if ((tempBits & 0x800000L) != 0) - { - tempBits ^= 0x800000L; - values = ref _headers._KeepAlive; - keyStart = 427; - keyLength = 14; - next = 25; - break; // OutputHeader - } - goto case 25; - case 25: // Header: "Last-Modified" - if ((tempBits & 0x1000000L) != 0) - { - tempBits ^= 0x1000000L; - values = ref _headers._LastModified; - keyStart = 441; - keyLength = 17; - next = 26; - break; // OutputHeader - } - goto case 26; - case 26: // Header: "Location" - if ((tempBits & 0x2000000L) != 0) - { - tempBits ^= 0x2000000L; - values = ref _headers._Location; - keyStart = 458; - keyLength = 12; - next = 27; - break; // OutputHeader - } - goto case 27; - case 27: // Header: "Pragma" - if ((tempBits & 0x4000000L) != 0) - { - tempBits ^= 0x4000000L; - values = ref _headers._Pragma; - keyStart = 470; - keyLength = 10; - next = 28; - break; // OutputHeader - } - goto case 28; - case 28: // Header: "Proxy-Authenticate" - if ((tempBits & 0x8000000L) != 0) - { - tempBits ^= 0x8000000L; - values = ref _headers._ProxyAuthenticate; - keyStart = 480; - keyLength = 22; - next = 29; - break; // OutputHeader - } - goto case 29; - case 29: // Header: "Proxy-Connection" - if ((tempBits & 0x10000000L) != 0) - { - tempBits ^= 0x10000000L; - values = ref _headers._ProxyConnection; - keyStart = 502; - keyLength = 20; - next = 30; - break; // OutputHeader - } - goto case 30; - case 30: // Header: "Retry-After" - if ((tempBits & 0x20000000L) != 0) - { - tempBits ^= 0x20000000L; - values = ref _headers._RetryAfter; - keyStart = 522; - keyLength = 15; - next = 31; - break; // OutputHeader - } - goto case 31; - case 31: // Header: "Set-Cookie" - if ((tempBits & 0x40000000L) != 0) - { - tempBits ^= 0x40000000L; - values = ref _headers._SetCookie; - keyStart = 537; - keyLength = 14; - next = 32; - break; // OutputHeader } - goto case 32; - case 32: // Header: "Trailer" - if ((tempBits & 0x80000000L) != 0) + break; // OutputHeader + + case 3: // Header: "Server" + Debug.Assert((tempBits & 0x8L) != 0); + if (_headers._rawServer != null) { - tempBits ^= 0x80000000L; - values = ref _headers._Trailer; - keyStart = 551; - keyLength = 11; - next = 33; - break; // OutputHeader + // Clear and set next as not using common output. + tempBits ^= 0x8L; + next = BitOperations.TrailingZeroCount(tempBits); + output.Write(_headers._rawServer); + continue; // Jump to next, already output header } - goto case 33; - case 33: // Header: "Transfer-Encoding" - if ((tempBits & 0x100000000L) != 0) + else { + values = ref _headers._Server; + keyStart = 38; + keyLength = 10; + } + break; // OutputHeader + + case 4: // Header: "Accept-Ranges" + Debug.Assert((tempBits & 0x10L) != 0); + values = ref _headers._AcceptRanges; + keyStart = 48; + keyLength = 17; + break; // OutputHeader + + case 5: // Header: "Access-Control-Allow-Credentials" + Debug.Assert((tempBits & 0x20L) != 0); + values = ref _headers._AccessControlAllowCredentials; + keyStart = 65; + keyLength = 36; + break; // OutputHeader + + case 6: // Header: "Access-Control-Allow-Headers" + Debug.Assert((tempBits & 0x40L) != 0); + values = ref _headers._AccessControlAllowHeaders; + keyStart = 101; + keyLength = 32; + break; // OutputHeader + + case 7: // Header: "Access-Control-Allow-Methods" + Debug.Assert((tempBits & 0x80L) != 0); + values = ref _headers._AccessControlAllowMethods; + keyStart = 133; + keyLength = 32; + break; // OutputHeader + + case 8: // Header: "Access-Control-Allow-Origin" + Debug.Assert((tempBits & 0x100L) != 0); + values = ref _headers._AccessControlAllowOrigin; + keyStart = 165; + keyLength = 31; + break; // OutputHeader + + case 9: // Header: "Access-Control-Expose-Headers" + Debug.Assert((tempBits & 0x200L) != 0); + values = ref _headers._AccessControlExposeHeaders; + keyStart = 196; + keyLength = 33; + break; // OutputHeader + + case 10: // Header: "Access-Control-Max-Age" + Debug.Assert((tempBits & 0x400L) != 0); + values = ref _headers._AccessControlMaxAge; + keyStart = 229; + keyLength = 26; + break; // OutputHeader + + case 11: // Header: "Age" + Debug.Assert((tempBits & 0x800L) != 0); + values = ref _headers._Age; + keyStart = 255; + keyLength = 7; + break; // OutputHeader + + case 12: // Header: "Allow" + Debug.Assert((tempBits & 0x1000L) != 0); + values = ref _headers._Allow; + keyStart = 262; + keyLength = 9; + break; // OutputHeader + + case 13: // Header: "Alt-Svc" + Debug.Assert((tempBits & 0x2000L) != 0); + values = ref _headers._AltSvc; + keyStart = 271; + keyLength = 11; + break; // OutputHeader + + case 14: // Header: "Cache-Control" + Debug.Assert((tempBits & 0x4000L) != 0); + values = ref _headers._CacheControl; + keyStart = 282; + keyLength = 17; + break; // OutputHeader + + case 15: // Header: "Content-Encoding" + Debug.Assert((tempBits & 0x8000L) != 0); + values = ref _headers._ContentEncoding; + keyStart = 299; + keyLength = 20; + break; // OutputHeader + + case 16: // Header: "Content-Language" + Debug.Assert((tempBits & 0x10000L) != 0); + values = ref _headers._ContentLanguage; + keyStart = 319; + keyLength = 20; + break; // OutputHeader + + case 17: // Header: "Content-Location" + Debug.Assert((tempBits & 0x20000L) != 0); + values = ref _headers._ContentLocation; + keyStart = 339; + keyLength = 20; + break; // OutputHeader + + case 18: // Header: "Content-MD5" + Debug.Assert((tempBits & 0x40000L) != 0); + values = ref _headers._ContentMD5; + keyStart = 359; + keyLength = 15; + break; // OutputHeader + + case 19: // Header: "Content-Range" + Debug.Assert((tempBits & 0x80000L) != 0); + values = ref _headers._ContentRange; + keyStart = 374; + keyLength = 17; + break; // OutputHeader + + case 20: // Header: "ETag" + Debug.Assert((tempBits & 0x100000L) != 0); + values = ref _headers._ETag; + keyStart = 391; + keyLength = 8; + break; // OutputHeader + + case 21: // Header: "Expires" + Debug.Assert((tempBits & 0x200000L) != 0); + values = ref _headers._Expires; + keyStart = 399; + keyLength = 11; + break; // OutputHeader + + case 22: // Header: "Grpc-Encoding" + Debug.Assert((tempBits & 0x400000L) != 0); + values = ref _headers._GrpcEncoding; + keyStart = 410; + keyLength = 17; + break; // OutputHeader + + case 23: // Header: "Keep-Alive" + Debug.Assert((tempBits & 0x800000L) != 0); + values = ref _headers._KeepAlive; + keyStart = 427; + keyLength = 14; + break; // OutputHeader + + case 24: // Header: "Last-Modified" + Debug.Assert((tempBits & 0x1000000L) != 0); + values = ref _headers._LastModified; + keyStart = 441; + keyLength = 17; + break; // OutputHeader + + case 25: // Header: "Location" + Debug.Assert((tempBits & 0x2000000L) != 0); + values = ref _headers._Location; + keyStart = 458; + keyLength = 12; + break; // OutputHeader + + case 26: // Header: "Pragma" + Debug.Assert((tempBits & 0x4000000L) != 0); + values = ref _headers._Pragma; + keyStart = 470; + keyLength = 10; + break; // OutputHeader + + case 27: // Header: "Proxy-Authenticate" + Debug.Assert((tempBits & 0x8000000L) != 0); + values = ref _headers._ProxyAuthenticate; + keyStart = 480; + keyLength = 22; + break; // OutputHeader + + case 28: // Header: "Proxy-Connection" + Debug.Assert((tempBits & 0x10000000L) != 0); + values = ref _headers._ProxyConnection; + keyStart = 502; + keyLength = 20; + break; // OutputHeader + + case 29: // Header: "Retry-After" + Debug.Assert((tempBits & 0x20000000L) != 0); + values = ref _headers._RetryAfter; + keyStart = 522; + keyLength = 15; + break; // OutputHeader + + case 30: // Header: "Set-Cookie" + Debug.Assert((tempBits & 0x40000000L) != 0); + values = ref _headers._SetCookie; + keyStart = 537; + keyLength = 14; + break; // OutputHeader + + case 31: // Header: "Trailer" + Debug.Assert((tempBits & 0x80000000L) != 0); + values = ref _headers._Trailer; + keyStart = 551; + keyLength = 11; + break; // OutputHeader + + case 32: // Header: "Transfer-Encoding" + Debug.Assert((tempBits & 0x100000000L) != 0); + if (_headers._rawTransferEncoding != null) + { + // Clear and set next as not using common output. tempBits ^= 0x100000000L; - if (_headers._rawTransferEncoding != null) - { - output.Write(_headers._rawTransferEncoding); - } - else - { - values = ref _headers._TransferEncoding; - keyStart = 562; - keyLength = 21; - next = 34; - break; // OutputHeader - } - } - goto case 34; - case 34: // Header: "Upgrade" - if ((tempBits & 0x200000000L) != 0) - { - tempBits ^= 0x200000000L; - values = ref _headers._Upgrade; - keyStart = 583; - keyLength = 11; - next = 35; - break; // OutputHeader - } - goto case 35; - case 35: // Header: "Vary" - if ((tempBits & 0x400000000L) != 0) - { - tempBits ^= 0x400000000L; - values = ref _headers._Vary; - keyStart = 594; - keyLength = 8; - next = 36; - break; // OutputHeader - } - goto case 36; - case 36: // Header: "Via" - if ((tempBits & 0x800000000L) != 0) - { - tempBits ^= 0x800000000L; - values = ref _headers._Via; - keyStart = 602; - keyLength = 7; - next = 37; - break; // OutputHeader - } - goto case 37; - case 37: // Header: "Warning" - if ((tempBits & 0x1000000000L) != 0) - { - tempBits ^= 0x1000000000L; - values = ref _headers._Warning; - keyStart = 609; - keyLength = 11; - next = 38; - break; // OutputHeader - } - goto case 38; - case 38: // Header: "WWW-Authenticate" - if ((tempBits & 0x2000000000L) != 0) - { - tempBits ^= 0x2000000000L; - values = ref _headers._WWWAuthenticate; - keyStart = 620; - keyLength = 20; - next = 39; - break; // OutputHeader + next = BitOperations.TrailingZeroCount(tempBits); + output.Write(_headers._rawTransferEncoding); + continue; // Jump to next, already output header } - return; + else + { + values = ref _headers._TransferEncoding; + keyStart = 562; + keyLength = 21; + } + break; // OutputHeader + + case 33: // Header: "Upgrade" + Debug.Assert((tempBits & 0x200000000L) != 0); + values = ref _headers._Upgrade; + keyStart = 583; + keyLength = 11; + break; // OutputHeader + + case 34: // Header: "Vary" + Debug.Assert((tempBits & 0x400000000L) != 0); + values = ref _headers._Vary; + keyStart = 594; + keyLength = 8; + break; // OutputHeader + + case 35: // Header: "Via" + Debug.Assert((tempBits & 0x800000000L) != 0); + values = ref _headers._Via; + keyStart = 602; + keyLength = 7; + break; // OutputHeader + + case 36: // Header: "Warning" + Debug.Assert((tempBits & 0x1000000000L) != 0); + values = ref _headers._Warning; + keyStart = 609; + keyLength = 11; + break; // OutputHeader + + case 37: // Header: "WWW-Authenticate" + Debug.Assert((tempBits & 0x2000000000L) != 0); + values = ref _headers._WWWAuthenticate; + keyStart = 620; + keyLength = 20; + break; // OutputHeader + default: + ThrowInvalidHeaderBits(); return; } // OutputHeader { + // Clear bit + tempBits ^= (1UL << next); var valueCount = values.Count; + Debug.Assert(valueCount > 0); + var headerKey = HeaderBytes.Slice(keyStart, keyLength); for (var i = 0; i < valueCount; i++) { @@ -14746,6 +14616,8 @@ internal unsafe void CopyToFast(ref BufferWriter output) output.WriteAscii(value); } } + // Set exact next + next = BitOperations.TrailingZeroCount(tempBits); } } while (tempBits != 0); } diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/HttpResponseHeaders.cs b/src/Servers/Kestrel/Core/src/Internal/Http/HttpResponseHeaders.cs index bdefaf8e9861..ae51e3c535e9 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/HttpResponseHeaders.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/HttpResponseHeaders.cs @@ -3,6 +3,7 @@ using System; using System.Buffers; +using System.Diagnostics.CodeAnalysis; using System.IO.Pipelines; using System.Collections; using System.Collections.Generic; @@ -67,11 +68,18 @@ private static long ParseContentLength(string value) return parsed; } + [DoesNotReturn] private static void ThrowInvalidContentLengthException(string value) { throw new InvalidOperationException(CoreStrings.FormatInvalidContentLength_InvalidNumber(value)); } + [DoesNotReturn] + private static void ThrowInvalidHeaderBits() + { + throw new InvalidOperationException("Invalid Header Bits"); + } + [MethodImpl(MethodImplOptions.NoInlining)] private void SetValueUnknown(string key, StringValues value) { diff --git a/src/Servers/Kestrel/perf/Microbenchmarks/InMemoryTransportBenchmark.cs b/src/Servers/Kestrel/perf/Microbenchmarks/InMemoryTransportBenchmark.cs index 32a6d5c320ce..b6a068a72682 100644 --- a/src/Servers/Kestrel/perf/Microbenchmarks/InMemoryTransportBenchmark.cs +++ b/src/Servers/Kestrel/perf/Microbenchmarks/InMemoryTransportBenchmark.cs @@ -24,10 +24,10 @@ public class InMemoryTransportBenchmark { private const string _plaintextExpectedResponse = "HTTP/1.1 200 OK\r\n" + + "Content-Length: 13\r\n" + "Date: Fri, 02 Mar 2018 18:37:05 GMT\r\n" + "Content-Type: text/plain\r\n" + "Server: Kestrel\r\n" + - "Content-Length: 13\r\n" + "\r\n" + "Hello, World!"; diff --git a/src/Servers/Kestrel/perf/Microbenchmarks/ResponseHeadersWritingBenchmark.cs b/src/Servers/Kestrel/perf/Microbenchmarks/ResponseHeadersWritingBenchmark.cs index 0157e8c6fbd9..1c7282375aa2 100644 --- a/src/Servers/Kestrel/perf/Microbenchmarks/ResponseHeadersWritingBenchmark.cs +++ b/src/Servers/Kestrel/perf/Microbenchmarks/ResponseHeadersWritingBenchmark.cs @@ -17,6 +17,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Microbenchmarks { public class ResponseHeadersWritingBenchmark { + private const int Iterations = 1000; + private static readonly byte[] _bytesServer = Encoding.ASCII.GetBytes("\r\nServer: " + Constants.ServerName); private static readonly byte[] _helloWorldPayload = Encoding.ASCII.GetBytes("Hello, World!"); @@ -32,11 +34,12 @@ public class ResponseHeadersWritingBenchmark BenchmarkTypes.PlaintextChunked, BenchmarkTypes.PlaintextWithCookie, BenchmarkTypes.PlaintextChunkedWithCookie, - BenchmarkTypes.LiveAspNet + BenchmarkTypes.LiveAspNet, + BenchmarkTypes.Common )] public BenchmarkTypes Type { get; set; } - [Benchmark] + [Benchmark(OperationsPerInvoke = Iterations)] public void Output() { switch (Type) @@ -56,6 +59,9 @@ public void Output() case BenchmarkTypes.LiveAspNet: LiveAspNet(); break; + case BenchmarkTypes.Common: + Common(); + break; } } @@ -66,7 +72,11 @@ private void TechEmpowerPlaintext() responseHeaders.ContentLength = _helloWorldPayload.Length; var writer = new BufferWriter(_writer); - _responseHeaders.CopyTo(ref writer); + + for (var i = 0; i < Iterations; i++) + { + _responseHeaders.CopyTo(ref writer); + } } private void PlaintextChunked() @@ -75,7 +85,11 @@ private void PlaintextChunked() responseHeaders.ContentType = "text/plain"; var writer = new BufferWriter(_writer); - _responseHeaders.CopyTo(ref writer); + + for (var i = 0; i < Iterations; i++) + { + _responseHeaders.CopyTo(ref writer); + } } private void LiveAspNet() @@ -88,7 +102,45 @@ private void LiveAspNet() _responseHeadersDict["X-Powered-By"] = "ASP.NET"; var writer = new BufferWriter(_writer); - _responseHeaders.CopyTo(ref writer); + + for (var i = 0; i < Iterations; i++) + { + _responseHeaders.CopyTo(ref writer); + } + } + + private void Common() + { + var responseHeaders = _responseHeadersDict; + responseHeaders.ContentType = "text/css"; + responseHeaders.ContentLength = 421; + + responseHeaders.Connection = "Close"; + responseHeaders.CacheControl = "public, max-age=30672000"; + responseHeaders.Vary = "Accept-Encoding"; + responseHeaders.ContentEncoding = "gzip"; + responseHeaders.Expires = "Fri, 12 Jan 2018 22:01:55 GMT"; + responseHeaders.LastModified = "Wed, 22 Jun 2016 20:08:29 GMT"; + responseHeaders.SetCookie = "prov=20629ccd-8b0f-e8ef-2935-cd26609fc0bc; __qca=P0-1591065732-1479167353442; _ga=GA1.2.1298898376.1479167354; _gat=1; sgt=id=9519gfde_3347_4762_8762_df51458c8ec2; acct=t=why-is-%e0%a5%a7%e0%a5%a8%e0%a5%a9-numeric&s=why-is-%e0%a5%a7%e0%a5%a8%e0%a5%a9-numeric"; + responseHeaders.ETag = "\"54ef7954-1078\""; + responseHeaders.TransferEncoding = "chunked"; + responseHeaders.ContentLanguage = "en-gb"; + responseHeaders.Upgrade = "websocket"; + responseHeaders.Via = "1.1 varnish"; + responseHeaders.AccessControlAllowOrigin = "*"; + responseHeaders.AccessControlAllowCredentials = "true"; + responseHeaders.AccessControlExposeHeaders = "Client-Protocol, Content-Length, Content-Type, X-Bandwidth-Est, X-Bandwidth-Est2, X-Bandwidth-Est-Comp, X-Bandwidth-Avg, X-Walltime-Ms, X-Sequence-Num"; + + var dateHeaderValues = _dateHeaderValueManager.GetDateHeaderValues(); + _responseHeaders.SetRawDate(dateHeaderValues.String, dateHeaderValues.Bytes); + _responseHeaders.SetRawServer("Kestrel", _bytesServer); + + var writer = new BufferWriter(_writer); + + for (var i = 0; i < Iterations; i++) + { + _responseHeaders.CopyTo(ref writer); + } } private void PlaintextWithCookie() @@ -99,7 +151,11 @@ private void PlaintextWithCookie() responseHeaders.ContentLength = _helloWorldPayload.Length; var writer = new BufferWriter(_writer); - _responseHeaders.CopyTo(ref writer); + + for (var i = 0; i < Iterations; i++) + { + _responseHeaders.CopyTo(ref writer); + } } private void PlaintextChunkedWithCookie() @@ -110,7 +166,11 @@ private void PlaintextChunkedWithCookie() responseHeaders.TransferEncoding = "chunked"; var writer = new BufferWriter(_writer); - _responseHeaders.CopyTo(ref writer); + + for (var i = 0; i < Iterations; i++) + { + _responseHeaders.CopyTo(ref writer); + } } [GlobalSetup] @@ -151,7 +211,8 @@ public enum BenchmarkTypes PlaintextChunked, PlaintextWithCookie, PlaintextChunkedWithCookie, - LiveAspNet + LiveAspNet, + Common } } } diff --git a/src/Servers/Kestrel/shared/KnownHeaders.cs b/src/Servers/Kestrel/shared/KnownHeaders.cs index 4a9db696c252..9ccbc432fb12 100644 --- a/src/Servers/Kestrel/shared/KnownHeaders.cs +++ b/src/Servers/Kestrel/shared/KnownHeaders.cs @@ -769,6 +769,7 @@ public static string GeneratedFile() using System; using System.Collections.Generic; +using System.Diagnostics; using System.Buffers; using System.IO.Pipelines; using System.Numerics; @@ -1150,52 +1151,61 @@ internal void ClearInvalidH2H3Headers() }} internal unsafe void CopyToFast(ref BufferWriter output) {{ - var tempBits = (ulong)_bits | (_contentLength.HasValue ? {"0x" + (1L << 63).ToString("x" , CultureInfo.InvariantCulture)}L : 0); - var next = 0; - var keyStart = 0; - var keyLength = 0; - ref readonly StringValues values = ref Unsafe.AsRef(null); + var tempBits = (ulong)_bits; + // Set exact next + var next = BitOperations.TrailingZeroCount(tempBits); + + // Output Content-Length now as it isn't contained in the bit flags. + if (_contentLength.HasValue) + {{ + output.Write(HeaderBytes.Slice(640, 18)); + output.WriteNumeric((ulong)ContentLength.GetValueOrDefault()); + }} + if (tempBits == 0) + {{ + return; + }} + ref readonly StringValues values = ref Unsafe.AsRef(null); do {{ + int keyStart; + int keyLength; switch (next) - {{{Each(loop.Headers.OrderBy(h => !h.PrimaryHeader).Select((h, i) => (Header: h, Index: i)), hi => $@" - case {hi.Index}: // Header: ""{hi.Header.Name}"" - if ({hi.Header.TestTempBit()}) + {{{Each(loop.Headers.OrderBy(h => h.Index).Where(h => h.Identifier != "ContentLength"), header => $@" + case {header.Index}: // Header: ""{header.Name}"" + Debug.Assert({header.TestTempBit()});{(header.EnhancedSetter == false ? $@" + values = ref _headers._{header.Identifier}; + keyStart = {header.BytesOffset}; + keyLength = {header.BytesCount};" : $@" + if (_headers._raw{header.Identifier} != null) {{ - tempBits ^= {"0x" + (1L << hi.Header.Index).ToString("x" , CultureInfo.InvariantCulture)}L;{(hi.Header.Identifier != "ContentLength" ? $@"{(hi.Header.EnhancedSetter == false ? $@" - values = ref _headers._{hi.Header.Identifier}; - keyStart = {hi.Header.BytesOffset}; - keyLength = {hi.Header.BytesCount}; - next = {hi.Index + 1}; - break; // OutputHeader" : $@" - if (_headers._raw{hi.Header.Identifier} != null) - {{ - output.Write(_headers._raw{hi.Header.Identifier}); - }} - else - {{ - values = ref _headers._{hi.Header.Identifier}; - keyStart = {hi.Header.BytesOffset}; - keyLength = {hi.Header.BytesCount}; - next = {hi.Index + 1}; - break; // OutputHeader - }}")}" : $@" - output.Write(HeaderBytes.Slice({hi.Header.BytesOffset}, {hi.Header.BytesCount})); - output.WriteNumeric((ulong)ContentLength.GetValueOrDefault()); - if (tempBits == 0) - {{ - return; - }}")} + // Clear and set next as not using common output. + tempBits ^= {"0x" + (1L << header.Index).ToString("x", CultureInfo.InvariantCulture)}L; + next = BitOperations.TrailingZeroCount(tempBits); + output.Write(_headers._raw{header.Identifier}); + continue; // Jump to next, already output header }} - {(hi.Index + 1 < loop.Headers.Length ? $"goto case {hi.Index + 1};" : "return;")}")} + else + {{ + values = ref _headers._{header.Identifier}; + keyStart = {header.BytesOffset}; + keyLength = {header.BytesCount}; + }}")} + break; // OutputHeader +")} default: + ThrowInvalidHeaderBits(); return; }} // OutputHeader {{ + // Clear bit + tempBits ^= (1UL << next); var valueCount = values.Count; + Debug.Assert(valueCount > 0); + var headerKey = HeaderBytes.Slice(keyStart, keyLength); for (var i = 0; i < valueCount; i++) {{ @@ -1206,6 +1216,8 @@ internal unsafe void CopyToFast(ref BufferWriter output) output.WriteAscii(value); }} }} + // Set exact next + next = BitOperations.TrailingZeroCount(tempBits); }} }} while (tempBits != 0); }}" : "")}{(loop.ClassName == "HttpRequestHeaders" ? $@" diff --git a/src/Servers/Kestrel/test/FunctionalTests/ListenHandleTests.cs b/src/Servers/Kestrel/test/FunctionalTests/ListenHandleTests.cs index 28c233d02f7a..4cb239f2e44c 100644 --- a/src/Servers/Kestrel/test/FunctionalTests/ListenHandleTests.cs +++ b/src/Servers/Kestrel/test/FunctionalTests/ListenHandleTests.cs @@ -37,8 +37,8 @@ public async Task CanListenToOpenTcpSocketHandle() await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 0", + $"Date: {server.Context.DateHeaderValue}", "", ""); } diff --git a/src/Servers/Kestrel/test/FunctionalTests/RequestTests.cs b/src/Servers/Kestrel/test/FunctionalTests/RequestTests.cs index aff2e112b1af..8d97d23eb305 100644 --- a/src/Servers/Kestrel/test/FunctionalTests/RequestTests.cs +++ b/src/Servers/Kestrel/test/FunctionalTests/RequestTests.cs @@ -214,13 +214,13 @@ await connection2.Send( ""); await connection1.Receive($"HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 0", + $"Date: {server.Context.DateHeaderValue}", "", ""); await connection2.Receive($"HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 0", + $"Date: {server.Context.DateHeaderValue}", "", ""); } @@ -319,8 +319,8 @@ await connection.Send( // a more critical log message. await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 0", + $"Date: {server.Context.DateHeaderValue}", "", ""); @@ -583,9 +583,9 @@ await connection.Send( await connectionClosedTcs.Task.DefaultTimeout(); await connection.ReceiveEnd($"HTTP/1.1 200 OK", + "Content-Length: 0", "Connection: close", $"Date: {server.Context.DateHeaderValue}", - "Content-Length: 0", "", ""); } @@ -698,8 +698,8 @@ await connection.Send( await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {testContext.DateHeaderValue}", "Content-Length: 5", + $"Date: {testContext.DateHeaderValue}", "", "World"); diff --git a/src/Servers/Kestrel/test/FunctionalTests/ResponseTests.cs b/src/Servers/Kestrel/test/FunctionalTests/ResponseTests.cs index c66a7ac7c557..e0e2a4793279 100644 --- a/src/Servers/Kestrel/test/FunctionalTests/ResponseTests.cs +++ b/src/Servers/Kestrel/test/FunctionalTests/ResponseTests.cs @@ -880,6 +880,7 @@ await connection.Send( await connection.Receive( "HTTP/1.1 200 OK", + "Content-Length: 0", $"Date: {dateHeaderValueManager.GetDateHeaderValues().String}"); var minResponseSize = headerSize * headerCount; diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/BadHttpRequestTests.cs b/src/Servers/Kestrel/test/InMemory.FunctionalTests/BadHttpRequestTests.cs index e943af69fc4d..b85839249ab6 100644 --- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/BadHttpRequestTests.cs +++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/BadHttpRequestTests.cs @@ -225,9 +225,9 @@ private async Task ReceiveBadRequestResponse(InMemoryConnection connection, stri var lines = new[] { $"HTTP/1.1 {expectedResponseStatusCode}", + "Content-Length: 0", "Connection: close", $"Date: {expectedDateHeaderValue}", - "Content-Length: 0", expectedAllowHeader, "", "" diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/ChunkedRequestTests.cs b/src/Servers/Kestrel/test/InMemory.FunctionalTests/ChunkedRequestTests.cs index 8917f8e82a79..56f8deaa0a8d 100644 --- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/ChunkedRequestTests.cs +++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/ChunkedRequestTests.cs @@ -153,16 +153,16 @@ await connection.Send( "Goodbye"); await connection.Receive( "HTTP/1.1 200 OK", + "Content-Length: 11", "Connection: keep-alive", $"Date: {testContext.DateHeaderValue}", - "Content-Length: 11", "", "Hello World"); await connection.ReceiveEnd( "HTTP/1.1 200 OK", + "Content-Length: 7", "Connection: close", $"Date: {testContext.DateHeaderValue}", - "Content-Length: 7", "", "Goodbye"); } @@ -208,16 +208,16 @@ await connection.Send( "Goodbye"); await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {testContext.DateHeaderValue}", "Content-Length: 11", + $"Date: {testContext.DateHeaderValue}", "", "Hello WorldHTTP/1.1 200 OK", - $"Date: {testContext.DateHeaderValue}", "Content-Length: 11", + $"Date: {testContext.DateHeaderValue}", "", "Hello WorldHTTP/1.1 200 OK", - $"Date: {testContext.DateHeaderValue}", "Content-Length: 11", + $"Date: {testContext.DateHeaderValue}", "", "Hello World"); } @@ -302,8 +302,8 @@ public async Task TrailingHeadersAreParsed() { var response = string.Join("\r\n", new string[] { "HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 11", + $"Date: {server.Context.DateHeaderValue}", "", "Hello World"}); @@ -433,8 +433,8 @@ public async Task TrailingHeadersAreParsedWithPipe() { var response = string.Join("\r\n", new string[] { "HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 11", + $"Date: {server.Context.DateHeaderValue}", "", "Hello World"}); @@ -517,9 +517,9 @@ await connection.SendAll( ""); await connection.ReceiveEnd( "HTTP/1.1 431 Request Header Fields Too Large", + "Content-Length: 0", "Connection: close", $"Date: {testContext.DateHeaderValue}", - "Content-Length: 0", "", ""); } @@ -558,9 +558,9 @@ await connection.SendAll( ""); await connection.ReceiveEnd( "HTTP/1.1 431 Request Header Fields Too Large", + "Content-Length: 0", "Connection: close", $"Date: {testContext.DateHeaderValue}", - "Content-Length: 0", "", ""); } @@ -602,8 +602,8 @@ public async Task ExtensionsAreIgnored() { var response = string.Join("\r\n", new string[] { "HTTP/1.1 200 OK", - $"Date: {testContext.DateHeaderValue}", "Content-Length: 11", + $"Date: {testContext.DateHeaderValue}", "", "Hello World"}); @@ -684,11 +684,11 @@ await connection.SendAll( await connection.Receive( "HTTP/1.1 400 Bad Request", + "Content-Length: 0", "Connection: close", ""); await connection.ReceiveEnd( $"Date: {testContext.DateHeaderValue}", - "Content-Length: 0", "", ""); } @@ -729,11 +729,11 @@ await connection.SendAll( await connection.Receive( "HTTP/1.1 400 Bad Request", + "Content-Length: 0", "Connection: close", ""); await connection.ReceiveEnd( $"Date: {testContext.DateHeaderValue}", - "Content-Length: 0", "", ""); } @@ -765,9 +765,9 @@ await connection.SendAll( await connection.ReceiveEnd( "HTTP/1.1 400 Bad Request", + "Content-Length: 0", "Connection: close", $"Date: {testContext.DateHeaderValue}", - "Content-Length: 0", "", ""); } @@ -789,9 +789,9 @@ await connection.SendAll( await connection.ReceiveEnd( "HTTP/1.1 400 Bad Request", + "Content-Length: 0", "Connection: close", $"Date: {testContext.DateHeaderValue}", - "Content-Length: 0", "", ""); } @@ -811,9 +811,9 @@ await connection.SendAll( await connection.ReceiveEnd( "HTTP/1.1 400 Bad Request", + "Content-Length: 0", "Connection: close", $"Date: {testContext.DateHeaderValue}", - "Content-Length: 0", "", ""); } @@ -835,9 +835,9 @@ await connection.SendAll( await connection.ReceiveEnd( "HTTP/1.1 400 Bad Request", + "Content-Length: 0", "Connection: close", $"Date: {testContext.DateHeaderValue}", - "Content-Length: 0", "", ""); } @@ -944,8 +944,8 @@ await connection.Send( await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {testContext.DateHeaderValue}", "Content-Length: 11", + $"Date: {testContext.DateHeaderValue}", "", "Hello World"); } @@ -994,8 +994,8 @@ await connection.Send( await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {testContext.DateHeaderValue}", "Content-Length: 11", + $"Date: {testContext.DateHeaderValue}", "", "Hello World"); } @@ -1038,8 +1038,8 @@ await connection.Send( await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {testContext.DateHeaderValue}", "Content-Length: 0", + $"Date: {testContext.DateHeaderValue}", "", ""); @@ -1055,8 +1055,8 @@ await connection.Send( await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {testContext.DateHeaderValue}", "Content-Length: 0", + $"Date: {testContext.DateHeaderValue}", "", ""); } @@ -1103,8 +1103,8 @@ await connection.SendAll( await connection.Receive( "HTTP/1.1 500 Internal Server Error", - $"Date: {testContext.DateHeaderValue}", "Content-Length: 0", + $"Date: {testContext.DateHeaderValue}", "", ""); } diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/ChunkedResponseTests.cs b/src/Servers/Kestrel/test/InMemory.FunctionalTests/ChunkedResponseTests.cs index 0224afa97d87..f750353b9e32 100644 --- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/ChunkedResponseTests.cs +++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/ChunkedResponseTests.cs @@ -1055,8 +1055,8 @@ await connection.Send( ""); await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {testContext.DateHeaderValue}", "Content-Length: 0", + $"Date: {testContext.DateHeaderValue}", "", ""); } diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/DefaultHeaderTests.cs b/src/Servers/Kestrel/test/InMemory.FunctionalTests/DefaultHeaderTests.cs index 57166bd98c76..7e906663c747 100644 --- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/DefaultHeaderTests.cs +++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/DefaultHeaderTests.cs @@ -32,15 +32,15 @@ await connection.Send( await connection.ReceiveEnd( "HTTP/1.1 200 OK", + "Content-Length: 0", $"Date: {testContext.DateHeaderValue}", "Server: Kestrel", - "Content-Length: 0", "", "HTTP/1.1 200 OK", + "Content-Length: 0", "Connection: close", $"Date: {testContext.DateHeaderValue}", "Server: Kestrel", - "Content-Length: 0", "", ""); } diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/EventSourceTests.cs b/src/Servers/Kestrel/test/InMemory.FunctionalTests/EventSourceTests.cs index 9782539ba180..d56ed67df83e 100644 --- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/EventSourceTests.cs +++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/EventSourceTests.cs @@ -66,8 +66,8 @@ public async Task Http1_EmitsStartAndStopEventsWithActivityIds() await connection.SendEmptyGet(); await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 0", + $"Date: {server.Context.DateHeaderValue}", "", ""); diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/MaxRequestBodySizeTests.cs b/src/Servers/Kestrel/test/InMemory.FunctionalTests/MaxRequestBodySizeTests.cs index e577f80b2a53..4423d536829e 100644 --- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/MaxRequestBodySizeTests.cs +++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/MaxRequestBodySizeTests.cs @@ -48,9 +48,9 @@ await connection.Send( ""); await connection.ReceiveEnd( "HTTP/1.1 413 Payload Too Large", + "Content-Length: 0", "Connection: close", $"Date: {server.Context.DateHeaderValue}", - "Content-Length: 0", "", ""); } @@ -98,9 +98,9 @@ await connection.Send( ""); await connection.ReceiveEnd( "HTTP/1.1 413 Payload Too Large", + "Content-Length: 0", "Connection: close", $"Date: {server.Context.DateHeaderValue}", - "Content-Length: 0", "", ""); } @@ -142,8 +142,8 @@ await connection.Send( "A"); await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 1", + $"Date: {server.Context.DateHeaderValue}", "", "A"); } @@ -169,13 +169,13 @@ await connection.Send( ""); await connection.ReceiveEnd( "HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 0", + $"Date: {server.Context.DateHeaderValue}", "", "HTTP/1.1 413 Payload Too Large", + "Content-Length: 0", "Connection: close", $"Date: {server.Context.DateHeaderValue}", - "Content-Length: 0", "", ""); } @@ -214,8 +214,8 @@ await connection.Send( payload); await connection.Receive( "HTTP/1.1 500 Internal Server Error", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 0", + $"Date: {server.Context.DateHeaderValue}", "", ""); } @@ -295,9 +295,9 @@ await connection.Send( ""); await connection.ReceiveEnd( "HTTP/1.1 413 Payload Too Large", + "Content-Length: 0", "Connection: close", $"Date: {server.Context.DateHeaderValue}", - "Content-Length: 0", "", ""); } @@ -346,9 +346,9 @@ await connection.Send( chunkedPayload); await connection.ReceiveEnd( "HTTP/1.1 413 Payload Too Large", + "Content-Length: 0", "Connection: close", $"Date: {server.Context.DateHeaderValue}", - "Content-Length: 0", "", ""); } @@ -392,8 +392,8 @@ await connection.Send( chunkedPayload + trailingHeaders); await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 0", + $"Date: {server.Context.DateHeaderValue}", "", ""); } @@ -459,13 +459,13 @@ await connection.Send( chunkedPayload); await connection.ReceiveEnd( "HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 0", + $"Date: {server.Context.DateHeaderValue}", "", "HTTP/1.1 413 Payload Too Large", + "Content-Length: 0", "Connection: close", $"Date: {server.Context.DateHeaderValue}", - "Content-Length: 0", "", ""); } @@ -506,9 +506,9 @@ await connection.Send( "1\r\n"); await connection.ReceiveEnd( "HTTP/1.1 413 Payload Too Large", + "Content-Length: 0", "Connection: close", $"Date: {server.Context.DateHeaderValue}", - "Content-Length: 0", "", ""); } diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/MaxRequestLineSizeTests.cs b/src/Servers/Kestrel/test/InMemory.FunctionalTests/MaxRequestLineSizeTests.cs index 70c83b3e8327..ae5c1b65da47 100644 --- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/MaxRequestLineSizeTests.cs +++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/MaxRequestLineSizeTests.cs @@ -61,9 +61,9 @@ public async Task ServerRejectsRequestLineExceedingLimit(string requestLine) await connection.SendAll(requestLine); await connection.ReceiveEnd( "HTTP/1.1 414 URI Too Long", + "Content-Length: 0", "Connection: close", $"Date: {server.Context.DateHeaderValue}", - "Content-Length: 0", "", ""); } diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/RequestBodyTimeoutTests.cs b/src/Servers/Kestrel/test/InMemory.FunctionalTests/RequestBodyTimeoutTests.cs index cde0e630d803..97f80c2090ab 100644 --- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/RequestBodyTimeoutTests.cs +++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/RequestBodyTimeoutTests.cs @@ -81,9 +81,9 @@ await connection.Receive( "HTTP/1.1 408 Request Timeout", ""); await connection.ReceiveEnd( + "Content-Length: 0", "Connection: close", $"Date: {serviceContext.DateHeaderValue}", - "Content-Length: 0", "", ""); } @@ -127,8 +127,8 @@ await connection.Send( // Disconnects after response completes due to the timeout await connection.ReceiveEnd( "HTTP/1.1 200 OK", - $"Date: {serviceContext.DateHeaderValue}", "Content-Length: 0", + $"Date: {serviceContext.DateHeaderValue}", "", ""); } @@ -200,8 +200,8 @@ await connection.Receive( "HTTP/1.1 200 OK", ""); await connection.ReceiveEnd( - $"Date: {serviceContext.DateHeaderValue}", "Content-Length: 12", + $"Date: {serviceContext.DateHeaderValue}", "", "hello, world"); } diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/RequestHeaderLimitsTests.cs b/src/Servers/Kestrel/test/InMemory.FunctionalTests/RequestHeaderLimitsTests.cs index c177d235c67f..85cbf98f02e7 100644 --- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/RequestHeaderLimitsTests.cs +++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/RequestHeaderLimitsTests.cs @@ -91,9 +91,9 @@ public async Task ServerRejectsRequestWithHeaderTotalSizeOverLimit(int headerCou await connection.SendAll($"GET / HTTP/1.1\r\n{headers}\r\n"); await connection.ReceiveEnd( "HTTP/1.1 431 Request Header Fields Too Large", + "Content-Length: 0", "Connection: close", $"Date: {server.Context.DateHeaderValue}", - "Content-Length: 0", "", ""); } @@ -115,9 +115,9 @@ public async Task ServerRejectsRequestWithHeaderCountOverLimit(int headerCount, await connection.SendAll($"GET / HTTP/1.1\r\n{headers}\r\n"); await connection.ReceiveEnd( "HTTP/1.1 431 Request Header Fields Too Large", + "Content-Length: 0", "Connection: close", $"Date: {server.Context.DateHeaderValue}", - "Content-Length: 0", "", ""); } diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/RequestHeadersTimeoutTests.cs b/src/Servers/Kestrel/test/InMemory.FunctionalTests/RequestHeadersTimeoutTests.cs index ca34052301ca..44c600273cfc 100644 --- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/RequestHeadersTimeoutTests.cs +++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/RequestHeadersTimeoutTests.cs @@ -164,9 +164,9 @@ private async Task ReceiveTimeoutResponse(InMemoryConnection connection, TestSer { await connection.Receive( "HTTP/1.1 408 Request Timeout", + "Content-Length: 0", "Connection: close", $"Date: {testContext.DateHeaderValue}", - "Content-Length: 0", "", ""); } diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/RequestTargetProcessingTests.cs b/src/Servers/Kestrel/test/InMemory.FunctionalTests/RequestTargetProcessingTests.cs index 693565b30083..f877faa26628 100644 --- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/RequestTargetProcessingTests.cs +++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/RequestTargetProcessingTests.cs @@ -36,8 +36,8 @@ await connection.Send( ""); await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {testContext.DateHeaderValue}", "Content-Length: 11", + $"Date: {testContext.DateHeaderValue}", "", "Hello World"); } @@ -81,8 +81,8 @@ await connection.Send( ""); await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {testContext.DateHeaderValue}", "Content-Length: 11", + $"Date: {testContext.DateHeaderValue}", "", "Hello World"); } @@ -121,8 +121,8 @@ await connection.Send( ""); await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {testContext.DateHeaderValue}", "Content-Length: 11", + $"Date: {testContext.DateHeaderValue}", "", "Hello World"); } diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/RequestTests.cs b/src/Servers/Kestrel/test/InMemory.FunctionalTests/RequestTests.cs index 431327f0caac..cb7a21fe86d9 100644 --- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/RequestTests.cs +++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/RequestTests.cs @@ -139,8 +139,8 @@ await connection.Send( cts.Cancel(); await connection.Receive($"HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 14", + $"Date: {server.Context.DateHeaderValue}", "", "Read cancelled"); } @@ -271,12 +271,12 @@ await connection.Send( ""); await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {testContext.DateHeaderValue}", "Content-Length: 0", + $"Date: {testContext.DateHeaderValue}", "", "HTTP/1.1 200 OK", - $"Date: {testContext.DateHeaderValue}", "Content-Length: 0", + $"Date: {testContext.DateHeaderValue}", "", ""); } @@ -522,8 +522,8 @@ await connection.Send( await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {testContext.DateHeaderValue}", "Content-Length: 1", + $"Date: {testContext.DateHeaderValue}", "", "0"); @@ -535,8 +535,8 @@ await connection.Send( await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {testContext.DateHeaderValue}", "Content-Length: 1", + $"Date: {testContext.DateHeaderValue}", "", "0"); } @@ -588,8 +588,8 @@ public async Task TraceIdentifierIsUnique() await connection.SendEmptyGet(); await connection.Receive($"HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", $"Content-Length: {identifierLength}", + $"Date: {server.Context.DateHeaderValue}", "", ""); @@ -633,13 +633,13 @@ await connection.Send( "Goodbye"); await connection.ReceiveEnd( "HTTP/1.1 200 OK", - $"Date: {testContext.DateHeaderValue}", "Content-Length: 0", + $"Date: {testContext.DateHeaderValue}", "", "HTTP/1.1 200 OK", + "Content-Length: 7", "Connection: close", $"Date: {testContext.DateHeaderValue}", - "Content-Length: 7", "", "Goodbye"); } @@ -661,9 +661,9 @@ await connection.Send( ""); await connection.ReceiveEnd( "HTTP/1.1 200 OK", + "Content-Length: 0", "Connection: close", $"Date: {testContext.DateHeaderValue}", - "Content-Length: 0", "", ""); } @@ -704,15 +704,15 @@ await connection.Send( "Goodbye"); await connection.Receive( "HTTP/1.1 200 OK", + "Content-Length: 0", "Connection: keep-alive", $"Date: {testContext.DateHeaderValue}", - "Content-Length: 0", "\r\n"); await connection.ReceiveEnd( "HTTP/1.1 200 OK", + "Content-Length: 7", "Connection: close", $"Date: {testContext.DateHeaderValue}", - "Content-Length: 7", "", "Goodbye"); } @@ -736,9 +736,9 @@ await connection.Send( await connection.Receive( "HTTP/1.1 200 OK", + "Content-Length: 0", "Connection: keep-alive", $"Date: {testContext.DateHeaderValue}", - "Content-Length: 0", "\r\n"); await connection.Send( @@ -776,9 +776,9 @@ await connection.Send( await connection.Receive( "HTTP/1.1 200 OK", + "Content-Length: 11", "Connection: keep-alive", $"Date: {testContext.DateHeaderValue}", - "Content-Length: 11", "", "Hello World"); @@ -791,9 +791,9 @@ await connection.Send( await connection.Receive( "HTTP/1.1 200 OK", + "Content-Length: 11", "Connection: keep-alive", $"Date: {testContext.DateHeaderValue}", - "Content-Length: 11", "", "Hello Again"); @@ -805,9 +805,9 @@ await connection.Send( await connection.ReceiveEnd( "HTTP/1.1 200 OK", + "Content-Length: 7", "Connection: close", $"Date: {testContext.DateHeaderValue}", - "Content-Length: 7", "", "Goodbye"); } @@ -837,9 +837,9 @@ await connection.Receive( await connection.Send("Hello World"); await connection.ReceiveEnd( "HTTP/1.1 200 OK", + "Content-Length: 11", "Connection: close", $"Date: {testContext.DateHeaderValue}", - "Content-Length: 11", "", "Hello World"); } @@ -873,9 +873,9 @@ await connection.Receive( await connection.Send("Hello World"); await connection.ReceiveEnd( "HTTP/1.1 200 OK", + "Content-Length: 11", "Connection: close", $"Date: {testContext.DateHeaderValue}", - "Content-Length: 11", "", "Hello World"); } @@ -903,9 +903,9 @@ await connection.Send( ""); await connection.ReceiveEnd( "HTTP/1.1 200 OK", + "Content-Length: 0", "Connection: close", $"Date: {testContext.DateHeaderValue}", - "Content-Length: 0", "", ""); } @@ -919,9 +919,9 @@ await connection.Send( ""); await connection.ReceiveEnd( "HTTP/1.1 200 OK", + "Content-Length: 0", "Connection: close", $"Date: {testContext.DateHeaderValue}", - "Content-Length: 0", "", ""); } @@ -950,9 +950,9 @@ await connection.Send( ""); await connection.ReceiveEnd( "HTTP/1.1 200 OK", + "Content-Length: 0", "Connection: close", $"Date: {testContext.DateHeaderValue}", - "Content-Length: 0", "", ""); } @@ -966,9 +966,9 @@ await connection.Send( ""); await connection.ReceiveEnd( "HTTP/1.1 200 OK", + "Content-Length: 0", "Connection: close", $"Date: {testContext.DateHeaderValue}", - "Content-Length: 0", "", ""); } @@ -998,9 +998,9 @@ await connection.SendAll( "hello"); await connection.ReceiveEnd( "HTTP/1.1 200 OK", + "Content-Length: 0", "Connection: close", $"Date: {testContext.DateHeaderValue}", - "Content-Length: 0", "", ""); } @@ -1033,9 +1033,9 @@ await connection.SendAll( "hello"); await connection.ReceiveEnd( "HTTP/1.1 200 OK", + "Content-Length: 0", "Connection: close", $"Date: {testContext.DateHeaderValue}", - "Content-Length: 0", "", ""); } @@ -1072,9 +1072,9 @@ await connection.SendAll( "hello"); await connection.ReceiveEnd( "HTTP/1.1 200 OK", + "Content-Length: 0", "Connection: close", $"Date: {testContext.DateHeaderValue}", - "Content-Length: 0", "", ""); } @@ -1146,9 +1146,9 @@ await connection.Send( "y"); await connection.ReceiveEnd( "HTTP/1.1 200 OK", + "Content-Length: 0", "Connection: close", $"Date: {testContext.DateHeaderValue}", - "Content-Length: 0", "", ""); } @@ -1180,9 +1180,9 @@ await connection.SendAll( await connection.ReceiveEnd( "HTTP/1.1 200 OK", + "Content-Length: 0", "Connection: close", $"Date: {testContext.DateHeaderValue}", - "Content-Length: 0", "", ""); } @@ -1259,12 +1259,12 @@ await connection.Send( ""); await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {testContext.DateHeaderValue}", "Content-Length: 0", + $"Date: {testContext.DateHeaderValue}", "", "HTTP/1.1 200 OK", - $"Date: {testContext.DateHeaderValue}", "Content-Length: 0", + $"Date: {testContext.DateHeaderValue}", "", ""); } @@ -1355,16 +1355,16 @@ public async Task HeadersAndStreamsAreReusedAcrossRequests() var response = string.Join("\r\n", new string[] { "HTTP/1.1 200 OK", - $"Date: {testContext.DateHeaderValue}", "Content-Length: 0", + $"Date: {testContext.DateHeaderValue}", ""}); var lastResponse = string.Join("\r\n", new string[] { "HTTP/1.1 200 OK", + "Content-Length: 7", "Connection: close", $"Date: {testContext.DateHeaderValue}", - "Content-Length: 7", "", "Goodbye" }); @@ -1419,8 +1419,8 @@ await connection.Send( await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 0", + $"Date: {server.Context.DateHeaderValue}", "", ""); @@ -1435,8 +1435,8 @@ await connection.Send( await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 0", + $"Date: {server.Context.DateHeaderValue}", "", ""); } @@ -1467,8 +1467,8 @@ await connection.Send( await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 0", + $"Date: {server.Context.DateHeaderValue}", "", ""); @@ -1483,8 +1483,8 @@ await connection.Send( await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 0", + $"Date: {server.Context.DateHeaderValue}", "", ""); } @@ -1508,9 +1508,9 @@ await connection.SendAll( await connection.ReceiveEnd( "HTTP/1.1 200 OK", + "Content-Length: 0", "Connection: close", $"Date: {server.Context.DateHeaderValue}", - "Content-Length: 0", "", ""); } @@ -1652,8 +1652,8 @@ await connection.Send( "Hello"); await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 6", + $"Date: {server.Context.DateHeaderValue}", "", "Hello1"); } @@ -1695,8 +1695,8 @@ await connection.Send( "Hello"); await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 5", + $"Date: {server.Context.DateHeaderValue}", "", "Hello"); } @@ -1739,8 +1739,8 @@ await connection.Send( "Hello"); await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 0", + $"Date: {server.Context.DateHeaderValue}", "", ""); } @@ -1781,8 +1781,8 @@ await connection.Send( "Hello"); await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 0", + $"Date: {server.Context.DateHeaderValue}", "", ""); } @@ -1865,8 +1865,8 @@ await connection.Send( "ello"); await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {testContext.DateHeaderValue}", "Content-Length: 11", + $"Date: {testContext.DateHeaderValue}", "", "Hello World"); } @@ -1909,8 +1909,8 @@ await connection.Send( await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {testContext.DateHeaderValue}", "Content-Length: 11", + $"Date: {testContext.DateHeaderValue}", "", "Hello World"); } @@ -1948,8 +1948,8 @@ await connection.Send( await connection.Send("llo"); await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {testContext.DateHeaderValue}", "Content-Length: 0", + $"Date: {testContext.DateHeaderValue}", "", ""); } @@ -1992,8 +1992,8 @@ await connection.Send( await connection.Receive( "HTTP/1.1 500 Internal Server Error", - $"Date: {testContext.DateHeaderValue}", "Content-Length: 0", + $"Date: {testContext.DateHeaderValue}", "", ""); } @@ -2026,8 +2026,8 @@ await connection.Send( ""); await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {testContext.DateHeaderValue}", "Content-Length: 0", + $"Date: {testContext.DateHeaderValue}", "", ""); @@ -2044,8 +2044,8 @@ await connection.Send( ""); await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {testContext.DateHeaderValue}", "Content-Length: 0", + $"Date: {testContext.DateHeaderValue}", "", ""); @@ -2081,8 +2081,8 @@ await connection.Send( await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {testContext.DateHeaderValue}", "Content-Length: 0", + $"Date: {testContext.DateHeaderValue}", "", ""); } @@ -2109,9 +2109,9 @@ await connection.Send( await connection.ReceiveEnd( "HTTP/1.1 400 Bad Request", + "Content-Length: 0", "Connection: close", $"Date: {testContext.DateHeaderValue}", - "Content-Length: 0", "", ""); } @@ -2146,8 +2146,8 @@ await connection.Send("", await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {testContext.DateHeaderValue}", "Content-Length: 0", + $"Date: {testContext.DateHeaderValue}", "", ""); } diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/ResponseTests.cs b/src/Servers/Kestrel/test/InMemory.FunctionalTests/ResponseTests.cs index 1ac072438769..330b443cc723 100644 --- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/ResponseTests.cs +++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/ResponseTests.cs @@ -59,8 +59,8 @@ await connection.Send( await connection.Receive( $"HTTP/1.1 500 Internal Server Error", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 0", + $"Date: {server.Context.DateHeaderValue}", "", ""); @@ -391,8 +391,8 @@ await connection.Send( await connection.ReceiveEnd( "HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 0", + $"Date: {server.Context.DateHeaderValue}", "", ""); } @@ -427,8 +427,8 @@ await connection.Send( "gg"); await connection.ReceiveEnd( "HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 0", + $"Date: {server.Context.DateHeaderValue}", "", ""); } @@ -519,8 +519,8 @@ await connection.Send( ""); await connection.Receive( $"HTTP/1.1 205 Reset Content", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 0", + $"Date: {server.Context.DateHeaderValue}", "", ""); } @@ -608,8 +608,8 @@ await connection.Send( await connection.Receive( $"HTTP/1.1 205 Reset Content", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 0", + $"Date: {server.Context.DateHeaderValue}", "", ""); } @@ -705,8 +705,8 @@ await connection.Send( ""); await connection.Receive( $"HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 11", + $"Date: {server.Context.DateHeaderValue}", "", "hello,"); @@ -743,8 +743,8 @@ await connection.Send( ""); await connection.ReceiveEnd( $"HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 11", + $"Date: {server.Context.DateHeaderValue}", "", "hello,"); } @@ -780,9 +780,9 @@ await connection.Send( ""); await connection.ReceiveEnd( $"HTTP/1.1 500 Internal Server Error", + "Content-Length: 0", "Connection: close", $"Date: {server.Context.DateHeaderValue}", - "Content-Length: 0", "", ""); } @@ -815,9 +815,9 @@ await connection.Send( ""); await connection.ReceiveEnd( $"HTTP/1.1 500 Internal Server Error", + "Content-Length: 0", "Connection: close", $"Date: {server.Context.DateHeaderValue}", - "Content-Length: 0", "", ""); } @@ -861,8 +861,8 @@ await connection.Send( // will be skipped. await connection.Receive( $"HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 13", + $"Date: {server.Context.DateHeaderValue}", "", "hello, world"); @@ -919,8 +919,8 @@ await connection.Send( // will be skipped. await connection.Receive( $"HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 13", + $"Date: {server.Context.DateHeaderValue}", "", "hello, world"); @@ -971,8 +971,8 @@ await connection.Send( ""); await connection.Receive( $"HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 12", + $"Date: {server.Context.DateHeaderValue}", "", "hello,"); } @@ -1013,12 +1013,12 @@ await connection.Send( ""); await connection.Receive( "HTTP/1.1 500 Internal Server Error", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 0", + $"Date: {server.Context.DateHeaderValue}", "", "HTTP/1.1 500 Internal Server Error", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 0", + $"Date: {server.Context.DateHeaderValue}", "", ""); } @@ -1055,8 +1055,8 @@ await connection.Send( ""); await connection.Receive( $"HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 0", + $"Date: {server.Context.DateHeaderValue}", "", ""); } @@ -1090,8 +1090,8 @@ await connection.Send( ""); await connection.Receive( $"HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 13", + $"Date: {server.Context.DateHeaderValue}", "Transfer-Encoding: chunked", "", "hello, world"); @@ -1126,8 +1126,8 @@ await connection.Send( ""); await connection.Receive( $"HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 11", + $"Date: {server.Context.DateHeaderValue}", "Transfer-Encoding: chunked", "", "hello, world"); @@ -1155,8 +1155,8 @@ await connection.Send( ""); await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 42", + $"Date: {server.Context.DateHeaderValue}", "", ""); } @@ -1184,8 +1184,8 @@ await connection.Send( ""); await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 12", + $"Date: {server.Context.DateHeaderValue}", "", ""); @@ -1217,8 +1217,8 @@ await connection.Send( ""); await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 12", + $"Date: {server.Context.DateHeaderValue}", "", ""); @@ -1249,8 +1249,8 @@ await connection.Send( ""); await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 12", + $"Date: {server.Context.DateHeaderValue}", "", ""); @@ -1294,8 +1294,8 @@ await connection.Send( await responseWritten.Task.DefaultTimeout(); await connection.ReceiveEnd( "HTTP/1.1 400 Bad Request", - $"Date: {server.Context.DateHeaderValue}", $"Content-Length: {expectedResponse.Length}", + $"Date: {server.Context.DateHeaderValue}", "", expectedResponse); } @@ -1750,8 +1750,8 @@ await connection.Send( // the connection. await connection.ReceiveEnd( "HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 0", + $"Date: {server.Context.DateHeaderValue}", "", ""); } @@ -1795,8 +1795,8 @@ await connection.Send( await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 0", + $"Date: {server.Context.DateHeaderValue}", "", ""); @@ -1866,9 +1866,9 @@ await connection.Send( // bad chunk header above, making this test fail. await connection.ReceiveEnd( "HTTP/1.1 400 Bad Request", + "Content-Length: 0", "Connection: close", $"Date: {server.Context.DateHeaderValue}", - "Content-Length: 0", "", ""); } @@ -1970,13 +1970,13 @@ await connection.Send( ""); await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {testContext.DateHeaderValue}", "Content-Length: 0", + $"Date: {testContext.DateHeaderValue}", "", "HTTP/1.1 200 OK", + "Content-Length: 0", "Connection: keep-alive", $"Date: {testContext.DateHeaderValue}", - "Content-Length: 0", "", ""); } @@ -2003,9 +2003,9 @@ await connection.Send( ""); await connection.ReceiveEnd( "HTTP/1.1 200 OK", + "Content-Length: 0", "Connection: close", $"Date: {testContext.DateHeaderValue}", - "Content-Length: 0", "", ""); } @@ -2018,9 +2018,9 @@ await connection.Send( ""); await connection.ReceiveEnd( "HTTP/1.1 200 OK", + "Content-Length: 0", "Connection: close", $"Date: {testContext.DateHeaderValue}", - "Content-Length: 0", "", ""); } @@ -2091,8 +2091,8 @@ await connection.Receive( $"Date: {testContext.DateHeaderValue}", "", "HTTP/1.1 200 OK", - $"Date: {testContext.DateHeaderValue}", "Content-Length: 0", + $"Date: {testContext.DateHeaderValue}", "", ""); } @@ -2179,13 +2179,13 @@ await connection.Send( ""); await connection.ReceiveEnd( "HTTP/1.1 500 Internal Server Error", - $"Date: {testContext.DateHeaderValue}", "Content-Length: 0", + $"Date: {testContext.DateHeaderValue}", "", "HTTP/1.1 500 Internal Server Error", + "Content-Length: 0", "Connection: close", $"Date: {testContext.DateHeaderValue}", - "Content-Length: 0", "", ""); } @@ -2236,12 +2236,12 @@ await connection.Send( ""); await connection.Receive( "HTTP/1.1 500 Internal Server Error", - $"Date: {testContext.DateHeaderValue}", "Content-Length: 0", + $"Date: {testContext.DateHeaderValue}", "", "HTTP/1.1 500 Internal Server Error", - $"Date: {testContext.DateHeaderValue}", "Content-Length: 0", + $"Date: {testContext.DateHeaderValue}", "", ""); } @@ -2290,6 +2290,7 @@ await connection.Send( ""); await connection.Receive( "HTTP/1.1 200 OK", + "Content-Length: 11", $"Date: {testContext.DateHeaderValue}", ""); @@ -2335,6 +2336,7 @@ await connection.Send( ""); await connection.Receive( "HTTP/1.1 200 OK", + "Content-Length: 11", $"Date: {testContext.DateHeaderValue}", ""); @@ -2379,8 +2381,8 @@ await connection.Send( ""); await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {testContext.DateHeaderValue}", "Content-Length: 11", + $"Date: {testContext.DateHeaderValue}", "", "Hello World"); } @@ -2422,8 +2424,8 @@ await connection.Send( ""); await connection.ReceiveEnd( "HTTP/1.1 200 OK", - $"Date: {testContext.DateHeaderValue}", "Content-Length: 11", + $"Date: {testContext.DateHeaderValue}", "", "Hello World"); } @@ -2463,8 +2465,8 @@ await connection.Send( ""); await connection.ReceiveEnd( "HTTP/1.1 200 OK", - $"Date: {testContext.DateHeaderValue}", "Content-Length: 11", + $"Date: {testContext.DateHeaderValue}", "", "Hello"); } @@ -2495,9 +2497,9 @@ await connection.Send( ""); await connection.ReceiveEnd( "HTTP/1.1 200 OK", + "Content-Length: 11", "Connection: close", $"Date: {testContext.DateHeaderValue}", - "Content-Length: 11", "", "Hello World"); } @@ -2625,12 +2627,12 @@ await connection.Send( ""); await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {testContext.DateHeaderValue}", "Content-Length: 0", + $"Date: {testContext.DateHeaderValue}", "", "HTTP/1.1 200 OK", - $"Date: {testContext.DateHeaderValue}", "Content-Length: 0", + $"Date: {testContext.DateHeaderValue}", "", ""); } @@ -2687,8 +2689,8 @@ await connection.Send( ""); await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {testContext.DateHeaderValue}", "Content-Length: 0", + $"Date: {testContext.DateHeaderValue}", ""); } } @@ -2835,8 +2837,8 @@ await connection.Send( ""); await connection.ReceiveEnd( "HTTP/1.1 200 OK", - $"Date: {testContext.DateHeaderValue}", "Content-Length: 11", + $"Date: {testContext.DateHeaderValue}", "", ""); } @@ -2903,8 +2905,8 @@ await connection.Send( ""); await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {testContext.DateHeaderValue}", "Content-Length: 11", + $"Date: {testContext.DateHeaderValue}", "", "Hello World"); } @@ -2933,8 +2935,8 @@ await connection.Send( ""); await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {testContext.DateHeaderValue}", $"Content-Length: {expectedLength}", + $"Date: {testContext.DateHeaderValue}", "", expectedString); } @@ -2982,8 +2984,8 @@ await connection.Send( ""); await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {testContext.DateHeaderValue}", $"Content-Length: {expectedLength}", + $"Date: {testContext.DateHeaderValue}", "", expectedString); } @@ -3058,8 +3060,8 @@ await connection.Send( ""); await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {testContext.DateHeaderValue}", $"Content-Length: {response.Length}", + $"Date: {testContext.DateHeaderValue}", "", "hello, world"); @@ -3109,8 +3111,8 @@ await connection.Send( ""); await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {testContext.DateHeaderValue}", $"Content-Length: {response.Length}", + $"Date: {testContext.DateHeaderValue}", "", "hello, world"); @@ -3145,8 +3147,8 @@ public async Task SynchronousWritesDisallowedByDefault() await connection.SendEmptyGet(); await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 6", + $"Date: {server.Context.DateHeaderValue}", "", "Hello1"); } @@ -3171,8 +3173,8 @@ public async Task SynchronousWritesAllowedByOptIn() await connection.SendEmptyGet(); await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 6", + $"Date: {server.Context.DateHeaderValue}", "", "Hello1"); } @@ -3206,8 +3208,8 @@ await connection.Send( ""); await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 6", + $"Date: {server.Context.DateHeaderValue}", "", "Hello!"); } @@ -3245,8 +3247,8 @@ await connection.Send( ""); await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 6", + $"Date: {server.Context.DateHeaderValue}", "", "Hello!"); } @@ -3274,8 +3276,8 @@ await connection.Send( ""); await connection.Receive( "HTTP/1.1 304 Not Modified", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 42", + $"Date: {server.Context.DateHeaderValue}", "", ""); } @@ -3337,8 +3339,8 @@ await connection.Send( ""); await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {testContext.DateHeaderValue}", "Content-Length: 0", + $"Date: {testContext.DateHeaderValue}", "", ""); } @@ -3407,8 +3409,8 @@ await connection.Send( ""); await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {testContext.DateHeaderValue}", "Content-Length: 12", + $"Date: {testContext.DateHeaderValue}", "", "Hello World!"); } @@ -3446,8 +3448,8 @@ await connection.Send( ""); await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {testContext.DateHeaderValue}", "Content-Length: 12", + $"Date: {testContext.DateHeaderValue}", "", "Hello World!"); } @@ -3472,8 +3474,8 @@ await connection.Send( ""); await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 12", + $"Date: {server.Context.DateHeaderValue}", "", "hello, world"); } @@ -3511,8 +3513,8 @@ await connection.Send( ""); await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 54", + $"Date: {server.Context.DateHeaderValue}", "", "hello, world", "hello, world", @@ -3540,8 +3542,8 @@ await connection.Send( ""); await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 0", + $"Date: {server.Context.DateHeaderValue}", "", ""); } @@ -3569,8 +3571,8 @@ await connection.Send( await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 0", + $"Date: {server.Context.DateHeaderValue}", "", ""); } @@ -3657,8 +3659,8 @@ await connection.Send( ""); await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 0", + $"Date: {server.Context.DateHeaderValue}", "", ""); } @@ -3766,8 +3768,8 @@ await connection.Send( ""); await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 1", + $"Date: {server.Context.DateHeaderValue}", "", "a"); } @@ -3800,8 +3802,8 @@ await connection.Send( ""); await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 0", + $"Date: {server.Context.DateHeaderValue}", "", ""); @@ -3812,8 +3814,8 @@ await connection.Send( ""); await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 0", + $"Date: {server.Context.DateHeaderValue}", "", ""); } @@ -3839,8 +3841,8 @@ await connection.Send( ""); await connection.Receive( $"HTTP/1.1 500 Internal Server Error", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 0", + $"Date: {server.Context.DateHeaderValue}", "", ""); Assert.Contains(TestSink.Writes, w => w.EventId.Id == 13 && w.LogLevel == LogLevel.Error @@ -3902,8 +3904,8 @@ await connection.Send( ""); await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 0", + $"Date: {server.Context.DateHeaderValue}", "", ""); } @@ -4000,8 +4002,8 @@ await connection.Send( ""); await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 0", + $"Date: {server.Context.DateHeaderValue}", "", ""); } @@ -4034,8 +4036,8 @@ await connection.Send( ""); await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 0", + $"Date: {server.Context.DateHeaderValue}", "", ""); } @@ -4068,8 +4070,8 @@ await connection.Send( ""); await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 0", + $"Date: {server.Context.DateHeaderValue}", "", ""); } @@ -4102,8 +4104,8 @@ await connection.Send( await connection.Receive( $"HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 0", + $"Date: {server.Context.DateHeaderValue}", @"Alt-Svc: h3-29="":1""; ma=84600", "", ""); @@ -4174,8 +4176,8 @@ await connection.Send( { await connection.ReceiveEnd( "HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 0", + $"Date: {server.Context.DateHeaderValue}", "", ""); } @@ -4183,9 +4185,9 @@ await connection.ReceiveEnd( { await connection.ReceiveEnd( "HTTP/1.1 400 Bad Request", + "Content-Length: 0", "Connection: close", $"Date: {server.Context.DateHeaderValue}", - "Content-Length: 0", "", ""); } diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/UpgradeTests.cs b/src/Servers/Kestrel/test/InMemory.FunctionalTests/UpgradeTests.cs index 254cf0c04735..070dd47a49ff 100644 --- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/UpgradeTests.cs +++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/UpgradeTests.cs @@ -443,8 +443,8 @@ public async Task DoesNotCloseConnectionWithout101Response() await connection.SendEmptyGetWithUpgrade(); await connection.Receive( "HTTP/1.1 200 OK", - $"Date: {server.Context.DateHeaderValue}", "Content-Length: 0", + $"Date: {server.Context.DateHeaderValue}", "", "");