From f5eb3dc3392b76880477f50efa1bc1388c0584ad Mon Sep 17 00:00:00 2001 From: James Newton-King Date: Wed, 26 Feb 2020 09:48:46 +1300 Subject: [PATCH] HTTP2: Fix HttpRequestHeaders no longer being pooled (#19329) --- .../Core/src/Internal/Http/HttpHeaders.Generated.cs | 4 ++-- .../Kestrel/Core/src/Internal/Http/HttpProtocol.cs | 9 +++------ .../Core/src/Internal/Http/HttpRequestHeaders.cs | 10 +++++----- src/Servers/Kestrel/shared/KnownHeaders.cs | 4 ++-- 4 files changed, 12 insertions(+), 15 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 c46e2183c5..0abb6da2a0 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/HttpHeaders.Generated.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/HttpHeaders.Generated.cs @@ -6105,7 +6105,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } // We didn't have a previous matching header value, or have already added a header, so get the string for this value. - var valueStr = value.GetRequestHeaderStringNonNullCharacters(_useLatin1); + var valueStr = value.GetRequestHeaderStringNonNullCharacters(UseLatin1); if ((_bits & flag) == 0) { // We didn't already have a header set, so add a new one. @@ -6123,7 +6123,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http // The header was not one of the "known" headers. // Convert value to string first, because passing two spans causes 8 bytes stack zeroing in // this method with rep stosd, which is slower than necessary. - var valueStr = value.GetRequestHeaderStringNonNullCharacters(_useLatin1); + var valueStr = value.GetRequestHeaderStringNonNullCharacters(UseLatin1); AppendUnknownHeaders(name, valueStr); } } diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/HttpProtocol.cs b/src/Servers/Kestrel/Core/src/Internal/Http/HttpProtocol.cs index 8ca14493dc..539c386efa 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/HttpProtocol.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/HttpProtocol.cs @@ -8,6 +8,7 @@ using System.IO; using System.IO.Pipelines; using System.Linq; using System.Net; +using System.Net.Http.Headers; using System.Runtime.CompilerServices; using System.Text; using System.Threading; @@ -81,14 +82,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http ServerOptions = ServiceContext.ServerOptions; - HttpRequestHeaders = new HttpRequestHeaders( - reuseHeaderValues: !ServerOptions.DisableStringReuse, - useLatin1: ServerOptions.Latin1RequestHeaders); - Reset(); - HttpRequestHeaders.ReuseHeaderValues = !ServerOptions.DisableStringReuse; - HttpResponseControl = this; } @@ -371,6 +366,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http ConnectionIdFeature = ConnectionId; HttpRequestHeaders.Reset(); + HttpRequestHeaders.UseLatin1 = ServerOptions.Latin1RequestHeaders; + HttpRequestHeaders.ReuseHeaderValues = !ServerOptions.DisableStringReuse; HttpResponseHeaders.Reset(); RequestHeaders = HttpRequestHeaders; ResponseHeaders = HttpResponseHeaders; diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/HttpRequestHeaders.cs b/src/Servers/Kestrel/Core/src/Internal/Http/HttpRequestHeaders.cs index 39a5ce81df..f22588078c 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/HttpRequestHeaders.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/HttpRequestHeaders.cs @@ -14,17 +14,17 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { internal sealed partial class HttpRequestHeaders : HttpHeaders { - private readonly bool _useLatin1; private long _previousBits = 0; + public bool ReuseHeaderValues { get; set; } + public bool UseLatin1 { get; set; } + public HttpRequestHeaders(bool reuseHeaderValues = true, bool useLatin1 = false) { ReuseHeaderValues = reuseHeaderValues; - _useLatin1 = useLatin1; + UseLatin1 = useLatin1; } - public bool ReuseHeaderValues { get; set; } - public void OnHeadersComplete() { var bitsToClear = _previousBits & ~_bits; @@ -83,7 +83,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http parsed < 0 || consumed != value.Length) { - BadHttpRequestException.Throw(RequestRejectionReason.InvalidContentLength, value.GetRequestHeaderStringNonNullCharacters(_useLatin1)); + BadHttpRequestException.Throw(RequestRejectionReason.InvalidContentLength, value.GetRequestHeaderStringNonNullCharacters(UseLatin1)); } _contentLength = parsed; diff --git a/src/Servers/Kestrel/shared/KnownHeaders.cs b/src/Servers/Kestrel/shared/KnownHeaders.cs index fe643020d4..179911a476 100644 --- a/src/Servers/Kestrel/shared/KnownHeaders.cs +++ b/src/Servers/Kestrel/shared/KnownHeaders.cs @@ -986,7 +986,7 @@ $@" private void Clear(long bitsToClear) }} // We didn't have a previous matching header value, or have already added a header, so get the string for this value. - var valueStr = value.GetRequestHeaderStringNonNullCharacters(_useLatin1); + var valueStr = value.GetRequestHeaderStringNonNullCharacters(UseLatin1); if ((_bits & flag) == 0) {{ // We didn't already have a header set, so add a new one. @@ -1004,7 +1004,7 @@ $@" private void Clear(long bitsToClear) // The header was not one of the ""known"" headers. // Convert value to string first, because passing two spans causes 8 bytes stack zeroing in // this method with rep stosd, which is slower than necessary. - var valueStr = value.GetRequestHeaderStringNonNullCharacters(_useLatin1); + var valueStr = value.GetRequestHeaderStringNonNullCharacters(UseLatin1); AppendUnknownHeaders(name, valueStr); }} }}" : "")}