From c2a38e8ce9268be9febbb4b0b9f3837a8c89fd8b Mon Sep 17 00:00:00 2001 From: Kahbazi Date: Thu, 8 Oct 2020 13:51:23 +0330 Subject: [PATCH 1/7] Remove connection-specific headeres for HTTP/2 and HTTP/3 --- src/Http/Headers/src/HeaderNames.cs | 1 + .../Internal/Http/HttpHeaders.Generated.cs | 1314 +++++++++++++---- .../Core/src/Internal/Http/HttpProtocol.cs | 15 + src/Servers/Kestrel/shared/KnownHeaders.cs | 8 + .../Http2/Http2StreamTests.cs | 41 + .../Http3/Http3StreamTests.cs | 34 + 6 files changed, 1113 insertions(+), 300 deletions(-) diff --git a/src/Http/Headers/src/HeaderNames.cs b/src/Http/Headers/src/HeaderNames.cs index 5b375d2390de..41fb2ebd1581 100644 --- a/src/Http/Headers/src/HeaderNames.cs +++ b/src/Http/Headers/src/HeaderNames.cs @@ -65,6 +65,7 @@ public static class HeaderNames public static readonly string Pragma = "Pragma"; public static readonly string ProxyAuthenticate = "Proxy-Authenticate"; public static readonly string ProxyAuthorization = "Proxy-Authorization"; + public static readonly string ProxyConnection = "Proxy-Connection"; public static readonly string Range = "Range"; public static readonly string Referer = "Referer"; public static readonly string RetryAfter = "Retry-After"; 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 8e2065897209..34d42dbf144c 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/HttpHeaders.Generated.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/HttpHeaders.Generated.cs @@ -73,6 +73,7 @@ internal enum KnownHeaderType Pragma, ProxyAuthenticate, ProxyAuthorization, + ProxyConnection, Range, Referer, RequestId, @@ -1073,6 +1074,343 @@ public StringValues HeaderContentLength } } + + public void ClearCacheControl() + { + _bits &= ~0x1L; + _headers._CacheControl = default; + + } + public void ClearConnection() + { + _bits &= ~0x2L; + _headers._Connection = default; + + } + public void ClearDate() + { + _bits &= ~0x4L; + _headers._Date = default; + + } + public void ClearGrpcEncoding() + { + _bits &= ~0x8L; + _headers._GrpcEncoding = default; + + } + public void ClearKeepAlive() + { + _bits &= ~0x10L; + _headers._KeepAlive = default; + + } + public void ClearPragma() + { + _bits &= ~0x20L; + _headers._Pragma = default; + + } + public void ClearTrailer() + { + _bits &= ~0x40L; + _headers._Trailer = default; + + } + public void ClearTransferEncoding() + { + _bits &= ~0x80L; + _headers._TransferEncoding = default; + + } + public void ClearUpgrade() + { + _bits &= ~0x100L; + _headers._Upgrade = default; + + } + public void ClearVia() + { + _bits &= ~0x200L; + _headers._Via = default; + + } + public void ClearWarning() + { + _bits &= ~0x400L; + _headers._Warning = default; + + } + public void ClearAllow() + { + _bits &= ~0x800L; + _headers._Allow = default; + + } + public void ClearContentType() + { + _bits &= ~0x1000L; + _headers._ContentType = default; + + } + public void ClearContentEncoding() + { + _bits &= ~0x2000L; + _headers._ContentEncoding = default; + + } + public void ClearContentLanguage() + { + _bits &= ~0x4000L; + _headers._ContentLanguage = default; + + } + public void ClearContentLocation() + { + _bits &= ~0x8000L; + _headers._ContentLocation = default; + + } + public void ClearContentMD5() + { + _bits &= ~0x10000L; + _headers._ContentMD5 = default; + + } + public void ClearContentRange() + { + _bits &= ~0x20000L; + _headers._ContentRange = default; + + } + public void ClearExpires() + { + _bits &= ~0x40000L; + _headers._Expires = default; + + } + public void ClearLastModified() + { + _bits &= ~0x80000L; + _headers._LastModified = default; + + } + public void ClearAuthority() + { + _bits &= ~0x100000L; + _headers._Authority = default; + + } + public void ClearMethod() + { + _bits &= ~0x200000L; + _headers._Method = default; + + } + public void ClearPath() + { + _bits &= ~0x400000L; + _headers._Path = default; + + } + public void ClearScheme() + { + _bits &= ~0x800000L; + _headers._Scheme = default; + + } + public void ClearAccept() + { + _bits &= ~0x1000000L; + _headers._Accept = default; + + } + public void ClearAcceptCharset() + { + _bits &= ~0x2000000L; + _headers._AcceptCharset = default; + + } + public void ClearAcceptEncoding() + { + _bits &= ~0x4000000L; + _headers._AcceptEncoding = default; + + } + public void ClearAcceptLanguage() + { + _bits &= ~0x8000000L; + _headers._AcceptLanguage = default; + + } + public void ClearAuthorization() + { + _bits &= ~0x10000000L; + _headers._Authorization = default; + + } + public void ClearCookie() + { + _bits &= ~0x20000000L; + _headers._Cookie = default; + + } + public void ClearExpect() + { + _bits &= ~0x40000000L; + _headers._Expect = default; + + } + public void ClearFrom() + { + _bits &= ~0x80000000L; + _headers._From = default; + + } + public void ClearGrpcAcceptEncoding() + { + _bits &= ~0x100000000L; + _headers._GrpcAcceptEncoding = default; + + } + public void ClearGrpcTimeout() + { + _bits &= ~0x200000000L; + _headers._GrpcTimeout = default; + + } + public void ClearHost() + { + _bits &= ~0x400000000L; + _headers._Host = default; + + } + public void ClearIfMatch() + { + _bits &= ~0x800000000L; + _headers._IfMatch = default; + + } + public void ClearIfModifiedSince() + { + _bits &= ~0x1000000000L; + _headers._IfModifiedSince = default; + + } + public void ClearIfNoneMatch() + { + _bits &= ~0x2000000000L; + _headers._IfNoneMatch = default; + + } + public void ClearIfRange() + { + _bits &= ~0x4000000000L; + _headers._IfRange = default; + + } + public void ClearIfUnmodifiedSince() + { + _bits &= ~0x8000000000L; + _headers._IfUnmodifiedSince = default; + + } + public void ClearMaxForwards() + { + _bits &= ~0x10000000000L; + _headers._MaxForwards = default; + + } + public void ClearProxyAuthorization() + { + _bits &= ~0x20000000000L; + _headers._ProxyAuthorization = default; + + } + public void ClearReferer() + { + _bits &= ~0x40000000000L; + _headers._Referer = default; + + } + public void ClearRange() + { + _bits &= ~0x80000000000L; + _headers._Range = default; + + } + public void ClearTE() + { + _bits &= ~0x100000000000L; + _headers._TE = default; + + } + public void ClearTranslate() + { + _bits &= ~0x200000000000L; + _headers._Translate = default; + + } + public void ClearUserAgent() + { + _bits &= ~0x400000000000L; + _headers._UserAgent = default; + + } + public void ClearDNT() + { + _bits &= ~0x800000000000L; + _headers._DNT = default; + + } + public void ClearUpgradeInsecureRequests() + { + _bits &= ~0x1000000000000L; + _headers._UpgradeInsecureRequests = default; + + } + public void ClearRequestId() + { + _bits &= ~0x2000000000000L; + _headers._RequestId = default; + + } + public void ClearCorrelationContext() + { + _bits &= ~0x4000000000000L; + _headers._CorrelationContext = default; + + } + public void ClearTraceParent() + { + _bits &= ~0x8000000000000L; + _headers._TraceParent = default; + + } + public void ClearTraceState() + { + _bits &= ~0x10000000000000L; + _headers._TraceState = default; + + } + public void ClearOrigin() + { + _bits &= ~0x20000000000000L; + _headers._Origin = default; + + } + public void ClearAccessControlRequestMethod() + { + _bits &= ~0x40000000000000L; + _headers._AccessControlRequestMethod = default; + + } + public void ClearAccessControlRequestHeaders() + { + _bits &= ~0x80000000000000L; + _headers._AccessControlRequestHeaders = default; + + } protected override int GetCountFast() { return (_contentLength.HasValue ? 1 : 0 ) + BitOperations.PopCount((ulong)_bits) + (MaybeUnknown?.Count ?? 0); @@ -7975,14 +8313,14 @@ internal partial class HttpResponseHeaders { private static ReadOnlySpan HeaderBytes => new byte[] { - 13,10,67,97,99,104,101,45,67,111,110,116,114,111,108,58,32,13,10,67,111,110,110,101,99,116,105,111,110,58,32,13,10,68,97,116,101,58,32,13,10,71,114,112,99,45,69,110,99,111,100,105,110,103,58,32,13,10,75,101,101,112,45,65,108,105,118,101,58,32,13,10,80,114,97,103,109,97,58,32,13,10,84,114,97,105,108,101,114,58,32,13,10,84,114,97,110,115,102,101,114,45,69,110,99,111,100,105,110,103,58,32,13,10,85,112,103,114,97,100,101,58,32,13,10,86,105,97,58,32,13,10,87,97,114,110,105,110,103,58,32,13,10,65,108,108,111,119,58,32,13,10,67,111,110,116,101,110,116,45,84,121,112,101,58,32,13,10,67,111,110,116,101,110,116,45,69,110,99,111,100,105,110,103,58,32,13,10,67,111,110,116,101,110,116,45,76,97,110,103,117,97,103,101,58,32,13,10,67,111,110,116,101,110,116,45,76,111,99,97,116,105,111,110,58,32,13,10,67,111,110,116,101,110,116,45,77,68,53,58,32,13,10,67,111,110,116,101,110,116,45,82,97,110,103,101,58,32,13,10,69,120,112,105,114,101,115,58,32,13,10,76,97,115,116,45,77,111,100,105,102,105,101,100,58,32,13,10,65,99,99,101,112,116,45,82,97,110,103,101,115,58,32,13,10,65,103,101,58,32,13,10,65,108,116,45,83,118,99,58,32,13,10,69,84,97,103,58,32,13,10,76,111,99,97,116,105,111,110,58,32,13,10,80,114,111,120,121,45,65,117,116,104,101,110,116,105,99,97,116,101,58,32,13,10,82,101,116,114,121,45,65,102,116,101,114,58,32,13,10,83,101,114,118,101,114,58,32,13,10,83,101,116,45,67,111,111,107,105,101,58,32,13,10,86,97,114,121,58,32,13,10,87,87,87,45,65,117,116,104,101,110,116,105,99,97,116,101,58,32,13,10,65,99,99,101,115,115,45,67,111,110,116,114,111,108,45,65,108,108,111,119,45,67,114,101,100,101,110,116,105,97,108,115,58,32,13,10,65,99,99,101,115,115,45,67,111,110,116,114,111,108,45,65,108,108,111,119,45,72,101,97,100,101,114,115,58,32,13,10,65,99,99,101,115,115,45,67,111,110,116,114,111,108,45,65,108,108,111,119,45,77,101,116,104,111,100,115,58,32,13,10,65,99,99,101,115,115,45,67,111,110,116,114,111,108,45,65,108,108,111,119,45,79,114,105,103,105,110,58,32,13,10,65,99,99,101,115,115,45,67,111,110,116,114,111,108,45,69,120,112,111,115,101,45,72,101,97,100,101,114,115,58,32,13,10,65,99,99,101,115,115,45,67,111,110,116,114,111,108,45,77,97,120,45,65,103,101,58,32,13,10,67,111,110,116,101,110,116,45,76,101,110,103,116,104,58,32, + 13,10,67,97,99,104,101,45,67,111,110,116,114,111,108,58,32,13,10,67,111,110,110,101,99,116,105,111,110,58,32,13,10,68,97,116,101,58,32,13,10,71,114,112,99,45,69,110,99,111,100,105,110,103,58,32,13,10,75,101,101,112,45,65,108,105,118,101,58,32,13,10,80,114,97,103,109,97,58,32,13,10,84,114,97,105,108,101,114,58,32,13,10,84,114,97,110,115,102,101,114,45,69,110,99,111,100,105,110,103,58,32,13,10,85,112,103,114,97,100,101,58,32,13,10,86,105,97,58,32,13,10,87,97,114,110,105,110,103,58,32,13,10,65,108,108,111,119,58,32,13,10,67,111,110,116,101,110,116,45,84,121,112,101,58,32,13,10,67,111,110,116,101,110,116,45,69,110,99,111,100,105,110,103,58,32,13,10,67,111,110,116,101,110,116,45,76,97,110,103,117,97,103,101,58,32,13,10,67,111,110,116,101,110,116,45,76,111,99,97,116,105,111,110,58,32,13,10,67,111,110,116,101,110,116,45,77,68,53,58,32,13,10,67,111,110,116,101,110,116,45,82,97,110,103,101,58,32,13,10,69,120,112,105,114,101,115,58,32,13,10,76,97,115,116,45,77,111,100,105,102,105,101,100,58,32,13,10,65,99,99,101,112,116,45,82,97,110,103,101,115,58,32,13,10,65,103,101,58,32,13,10,65,108,116,45,83,118,99,58,32,13,10,69,84,97,103,58,32,13,10,76,111,99,97,116,105,111,110,58,32,13,10,80,114,111,120,121,45,65,117,116,104,101,110,116,105,99,97,116,101,58,32,13,10,80,114,111,120,121,45,67,111,110,110,101,99,116,105,111,110,58,32,13,10,82,101,116,114,121,45,65,102,116,101,114,58,32,13,10,83,101,114,118,101,114,58,32,13,10,83,101,116,45,67,111,111,107,105,101,58,32,13,10,86,97,114,121,58,32,13,10,87,87,87,45,65,117,116,104,101,110,116,105,99,97,116,101,58,32,13,10,65,99,99,101,115,115,45,67,111,110,116,114,111,108,45,65,108,108,111,119,45,67,114,101,100,101,110,116,105,97,108,115,58,32,13,10,65,99,99,101,115,115,45,67,111,110,116,114,111,108,45,65,108,108,111,119,45,72,101,97,100,101,114,115,58,32,13,10,65,99,99,101,115,115,45,67,111,110,116,114,111,108,45,65,108,108,111,119,45,77,101,116,104,111,100,115,58,32,13,10,65,99,99,101,115,115,45,67,111,110,116,114,111,108,45,65,108,108,111,119,45,79,114,105,103,105,110,58,32,13,10,65,99,99,101,115,115,45,67,111,110,116,114,111,108,45,69,120,112,111,115,101,45,72,101,97,100,101,114,115,58,32,13,10,65,99,99,101,115,115,45,67,111,110,116,114,111,108,45,77,97,120,45,65,103,101,58,32,13,10,67,111,110,116,101,110,116,45,76,101,110,103,116,104,58,32, }; private HeaderReferences _headers; public bool HasConnection => (_bits & 0x2L) != 0; public bool HasDate => (_bits & 0x4L) != 0; public bool HasTransferEncoding => (_bits & 0x80L) != 0; - public bool HasServer => (_bits & 0x8000000L) != 0; + public bool HasServer => (_bits & 0x10000000L) != 0; public StringValues HeaderCacheControl @@ -8430,20 +8768,37 @@ public StringValues HeaderProxyAuthenticate _headers._ProxyAuthenticate = value; } } - public StringValues HeaderRetryAfter + public StringValues HeaderProxyConnection { get { StringValues value = default; if ((_bits & 0x4000000L) != 0) { - value = _headers._RetryAfter; + value = _headers._ProxyConnection; } return value; } set { _bits |= 0x4000000L; + _headers._ProxyConnection = value; + } + } + public StringValues HeaderRetryAfter + { + get + { + StringValues value = default; + if ((_bits & 0x8000000L) != 0) + { + value = _headers._RetryAfter; + } + return value; + } + set + { + _bits |= 0x8000000L; _headers._RetryAfter = value; } } @@ -8452,7 +8807,7 @@ public StringValues HeaderServer get { StringValues value = default; - if ((_bits & 0x8000000L) != 0) + if ((_bits & 0x10000000L) != 0) { value = _headers._Server; } @@ -8460,7 +8815,7 @@ public StringValues HeaderServer } set { - _bits |= 0x8000000L; + _bits |= 0x10000000L; _headers._Server = value; _headers._rawServer = null; } @@ -8470,7 +8825,7 @@ public StringValues HeaderSetCookie get { StringValues value = default; - if ((_bits & 0x10000000L) != 0) + if ((_bits & 0x20000000L) != 0) { value = _headers._SetCookie; } @@ -8478,7 +8833,7 @@ public StringValues HeaderSetCookie } set { - _bits |= 0x10000000L; + _bits |= 0x20000000L; _headers._SetCookie = value; } } @@ -8487,7 +8842,7 @@ public StringValues HeaderVary get { StringValues value = default; - if ((_bits & 0x20000000L) != 0) + if ((_bits & 0x40000000L) != 0) { value = _headers._Vary; } @@ -8495,7 +8850,7 @@ public StringValues HeaderVary } set { - _bits |= 0x20000000L; + _bits |= 0x40000000L; _headers._Vary = value; } } @@ -8504,7 +8859,7 @@ public StringValues HeaderWWWAuthenticate get { StringValues value = default; - if ((_bits & 0x40000000L) != 0) + if ((_bits & 0x80000000L) != 0) { value = _headers._WWWAuthenticate; } @@ -8512,7 +8867,7 @@ public StringValues HeaderWWWAuthenticate } set { - _bits |= 0x40000000L; + _bits |= 0x80000000L; _headers._WWWAuthenticate = value; } } @@ -8521,7 +8876,7 @@ public StringValues HeaderAccessControlAllowCredentials get { StringValues value = default; - if ((_bits & 0x80000000L) != 0) + if ((_bits & 0x100000000L) != 0) { value = _headers._AccessControlAllowCredentials; } @@ -8529,7 +8884,7 @@ public StringValues HeaderAccessControlAllowCredentials } set { - _bits |= 0x80000000L; + _bits |= 0x100000000L; _headers._AccessControlAllowCredentials = value; } } @@ -8538,7 +8893,7 @@ public StringValues HeaderAccessControlAllowHeaders get { StringValues value = default; - if ((_bits & 0x100000000L) != 0) + if ((_bits & 0x200000000L) != 0) { value = _headers._AccessControlAllowHeaders; } @@ -8546,7 +8901,7 @@ public StringValues HeaderAccessControlAllowHeaders } set { - _bits |= 0x100000000L; + _bits |= 0x200000000L; _headers._AccessControlAllowHeaders = value; } } @@ -8555,7 +8910,7 @@ public StringValues HeaderAccessControlAllowMethods get { StringValues value = default; - if ((_bits & 0x200000000L) != 0) + if ((_bits & 0x400000000L) != 0) { value = _headers._AccessControlAllowMethods; } @@ -8563,7 +8918,7 @@ public StringValues HeaderAccessControlAllowMethods } set { - _bits |= 0x200000000L; + _bits |= 0x400000000L; _headers._AccessControlAllowMethods = value; } } @@ -8572,7 +8927,7 @@ public StringValues HeaderAccessControlAllowOrigin get { StringValues value = default; - if ((_bits & 0x400000000L) != 0) + if ((_bits & 0x800000000L) != 0) { value = _headers._AccessControlAllowOrigin; } @@ -8580,7 +8935,7 @@ public StringValues HeaderAccessControlAllowOrigin } set { - _bits |= 0x400000000L; + _bits |= 0x800000000L; _headers._AccessControlAllowOrigin = value; } } @@ -8589,7 +8944,7 @@ public StringValues HeaderAccessControlExposeHeaders get { StringValues value = default; - if ((_bits & 0x800000000L) != 0) + if ((_bits & 0x1000000000L) != 0) { value = _headers._AccessControlExposeHeaders; } @@ -8597,7 +8952,7 @@ public StringValues HeaderAccessControlExposeHeaders } set { - _bits |= 0x800000000L; + _bits |= 0x1000000000L; _headers._AccessControlExposeHeaders = value; } } @@ -8606,7 +8961,7 @@ public StringValues HeaderAccessControlMaxAge get { StringValues value = default; - if ((_bits & 0x1000000000L) != 0) + if ((_bits & 0x2000000000L) != 0) { value = _headers._AccessControlMaxAge; } @@ -8614,7 +8969,7 @@ public StringValues HeaderAccessControlMaxAge } set { - _bits |= 0x1000000000L; + _bits |= 0x2000000000L; _headers._AccessControlMaxAge = value; } } @@ -8655,40 +9010,269 @@ public void SetRawTransferEncoding(StringValues value, byte[] raw) } public void SetRawServer(StringValues value, byte[] raw) { - _bits |= 0x8000000L; + _bits |= 0x10000000L; _headers._Server = value; _headers._rawServer = raw; } - protected override int GetCountFast() + + public void ClearCacheControl() { - return (_contentLength.HasValue ? 1 : 0 ) + BitOperations.PopCount((ulong)_bits) + (MaybeUnknown?.Count ?? 0); + _bits &= ~0x1L; + _headers._CacheControl = default; + } - - protected override bool TryGetValueFast(string key, out StringValues value) + public void ClearConnection() { - value = default; - switch (key.Length) - { - case 3: - { - if (ReferenceEquals(HeaderNames.Via, key)) - { - if ((_bits & 0x200L) != 0) - { - value = _headers._Via; - return true; - } - return false; - } - if (ReferenceEquals(HeaderNames.Age, key)) - { - if ((_bits & 0x200000L) != 0) - { - value = _headers._Age; - return true; - } - return false; - } + _bits &= ~0x2L; + _headers._Connection = default; + _headers._rawConnection = null; + } + public void ClearDate() + { + _bits &= ~0x4L; + _headers._Date = default; + _headers._rawDate = null; + } + public void ClearGrpcEncoding() + { + _bits &= ~0x8L; + _headers._GrpcEncoding = default; + + } + public void ClearKeepAlive() + { + _bits &= ~0x10L; + _headers._KeepAlive = default; + + } + public void ClearPragma() + { + _bits &= ~0x20L; + _headers._Pragma = default; + + } + public void ClearTrailer() + { + _bits &= ~0x40L; + _headers._Trailer = default; + + } + public void ClearTransferEncoding() + { + _bits &= ~0x80L; + _headers._TransferEncoding = default; + _headers._rawTransferEncoding = null; + } + public void ClearUpgrade() + { + _bits &= ~0x100L; + _headers._Upgrade = default; + + } + public void ClearVia() + { + _bits &= ~0x200L; + _headers._Via = default; + + } + public void ClearWarning() + { + _bits &= ~0x400L; + _headers._Warning = default; + + } + public void ClearAllow() + { + _bits &= ~0x800L; + _headers._Allow = default; + + } + public void ClearContentType() + { + _bits &= ~0x1000L; + _headers._ContentType = default; + + } + public void ClearContentEncoding() + { + _bits &= ~0x2000L; + _headers._ContentEncoding = default; + + } + public void ClearContentLanguage() + { + _bits &= ~0x4000L; + _headers._ContentLanguage = default; + + } + public void ClearContentLocation() + { + _bits &= ~0x8000L; + _headers._ContentLocation = default; + + } + public void ClearContentMD5() + { + _bits &= ~0x10000L; + _headers._ContentMD5 = default; + + } + public void ClearContentRange() + { + _bits &= ~0x20000L; + _headers._ContentRange = default; + + } + public void ClearExpires() + { + _bits &= ~0x40000L; + _headers._Expires = default; + + } + public void ClearLastModified() + { + _bits &= ~0x80000L; + _headers._LastModified = default; + + } + public void ClearAcceptRanges() + { + _bits &= ~0x100000L; + _headers._AcceptRanges = default; + + } + public void ClearAge() + { + _bits &= ~0x200000L; + _headers._Age = default; + + } + public void ClearAltSvc() + { + _bits &= ~0x400000L; + _headers._AltSvc = default; + + } + public void ClearETag() + { + _bits &= ~0x800000L; + _headers._ETag = default; + + } + public void ClearLocation() + { + _bits &= ~0x1000000L; + _headers._Location = default; + + } + public void ClearProxyAuthenticate() + { + _bits &= ~0x2000000L; + _headers._ProxyAuthenticate = default; + + } + public void ClearProxyConnection() + { + _bits &= ~0x4000000L; + _headers._ProxyConnection = default; + + } + public void ClearRetryAfter() + { + _bits &= ~0x8000000L; + _headers._RetryAfter = default; + + } + public void ClearServer() + { + _bits &= ~0x10000000L; + _headers._Server = default; + _headers._rawServer = null; + } + public void ClearSetCookie() + { + _bits &= ~0x20000000L; + _headers._SetCookie = default; + + } + public void ClearVary() + { + _bits &= ~0x40000000L; + _headers._Vary = default; + + } + public void ClearWWWAuthenticate() + { + _bits &= ~0x80000000L; + _headers._WWWAuthenticate = default; + + } + public void ClearAccessControlAllowCredentials() + { + _bits &= ~0x100000000L; + _headers._AccessControlAllowCredentials = default; + + } + public void ClearAccessControlAllowHeaders() + { + _bits &= ~0x200000000L; + _headers._AccessControlAllowHeaders = default; + + } + public void ClearAccessControlAllowMethods() + { + _bits &= ~0x400000000L; + _headers._AccessControlAllowMethods = default; + + } + public void ClearAccessControlAllowOrigin() + { + _bits &= ~0x800000000L; + _headers._AccessControlAllowOrigin = default; + + } + public void ClearAccessControlExposeHeaders() + { + _bits &= ~0x1000000000L; + _headers._AccessControlExposeHeaders = default; + + } + public void ClearAccessControlMaxAge() + { + _bits &= ~0x2000000000L; + _headers._AccessControlMaxAge = default; + + } + protected override int GetCountFast() + { + return (_contentLength.HasValue ? 1 : 0 ) + BitOperations.PopCount((ulong)_bits) + (MaybeUnknown?.Count ?? 0); + } + + protected override bool TryGetValueFast(string key, out StringValues value) + { + value = default; + switch (key.Length) + { + case 3: + { + if (ReferenceEquals(HeaderNames.Via, key)) + { + if ((_bits & 0x200L) != 0) + { + value = _headers._Via; + return true; + } + return false; + } + if (ReferenceEquals(HeaderNames.Age, key)) + { + if ((_bits & 0x200000L) != 0) + { + value = _headers._Age; + return true; + } + return false; + } if (HeaderNames.Via.Equals(key, StringComparison.OrdinalIgnoreCase)) { @@ -8732,7 +9316,7 @@ protected override bool TryGetValueFast(string key, out StringValues value) } if (ReferenceEquals(HeaderNames.Vary, key)) { - if ((_bits & 0x20000000L) != 0) + if ((_bits & 0x40000000L) != 0) { value = _headers._Vary; return true; @@ -8760,7 +9344,7 @@ protected override bool TryGetValueFast(string key, out StringValues value) } if (HeaderNames.Vary.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x20000000L) != 0) + if ((_bits & 0x40000000L) != 0) { value = _headers._Vary; return true; @@ -8796,7 +9380,7 @@ protected override bool TryGetValueFast(string key, out StringValues value) { if (ReferenceEquals(HeaderNames.Server, key)) { - if ((_bits & 0x8000000L) != 0) + if ((_bits & 0x10000000L) != 0) { value = _headers._Server; return true; @@ -8815,7 +9399,7 @@ protected override bool TryGetValueFast(string key, out StringValues value) if (HeaderNames.Server.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x8000000L) != 0) + if ((_bits & 0x10000000L) != 0) { value = _headers._Server; return true; @@ -8973,7 +9557,7 @@ protected override bool TryGetValueFast(string key, out StringValues value) } if (ReferenceEquals(HeaderNames.SetCookie, key)) { - if ((_bits & 0x10000000L) != 0) + if ((_bits & 0x20000000L) != 0) { value = _headers._SetCookie; return true; @@ -9001,7 +9585,7 @@ protected override bool TryGetValueFast(string key, out StringValues value) } if (HeaderNames.SetCookie.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x10000000L) != 0) + if ((_bits & 0x20000000L) != 0) { value = _headers._SetCookie; return true; @@ -9023,7 +9607,7 @@ protected override bool TryGetValueFast(string key, out StringValues value) } if (ReferenceEquals(HeaderNames.RetryAfter, key)) { - if ((_bits & 0x4000000L) != 0) + if ((_bits & 0x8000000L) != 0) { value = _headers._RetryAfter; return true; @@ -9042,7 +9626,7 @@ protected override bool TryGetValueFast(string key, out StringValues value) } if (HeaderNames.RetryAfter.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x4000000L) != 0) + if ((_bits & 0x8000000L) != 0) { value = _headers._RetryAfter; return true; @@ -9221,9 +9805,18 @@ protected override bool TryGetValueFast(string key, out StringValues value) } return false; } + if (ReferenceEquals(HeaderNames.ProxyConnection, key)) + { + if ((_bits & 0x4000000L) != 0) + { + value = _headers._ProxyConnection; + return true; + } + return false; + } if (ReferenceEquals(HeaderNames.WWWAuthenticate, key)) { - if ((_bits & 0x40000000L) != 0) + if ((_bits & 0x80000000L) != 0) { value = _headers._WWWAuthenticate; return true; @@ -9258,9 +9851,18 @@ protected override bool TryGetValueFast(string key, out StringValues value) } return false; } + if (HeaderNames.ProxyConnection.Equals(key, StringComparison.OrdinalIgnoreCase)) + { + if ((_bits & 0x4000000L) != 0) + { + value = _headers._ProxyConnection; + return true; + } + return false; + } if (HeaderNames.WWWAuthenticate.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x40000000L) != 0) + if ((_bits & 0x80000000L) != 0) { value = _headers._WWWAuthenticate; return true; @@ -9319,7 +9921,7 @@ protected override bool TryGetValueFast(string key, out StringValues value) { if (ReferenceEquals(HeaderNames.AccessControlMaxAge, key)) { - if ((_bits & 0x1000000000L) != 0) + if ((_bits & 0x2000000000L) != 0) { value = _headers._AccessControlMaxAge; return true; @@ -9329,7 +9931,7 @@ protected override bool TryGetValueFast(string key, out StringValues value) if (HeaderNames.AccessControlMaxAge.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x1000000000L) != 0) + if ((_bits & 0x2000000000L) != 0) { value = _headers._AccessControlMaxAge; return true; @@ -9342,7 +9944,7 @@ protected override bool TryGetValueFast(string key, out StringValues value) { if (ReferenceEquals(HeaderNames.AccessControlAllowOrigin, key)) { - if ((_bits & 0x400000000L) != 0) + if ((_bits & 0x800000000L) != 0) { value = _headers._AccessControlAllowOrigin; return true; @@ -9352,7 +9954,7 @@ protected override bool TryGetValueFast(string key, out StringValues value) if (HeaderNames.AccessControlAllowOrigin.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x400000000L) != 0) + if ((_bits & 0x800000000L) != 0) { value = _headers._AccessControlAllowOrigin; return true; @@ -9365,7 +9967,7 @@ protected override bool TryGetValueFast(string key, out StringValues value) { if (ReferenceEquals(HeaderNames.AccessControlAllowHeaders, key)) { - if ((_bits & 0x100000000L) != 0) + if ((_bits & 0x200000000L) != 0) { value = _headers._AccessControlAllowHeaders; return true; @@ -9374,7 +9976,7 @@ protected override bool TryGetValueFast(string key, out StringValues value) } if (ReferenceEquals(HeaderNames.AccessControlAllowMethods, key)) { - if ((_bits & 0x200000000L) != 0) + if ((_bits & 0x400000000L) != 0) { value = _headers._AccessControlAllowMethods; return true; @@ -9384,7 +9986,7 @@ protected override bool TryGetValueFast(string key, out StringValues value) if (HeaderNames.AccessControlAllowHeaders.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x100000000L) != 0) + if ((_bits & 0x200000000L) != 0) { value = _headers._AccessControlAllowHeaders; return true; @@ -9393,7 +9995,7 @@ protected override bool TryGetValueFast(string key, out StringValues value) } if (HeaderNames.AccessControlAllowMethods.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x200000000L) != 0) + if ((_bits & 0x400000000L) != 0) { value = _headers._AccessControlAllowMethods; return true; @@ -9406,7 +10008,7 @@ protected override bool TryGetValueFast(string key, out StringValues value) { if (ReferenceEquals(HeaderNames.AccessControlExposeHeaders, key)) { - if ((_bits & 0x800000000L) != 0) + if ((_bits & 0x1000000000L) != 0) { value = _headers._AccessControlExposeHeaders; return true; @@ -9416,7 +10018,7 @@ protected override bool TryGetValueFast(string key, out StringValues value) if (HeaderNames.AccessControlExposeHeaders.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x800000000L) != 0) + if ((_bits & 0x1000000000L) != 0) { value = _headers._AccessControlExposeHeaders; return true; @@ -9429,7 +10031,7 @@ protected override bool TryGetValueFast(string key, out StringValues value) { if (ReferenceEquals(HeaderNames.AccessControlAllowCredentials, key)) { - if ((_bits & 0x80000000L) != 0) + if ((_bits & 0x100000000L) != 0) { value = _headers._AccessControlAllowCredentials; return true; @@ -9439,7 +10041,7 @@ protected override bool TryGetValueFast(string key, out StringValues value) if (HeaderNames.AccessControlAllowCredentials.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x80000000L) != 0) + if ((_bits & 0x100000000L) != 0) { value = _headers._AccessControlAllowCredentials; return true; @@ -9504,7 +10106,7 @@ protected override void SetValueFast(string key, StringValues value) } if (ReferenceEquals(HeaderNames.Vary, key)) { - _bits |= 0x20000000L; + _bits |= 0x40000000L; _headers._Vary = value; return; } @@ -9524,7 +10126,7 @@ protected override void SetValueFast(string key, StringValues value) } if (HeaderNames.Vary.Equals(key, StringComparison.OrdinalIgnoreCase)) { - _bits |= 0x20000000L; + _bits |= 0x40000000L; _headers._Vary = value; return; } @@ -9551,7 +10153,7 @@ protected override void SetValueFast(string key, StringValues value) { if (ReferenceEquals(HeaderNames.Server, key)) { - _bits |= 0x8000000L; + _bits |= 0x10000000L; _headers._Server = value; _headers._rawServer = null; return; @@ -9565,7 +10167,7 @@ protected override void SetValueFast(string key, StringValues value) if (HeaderNames.Server.Equals(key, StringComparison.OrdinalIgnoreCase)) { - _bits |= 0x8000000L; + _bits |= 0x10000000L; _headers._Server = value; _headers._rawServer = null; return; @@ -9677,7 +10279,7 @@ protected override void SetValueFast(string key, StringValues value) } if (ReferenceEquals(HeaderNames.SetCookie, key)) { - _bits |= 0x10000000L; + _bits |= 0x20000000L; _headers._SetCookie = value; return; } @@ -9697,7 +10299,7 @@ protected override void SetValueFast(string key, StringValues value) } if (HeaderNames.SetCookie.Equals(key, StringComparison.OrdinalIgnoreCase)) { - _bits |= 0x10000000L; + _bits |= 0x20000000L; _headers._SetCookie = value; return; } @@ -9713,7 +10315,7 @@ protected override void SetValueFast(string key, StringValues value) } if (ReferenceEquals(HeaderNames.RetryAfter, key)) { - _bits |= 0x4000000L; + _bits |= 0x8000000L; _headers._RetryAfter = value; return; } @@ -9726,7 +10328,7 @@ protected override void SetValueFast(string key, StringValues value) } if (HeaderNames.RetryAfter.Equals(key, StringComparison.OrdinalIgnoreCase)) { - _bits |= 0x4000000L; + _bits |= 0x8000000L; _headers._RetryAfter = value; return; } @@ -9849,9 +10451,15 @@ protected override void SetValueFast(string key, StringValues value) _headers._ContentLocation = value; return; } + if (ReferenceEquals(HeaderNames.ProxyConnection, key)) + { + _bits |= 0x4000000L; + _headers._ProxyConnection = value; + return; + } if (ReferenceEquals(HeaderNames.WWWAuthenticate, key)) { - _bits |= 0x40000000L; + _bits |= 0x80000000L; _headers._WWWAuthenticate = value; return; } @@ -9874,9 +10482,15 @@ protected override void SetValueFast(string key, StringValues value) _headers._ContentLocation = value; return; } + if (HeaderNames.ProxyConnection.Equals(key, StringComparison.OrdinalIgnoreCase)) + { + _bits |= 0x4000000L; + _headers._ProxyConnection = value; + return; + } if (HeaderNames.WWWAuthenticate.Equals(key, StringComparison.OrdinalIgnoreCase)) { - _bits |= 0x40000000L; + _bits |= 0x80000000L; _headers._WWWAuthenticate = value; return; } @@ -9922,14 +10536,14 @@ protected override void SetValueFast(string key, StringValues value) { if (ReferenceEquals(HeaderNames.AccessControlMaxAge, key)) { - _bits |= 0x1000000000L; + _bits |= 0x2000000000L; _headers._AccessControlMaxAge = value; return; } if (HeaderNames.AccessControlMaxAge.Equals(key, StringComparison.OrdinalIgnoreCase)) { - _bits |= 0x1000000000L; + _bits |= 0x2000000000L; _headers._AccessControlMaxAge = value; return; } @@ -9939,14 +10553,14 @@ protected override void SetValueFast(string key, StringValues value) { if (ReferenceEquals(HeaderNames.AccessControlAllowOrigin, key)) { - _bits |= 0x400000000L; + _bits |= 0x800000000L; _headers._AccessControlAllowOrigin = value; return; } if (HeaderNames.AccessControlAllowOrigin.Equals(key, StringComparison.OrdinalIgnoreCase)) { - _bits |= 0x400000000L; + _bits |= 0x800000000L; _headers._AccessControlAllowOrigin = value; return; } @@ -9956,26 +10570,26 @@ protected override void SetValueFast(string key, StringValues value) { if (ReferenceEquals(HeaderNames.AccessControlAllowHeaders, key)) { - _bits |= 0x100000000L; + _bits |= 0x200000000L; _headers._AccessControlAllowHeaders = value; return; } if (ReferenceEquals(HeaderNames.AccessControlAllowMethods, key)) { - _bits |= 0x200000000L; + _bits |= 0x400000000L; _headers._AccessControlAllowMethods = value; return; } if (HeaderNames.AccessControlAllowHeaders.Equals(key, StringComparison.OrdinalIgnoreCase)) { - _bits |= 0x100000000L; + _bits |= 0x200000000L; _headers._AccessControlAllowHeaders = value; return; } if (HeaderNames.AccessControlAllowMethods.Equals(key, StringComparison.OrdinalIgnoreCase)) { - _bits |= 0x200000000L; + _bits |= 0x400000000L; _headers._AccessControlAllowMethods = value; return; } @@ -9985,14 +10599,14 @@ protected override void SetValueFast(string key, StringValues value) { if (ReferenceEquals(HeaderNames.AccessControlExposeHeaders, key)) { - _bits |= 0x800000000L; + _bits |= 0x1000000000L; _headers._AccessControlExposeHeaders = value; return; } if (HeaderNames.AccessControlExposeHeaders.Equals(key, StringComparison.OrdinalIgnoreCase)) { - _bits |= 0x800000000L; + _bits |= 0x1000000000L; _headers._AccessControlExposeHeaders = value; return; } @@ -10002,14 +10616,14 @@ protected override void SetValueFast(string key, StringValues value) { if (ReferenceEquals(HeaderNames.AccessControlAllowCredentials, key)) { - _bits |= 0x80000000L; + _bits |= 0x100000000L; _headers._AccessControlAllowCredentials = value; return; } if (HeaderNames.AccessControlAllowCredentials.Equals(key, StringComparison.OrdinalIgnoreCase)) { - _bits |= 0x80000000L; + _bits |= 0x100000000L; _headers._AccessControlAllowCredentials = value; return; } @@ -10095,9 +10709,9 @@ protected override bool AddValueFast(string key, StringValues value) } if (ReferenceEquals(HeaderNames.Vary, key)) { - if ((_bits & 0x20000000L) == 0) + if ((_bits & 0x40000000L) == 0) { - _bits |= 0x20000000L; + _bits |= 0x40000000L; _headers._Vary = value; return true; } @@ -10127,9 +10741,9 @@ protected override bool AddValueFast(string key, StringValues value) } if (HeaderNames.Vary.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x20000000L) == 0) + if ((_bits & 0x40000000L) == 0) { - _bits |= 0x20000000L; + _bits |= 0x40000000L; _headers._Vary = value; return true; } @@ -10166,9 +10780,9 @@ protected override bool AddValueFast(string key, StringValues value) { if (ReferenceEquals(HeaderNames.Server, key)) { - if ((_bits & 0x8000000L) == 0) + if ((_bits & 0x10000000L) == 0) { - _bits |= 0x8000000L; + _bits |= 0x10000000L; _headers._Server = value; _headers._rawServer = null; return true; @@ -10188,9 +10802,9 @@ protected override bool AddValueFast(string key, StringValues value) if (HeaderNames.Server.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x8000000L) == 0) + if ((_bits & 0x10000000L) == 0) { - _bits |= 0x8000000L; + _bits |= 0x10000000L; _headers._Server = value; _headers._rawServer = null; return true; @@ -10364,9 +10978,9 @@ protected override bool AddValueFast(string key, StringValues value) } if (ReferenceEquals(HeaderNames.SetCookie, key)) { - if ((_bits & 0x10000000L) == 0) + if ((_bits & 0x20000000L) == 0) { - _bits |= 0x10000000L; + _bits |= 0x20000000L; _headers._SetCookie = value; return true; } @@ -10396,9 +11010,9 @@ protected override bool AddValueFast(string key, StringValues value) } if (HeaderNames.SetCookie.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x10000000L) == 0) + if ((_bits & 0x20000000L) == 0) { - _bits |= 0x10000000L; + _bits |= 0x20000000L; _headers._SetCookie = value; return true; } @@ -10420,9 +11034,9 @@ protected override bool AddValueFast(string key, StringValues value) } if (ReferenceEquals(HeaderNames.RetryAfter, key)) { - if ((_bits & 0x4000000L) == 0) + if ((_bits & 0x8000000L) == 0) { - _bits |= 0x4000000L; + _bits |= 0x8000000L; _headers._RetryAfter = value; return true; } @@ -10441,9 +11055,9 @@ protected override bool AddValueFast(string key, StringValues value) } if (HeaderNames.RetryAfter.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x4000000L) == 0) + if ((_bits & 0x8000000L) == 0) { - _bits |= 0x4000000L; + _bits |= 0x8000000L; _headers._RetryAfter = value; return true; } @@ -10636,11 +11250,21 @@ protected override bool AddValueFast(string key, StringValues value) } return false; } + if (ReferenceEquals(HeaderNames.ProxyConnection, key)) + { + if ((_bits & 0x4000000L) == 0) + { + _bits |= 0x4000000L; + _headers._ProxyConnection = value; + return true; + } + return false; + } if (ReferenceEquals(HeaderNames.WWWAuthenticate, key)) { - if ((_bits & 0x40000000L) == 0) + if ((_bits & 0x80000000L) == 0) { - _bits |= 0x40000000L; + _bits |= 0x80000000L; _headers._WWWAuthenticate = value; return true; } @@ -10677,11 +11301,21 @@ protected override bool AddValueFast(string key, StringValues value) } return false; } + if (HeaderNames.ProxyConnection.Equals(key, StringComparison.OrdinalIgnoreCase)) + { + if ((_bits & 0x4000000L) == 0) + { + _bits |= 0x4000000L; + _headers._ProxyConnection = value; + return true; + } + return false; + } if (HeaderNames.WWWAuthenticate.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x40000000L) == 0) + if ((_bits & 0x80000000L) == 0) { - _bits |= 0x40000000L; + _bits |= 0x80000000L; _headers._WWWAuthenticate = value; return true; } @@ -10745,9 +11379,9 @@ protected override bool AddValueFast(string key, StringValues value) { if (ReferenceEquals(HeaderNames.AccessControlMaxAge, key)) { - if ((_bits & 0x1000000000L) == 0) + if ((_bits & 0x2000000000L) == 0) { - _bits |= 0x1000000000L; + _bits |= 0x2000000000L; _headers._AccessControlMaxAge = value; return true; } @@ -10756,9 +11390,9 @@ protected override bool AddValueFast(string key, StringValues value) if (HeaderNames.AccessControlMaxAge.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x1000000000L) == 0) + if ((_bits & 0x2000000000L) == 0) { - _bits |= 0x1000000000L; + _bits |= 0x2000000000L; _headers._AccessControlMaxAge = value; return true; } @@ -10770,9 +11404,9 @@ protected override bool AddValueFast(string key, StringValues value) { if (ReferenceEquals(HeaderNames.AccessControlAllowOrigin, key)) { - if ((_bits & 0x400000000L) == 0) + if ((_bits & 0x800000000L) == 0) { - _bits |= 0x400000000L; + _bits |= 0x800000000L; _headers._AccessControlAllowOrigin = value; return true; } @@ -10781,9 +11415,9 @@ protected override bool AddValueFast(string key, StringValues value) if (HeaderNames.AccessControlAllowOrigin.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x400000000L) == 0) + if ((_bits & 0x800000000L) == 0) { - _bits |= 0x400000000L; + _bits |= 0x800000000L; _headers._AccessControlAllowOrigin = value; return true; } @@ -10795,9 +11429,9 @@ protected override bool AddValueFast(string key, StringValues value) { if (ReferenceEquals(HeaderNames.AccessControlAllowHeaders, key)) { - if ((_bits & 0x100000000L) == 0) + if ((_bits & 0x200000000L) == 0) { - _bits |= 0x100000000L; + _bits |= 0x200000000L; _headers._AccessControlAllowHeaders = value; return true; } @@ -10805,9 +11439,9 @@ protected override bool AddValueFast(string key, StringValues value) } if (ReferenceEquals(HeaderNames.AccessControlAllowMethods, key)) { - if ((_bits & 0x200000000L) == 0) + if ((_bits & 0x400000000L) == 0) { - _bits |= 0x200000000L; + _bits |= 0x400000000L; _headers._AccessControlAllowMethods = value; return true; } @@ -10816,9 +11450,9 @@ protected override bool AddValueFast(string key, StringValues value) if (HeaderNames.AccessControlAllowHeaders.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x100000000L) == 0) + if ((_bits & 0x200000000L) == 0) { - _bits |= 0x100000000L; + _bits |= 0x200000000L; _headers._AccessControlAllowHeaders = value; return true; } @@ -10826,9 +11460,9 @@ protected override bool AddValueFast(string key, StringValues value) } if (HeaderNames.AccessControlAllowMethods.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x200000000L) == 0) + if ((_bits & 0x400000000L) == 0) { - _bits |= 0x200000000L; + _bits |= 0x400000000L; _headers._AccessControlAllowMethods = value; return true; } @@ -10840,9 +11474,9 @@ protected override bool AddValueFast(string key, StringValues value) { if (ReferenceEquals(HeaderNames.AccessControlExposeHeaders, key)) { - if ((_bits & 0x800000000L) == 0) + if ((_bits & 0x1000000000L) == 0) { - _bits |= 0x800000000L; + _bits |= 0x1000000000L; _headers._AccessControlExposeHeaders = value; return true; } @@ -10851,9 +11485,9 @@ protected override bool AddValueFast(string key, StringValues value) if (HeaderNames.AccessControlExposeHeaders.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x800000000L) == 0) + if ((_bits & 0x1000000000L) == 0) { - _bits |= 0x800000000L; + _bits |= 0x1000000000L; _headers._AccessControlExposeHeaders = value; return true; } @@ -10865,9 +11499,9 @@ protected override bool AddValueFast(string key, StringValues value) { if (ReferenceEquals(HeaderNames.AccessControlAllowCredentials, key)) { - if ((_bits & 0x80000000L) == 0) + if ((_bits & 0x100000000L) == 0) { - _bits |= 0x80000000L; + _bits |= 0x100000000L; _headers._AccessControlAllowCredentials = value; return true; } @@ -10876,9 +11510,9 @@ protected override bool AddValueFast(string key, StringValues value) if (HeaderNames.AccessControlAllowCredentials.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x80000000L) == 0) + if ((_bits & 0x100000000L) == 0) { - _bits |= 0x80000000L; + _bits |= 0x100000000L; _headers._AccessControlAllowCredentials = value; return true; } @@ -10965,9 +11599,9 @@ protected override bool RemoveFast(string key) } if (ReferenceEquals(HeaderNames.Vary, key)) { - if ((_bits & 0x20000000L) != 0) + if ((_bits & 0x40000000L) != 0) { - _bits &= ~0x20000000L; + _bits &= ~0x40000000L; _headers._Vary = default(StringValues); return true; } @@ -10997,9 +11631,9 @@ protected override bool RemoveFast(string key) } if (HeaderNames.Vary.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x20000000L) != 0) + if ((_bits & 0x40000000L) != 0) { - _bits &= ~0x20000000L; + _bits &= ~0x40000000L; _headers._Vary = default(StringValues); return true; } @@ -11036,9 +11670,9 @@ protected override bool RemoveFast(string key) { if (ReferenceEquals(HeaderNames.Server, key)) { - if ((_bits & 0x8000000L) != 0) + if ((_bits & 0x10000000L) != 0) { - _bits &= ~0x8000000L; + _bits &= ~0x10000000L; _headers._Server = default(StringValues); _headers._rawServer = null; return true; @@ -11058,9 +11692,9 @@ protected override bool RemoveFast(string key) if (HeaderNames.Server.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x8000000L) != 0) + if ((_bits & 0x10000000L) != 0) { - _bits &= ~0x8000000L; + _bits &= ~0x10000000L; _headers._Server = default(StringValues); _headers._rawServer = null; return true; @@ -11234,9 +11868,9 @@ protected override bool RemoveFast(string key) } if (ReferenceEquals(HeaderNames.SetCookie, key)) { - if ((_bits & 0x10000000L) != 0) + if ((_bits & 0x20000000L) != 0) { - _bits &= ~0x10000000L; + _bits &= ~0x20000000L; _headers._SetCookie = default(StringValues); return true; } @@ -11266,9 +11900,9 @@ protected override bool RemoveFast(string key) } if (HeaderNames.SetCookie.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x10000000L) != 0) + if ((_bits & 0x20000000L) != 0) { - _bits &= ~0x10000000L; + _bits &= ~0x20000000L; _headers._SetCookie = default(StringValues); return true; } @@ -11290,9 +11924,9 @@ protected override bool RemoveFast(string key) } if (ReferenceEquals(HeaderNames.RetryAfter, key)) { - if ((_bits & 0x4000000L) != 0) + if ((_bits & 0x8000000L) != 0) { - _bits &= ~0x4000000L; + _bits &= ~0x8000000L; _headers._RetryAfter = default(StringValues); return true; } @@ -11311,9 +11945,9 @@ protected override bool RemoveFast(string key) } if (HeaderNames.RetryAfter.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x4000000L) != 0) + if ((_bits & 0x8000000L) != 0) { - _bits &= ~0x4000000L; + _bits &= ~0x8000000L; _headers._RetryAfter = default(StringValues); return true; } @@ -11506,11 +12140,21 @@ protected override bool RemoveFast(string key) } return false; } + if (ReferenceEquals(HeaderNames.ProxyConnection, key)) + { + if ((_bits & 0x4000000L) != 0) + { + _bits &= ~0x4000000L; + _headers._ProxyConnection = default(StringValues); + return true; + } + return false; + } if (ReferenceEquals(HeaderNames.WWWAuthenticate, key)) { - if ((_bits & 0x40000000L) != 0) + if ((_bits & 0x80000000L) != 0) { - _bits &= ~0x40000000L; + _bits &= ~0x80000000L; _headers._WWWAuthenticate = default(StringValues); return true; } @@ -11539,19 +12183,29 @@ protected override bool RemoveFast(string key) } if (HeaderNames.ContentLocation.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x8000L) != 0) + if ((_bits & 0x8000L) != 0) + { + _bits &= ~0x8000L; + _headers._ContentLocation = default(StringValues); + return true; + } + return false; + } + if (HeaderNames.ProxyConnection.Equals(key, StringComparison.OrdinalIgnoreCase)) + { + if ((_bits & 0x4000000L) != 0) { - _bits &= ~0x8000L; - _headers._ContentLocation = default(StringValues); + _bits &= ~0x4000000L; + _headers._ProxyConnection = default(StringValues); return true; } return false; } if (HeaderNames.WWWAuthenticate.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x40000000L) != 0) + if ((_bits & 0x80000000L) != 0) { - _bits &= ~0x40000000L; + _bits &= ~0x80000000L; _headers._WWWAuthenticate = default(StringValues); return true; } @@ -11615,9 +12269,9 @@ protected override bool RemoveFast(string key) { if (ReferenceEquals(HeaderNames.AccessControlMaxAge, key)) { - if ((_bits & 0x1000000000L) != 0) + if ((_bits & 0x2000000000L) != 0) { - _bits &= ~0x1000000000L; + _bits &= ~0x2000000000L; _headers._AccessControlMaxAge = default(StringValues); return true; } @@ -11626,9 +12280,9 @@ protected override bool RemoveFast(string key) if (HeaderNames.AccessControlMaxAge.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x1000000000L) != 0) + if ((_bits & 0x2000000000L) != 0) { - _bits &= ~0x1000000000L; + _bits &= ~0x2000000000L; _headers._AccessControlMaxAge = default(StringValues); return true; } @@ -11640,9 +12294,9 @@ protected override bool RemoveFast(string key) { if (ReferenceEquals(HeaderNames.AccessControlAllowOrigin, key)) { - if ((_bits & 0x400000000L) != 0) + if ((_bits & 0x800000000L) != 0) { - _bits &= ~0x400000000L; + _bits &= ~0x800000000L; _headers._AccessControlAllowOrigin = default(StringValues); return true; } @@ -11651,9 +12305,9 @@ protected override bool RemoveFast(string key) if (HeaderNames.AccessControlAllowOrigin.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x400000000L) != 0) + if ((_bits & 0x800000000L) != 0) { - _bits &= ~0x400000000L; + _bits &= ~0x800000000L; _headers._AccessControlAllowOrigin = default(StringValues); return true; } @@ -11665,9 +12319,9 @@ protected override bool RemoveFast(string key) { if (ReferenceEquals(HeaderNames.AccessControlAllowHeaders, key)) { - if ((_bits & 0x100000000L) != 0) + if ((_bits & 0x200000000L) != 0) { - _bits &= ~0x100000000L; + _bits &= ~0x200000000L; _headers._AccessControlAllowHeaders = default(StringValues); return true; } @@ -11675,9 +12329,9 @@ protected override bool RemoveFast(string key) } if (ReferenceEquals(HeaderNames.AccessControlAllowMethods, key)) { - if ((_bits & 0x200000000L) != 0) + if ((_bits & 0x400000000L) != 0) { - _bits &= ~0x200000000L; + _bits &= ~0x400000000L; _headers._AccessControlAllowMethods = default(StringValues); return true; } @@ -11686,9 +12340,9 @@ protected override bool RemoveFast(string key) if (HeaderNames.AccessControlAllowHeaders.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x100000000L) != 0) + if ((_bits & 0x200000000L) != 0) { - _bits &= ~0x100000000L; + _bits &= ~0x200000000L; _headers._AccessControlAllowHeaders = default(StringValues); return true; } @@ -11696,9 +12350,9 @@ protected override bool RemoveFast(string key) } if (HeaderNames.AccessControlAllowMethods.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x200000000L) != 0) + if ((_bits & 0x400000000L) != 0) { - _bits &= ~0x200000000L; + _bits &= ~0x400000000L; _headers._AccessControlAllowMethods = default(StringValues); return true; } @@ -11710,9 +12364,9 @@ protected override bool RemoveFast(string key) { if (ReferenceEquals(HeaderNames.AccessControlExposeHeaders, key)) { - if ((_bits & 0x800000000L) != 0) + if ((_bits & 0x1000000000L) != 0) { - _bits &= ~0x800000000L; + _bits &= ~0x1000000000L; _headers._AccessControlExposeHeaders = default(StringValues); return true; } @@ -11721,9 +12375,9 @@ protected override bool RemoveFast(string key) if (HeaderNames.AccessControlExposeHeaders.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x800000000L) != 0) + if ((_bits & 0x1000000000L) != 0) { - _bits &= ~0x800000000L; + _bits &= ~0x1000000000L; _headers._AccessControlExposeHeaders = default(StringValues); return true; } @@ -11735,9 +12389,9 @@ protected override bool RemoveFast(string key) { if (ReferenceEquals(HeaderNames.AccessControlAllowCredentials, key)) { - if ((_bits & 0x80000000L) != 0) + if ((_bits & 0x100000000L) != 0) { - _bits &= ~0x80000000L; + _bits &= ~0x100000000L; _headers._AccessControlAllowCredentials = default(StringValues); return true; } @@ -11746,9 +12400,9 @@ protected override bool RemoveFast(string key) if (HeaderNames.AccessControlAllowCredentials.Equals(key, StringComparison.OrdinalIgnoreCase)) { - if ((_bits & 0x80000000L) != 0) + if ((_bits & 0x100000000L) != 0) { - _bits &= ~0x80000000L; + _bits &= ~0x100000000L; _headers._AccessControlAllowCredentials = default(StringValues); return true; } @@ -11802,14 +12456,14 @@ protected override void ClearFast() tempBits &= ~0x1000L; } - if ((tempBits & 0x8000000L) != 0) + if ((tempBits & 0x10000000L) != 0) { _headers._Server = default; - if((tempBits & ~0x8000000L) == 0) + if((tempBits & ~0x10000000L) == 0) { return; } - tempBits &= ~0x8000000L; + tempBits &= ~0x10000000L; } if ((tempBits & 0x1L) != 0) @@ -12044,7 +12698,7 @@ protected override void ClearFast() if ((tempBits & 0x4000000L) != 0) { - _headers._RetryAfter = default; + _headers._ProxyConnection = default; if((tempBits & ~0x4000000L) == 0) { return; @@ -12052,19 +12706,19 @@ protected override void ClearFast() tempBits &= ~0x4000000L; } - if ((tempBits & 0x10000000L) != 0) + if ((tempBits & 0x8000000L) != 0) { - _headers._SetCookie = default; - if((tempBits & ~0x10000000L) == 0) + _headers._RetryAfter = default; + if((tempBits & ~0x8000000L) == 0) { return; } - tempBits &= ~0x10000000L; + tempBits &= ~0x8000000L; } if ((tempBits & 0x20000000L) != 0) { - _headers._Vary = default; + _headers._SetCookie = default; if((tempBits & ~0x20000000L) == 0) { return; @@ -12074,7 +12728,7 @@ protected override void ClearFast() if ((tempBits & 0x40000000L) != 0) { - _headers._WWWAuthenticate = default; + _headers._Vary = default; if((tempBits & ~0x40000000L) == 0) { return; @@ -12084,7 +12738,7 @@ protected override void ClearFast() if ((tempBits & 0x80000000L) != 0) { - _headers._AccessControlAllowCredentials = default; + _headers._WWWAuthenticate = default; if((tempBits & ~0x80000000L) == 0) { return; @@ -12094,7 +12748,7 @@ protected override void ClearFast() if ((tempBits & 0x100000000L) != 0) { - _headers._AccessControlAllowHeaders = default; + _headers._AccessControlAllowCredentials = default; if((tempBits & ~0x100000000L) == 0) { return; @@ -12104,7 +12758,7 @@ protected override void ClearFast() if ((tempBits & 0x200000000L) != 0) { - _headers._AccessControlAllowMethods = default; + _headers._AccessControlAllowHeaders = default; if((tempBits & ~0x200000000L) == 0) { return; @@ -12114,7 +12768,7 @@ protected override void ClearFast() if ((tempBits & 0x400000000L) != 0) { - _headers._AccessControlAllowOrigin = default; + _headers._AccessControlAllowMethods = default; if((tempBits & ~0x400000000L) == 0) { return; @@ -12124,7 +12778,7 @@ protected override void ClearFast() if ((tempBits & 0x800000000L) != 0) { - _headers._AccessControlExposeHeaders = default; + _headers._AccessControlAllowOrigin = default; if((tempBits & ~0x800000000L) == 0) { return; @@ -12134,7 +12788,7 @@ protected override void ClearFast() if ((tempBits & 0x1000000000L) != 0) { - _headers._AccessControlMaxAge = default; + _headers._AccessControlExposeHeaders = default; if((tempBits & ~0x1000000000L) == 0) { return; @@ -12142,6 +12796,16 @@ protected override void ClearFast() tempBits &= ~0x1000000000L; } + if ((tempBits & 0x2000000000L) != 0) + { + _headers._AccessControlMaxAge = default; + if((tempBits & ~0x2000000000L) == 0) + { + return; + } + tempBits &= ~0x2000000000L; + } + } protected override bool CopyToFast(KeyValuePair[] array, int arrayIndex) @@ -12391,7 +13055,7 @@ protected override bool CopyToFast(KeyValuePair[] array, i { return false; } - array[arrayIndex] = new KeyValuePair(HeaderNames.RetryAfter, _headers._RetryAfter); + array[arrayIndex] = new KeyValuePair(HeaderNames.ProxyConnection, _headers._ProxyConnection); ++arrayIndex; } if ((_bits & 0x8000000L) != 0) @@ -12400,7 +13064,7 @@ protected override bool CopyToFast(KeyValuePair[] array, i { return false; } - array[arrayIndex] = new KeyValuePair(HeaderNames.Server, _headers._Server); + array[arrayIndex] = new KeyValuePair(HeaderNames.RetryAfter, _headers._RetryAfter); ++arrayIndex; } if ((_bits & 0x10000000L) != 0) @@ -12409,7 +13073,7 @@ protected override bool CopyToFast(KeyValuePair[] array, i { return false; } - array[arrayIndex] = new KeyValuePair(HeaderNames.SetCookie, _headers._SetCookie); + array[arrayIndex] = new KeyValuePair(HeaderNames.Server, _headers._Server); ++arrayIndex; } if ((_bits & 0x20000000L) != 0) @@ -12418,7 +13082,7 @@ protected override bool CopyToFast(KeyValuePair[] array, i { return false; } - array[arrayIndex] = new KeyValuePair(HeaderNames.Vary, _headers._Vary); + array[arrayIndex] = new KeyValuePair(HeaderNames.SetCookie, _headers._SetCookie); ++arrayIndex; } if ((_bits & 0x40000000L) != 0) @@ -12427,7 +13091,7 @@ protected override bool CopyToFast(KeyValuePair[] array, i { return false; } - array[arrayIndex] = new KeyValuePair(HeaderNames.WWWAuthenticate, _headers._WWWAuthenticate); + array[arrayIndex] = new KeyValuePair(HeaderNames.Vary, _headers._Vary); ++arrayIndex; } if ((_bits & 0x80000000L) != 0) @@ -12436,7 +13100,7 @@ protected override bool CopyToFast(KeyValuePair[] array, i { return false; } - array[arrayIndex] = new KeyValuePair(HeaderNames.AccessControlAllowCredentials, _headers._AccessControlAllowCredentials); + array[arrayIndex] = new KeyValuePair(HeaderNames.WWWAuthenticate, _headers._WWWAuthenticate); ++arrayIndex; } if ((_bits & 0x100000000L) != 0) @@ -12445,7 +13109,7 @@ protected override bool CopyToFast(KeyValuePair[] array, i { return false; } - array[arrayIndex] = new KeyValuePair(HeaderNames.AccessControlAllowHeaders, _headers._AccessControlAllowHeaders); + array[arrayIndex] = new KeyValuePair(HeaderNames.AccessControlAllowCredentials, _headers._AccessControlAllowCredentials); ++arrayIndex; } if ((_bits & 0x200000000L) != 0) @@ -12454,7 +13118,7 @@ protected override bool CopyToFast(KeyValuePair[] array, i { return false; } - array[arrayIndex] = new KeyValuePair(HeaderNames.AccessControlAllowMethods, _headers._AccessControlAllowMethods); + array[arrayIndex] = new KeyValuePair(HeaderNames.AccessControlAllowHeaders, _headers._AccessControlAllowHeaders); ++arrayIndex; } if ((_bits & 0x400000000L) != 0) @@ -12463,7 +13127,7 @@ protected override bool CopyToFast(KeyValuePair[] array, i { return false; } - array[arrayIndex] = new KeyValuePair(HeaderNames.AccessControlAllowOrigin, _headers._AccessControlAllowOrigin); + array[arrayIndex] = new KeyValuePair(HeaderNames.AccessControlAllowMethods, _headers._AccessControlAllowMethods); ++arrayIndex; } if ((_bits & 0x800000000L) != 0) @@ -12472,10 +13136,19 @@ protected override bool CopyToFast(KeyValuePair[] array, i { return false; } - array[arrayIndex] = new KeyValuePair(HeaderNames.AccessControlExposeHeaders, _headers._AccessControlExposeHeaders); + array[arrayIndex] = new KeyValuePair(HeaderNames.AccessControlAllowOrigin, _headers._AccessControlAllowOrigin); ++arrayIndex; } if ((_bits & 0x1000000000L) != 0) + { + if (arrayIndex == array.Length) + { + return false; + } + array[arrayIndex] = new KeyValuePair(HeaderNames.AccessControlExposeHeaders, _headers._AccessControlExposeHeaders); + ++arrayIndex; + } + if ((_bits & 0x2000000000L) != 0) { if (arrayIndex == array.Length) { @@ -12558,9 +13231,9 @@ internal unsafe void CopyToFast(ref BufferWriter output) } goto case 3; case 3: // Header: "Server" - if ((tempBits & 0x8000000L) != 0) + if ((tempBits & 0x10000000L) != 0) { - tempBits ^= 0x8000000L; + tempBits ^= 0x10000000L; if (_headers._rawServer != null) { output.Write(_headers._rawServer); @@ -12568,7 +13241,7 @@ internal unsafe void CopyToFast(ref BufferWriter output) else { values = ref _headers._Server; - keyStart = 378; + keyStart = 398; keyLength = 10; next = 4; break; // OutputHeader @@ -12579,7 +13252,7 @@ internal unsafe void CopyToFast(ref BufferWriter output) if ((tempBits & 0x8000000000000000L) != 0) { tempBits ^= 0x8000000000000000L; - output.Write(HeaderBytes.Slice(620, 18)); + output.Write(HeaderBytes.Slice(640, 18)); output.WriteNumeric((ulong)ContentLength.Value); if (tempBits == 0) { @@ -12847,113 +13520,124 @@ internal unsafe void CopyToFast(ref BufferWriter output) break; // OutputHeader } goto case 28; - case 28: // Header: "Retry-After" + case 28: // Header: "Proxy-Connection" if ((tempBits & 0x4000000L) != 0) { tempBits ^= 0x4000000L; - values = ref _headers._RetryAfter; + values = ref _headers._ProxyConnection; keyStart = 363; - keyLength = 15; + keyLength = 20; next = 29; break; // OutputHeader } goto case 29; - case 29: // Header: "Set-Cookie" - if ((tempBits & 0x10000000L) != 0) + case 29: // Header: "Retry-After" + if ((tempBits & 0x8000000L) != 0) { - tempBits ^= 0x10000000L; - values = ref _headers._SetCookie; - keyStart = 388; - keyLength = 14; + tempBits ^= 0x8000000L; + values = ref _headers._RetryAfter; + keyStart = 383; + keyLength = 15; next = 30; break; // OutputHeader } goto case 30; - case 30: // Header: "Vary" + case 30: // Header: "Set-Cookie" if ((tempBits & 0x20000000L) != 0) { tempBits ^= 0x20000000L; - values = ref _headers._Vary; - keyStart = 402; - keyLength = 8; + values = ref _headers._SetCookie; + keyStart = 408; + keyLength = 14; next = 31; break; // OutputHeader } goto case 31; - case 31: // Header: "WWW-Authenticate" + case 31: // Header: "Vary" if ((tempBits & 0x40000000L) != 0) { tempBits ^= 0x40000000L; - values = ref _headers._WWWAuthenticate; - keyStart = 410; - keyLength = 20; + values = ref _headers._Vary; + keyStart = 422; + keyLength = 8; next = 32; break; // OutputHeader } goto case 32; - case 32: // Header: "Access-Control-Allow-Credentials" + case 32: // Header: "WWW-Authenticate" if ((tempBits & 0x80000000L) != 0) { tempBits ^= 0x80000000L; - values = ref _headers._AccessControlAllowCredentials; + values = ref _headers._WWWAuthenticate; keyStart = 430; - keyLength = 36; + keyLength = 20; next = 33; break; // OutputHeader } goto case 33; - case 33: // Header: "Access-Control-Allow-Headers" + case 33: // Header: "Access-Control-Allow-Credentials" if ((tempBits & 0x100000000L) != 0) { tempBits ^= 0x100000000L; - values = ref _headers._AccessControlAllowHeaders; - keyStart = 466; - keyLength = 32; + values = ref _headers._AccessControlAllowCredentials; + keyStart = 450; + keyLength = 36; next = 34; break; // OutputHeader } goto case 34; - case 34: // Header: "Access-Control-Allow-Methods" + case 34: // Header: "Access-Control-Allow-Headers" if ((tempBits & 0x200000000L) != 0) { tempBits ^= 0x200000000L; - values = ref _headers._AccessControlAllowMethods; - keyStart = 498; + values = ref _headers._AccessControlAllowHeaders; + keyStart = 486; keyLength = 32; next = 35; break; // OutputHeader } goto case 35; - case 35: // Header: "Access-Control-Allow-Origin" + case 35: // Header: "Access-Control-Allow-Methods" if ((tempBits & 0x400000000L) != 0) { tempBits ^= 0x400000000L; - values = ref _headers._AccessControlAllowOrigin; - keyStart = 530; - keyLength = 31; + values = ref _headers._AccessControlAllowMethods; + keyStart = 518; + keyLength = 32; next = 36; break; // OutputHeader } goto case 36; - case 36: // Header: "Access-Control-Expose-Headers" + case 36: // Header: "Access-Control-Allow-Origin" if ((tempBits & 0x800000000L) != 0) { tempBits ^= 0x800000000L; - values = ref _headers._AccessControlExposeHeaders; - keyStart = 561; - keyLength = 33; + values = ref _headers._AccessControlAllowOrigin; + keyStart = 550; + keyLength = 31; next = 37; break; // OutputHeader } goto case 37; - case 37: // Header: "Access-Control-Max-Age" + case 37: // Header: "Access-Control-Expose-Headers" if ((tempBits & 0x1000000000L) != 0) { tempBits ^= 0x1000000000L; + values = ref _headers._AccessControlExposeHeaders; + keyStart = 581; + keyLength = 33; + next = 38; + break; // OutputHeader + } + goto case 38; + case 38: // Header: "Access-Control-Max-Age" + if ((tempBits & 0x2000000000L) != 0) + { + tempBits ^= 0x2000000000L; values = ref _headers._AccessControlMaxAge; - keyStart = 594; + keyStart = 614; keyLength = 26; - next = 38; + next = 39; break; // OutputHeader } return; @@ -13006,6 +13690,7 @@ private struct HeaderReferences public StringValues _ETag; public StringValues _Location; public StringValues _ProxyAuthenticate; + public StringValues _ProxyConnection; public StringValues _RetryAfter; public StringValues _Server; public StringValues _SetCookie; @@ -13084,28 +13769,30 @@ public bool MoveNext() case 25: goto HeaderProxyAuthenticate; case 26: - goto HeaderRetryAfter; + goto HeaderProxyConnection; case 27: - goto HeaderServer; + goto HeaderRetryAfter; case 28: - goto HeaderSetCookie; + goto HeaderServer; case 29: - goto HeaderVary; + goto HeaderSetCookie; case 30: - goto HeaderWWWAuthenticate; + goto HeaderVary; case 31: - goto HeaderAccessControlAllowCredentials; + goto HeaderWWWAuthenticate; case 32: - goto HeaderAccessControlAllowHeaders; + goto HeaderAccessControlAllowCredentials; case 33: - goto HeaderAccessControlAllowMethods; + goto HeaderAccessControlAllowHeaders; case 34: - goto HeaderAccessControlAllowOrigin; + goto HeaderAccessControlAllowMethods; case 35: - goto HeaderAccessControlExposeHeaders; + goto HeaderAccessControlAllowOrigin; case 36: - goto HeaderAccessControlMaxAge; + goto HeaderAccessControlExposeHeaders; case 37: + goto HeaderAccessControlMaxAge; + case 38: goto HeaderContentLength; default: goto ExtraHeaders; @@ -13319,100 +14006,108 @@ public bool MoveNext() _next = 26; return true; } - HeaderRetryAfter: // case 26 + HeaderProxyConnection: // case 26 if ((_bits & 0x4000000L) != 0) { - _current = new KeyValuePair(HeaderNames.RetryAfter, _collection._headers._RetryAfter); - _currentKnownType = KnownHeaderType.RetryAfter; + _current = new KeyValuePair(HeaderNames.ProxyConnection, _collection._headers._ProxyConnection); + _currentKnownType = KnownHeaderType.ProxyConnection; _next = 27; return true; } - HeaderServer: // case 27 + HeaderRetryAfter: // case 27 if ((_bits & 0x8000000L) != 0) { - _current = new KeyValuePair(HeaderNames.Server, _collection._headers._Server); - _currentKnownType = KnownHeaderType.Server; + _current = new KeyValuePair(HeaderNames.RetryAfter, _collection._headers._RetryAfter); + _currentKnownType = KnownHeaderType.RetryAfter; _next = 28; return true; } - HeaderSetCookie: // case 28 + HeaderServer: // case 28 if ((_bits & 0x10000000L) != 0) { - _current = new KeyValuePair(HeaderNames.SetCookie, _collection._headers._SetCookie); - _currentKnownType = KnownHeaderType.SetCookie; + _current = new KeyValuePair(HeaderNames.Server, _collection._headers._Server); + _currentKnownType = KnownHeaderType.Server; _next = 29; return true; } - HeaderVary: // case 29 + HeaderSetCookie: // case 29 if ((_bits & 0x20000000L) != 0) { - _current = new KeyValuePair(HeaderNames.Vary, _collection._headers._Vary); - _currentKnownType = KnownHeaderType.Vary; + _current = new KeyValuePair(HeaderNames.SetCookie, _collection._headers._SetCookie); + _currentKnownType = KnownHeaderType.SetCookie; _next = 30; return true; } - HeaderWWWAuthenticate: // case 30 + HeaderVary: // case 30 if ((_bits & 0x40000000L) != 0) { - _current = new KeyValuePair(HeaderNames.WWWAuthenticate, _collection._headers._WWWAuthenticate); - _currentKnownType = KnownHeaderType.WWWAuthenticate; + _current = new KeyValuePair(HeaderNames.Vary, _collection._headers._Vary); + _currentKnownType = KnownHeaderType.Vary; _next = 31; return true; } - HeaderAccessControlAllowCredentials: // case 31 + HeaderWWWAuthenticate: // case 31 if ((_bits & 0x80000000L) != 0) { - _current = new KeyValuePair(HeaderNames.AccessControlAllowCredentials, _collection._headers._AccessControlAllowCredentials); - _currentKnownType = KnownHeaderType.AccessControlAllowCredentials; + _current = new KeyValuePair(HeaderNames.WWWAuthenticate, _collection._headers._WWWAuthenticate); + _currentKnownType = KnownHeaderType.WWWAuthenticate; _next = 32; return true; } - HeaderAccessControlAllowHeaders: // case 32 + HeaderAccessControlAllowCredentials: // case 32 if ((_bits & 0x100000000L) != 0) { - _current = new KeyValuePair(HeaderNames.AccessControlAllowHeaders, _collection._headers._AccessControlAllowHeaders); - _currentKnownType = KnownHeaderType.AccessControlAllowHeaders; + _current = new KeyValuePair(HeaderNames.AccessControlAllowCredentials, _collection._headers._AccessControlAllowCredentials); + _currentKnownType = KnownHeaderType.AccessControlAllowCredentials; _next = 33; return true; } - HeaderAccessControlAllowMethods: // case 33 + HeaderAccessControlAllowHeaders: // case 33 if ((_bits & 0x200000000L) != 0) { - _current = new KeyValuePair(HeaderNames.AccessControlAllowMethods, _collection._headers._AccessControlAllowMethods); - _currentKnownType = KnownHeaderType.AccessControlAllowMethods; + _current = new KeyValuePair(HeaderNames.AccessControlAllowHeaders, _collection._headers._AccessControlAllowHeaders); + _currentKnownType = KnownHeaderType.AccessControlAllowHeaders; _next = 34; return true; } - HeaderAccessControlAllowOrigin: // case 34 + HeaderAccessControlAllowMethods: // case 34 if ((_bits & 0x400000000L) != 0) { - _current = new KeyValuePair(HeaderNames.AccessControlAllowOrigin, _collection._headers._AccessControlAllowOrigin); - _currentKnownType = KnownHeaderType.AccessControlAllowOrigin; + _current = new KeyValuePair(HeaderNames.AccessControlAllowMethods, _collection._headers._AccessControlAllowMethods); + _currentKnownType = KnownHeaderType.AccessControlAllowMethods; _next = 35; return true; } - HeaderAccessControlExposeHeaders: // case 35 + HeaderAccessControlAllowOrigin: // case 35 if ((_bits & 0x800000000L) != 0) { - _current = new KeyValuePair(HeaderNames.AccessControlExposeHeaders, _collection._headers._AccessControlExposeHeaders); - _currentKnownType = KnownHeaderType.AccessControlExposeHeaders; + _current = new KeyValuePair(HeaderNames.AccessControlAllowOrigin, _collection._headers._AccessControlAllowOrigin); + _currentKnownType = KnownHeaderType.AccessControlAllowOrigin; _next = 36; return true; } - HeaderAccessControlMaxAge: // case 36 + HeaderAccessControlExposeHeaders: // case 36 if ((_bits & 0x1000000000L) != 0) + { + _current = new KeyValuePair(HeaderNames.AccessControlExposeHeaders, _collection._headers._AccessControlExposeHeaders); + _currentKnownType = KnownHeaderType.AccessControlExposeHeaders; + _next = 37; + return true; + } + HeaderAccessControlMaxAge: // case 37 + if ((_bits & 0x2000000000L) != 0) { _current = new KeyValuePair(HeaderNames.AccessControlMaxAge, _collection._headers._AccessControlMaxAge); _currentKnownType = KnownHeaderType.AccessControlMaxAge; - _next = 37; + _next = 38; return true; } - HeaderContentLength: // case 37 + HeaderContentLength: // case 38 if (_collection._contentLength.HasValue) { _current = new KeyValuePair(HeaderNames.ContentLength, HeaderUtilities.FormatNonNegativeInt64(_collection._contentLength.Value)); _currentKnownType = KnownHeaderType.ContentLength; - _next = 38; + _next = 39; return true; } ExtraHeaders: @@ -13491,6 +14186,25 @@ public StringValues HeaderGrpcStatus } } + + public void ClearETag() + { + _bits &= ~0x1L; + _headers._ETag = default; + + } + public void ClearGrpcMessage() + { + _bits &= ~0x2L; + _headers._GrpcMessage = default; + + } + public void ClearGrpcStatus() + { + _bits &= ~0x4L; + _headers._GrpcStatus = default; + + } protected override int GetCountFast() { return (_contentLength.HasValue ? 1 : 0 ) + BitOperations.PopCount((ulong)_bits) + (MaybeUnknown?.Count ?? 0); diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/HttpProtocol.cs b/src/Servers/Kestrel/Core/src/Internal/Http/HttpProtocol.cs index 9fcd26f69b63..26a0b7d03c9e 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/HttpProtocol.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/HttpProtocol.cs @@ -1088,6 +1088,21 @@ private HttpResponseHeaders CreateResponseHeaders(bool appCompleted) var hasConnection = responseHeaders.HasConnection; var hasTransferEncoding = responseHeaders.HasTransferEncoding; + // https://tools.ietf.org/html/rfc7540#section-8.1.2.2 + // Such intermediaries SHOULD also remove other connection-specific header fields, such as Keep-Alive, + // Proxy-Connection, Transfer-Encoding, and Upgrade, even if they are not nominated by the Connection header field. + if (_httpVersion > Http.HttpVersion.Http11) + { + responseHeaders.ClearTransferEncoding(); + responseHeaders.ClearConnection(); + responseHeaders.ClearKeepAlive(); + responseHeaders.ClearUpgrade(); + responseHeaders.ClearProxyConnection(); + + hasTransferEncoding = false; + hasConnection = false; + } + if (_keepAlive && hasConnection && (HttpHeaders.ParseConnection(responseHeaders.HeaderConnection) & ConnectionOptions.KeepAlive) == 0) diff --git a/src/Servers/Kestrel/shared/KnownHeaders.cs b/src/Servers/Kestrel/shared/KnownHeaders.cs index 23fa4b790487..4fabcff58549 100644 --- a/src/Servers/Kestrel/shared/KnownHeaders.cs +++ b/src/Servers/Kestrel/shared/KnownHeaders.cs @@ -159,6 +159,7 @@ static KnownHeaders() "ETag", "Location", "Proxy-Authenticate", + "Proxy-Connection", "Retry-After", "Server", "Set-Cookie", @@ -767,6 +768,13 @@ public StringValues Header{header.Identifier} _headers._{header.Identifier} = value; _headers._raw{header.Identifier} = raw; }}")} +{Each(loop.Headers.Where(header => header.Identifier != "ContentLength"), header => $@" + public void Clear{header.Identifier}() + {{ + {header.ClearBit()}; + _headers._{header.Identifier} = default; + {(header.EnhancedSetter ? $"_headers._raw{header.Identifier} = null;" : "")} + }}")} protected override int GetCountFast() {{ return (_contentLength.HasValue ? 1 : 0 ) + BitOperations.PopCount((ulong)_bits) + (MaybeUnknown?.Count ?? 0); diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2StreamTests.cs b/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2StreamTests.cs index 4106889d1ace..a019c278de1a 100644 --- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2StreamTests.cs +++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2StreamTests.cs @@ -4785,5 +4785,46 @@ await WaitForConnectionErrorAsync( expectedErrorCode: Http2ErrorCode.PROTOCOL_ERROR, expectedErrorMessage: CoreStrings.BadRequest_MalformedRequestInvalidHeaders); } + + [Fact] + public async Task RemoveConnectionSpecificHeaders() + { + await InitializeConnectionAsync(async context => + { + var response = context.Response; + + response.Headers.Add(HeaderNames.TransferEncoding, "chunked"); + response.Headers.Add(HeaderNames.Upgrade, "websocket"); + response.Headers.Add(HeaderNames.Connection, "Keep-Alive"); + response.Headers.Add(HeaderNames.KeepAlive, "timeout=5, max=1000"); + response.Headers.Add(HeaderNames.ProxyConnection, "keep-alive"); + await response.WriteAsync("hello, world"); + }); + + await StartStreamAsync(1, _browserRequestHeaders, endStream: true); + + var headersFrame = await ExpectAsync(Http2FrameType.HEADERS, + withLength: 32, + withFlags: (byte)Http2HeadersFrameFlags.END_HEADERS, + withStreamId: 1); + var dataFrame1 = await ExpectAsync(Http2FrameType.DATA, + withLength: 12, + withFlags: (byte)Http2DataFrameFlags.NONE, + withStreamId: 1); + await ExpectAsync(Http2FrameType.DATA, + withLength: 0, + withFlags: (byte)Http2DataFrameFlags.END_STREAM, + withStreamId: 1); + + await StopConnectionAsync(expectedLastStreamId: 1, ignoreNonGoAwayFrames: false); + + _hpackDecoder.Decode(headersFrame.PayloadSequence, endHeaders: false, handler: this); + + Assert.Equal(2, _decodedHeaders.Count); + Assert.Contains("date", _decodedHeaders.Keys, StringComparer.OrdinalIgnoreCase); + Assert.Equal("200", _decodedHeaders[HeaderNames.Status]); + + Assert.True(_helloWorldBytes.AsSpan().SequenceEqual(dataFrame1.PayloadSequence.ToArray())); + } } } diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http3/Http3StreamTests.cs b/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http3/Http3StreamTests.cs index 0cad7c9736b3..6be2f333405e 100644 --- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http3/Http3StreamTests.cs +++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http3/Http3StreamTests.cs @@ -4,6 +4,7 @@ using System.Net.Http; using System.Text; using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Features; using Microsoft.AspNetCore.Testing; using Microsoft.Net.Http.Headers; @@ -586,6 +587,39 @@ public async Task ContentLength_Received_MultipleDataFrame_ReadViaPipe_Verified( Assert.Equal("0", responseHeaders[HeaderNames.ContentLength]); } + [Fact] + public async Task RemoveConnectionSpecificHeaders() + { + var headers = new[] + { + new KeyValuePair(HeaderNames.Method, "Custom"), + new KeyValuePair(HeaderNames.Path, "/"), + new KeyValuePair(HeaderNames.Scheme, "http"), + new KeyValuePair(HeaderNames.Authority, "localhost:80"), + }; + + var requestStream = await InitializeConnectionAndStreamsAsync(async context => + { + var response = context.Response; + + response.Headers.Add(HeaderNames.TransferEncoding, "chunked"); + response.Headers.Add(HeaderNames.Upgrade, "websocket"); + response.Headers.Add(HeaderNames.Connection, "Keep-Alive"); + response.Headers.Add(HeaderNames.KeepAlive, "timeout=5, max=1000"); + response.Headers.Add(HeaderNames.ProxyConnection, "keep-alive"); + + await response.WriteAsync("Hello world"); + }); + + var doneWithHeaders = await requestStream.SendHeadersAsync(headers, endStream: true); + + var responseHeaders = await requestStream.ExpectHeadersAsync(); + Assert.Equal(2, responseHeaders.Count); + + var responseData = await requestStream.ExpectDataAsync(); + Assert.Equal("Hello world", Encoding.ASCII.GetString(responseData.ToArray())); + } + [Fact(Skip = "Http3OutputProducer.Complete is called before input recognizes there is an error. Why is this different than HTTP/2?")] public async Task ContentLength_Received_NoDataFrames_Reset() { From cad4c5f0f9c4063a8f78215fde4d32c193da9a1e Mon Sep 17 00:00:00 2001 From: Chris R Date: Thu, 19 Nov 2020 17:04:55 -0800 Subject: [PATCH 2/7] Log --- src/Http/Headers/src/PublicAPI.Unshipped.txt | 2 +- .../Internal/Http/HttpHeaders.Generated.cs | 3 +++ .../Core/src/Internal/Http/HttpProtocol.cs | 19 +++++++++++++++++-- .../Internal/Infrastructure/IKestrelTrace.cs | 2 ++ .../Internal/Infrastructure/KestrelTrace.cs | 9 +++++++++ .../Kestrel.Performance/Mocks/MockTrace.cs | 1 + src/Servers/Kestrel/shared/KnownHeaders.cs | 5 ++++- .../shared/test/CompositeKestrelTrace.cs | 6 ++++++ .../Http2/Http2StreamTests.cs | 2 ++ .../Http3/Http3StreamTests.cs | 2 ++ 10 files changed, 47 insertions(+), 4 deletions(-) diff --git a/src/Http/Headers/src/PublicAPI.Unshipped.txt b/src/Http/Headers/src/PublicAPI.Unshipped.txt index 556023e54c2f..916ef82d2321 100644 --- a/src/Http/Headers/src/PublicAPI.Unshipped.txt +++ b/src/Http/Headers/src/PublicAPI.Unshipped.txt @@ -1,3 +1,3 @@ #nullable enable Microsoft.Net.Http.Headers.MediaTypeHeaderValue.MatchesMediaType(Microsoft.Extensions.Primitives.StringSegment otherMediaType) -> bool - +static readonly Microsoft.Net.Http.Headers.HeaderNames.ProxyConnection -> string! 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 34d42dbf144c..b2732936051a 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/HttpHeaders.Generated.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/HttpHeaders.Generated.cs @@ -8319,7 +8319,10 @@ internal partial class HttpResponseHeaders public bool HasConnection => (_bits & 0x2L) != 0; public bool HasDate => (_bits & 0x4L) != 0; + public bool HasKeepAlive => (_bits & 0x10L) != 0; public bool HasTransferEncoding => (_bits & 0x80L) != 0; + public bool HasUpgrade => (_bits & 0x100L) != 0; + public bool HasProxyConnection => (_bits & 0x4000000L) != 0; public bool HasServer => (_bits & 0x10000000L) != 0; diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/HttpProtocol.cs b/src/Servers/Kestrel/Core/src/Internal/Http/HttpProtocol.cs index 26a0b7d03c9e..ecd7cf8844d1 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/HttpProtocol.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/HttpProtocol.cs @@ -1088,10 +1088,23 @@ private HttpResponseHeaders CreateResponseHeaders(bool appCompleted) var hasConnection = responseHeaders.HasConnection; var hasTransferEncoding = responseHeaders.HasTransferEncoding; + // We opt to remove the following headers from an HTTP/2+ response since their presence would be considered a protocol violation. + // This is done quietly because these headers are valid in other contexts and this saves the app from being broken by + // low level protocol details. Http.Sys also removes these headers silently. + // // https://tools.ietf.org/html/rfc7540#section-8.1.2.2 + // "This means that an intermediary transforming an HTTP/1.x message to HTTP/2 will need to remove any header fields + // nominated by the Connection header field, along with the Connection header field itself. // Such intermediaries SHOULD also remove other connection-specific header fields, such as Keep-Alive, - // Proxy-Connection, Transfer-Encoding, and Upgrade, even if they are not nominated by the Connection header field. - if (_httpVersion > Http.HttpVersion.Http11) + // Proxy-Connection, Transfer-Encoding, and Upgrade, even if they are not nominated by the Connection header field." + // + // Http/3 has a similar requirement: https://quicwg.org/base-drafts/draft-ietf-quic-http.html#name-field-formatting-and-compre + if (_httpVersion > Http.HttpVersion.Http11 + && (hasTransferEncoding + || hasConnection + || responseHeaders.HasKeepAlive + || responseHeaders.HasUpgrade + || responseHeaders.HasProxyConnection)) { responseHeaders.ClearTransferEncoding(); responseHeaders.ClearConnection(); @@ -1101,6 +1114,8 @@ private HttpResponseHeaders CreateResponseHeaders(bool appCompleted) hasTransferEncoding = false; hasConnection = false; + + Log.InvalidResponseHeaderRemoved(); } if (_keepAlive && diff --git a/src/Servers/Kestrel/Core/src/Internal/Infrastructure/IKestrelTrace.cs b/src/Servers/Kestrel/Core/src/Internal/Infrastructure/IKestrelTrace.cs index 72442fa9627f..b1f5dfea5335 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Infrastructure/IKestrelTrace.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Infrastructure/IKestrelTrace.cs @@ -76,5 +76,7 @@ internal interface IKestrelTrace : ILogger void Http2FrameSending(string connectionId, Http2Frame frame); void Http2MaxConcurrentStreamsReached(string connectionId); + + void InvalidResponseHeaderRemoved(); } } diff --git a/src/Servers/Kestrel/Core/src/Internal/Infrastructure/KestrelTrace.cs b/src/Servers/Kestrel/Core/src/Internal/Infrastructure/KestrelTrace.cs index 5a85007aab30..fcee7cfef6af 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Infrastructure/KestrelTrace.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Infrastructure/KestrelTrace.cs @@ -117,6 +117,10 @@ internal class KestrelTrace : IKestrelTrace LoggerMessage.Define(LogLevel.Debug, new EventId(40, nameof(Http2MaxConcurrentStreamsReached)), @"Connection id ""{ConnectionId}"" reached the maximum number of concurrent HTTP/2 streams allowed."); + private static readonly Action _invalidResponseHeaderRemoved = + LoggerMessage.Define(LogLevel.Debug, new EventId(41, nameof(InvalidResponseHeaderRemoved)), + "A response header has been removed because it was invalid for the current protocol."); + protected readonly ILogger _logger; public KestrelTrace(ILogger logger) @@ -295,6 +299,11 @@ public void Http2MaxConcurrentStreamsReached(string connectionId) _http2MaxConcurrentStreamsReached(_logger, connectionId, null); } + public void InvalidResponseHeaderRemoved() + { + _invalidResponseHeaderRemoved(_logger, null); + } + public virtual void Log(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func formatter) => _logger.Log(logLevel, eventId, state, exception, formatter); diff --git a/src/Servers/Kestrel/perf/Kestrel.Performance/Mocks/MockTrace.cs b/src/Servers/Kestrel/perf/Kestrel.Performance/Mocks/MockTrace.cs index a8e1b76a9b9e..653d31d866aa 100644 --- a/src/Servers/Kestrel/perf/Kestrel.Performance/Mocks/MockTrace.cs +++ b/src/Servers/Kestrel/perf/Kestrel.Performance/Mocks/MockTrace.cs @@ -56,5 +56,6 @@ public void Http2ConnectionClosed(string connectionId, int highestOpenedStreamId public void Http2FrameReceived(string connectionId, Http2Frame frame) { } public void Http2FrameSending(string connectionId, Http2Frame frame) { } public void Http2MaxConcurrentStreamsReached(string connectionId) { } + public void InvalidResponseHeaderRemoved() { } } } diff --git a/src/Servers/Kestrel/shared/KnownHeaders.cs b/src/Servers/Kestrel/shared/KnownHeaders.cs index 4fabcff58549..a8ddb4bf6fe5 100644 --- a/src/Servers/Kestrel/shared/KnownHeaders.cs +++ b/src/Servers/Kestrel/shared/KnownHeaders.cs @@ -132,7 +132,10 @@ static KnownHeaders() "Connection", "Server", "Date", - "Transfer-Encoding" + "Transfer-Encoding", + "Keep-Alive", + "Upgrade", + "Proxy-Connection" }; var enhancedHeaders = new[] { diff --git a/src/Servers/Kestrel/shared/test/CompositeKestrelTrace.cs b/src/Servers/Kestrel/shared/test/CompositeKestrelTrace.cs index f22ebc810b14..9cdce02f8a75 100644 --- a/src/Servers/Kestrel/shared/test/CompositeKestrelTrace.cs +++ b/src/Servers/Kestrel/shared/test/CompositeKestrelTrace.cs @@ -235,5 +235,11 @@ public void Http2MaxConcurrentStreamsReached(string connectionId) _trace1.Http2MaxConcurrentStreamsReached(connectionId); _trace2.Http2MaxConcurrentStreamsReached(connectionId); } + + public void InvalidResponseHeaderRemoved() + { + _trace1.InvalidResponseHeaderRemoved(); + _trace2.InvalidResponseHeaderRemoved(); + } } } diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2StreamTests.cs b/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2StreamTests.cs index a019c278de1a..a29183ff46e5 100644 --- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2StreamTests.cs +++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2StreamTests.cs @@ -4825,6 +4825,8 @@ await ExpectAsync(Http2FrameType.DATA, Assert.Equal("200", _decodedHeaders[HeaderNames.Status]); Assert.True(_helloWorldBytes.AsSpan().SequenceEqual(dataFrame1.PayloadSequence.ToArray())); + + Assert.Contains(LogMessages, m => m.Message.Equals("A response header has been removed because it was invalid for the current protocol.")); } } } diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http3/Http3StreamTests.cs b/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http3/Http3StreamTests.cs index 6be2f333405e..d87f905654a7 100644 --- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http3/Http3StreamTests.cs +++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http3/Http3StreamTests.cs @@ -618,6 +618,8 @@ public async Task RemoveConnectionSpecificHeaders() var responseData = await requestStream.ExpectDataAsync(); Assert.Equal("Hello world", Encoding.ASCII.GetString(responseData.ToArray())); + + Assert.Contains(LogMessages, m => m.Message.Equals("A response header has been removed because it was invalid for the current protocol.")); } [Fact(Skip = "Http3OutputProducer.Complete is called before input recognizes there is an error. Why is this different than HTTP/2?")] From a106f0df5b3aff890407ef65aa686a6569a4d7df Mon Sep 17 00:00:00 2001 From: Chris R Date: Fri, 20 Nov 2020 13:55:07 -0800 Subject: [PATCH 3/7] Consolidate check --- .../Internal/Http/HttpHeaders.Generated.cs | 593 +----------------- .../Core/src/Internal/Http/HttpProtocol.cs | 16 +- src/Servers/Kestrel/shared/KnownHeaders.cs | 33 +- 3 files changed, 29 insertions(+), 613 deletions(-) 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 b2732936051a..95942ab1e1d5 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/HttpHeaders.Generated.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/HttpHeaders.Generated.cs @@ -1074,343 +1074,6 @@ public StringValues HeaderContentLength } } - - public void ClearCacheControl() - { - _bits &= ~0x1L; - _headers._CacheControl = default; - - } - public void ClearConnection() - { - _bits &= ~0x2L; - _headers._Connection = default; - - } - public void ClearDate() - { - _bits &= ~0x4L; - _headers._Date = default; - - } - public void ClearGrpcEncoding() - { - _bits &= ~0x8L; - _headers._GrpcEncoding = default; - - } - public void ClearKeepAlive() - { - _bits &= ~0x10L; - _headers._KeepAlive = default; - - } - public void ClearPragma() - { - _bits &= ~0x20L; - _headers._Pragma = default; - - } - public void ClearTrailer() - { - _bits &= ~0x40L; - _headers._Trailer = default; - - } - public void ClearTransferEncoding() - { - _bits &= ~0x80L; - _headers._TransferEncoding = default; - - } - public void ClearUpgrade() - { - _bits &= ~0x100L; - _headers._Upgrade = default; - - } - public void ClearVia() - { - _bits &= ~0x200L; - _headers._Via = default; - - } - public void ClearWarning() - { - _bits &= ~0x400L; - _headers._Warning = default; - - } - public void ClearAllow() - { - _bits &= ~0x800L; - _headers._Allow = default; - - } - public void ClearContentType() - { - _bits &= ~0x1000L; - _headers._ContentType = default; - - } - public void ClearContentEncoding() - { - _bits &= ~0x2000L; - _headers._ContentEncoding = default; - - } - public void ClearContentLanguage() - { - _bits &= ~0x4000L; - _headers._ContentLanguage = default; - - } - public void ClearContentLocation() - { - _bits &= ~0x8000L; - _headers._ContentLocation = default; - - } - public void ClearContentMD5() - { - _bits &= ~0x10000L; - _headers._ContentMD5 = default; - - } - public void ClearContentRange() - { - _bits &= ~0x20000L; - _headers._ContentRange = default; - - } - public void ClearExpires() - { - _bits &= ~0x40000L; - _headers._Expires = default; - - } - public void ClearLastModified() - { - _bits &= ~0x80000L; - _headers._LastModified = default; - - } - public void ClearAuthority() - { - _bits &= ~0x100000L; - _headers._Authority = default; - - } - public void ClearMethod() - { - _bits &= ~0x200000L; - _headers._Method = default; - - } - public void ClearPath() - { - _bits &= ~0x400000L; - _headers._Path = default; - - } - public void ClearScheme() - { - _bits &= ~0x800000L; - _headers._Scheme = default; - - } - public void ClearAccept() - { - _bits &= ~0x1000000L; - _headers._Accept = default; - - } - public void ClearAcceptCharset() - { - _bits &= ~0x2000000L; - _headers._AcceptCharset = default; - - } - public void ClearAcceptEncoding() - { - _bits &= ~0x4000000L; - _headers._AcceptEncoding = default; - - } - public void ClearAcceptLanguage() - { - _bits &= ~0x8000000L; - _headers._AcceptLanguage = default; - - } - public void ClearAuthorization() - { - _bits &= ~0x10000000L; - _headers._Authorization = default; - - } - public void ClearCookie() - { - _bits &= ~0x20000000L; - _headers._Cookie = default; - - } - public void ClearExpect() - { - _bits &= ~0x40000000L; - _headers._Expect = default; - - } - public void ClearFrom() - { - _bits &= ~0x80000000L; - _headers._From = default; - - } - public void ClearGrpcAcceptEncoding() - { - _bits &= ~0x100000000L; - _headers._GrpcAcceptEncoding = default; - - } - public void ClearGrpcTimeout() - { - _bits &= ~0x200000000L; - _headers._GrpcTimeout = default; - - } - public void ClearHost() - { - _bits &= ~0x400000000L; - _headers._Host = default; - - } - public void ClearIfMatch() - { - _bits &= ~0x800000000L; - _headers._IfMatch = default; - - } - public void ClearIfModifiedSince() - { - _bits &= ~0x1000000000L; - _headers._IfModifiedSince = default; - - } - public void ClearIfNoneMatch() - { - _bits &= ~0x2000000000L; - _headers._IfNoneMatch = default; - - } - public void ClearIfRange() - { - _bits &= ~0x4000000000L; - _headers._IfRange = default; - - } - public void ClearIfUnmodifiedSince() - { - _bits &= ~0x8000000000L; - _headers._IfUnmodifiedSince = default; - - } - public void ClearMaxForwards() - { - _bits &= ~0x10000000000L; - _headers._MaxForwards = default; - - } - public void ClearProxyAuthorization() - { - _bits &= ~0x20000000000L; - _headers._ProxyAuthorization = default; - - } - public void ClearReferer() - { - _bits &= ~0x40000000000L; - _headers._Referer = default; - - } - public void ClearRange() - { - _bits &= ~0x80000000000L; - _headers._Range = default; - - } - public void ClearTE() - { - _bits &= ~0x100000000000L; - _headers._TE = default; - - } - public void ClearTranslate() - { - _bits &= ~0x200000000000L; - _headers._Translate = default; - - } - public void ClearUserAgent() - { - _bits &= ~0x400000000000L; - _headers._UserAgent = default; - - } - public void ClearDNT() - { - _bits &= ~0x800000000000L; - _headers._DNT = default; - - } - public void ClearUpgradeInsecureRequests() - { - _bits &= ~0x1000000000000L; - _headers._UpgradeInsecureRequests = default; - - } - public void ClearRequestId() - { - _bits &= ~0x2000000000000L; - _headers._RequestId = default; - - } - public void ClearCorrelationContext() - { - _bits &= ~0x4000000000000L; - _headers._CorrelationContext = default; - - } - public void ClearTraceParent() - { - _bits &= ~0x8000000000000L; - _headers._TraceParent = default; - - } - public void ClearTraceState() - { - _bits &= ~0x10000000000000L; - _headers._TraceState = default; - - } - public void ClearOrigin() - { - _bits &= ~0x20000000000000L; - _headers._Origin = default; - - } - public void ClearAccessControlRequestMethod() - { - _bits &= ~0x40000000000000L; - _headers._AccessControlRequestMethod = default; - - } - public void ClearAccessControlRequestHeaders() - { - _bits &= ~0x80000000000000L; - _headers._AccessControlRequestHeaders = default; - - } protected override int GetCountFast() { return (_contentLength.HasValue ? 1 : 0 ) + BitOperations.PopCount((ulong)_bits) + (MaybeUnknown?.Count ?? 0); @@ -8319,10 +7982,7 @@ internal partial class HttpResponseHeaders public bool HasConnection => (_bits & 0x2L) != 0; public bool HasDate => (_bits & 0x4L) != 0; - public bool HasKeepAlive => (_bits & 0x10L) != 0; public bool HasTransferEncoding => (_bits & 0x80L) != 0; - public bool HasUpgrade => (_bits & 0x100L) != 0; - public bool HasProxyConnection => (_bits & 0x4000000L) != 0; public bool HasServer => (_bits & 0x10000000L) != 0; @@ -9017,235 +8677,6 @@ public void SetRawServer(StringValues value, byte[] raw) _headers._Server = value; _headers._rawServer = raw; } - - public void ClearCacheControl() - { - _bits &= ~0x1L; - _headers._CacheControl = default; - - } - public void ClearConnection() - { - _bits &= ~0x2L; - _headers._Connection = default; - _headers._rawConnection = null; - } - public void ClearDate() - { - _bits &= ~0x4L; - _headers._Date = default; - _headers._rawDate = null; - } - public void ClearGrpcEncoding() - { - _bits &= ~0x8L; - _headers._GrpcEncoding = default; - - } - public void ClearKeepAlive() - { - _bits &= ~0x10L; - _headers._KeepAlive = default; - - } - public void ClearPragma() - { - _bits &= ~0x20L; - _headers._Pragma = default; - - } - public void ClearTrailer() - { - _bits &= ~0x40L; - _headers._Trailer = default; - - } - public void ClearTransferEncoding() - { - _bits &= ~0x80L; - _headers._TransferEncoding = default; - _headers._rawTransferEncoding = null; - } - public void ClearUpgrade() - { - _bits &= ~0x100L; - _headers._Upgrade = default; - - } - public void ClearVia() - { - _bits &= ~0x200L; - _headers._Via = default; - - } - public void ClearWarning() - { - _bits &= ~0x400L; - _headers._Warning = default; - - } - public void ClearAllow() - { - _bits &= ~0x800L; - _headers._Allow = default; - - } - public void ClearContentType() - { - _bits &= ~0x1000L; - _headers._ContentType = default; - - } - public void ClearContentEncoding() - { - _bits &= ~0x2000L; - _headers._ContentEncoding = default; - - } - public void ClearContentLanguage() - { - _bits &= ~0x4000L; - _headers._ContentLanguage = default; - - } - public void ClearContentLocation() - { - _bits &= ~0x8000L; - _headers._ContentLocation = default; - - } - public void ClearContentMD5() - { - _bits &= ~0x10000L; - _headers._ContentMD5 = default; - - } - public void ClearContentRange() - { - _bits &= ~0x20000L; - _headers._ContentRange = default; - - } - public void ClearExpires() - { - _bits &= ~0x40000L; - _headers._Expires = default; - - } - public void ClearLastModified() - { - _bits &= ~0x80000L; - _headers._LastModified = default; - - } - public void ClearAcceptRanges() - { - _bits &= ~0x100000L; - _headers._AcceptRanges = default; - - } - public void ClearAge() - { - _bits &= ~0x200000L; - _headers._Age = default; - - } - public void ClearAltSvc() - { - _bits &= ~0x400000L; - _headers._AltSvc = default; - - } - public void ClearETag() - { - _bits &= ~0x800000L; - _headers._ETag = default; - - } - public void ClearLocation() - { - _bits &= ~0x1000000L; - _headers._Location = default; - - } - public void ClearProxyAuthenticate() - { - _bits &= ~0x2000000L; - _headers._ProxyAuthenticate = default; - - } - public void ClearProxyConnection() - { - _bits &= ~0x4000000L; - _headers._ProxyConnection = default; - - } - public void ClearRetryAfter() - { - _bits &= ~0x8000000L; - _headers._RetryAfter = default; - - } - public void ClearServer() - { - _bits &= ~0x10000000L; - _headers._Server = default; - _headers._rawServer = null; - } - public void ClearSetCookie() - { - _bits &= ~0x20000000L; - _headers._SetCookie = default; - - } - public void ClearVary() - { - _bits &= ~0x40000000L; - _headers._Vary = default; - - } - public void ClearWWWAuthenticate() - { - _bits &= ~0x80000000L; - _headers._WWWAuthenticate = default; - - } - public void ClearAccessControlAllowCredentials() - { - _bits &= ~0x100000000L; - _headers._AccessControlAllowCredentials = default; - - } - public void ClearAccessControlAllowHeaders() - { - _bits &= ~0x200000000L; - _headers._AccessControlAllowHeaders = default; - - } - public void ClearAccessControlAllowMethods() - { - _bits &= ~0x400000000L; - _headers._AccessControlAllowMethods = default; - - } - public void ClearAccessControlAllowOrigin() - { - _bits &= ~0x800000000L; - _headers._AccessControlAllowOrigin = default; - - } - public void ClearAccessControlExposeHeaders() - { - _bits &= ~0x1000000000L; - _headers._AccessControlExposeHeaders = default; - - } - public void ClearAccessControlMaxAge() - { - _bits &= ~0x2000000000L; - _headers._AccessControlMaxAge = default; - - } protected override int GetCountFast() { return (_contentLength.HasValue ? 1 : 0 ) + BitOperations.PopCount((ulong)_bits) + (MaybeUnknown?.Count ?? 0); @@ -13174,6 +12605,11 @@ protected override bool CopyToFast(KeyValuePair[] array, i return true; } + internal bool HasInvalidH2H3Headers => (_bits & 67109266) != 0; + internal void ClearInvalidH2H3Headers() + { + _bits &= ~67109266; + } internal unsafe void CopyToFast(ref BufferWriter output) { var tempBits = (ulong)_bits | (_contentLength.HasValue ? 0x8000000000000000L : 0); @@ -14189,25 +13625,6 @@ public StringValues HeaderGrpcStatus } } - - public void ClearETag() - { - _bits &= ~0x1L; - _headers._ETag = default; - - } - public void ClearGrpcMessage() - { - _bits &= ~0x2L; - _headers._GrpcMessage = default; - - } - public void ClearGrpcStatus() - { - _bits &= ~0x4L; - _headers._GrpcStatus = default; - - } protected override int GetCountFast() { return (_contentLength.HasValue ? 1 : 0 ) + BitOperations.PopCount((ulong)_bits) + (MaybeUnknown?.Count ?? 0); diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/HttpProtocol.cs b/src/Servers/Kestrel/Core/src/Internal/Http/HttpProtocol.cs index ecd7cf8844d1..4202cc5b4180 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/HttpProtocol.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/HttpProtocol.cs @@ -1099,19 +1099,9 @@ private HttpResponseHeaders CreateResponseHeaders(bool appCompleted) // Proxy-Connection, Transfer-Encoding, and Upgrade, even if they are not nominated by the Connection header field." // // Http/3 has a similar requirement: https://quicwg.org/base-drafts/draft-ietf-quic-http.html#name-field-formatting-and-compre - if (_httpVersion > Http.HttpVersion.Http11 - && (hasTransferEncoding - || hasConnection - || responseHeaders.HasKeepAlive - || responseHeaders.HasUpgrade - || responseHeaders.HasProxyConnection)) - { - responseHeaders.ClearTransferEncoding(); - responseHeaders.ClearConnection(); - responseHeaders.ClearKeepAlive(); - responseHeaders.ClearUpgrade(); - responseHeaders.ClearProxyConnection(); - + if (_httpVersion > Http.HttpVersion.Http11 && responseHeaders.HasInvalidH2H3Headers) + { + responseHeaders.ClearInvalidH2H3Headers(); hasTransferEncoding = false; hasConnection = false; diff --git a/src/Servers/Kestrel/shared/KnownHeaders.cs b/src/Servers/Kestrel/shared/KnownHeaders.cs index a8ddb4bf6fe5..176108eca8b4 100644 --- a/src/Servers/Kestrel/shared/KnownHeaders.cs +++ b/src/Servers/Kestrel/shared/KnownHeaders.cs @@ -8,7 +8,6 @@ using System.Linq; using System.Net.Http.HPack; using System.Text; -using Microsoft.Net.Http.Headers; namespace CodeGenerator { @@ -17,6 +16,7 @@ public class KnownHeaders public readonly static KnownHeader[] RequestHeaders; public readonly static KnownHeader[] ResponseHeaders; public readonly static KnownHeader[] ResponseTrailers; + public readonly static long InvalidH2H3ResponseHeadersBits; static KnownHeaders() { @@ -132,10 +132,7 @@ static KnownHeaders() "Connection", "Server", "Date", - "Transfer-Encoding", - "Keep-Alive", - "Upgrade", - "Proxy-Connection" + "Transfer-Encoding" }; var enhancedHeaders = new[] { @@ -202,6 +199,20 @@ static KnownHeaders() PrimaryHeader = responsePrimaryHeaders.Contains(header) }) .ToArray(); + + var invalidH2H3ResponseHeaders = new[] + { + "Connection", + "Transfer-Encoding", + "Keep-Alive", + "Upgrade", + "Proxy-Connection" + }; + + InvalidH2H3ResponseHeadersBits = ResponseHeaders + .Where(header => invalidH2H3ResponseHeaders.Contains(header.Name)) + .Select(header => 1L << header.Index) + .Aggregate((a, b) => a | b); } static string Each(IEnumerable values, Func formatter) @@ -771,13 +782,6 @@ public StringValues Header{header.Identifier} _headers._{header.Identifier} = value; _headers._raw{header.Identifier} = raw; }}")} -{Each(loop.Headers.Where(header => header.Identifier != "ContentLength"), header => $@" - public void Clear{header.Identifier}() - {{ - {header.ClearBit()}; - _headers._{header.Identifier} = default; - {(header.EnhancedSetter ? $"_headers._raw{header.Identifier} = null;" : "")} - }}")} protected override int GetCountFast() {{ return (_contentLength.HasValue ? 1 : 0 ) + BitOperations.PopCount((ulong)_bits) + (MaybeUnknown?.Count ?? 0); @@ -1026,6 +1030,11 @@ protected override bool CopyToFast(KeyValuePair[] array, i return true; }} {(loop.ClassName == "HttpResponseHeaders" ? $@" + internal bool HasInvalidH2H3Headers => (_bits & {InvalidH2H3ResponseHeadersBits}) != 0; + internal void ClearInvalidH2H3Headers() + {{ + _bits &= ~{InvalidH2H3ResponseHeadersBits}; + }} internal unsafe void CopyToFast(ref BufferWriter output) {{ var tempBits = (ulong)_bits | (_contentLength.HasValue ? {"0x" + (1L << 63).ToString("x" , CultureInfo.InvariantCulture)}L : 0); From a11da61d8f190f222c557cce1b853fee41a614f3 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Mon, 23 Nov 2020 21:46:34 -0800 Subject: [PATCH 4/7] Apply suggestions from code review Co-authored-by: Stephen Halter --- .../Kestrel/Core/src/Internal/Infrastructure/KestrelTrace.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Servers/Kestrel/Core/src/Internal/Infrastructure/KestrelTrace.cs b/src/Servers/Kestrel/Core/src/Internal/Infrastructure/KestrelTrace.cs index fcee7cfef6af..d865e495f91d 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Infrastructure/KestrelTrace.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Infrastructure/KestrelTrace.cs @@ -118,8 +118,8 @@ internal class KestrelTrace : IKestrelTrace @"Connection id ""{ConnectionId}"" reached the maximum number of concurrent HTTP/2 streams allowed."); private static readonly Action _invalidResponseHeaderRemoved = - LoggerMessage.Define(LogLevel.Debug, new EventId(41, nameof(InvalidResponseHeaderRemoved)), - "A response header has been removed because it was invalid for the current protocol."); + LoggerMessage.Define(LogLevel.Information, new EventId(41, nameof(InvalidResponseHeaderRemoved)), + "One or more of the following response headers have been removed because they are invalid for HTTP/2 and HTTP/3 responses: 'Connection', 'Transfer-Encoding', 'Keep-Alive', 'Upgrade' and 'Proxy-Connection'."); protected readonly ILogger _logger; From ccfe73a0ea1a0f65d1f562dddf99de1ae2d5418d Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Tue, 24 Nov 2020 08:49:23 -0800 Subject: [PATCH 5/7] Update src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2StreamTests.cs --- .../test/InMemory.FunctionalTests/Http2/Http2StreamTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2StreamTests.cs b/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2StreamTests.cs index a29183ff46e5..e7bbb37bcf61 100644 --- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2StreamTests.cs +++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http2/Http2StreamTests.cs @@ -4826,7 +4826,7 @@ await ExpectAsync(Http2FrameType.DATA, Assert.True(_helloWorldBytes.AsSpan().SequenceEqual(dataFrame1.PayloadSequence.ToArray())); - Assert.Contains(LogMessages, m => m.Message.Equals("A response header has been removed because it was invalid for the current protocol.")); + Assert.Contains(LogMessages, m => m.Message.Equals("One or more of the following response headers have been removed because they are invalid for HTTP/2 and HTTP/3 responses: 'Connection', 'Transfer-Encoding', 'Keep-Alive', 'Upgrade' and 'Proxy-Connection'.")); } } } From fa1f6a9f47437178faa946fbde634c7be3c281a8 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Tue, 24 Nov 2020 08:50:10 -0800 Subject: [PATCH 6/7] Update src/Servers/Kestrel/test/InMemory.FunctionalTests/Http3/Http3StreamTests.cs --- .../test/InMemory.FunctionalTests/Http3/Http3StreamTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http3/Http3StreamTests.cs b/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http3/Http3StreamTests.cs index d87f905654a7..a2ea57cb46eb 100644 --- a/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http3/Http3StreamTests.cs +++ b/src/Servers/Kestrel/test/InMemory.FunctionalTests/Http3/Http3StreamTests.cs @@ -619,7 +619,7 @@ public async Task RemoveConnectionSpecificHeaders() var responseData = await requestStream.ExpectDataAsync(); Assert.Equal("Hello world", Encoding.ASCII.GetString(responseData.ToArray())); - Assert.Contains(LogMessages, m => m.Message.Equals("A response header has been removed because it was invalid for the current protocol.")); + Assert.Contains(LogMessages, m => m.Message.Equals("One or more of the following response headers have been removed because they are invalid for HTTP/2 and HTTP/3 responses: 'Connection', 'Transfer-Encoding', 'Keep-Alive', 'Upgrade' and 'Proxy-Connection'.")); } [Fact(Skip = "Http3OutputProducer.Complete is called before input recognizes there is an error. Why is this different than HTTP/2?")] From 97d38f870d460c339bc9f529ca2dbc4e461486d1 Mon Sep 17 00:00:00 2001 From: Chris Ross Date: Wed, 25 Nov 2020 11:54:38 -0800 Subject: [PATCH 7/7] Update src/Servers/Kestrel/Core/src/Internal/Infrastructure/KestrelTrace.cs --- .../Kestrel/Core/src/Internal/Infrastructure/KestrelTrace.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Servers/Kestrel/Core/src/Internal/Infrastructure/KestrelTrace.cs b/src/Servers/Kestrel/Core/src/Internal/Infrastructure/KestrelTrace.cs index d865e495f91d..bb0cefeaf535 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Infrastructure/KestrelTrace.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Infrastructure/KestrelTrace.cs @@ -118,7 +118,7 @@ internal class KestrelTrace : IKestrelTrace @"Connection id ""{ConnectionId}"" reached the maximum number of concurrent HTTP/2 streams allowed."); private static readonly Action _invalidResponseHeaderRemoved = - LoggerMessage.Define(LogLevel.Information, new EventId(41, nameof(InvalidResponseHeaderRemoved)), + LoggerMessage.Define(LogLevel.Warning, new EventId(41, nameof(InvalidResponseHeaderRemoved)), "One or more of the following response headers have been removed because they are invalid for HTTP/2 and HTTP/3 responses: 'Connection', 'Transfer-Encoding', 'Keep-Alive', 'Upgrade' and 'Proxy-Connection'."); protected readonly ILogger _logger;