diff --git a/src/Microsoft.AspNet.Server.Kestrel/Http/DateHeaderValueManager.cs b/src/Microsoft.AspNet.Server.Kestrel/Http/DateHeaderValueManager.cs index c471067eca..b85aaa2b1a 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Http/DateHeaderValueManager.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/Http/DateHeaderValueManager.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; +using System.Text; using System.Threading; using Microsoft.AspNet.Server.Kestrel.Infrastructure; @@ -17,6 +18,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http private readonly TimeSpan _timerInterval; private volatile string _dateValue; + private volatile bool _activeDateBytes; + private readonly byte[] _dateBytes0 = Encoding.ASCII.GetBytes("\r\nDate: DDD, dd mmm yyyy hh:mm:ss GMT"); + private readonly byte[] _dateBytes1 = Encoding.ASCII.GetBytes("\r\nDate: DDD, dd mmm yyyy hh:mm:ss GMT"); private object _timerLocker = new object(); private bool _isDisposed = false; private bool _hadRequestsSinceLastTimerTick = false; @@ -62,6 +66,12 @@ namespace Microsoft.AspNet.Server.Kestrel.Http return _dateValue ?? _systemClock.UtcNow.ToString(Constants.RFC1123DateFormat); } + public byte[] GetDateHeaderValueBytes() + { + PumpTimer(); + return _activeDateBytes ? _dateBytes0 : _dateBytes1; + } + /// /// Releases all resources used by the current instance of . /// @@ -92,6 +102,8 @@ namespace Microsoft.AspNet.Server.Kestrel.Http // here as the timer won't fire until the timer interval has passed and we want a value assigned // inline now to serve requests that occur in the meantime. _dateValue = _systemClock.UtcNow.ToString(Constants.RFC1123DateFormat); + Encoding.ASCII.GetBytes(_dateValue, 0, _dateValue.Length, !_activeDateBytes ? _dateBytes0 : _dateBytes1, "\r\nDate: ".Length); + _activeDateBytes = !_activeDateBytes; _dateValueTimer = new Timer(UpdateDateValue, state: null, dueTime: _timerInterval, period: _timerInterval); } } @@ -105,6 +117,8 @@ namespace Microsoft.AspNet.Server.Kestrel.Http // See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.18 for required format of Date header _dateValue = now.ToString(Constants.RFC1123DateFormat); + Encoding.ASCII.GetBytes(_dateValue, 0, _dateValue.Length, !_activeDateBytes ? _dateBytes0 : _dateBytes1, "\r\nDate: ".Length); + _activeDateBytes = !_activeDateBytes; if (_hadRequestsSinceLastTimerTick) { diff --git a/src/Microsoft.AspNet.Server.Kestrel/Http/Frame.cs b/src/Microsoft.AspNet.Server.Kestrel/Http/Frame.cs index 8dc2670a6a..98652050cd 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Http/Frame.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/Http/Frame.cs @@ -29,6 +29,17 @@ namespace Microsoft.AspNet.Server.Kestrel.Http private static readonly ArraySegment _emptyData = new ArraySegment(new byte[0]); private static readonly byte[] _hex = Encoding.ASCII.GetBytes("0123456789abcdef"); + private static readonly byte[] _bytesConnectionClose = Encoding.ASCII.GetBytes("\r\nConnection: close"); + private static readonly byte[] _bytesConnectionKeepAlive = Encoding.ASCII.GetBytes("\r\nConnection: keep-alive"); + private static readonly byte[] _bytesTransferEncodingChunked = Encoding.ASCII.GetBytes("\r\nTransfer-Encoding: chunked"); + private static readonly byte[] _bytesHttpVersion1_0 = Encoding.ASCII.GetBytes("HTTP/1.0 "); + private static readonly byte[] _bytesHttpVersion1_1 = Encoding.ASCII.GetBytes("HTTP/1.1 "); + private static readonly byte[] _bytesContentLengthZero = Encoding.ASCII.GetBytes("\r\nContent-Length: 0"); + private static readonly byte[] _bytesSpace = Encoding.ASCII.GetBytes(" "); + private static readonly byte[] _bytesServer = Encoding.ASCII.GetBytes("\r\nServer: Kestrel"); + private static readonly byte[] _bytesDate = Encoding.ASCII.GetBytes("Date: "); + private static readonly byte[] _bytesEndHeaders = Encoding.ASCII.GetBytes("\r\n\r\n"); + private readonly object _onStartingSync = new Object(); private readonly object _onCompletedSync = new Object(); private readonly FrameRequestHeaders _requestHeaders = new FrameRequestHeaders(); @@ -53,6 +64,8 @@ namespace Microsoft.AspNet.Server.Kestrel.Http private bool _autoChunk; private Exception _applicationException; + private HttpVersionType _httpVersion; + private readonly IPEndPoint _localEndPoint; private readonly IPEndPoint _remoteEndPoint; private readonly Action _prepareRequest; @@ -81,7 +94,37 @@ namespace Microsoft.AspNet.Server.Kestrel.Http public string RequestUri { get; set; } public string Path { get; set; } public string QueryString { get; set; } - public string HttpVersion { get; set; } + public string HttpVersion + { + get + { + if (_httpVersion == HttpVersionType.Http1_1) + { + return "HTTP/1.1"; + } + if (_httpVersion == HttpVersionType.Http1_0) + { + return "HTTP/1.0"; + } + return ""; + } + set + { + if (value == "HTTP/1.1") + { + _httpVersion = HttpVersionType.Http1_1; + } + else if (value == "HTTP/1.0") + { + _httpVersion = HttpVersionType.Http1_0; + } + else + { + _httpVersion = HttpVersionType.Unknown; + } + } + } + public IHeaderDictionary RequestHeaders { get; set; } public Stream RequestBody { get; set; } @@ -118,7 +161,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http RequestUri = null; Path = null; QueryString = null; - HttpVersion = null; + _httpVersion = HttpVersionType.Unknown; RequestHeaders = _requestHeaders; RequestBody = null; StatusCode = 200; @@ -151,8 +194,12 @@ namespace Microsoft.AspNet.Server.Kestrel.Http public void ResetResponseHeaders() { _responseHeaders.Reset(); - _responseHeaders.HeaderServer = "Kestrel"; - _responseHeaders.HeaderDate = DateHeaderValueManager.GetDateHeaderValue(); + _responseHeaders.SetRawDate( + DateHeaderValueManager.GetDateHeaderValue(), + DateHeaderValueManager.GetDateHeaderValueBytes()); + _responseHeaders.SetRawServer( + "Kestrel", + _bytesServer); } /// @@ -502,7 +549,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http if (_responseStarted) return; StringValues expect; - if (HttpVersion.Equals("HTTP/1.1") && + if (_httpVersion == HttpVersionType.Http1_1 && RequestHeaders.TryGetValue("Expect", out expect) && (expect.FirstOrDefault() ?? "").Equals("100-continue", StringComparison.OrdinalIgnoreCase)) { @@ -526,19 +573,14 @@ namespace Microsoft.AspNet.Server.Kestrel.Http await ProduceStart(immediate, appCompleted: false); } - private async Task ProduceStart(bool immediate, bool appCompleted) + private Task ProduceStart(bool immediate, bool appCompleted) { - if (_responseStarted) return; + if (_responseStarted) return TaskUtilities.CompletedTask; _responseStarted = true; - var status = ReasonPhrases.ToStatus(StatusCode, ReasonPhrase); + var statusBytes = ReasonPhrases.ToStatusBytes(StatusCode, ReasonPhrase); - var responseHeader = CreateResponseHeader(status, appCompleted); - - using (responseHeader.Item2) - { - await SocketOutput.WriteAsync(responseHeader.Item1, immediate: immediate); - } + return CreateResponseHeader(statusBytes, appCompleted, immediate); } private async Task ProduceEnd() @@ -557,7 +599,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http ReasonPhrase = null; ResetResponseHeaders(); - _responseHeaders.HeaderContentLength = "0"; + _responseHeaders.SetRawContentLength("0", _bytesContentLengthZero); } } @@ -576,58 +618,26 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } - private Tuple, IDisposable> CreateResponseHeader( - string status, - bool appCompleted) + private Task CreateResponseHeader( + byte[] statusBytes, + bool appCompleted, + bool immediate) { - var writer = new MemoryPoolTextWriter(Memory); - writer.Write(HttpVersion); - writer.Write(' '); - writer.Write(status); - writer.Write('\r'); - writer.Write('\n'); - - var hasConnection = false; - var hasTransferEncoding = false; - var hasContentLength = false; - - foreach (var header in _responseHeaders) + var memoryBlock = Memory2.Lease(); + var begin = memoryBlock.GetIterator(); + var end = begin; + if (_keepAlive) { - var isConnection = false; - if (!hasConnection && - string.Equals(header.Key, "Connection", StringComparison.OrdinalIgnoreCase)) + foreach (var connectionValue in _responseHeaders.HeaderConnection) { - hasConnection = isConnection = true; - } - else if (!hasTransferEncoding && - string.Equals(header.Key, "Transfer-Encoding", StringComparison.OrdinalIgnoreCase)) - { - hasTransferEncoding = true; - } - else if (!hasContentLength && - string.Equals(header.Key, "Content-Length", StringComparison.OrdinalIgnoreCase)) - { - hasContentLength = true; - } - - foreach (var value in header.Value) - { - writer.Write(header.Key); - writer.Write(':'); - writer.Write(' '); - writer.Write(value); - writer.Write('\r'); - writer.Write('\n'); - - if (isConnection && value.IndexOf("close", StringComparison.OrdinalIgnoreCase) != -1) + if (connectionValue.IndexOf("close", StringComparison.OrdinalIgnoreCase) != -1) { _keepAlive = false; } } - } - if (_keepAlive && !hasTransferEncoding && !hasContentLength) + if (_keepAlive && !_responseHeaders.HasTransferEncoding && !_responseHeaders.HasContentLength) { if (appCompleted) { @@ -637,15 +647,15 @@ namespace Microsoft.AspNet.Server.Kestrel.Http { // Since the app has completed and we are only now generating // the headers we can safely set the Content-Length to 0. - writer.Write("Content-Length: 0\r\n"); + _responseHeaders.SetRawContentLength("0", _bytesContentLengthZero); } } else { - if (HttpVersion == "HTTP/1.1") + if (_httpVersion == HttpVersionType.Http1_1) { _autoChunk = true; - writer.Write("Transfer-Encoding: chunked\r\n"); + _responseHeaders.SetRawTransferEncoding("chunked", _bytesTransferEncodingChunked); } else { @@ -654,21 +664,58 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } - if (_keepAlive == false && hasConnection == false && HttpVersion == "HTTP/1.1") + if (_keepAlive == false && _responseHeaders.HasConnection == false && _httpVersion == HttpVersionType.Http1_1) { - writer.Write("Connection: close\r\n\r\n"); + _responseHeaders.SetRawConnection("close", _bytesConnectionClose); } - else if (_keepAlive && hasConnection == false && HttpVersion == "HTTP/1.0") + else if (_keepAlive && _responseHeaders.HasConnection == false && _httpVersion == HttpVersionType.Http1_0) { - writer.Write("Connection: keep-alive\r\n\r\n"); + _responseHeaders.SetRawConnection("keep-alive", _bytesConnectionKeepAlive); + } + + end.CopyFrom(_httpVersion == HttpVersionType.Http1_1 ? _bytesHttpVersion1_1 : _bytesHttpVersion1_0); + end.CopyFrom(statusBytes); + _responseHeaders.CopyTo(ref end); + end.CopyFrom(_bytesEndHeaders, 0, _bytesEndHeaders.Length); + + // TODO: change this to SocketOutput.ProduceStart/ProduceComplete once that change is made + var scan = begin.Block; + while (scan.Next != null) + { + if (scan.Start != scan.End) + { + SocketOutput.WriteAsync( + new ArraySegment(scan.Array, scan.Start, scan.End - scan.Start), + false); + } + var next = scan.Next; + Memory2.Return(scan); + scan = next; + } + var writeTask = SocketOutput.WriteAsync( + new ArraySegment(scan.Array, scan.Start, scan.End - scan.Start), + immediate); + + if (writeTask.IsCompleted) + { + Memory2.Return(scan); + return TaskUtilities.CompletedTask; } else { - writer.Write('\r'); - writer.Write('\n'); + return writeTask.ContinueWith( + (t, o) => + { + var mb = (MemoryPoolBlock2)o; + mb.Pool.Return(mb); + + if (t.IsFaulted) + { + throw t.Exception; + } + }, + scan); } - writer.Flush(); - return new Tuple, IDisposable>(writer.Buffer, writer); } private bool TakeStartLine(SocketInput input) @@ -877,5 +924,12 @@ namespace Microsoft.AspNet.Server.Kestrel.Http _applicationException = ex; Log.ApplicationError(ex); } + + private enum HttpVersionType + { + Unknown = -1, + Http1_0 = 0, + Http1_1 = 1 + } } } diff --git a/src/Microsoft.AspNet.Server.Kestrel/Http/FrameHeaders.Generated.cs b/src/Microsoft.AspNet.Server.Kestrel/Http/FrameHeaders.Generated.cs index 1b4415b5a9..5571e9c56b 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Http/FrameHeaders.Generated.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/Http/FrameHeaders.Generated.cs @@ -1,13 +1,16 @@ using System; using System.Collections.Generic; +using System.Text; +using Microsoft.AspNet.Server.Kestrel.Infrastructure; using Microsoft.Extensions.Primitives; namespace Microsoft.AspNet.Server.Kestrel.Http { - public partial class FrameRequestHeaders + public partial class FrameRequestHeaders { + private long _bits = 0; private StringValues _CacheControl; @@ -52,6 +55,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http private StringValues _Translate; private StringValues _UserAgent; + public StringValues HeaderCacheControl { get @@ -61,10 +65,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 1L; - _CacheControl = value; + _CacheControl = value; } } - public StringValues HeaderConnection { get @@ -74,10 +77,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 2L; - _Connection = value; + _Connection = value; } } - public StringValues HeaderDate { get @@ -87,10 +89,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 4L; - _Date = value; + _Date = value; } } - public StringValues HeaderKeepAlive { get @@ -100,10 +101,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 8L; - _KeepAlive = value; + _KeepAlive = value; } } - public StringValues HeaderPragma { get @@ -113,10 +113,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 16L; - _Pragma = value; + _Pragma = value; } } - public StringValues HeaderTrailer { get @@ -126,10 +125,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 32L; - _Trailer = value; + _Trailer = value; } } - public StringValues HeaderTransferEncoding { get @@ -139,10 +137,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 64L; - _TransferEncoding = value; + _TransferEncoding = value; } } - public StringValues HeaderUpgrade { get @@ -152,10 +149,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 128L; - _Upgrade = value; + _Upgrade = value; } } - public StringValues HeaderVia { get @@ -165,10 +161,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 256L; - _Via = value; + _Via = value; } } - public StringValues HeaderWarning { get @@ -178,10 +173,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 512L; - _Warning = value; + _Warning = value; } } - public StringValues HeaderAllow { get @@ -191,10 +185,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 1024L; - _Allow = value; + _Allow = value; } } - public StringValues HeaderContentLength { get @@ -204,10 +197,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 2048L; - _ContentLength = value; + _ContentLength = value; } } - public StringValues HeaderContentType { get @@ -217,10 +209,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 4096L; - _ContentType = value; + _ContentType = value; } } - public StringValues HeaderContentEncoding { get @@ -230,10 +221,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 8192L; - _ContentEncoding = value; + _ContentEncoding = value; } } - public StringValues HeaderContentLanguage { get @@ -243,10 +233,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 16384L; - _ContentLanguage = value; + _ContentLanguage = value; } } - public StringValues HeaderContentLocation { get @@ -256,10 +245,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 32768L; - _ContentLocation = value; + _ContentLocation = value; } } - public StringValues HeaderContentMD5 { get @@ -269,10 +257,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 65536L; - _ContentMD5 = value; + _ContentMD5 = value; } } - public StringValues HeaderContentRange { get @@ -282,10 +269,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 131072L; - _ContentRange = value; + _ContentRange = value; } } - public StringValues HeaderExpires { get @@ -295,10 +281,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 262144L; - _Expires = value; + _Expires = value; } } - public StringValues HeaderLastModified { get @@ -308,10 +293,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 524288L; - _LastModified = value; + _LastModified = value; } } - public StringValues HeaderAccept { get @@ -321,10 +305,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 1048576L; - _Accept = value; + _Accept = value; } } - public StringValues HeaderAcceptCharset { get @@ -334,10 +317,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 2097152L; - _AcceptCharset = value; + _AcceptCharset = value; } } - public StringValues HeaderAcceptEncoding { get @@ -347,10 +329,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 4194304L; - _AcceptEncoding = value; + _AcceptEncoding = value; } } - public StringValues HeaderAcceptLanguage { get @@ -360,10 +341,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 8388608L; - _AcceptLanguage = value; + _AcceptLanguage = value; } } - public StringValues HeaderAuthorization { get @@ -373,10 +353,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 16777216L; - _Authorization = value; + _Authorization = value; } } - public StringValues HeaderCookie { get @@ -386,10 +365,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 33554432L; - _Cookie = value; + _Cookie = value; } } - public StringValues HeaderExpect { get @@ -399,10 +377,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 67108864L; - _Expect = value; + _Expect = value; } } - public StringValues HeaderFrom { get @@ -412,10 +389,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 134217728L; - _From = value; + _From = value; } } - public StringValues HeaderHost { get @@ -425,10 +401,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 268435456L; - _Host = value; + _Host = value; } } - public StringValues HeaderIfMatch { get @@ -438,10 +413,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 536870912L; - _IfMatch = value; + _IfMatch = value; } } - public StringValues HeaderIfModifiedSince { get @@ -451,10 +425,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 1073741824L; - _IfModifiedSince = value; + _IfModifiedSince = value; } } - public StringValues HeaderIfNoneMatch { get @@ -464,10 +437,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 2147483648L; - _IfNoneMatch = value; + _IfNoneMatch = value; } } - public StringValues HeaderIfRange { get @@ -477,10 +449,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 4294967296L; - _IfRange = value; + _IfRange = value; } } - public StringValues HeaderIfUnmodifiedSince { get @@ -490,10 +461,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 8589934592L; - _IfUnmodifiedSince = value; + _IfUnmodifiedSince = value; } } - public StringValues HeaderMaxForwards { get @@ -503,10 +473,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 17179869184L; - _MaxForwards = value; + _MaxForwards = value; } } - public StringValues HeaderProxyAuthorization { get @@ -516,10 +485,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 34359738368L; - _ProxyAuthorization = value; + _ProxyAuthorization = value; } } - public StringValues HeaderReferer { get @@ -529,10 +497,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 68719476736L; - _Referer = value; + _Referer = value; } } - public StringValues HeaderRange { get @@ -542,10 +509,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 137438953472L; - _Range = value; + _Range = value; } } - public StringValues HeaderTE { get @@ -555,10 +521,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 274877906944L; - _TE = value; + _TE = value; } } - public StringValues HeaderTranslate { get @@ -568,10 +533,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 549755813888L; - _Translate = value; + _Translate = value; } } - public StringValues HeaderUserAgent { get @@ -581,7 +545,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 1099511627776L; - _UserAgent = value; + _UserAgent = value; } } @@ -589,14 +553,13 @@ namespace Microsoft.AspNet.Server.Kestrel.Http { return BitCount(_bits) + (MaybeUnknown?.Count ?? 0); } - protected override StringValues GetValueFast(string key) { switch(key.Length) { case 13: { - if ("Cache-Control".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Cache-Control".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 1L) != 0)) { @@ -608,7 +571,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } - if ("Content-Range".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Content-Range".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 131072L) != 0)) { @@ -620,7 +583,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } - if ("Last-Modified".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Last-Modified".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 524288L) != 0)) { @@ -632,7 +595,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } - if ("Authorization".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Authorization".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 16777216L) != 0)) { @@ -644,7 +607,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } - if ("If-None-Match".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("If-None-Match".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 2147483648L) != 0)) { @@ -657,10 +620,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 10: { - if ("Connection".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Connection".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 2L) != 0)) { @@ -672,7 +635,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } - if ("Keep-Alive".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Keep-Alive".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 8L) != 0)) { @@ -684,7 +647,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } - if ("User-Agent".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("User-Agent".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 1099511627776L) != 0)) { @@ -697,10 +660,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 4: { - if ("Date".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Date".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 4L) != 0)) { @@ -712,7 +675,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } - if ("From".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("From".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 134217728L) != 0)) { @@ -724,7 +687,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } - if ("Host".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Host".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 268435456L) != 0)) { @@ -737,10 +700,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 6: { - if ("Pragma".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Pragma".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 16L) != 0)) { @@ -752,7 +715,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } - if ("Accept".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Accept".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 1048576L) != 0)) { @@ -764,7 +727,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } - if ("Cookie".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Cookie".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 33554432L) != 0)) { @@ -776,7 +739,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } - if ("Expect".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Expect".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 67108864L) != 0)) { @@ -789,10 +752,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 7: { - if ("Trailer".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Trailer".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 32L) != 0)) { @@ -804,7 +767,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } - if ("Upgrade".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Upgrade".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 128L) != 0)) { @@ -816,7 +779,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } - if ("Warning".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Warning".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 512L) != 0)) { @@ -828,7 +791,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } - if ("Expires".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Expires".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 262144L) != 0)) { @@ -840,7 +803,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } - if ("Referer".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Referer".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 68719476736L) != 0)) { @@ -853,10 +816,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 17: { - if ("Transfer-Encoding".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Transfer-Encoding".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 64L) != 0)) { @@ -868,7 +831,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } - if ("If-Modified-Since".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("If-Modified-Since".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 1073741824L) != 0)) { @@ -881,10 +844,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 3: { - if ("Via".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Via".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 256L) != 0)) { @@ -897,10 +860,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 5: { - if ("Allow".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Allow".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 1024L) != 0)) { @@ -912,7 +875,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } - if ("Range".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Range".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 137438953472L) != 0)) { @@ -925,10 +888,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 14: { - if ("Content-Length".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Content-Length".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 2048L) != 0)) { @@ -940,7 +903,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } - if ("Accept-Charset".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Accept-Charset".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 2097152L) != 0)) { @@ -953,10 +916,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 12: { - if ("Content-Type".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Content-Type".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 4096L) != 0)) { @@ -968,7 +931,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } - if ("Max-Forwards".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Max-Forwards".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 17179869184L) != 0)) { @@ -981,10 +944,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 16: { - if ("Content-Encoding".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Content-Encoding".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 8192L) != 0)) { @@ -996,7 +959,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } - if ("Content-Language".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Content-Language".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 16384L) != 0)) { @@ -1008,7 +971,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } - if ("Content-Location".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Content-Location".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 32768L) != 0)) { @@ -1021,10 +984,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 11: { - if ("Content-MD5".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Content-MD5".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 65536L) != 0)) { @@ -1037,10 +1000,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 15: { - if ("Accept-Encoding".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Accept-Encoding".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 4194304L) != 0)) { @@ -1052,7 +1015,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } - if ("Accept-Language".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Accept-Language".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 8388608L) != 0)) { @@ -1065,10 +1028,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 8: { - if ("If-Match".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("If-Match".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 536870912L) != 0)) { @@ -1080,7 +1043,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } - if ("If-Range".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("If-Range".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 4294967296L) != 0)) { @@ -1093,10 +1056,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 19: { - if ("If-Unmodified-Since".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("If-Unmodified-Since".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 8589934592L) != 0)) { @@ -1108,7 +1071,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } - if ("Proxy-Authorization".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Proxy-Authorization".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 34359738368L) != 0)) { @@ -1121,10 +1084,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 2: { - if ("TE".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("TE".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 274877906944L) != 0)) { @@ -1137,10 +1100,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 9: { - if ("Translate".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Translate".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 549755813888L) != 0)) { @@ -1153,14 +1116,13 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - } +} if (MaybeUnknown == null) { throw new System.Collections.Generic.KeyNotFoundException(); } return MaybeUnknown[key]; } - protected override bool TryGetValueFast(string key, out StringValues value) { switch(key.Length) @@ -1238,7 +1200,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 10: { if ("Connection".Equals(key, StringComparison.OrdinalIgnoreCase)) @@ -1284,7 +1246,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 4: { if ("Date".Equals(key, StringComparison.OrdinalIgnoreCase)) @@ -1330,7 +1292,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 6: { if ("Pragma".Equals(key, StringComparison.OrdinalIgnoreCase)) @@ -1390,7 +1352,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 7: { if ("Trailer".Equals(key, StringComparison.OrdinalIgnoreCase)) @@ -1464,7 +1426,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 17: { if ("Transfer-Encoding".Equals(key, StringComparison.OrdinalIgnoreCase)) @@ -1496,7 +1458,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 3: { if ("Via".Equals(key, StringComparison.OrdinalIgnoreCase)) @@ -1514,7 +1476,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 5: { if ("Allow".Equals(key, StringComparison.OrdinalIgnoreCase)) @@ -1546,7 +1508,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 14: { if ("Content-Length".Equals(key, StringComparison.OrdinalIgnoreCase)) @@ -1578,7 +1540,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 12: { if ("Content-Type".Equals(key, StringComparison.OrdinalIgnoreCase)) @@ -1610,7 +1572,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 16: { if ("Content-Encoding".Equals(key, StringComparison.OrdinalIgnoreCase)) @@ -1656,7 +1618,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 11: { if ("Content-MD5".Equals(key, StringComparison.OrdinalIgnoreCase)) @@ -1674,7 +1636,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 15: { if ("Accept-Encoding".Equals(key, StringComparison.OrdinalIgnoreCase)) @@ -1706,7 +1668,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 8: { if ("If-Match".Equals(key, StringComparison.OrdinalIgnoreCase)) @@ -1738,7 +1700,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 19: { if ("If-Unmodified-Since".Equals(key, StringComparison.OrdinalIgnoreCase)) @@ -1770,7 +1732,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 2: { if ("TE".Equals(key, StringComparison.OrdinalIgnoreCase)) @@ -1788,7 +1750,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 9: { if ("Translate".Equals(key, StringComparison.OrdinalIgnoreCase)) @@ -1806,11 +1768,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - } +} value = StringValues.Empty; return MaybeUnknown?.TryGetValue(key, out value) ?? false; } - protected override void SetValueFast(string key, StringValues value) { switch(key.Length) @@ -1853,7 +1814,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 10: { if ("Connection".Equals(key, StringComparison.OrdinalIgnoreCase)) @@ -1878,7 +1839,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 4: { if ("Date".Equals(key, StringComparison.OrdinalIgnoreCase)) @@ -1903,7 +1864,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 6: { if ("Pragma".Equals(key, StringComparison.OrdinalIgnoreCase)) @@ -1935,7 +1896,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 7: { if ("Trailer".Equals(key, StringComparison.OrdinalIgnoreCase)) @@ -1974,7 +1935,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 17: { if ("Transfer-Encoding".Equals(key, StringComparison.OrdinalIgnoreCase)) @@ -1992,7 +1953,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 3: { if ("Via".Equals(key, StringComparison.OrdinalIgnoreCase)) @@ -2003,7 +1964,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 5: { if ("Allow".Equals(key, StringComparison.OrdinalIgnoreCase)) @@ -2021,7 +1982,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 14: { if ("Content-Length".Equals(key, StringComparison.OrdinalIgnoreCase)) @@ -2039,7 +2000,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 12: { if ("Content-Type".Equals(key, StringComparison.OrdinalIgnoreCase)) @@ -2057,7 +2018,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 16: { if ("Content-Encoding".Equals(key, StringComparison.OrdinalIgnoreCase)) @@ -2082,7 +2043,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 11: { if ("Content-MD5".Equals(key, StringComparison.OrdinalIgnoreCase)) @@ -2093,7 +2054,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 15: { if ("Accept-Encoding".Equals(key, StringComparison.OrdinalIgnoreCase)) @@ -2111,7 +2072,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 8: { if ("If-Match".Equals(key, StringComparison.OrdinalIgnoreCase)) @@ -2129,7 +2090,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 19: { if ("If-Unmodified-Since".Equals(key, StringComparison.OrdinalIgnoreCase)) @@ -2147,7 +2108,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 2: { if ("TE".Equals(key, StringComparison.OrdinalIgnoreCase)) @@ -2158,7 +2119,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 9: { if ("Translate".Equals(key, StringComparison.OrdinalIgnoreCase)) @@ -2169,17 +2130,16 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - } +} Unknown[key] = value; } - protected override void AddValueFast(string key, StringValues value) { switch(key.Length) { case 13: { - if ("Cache-Control".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Cache-Control".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 1L) != 0)) { @@ -2190,7 +2150,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http return; } - if ("Content-Range".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Content-Range".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 131072L) != 0)) { @@ -2201,7 +2161,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http return; } - if ("Last-Modified".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Last-Modified".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 524288L) != 0)) { @@ -2212,7 +2172,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http return; } - if ("Authorization".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Authorization".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 16777216L) != 0)) { @@ -2223,7 +2183,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http return; } - if ("If-None-Match".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("If-None-Match".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 2147483648L) != 0)) { @@ -2238,7 +2198,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http case 10: { - if ("Connection".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Connection".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 2L) != 0)) { @@ -2249,7 +2209,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http return; } - if ("Keep-Alive".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Keep-Alive".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 8L) != 0)) { @@ -2260,7 +2220,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http return; } - if ("User-Agent".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("User-Agent".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 1099511627776L) != 0)) { @@ -2275,7 +2235,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http case 4: { - if ("Date".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Date".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 4L) != 0)) { @@ -2286,7 +2246,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http return; } - if ("From".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("From".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 134217728L) != 0)) { @@ -2297,7 +2257,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http return; } - if ("Host".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Host".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 268435456L) != 0)) { @@ -2312,7 +2272,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http case 6: { - if ("Pragma".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Pragma".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 16L) != 0)) { @@ -2323,7 +2283,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http return; } - if ("Accept".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Accept".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 1048576L) != 0)) { @@ -2334,7 +2294,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http return; } - if ("Cookie".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Cookie".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 33554432L) != 0)) { @@ -2345,7 +2305,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http return; } - if ("Expect".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Expect".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 67108864L) != 0)) { @@ -2360,7 +2320,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http case 7: { - if ("Trailer".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Trailer".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 32L) != 0)) { @@ -2371,7 +2331,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http return; } - if ("Upgrade".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Upgrade".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 128L) != 0)) { @@ -2382,7 +2342,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http return; } - if ("Warning".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Warning".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 512L) != 0)) { @@ -2393,7 +2353,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http return; } - if ("Expires".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Expires".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 262144L) != 0)) { @@ -2404,7 +2364,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http return; } - if ("Referer".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Referer".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 68719476736L) != 0)) { @@ -2419,7 +2379,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http case 17: { - if ("Transfer-Encoding".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Transfer-Encoding".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 64L) != 0)) { @@ -2430,7 +2390,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http return; } - if ("If-Modified-Since".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("If-Modified-Since".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 1073741824L) != 0)) { @@ -2445,7 +2405,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http case 3: { - if ("Via".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Via".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 256L) != 0)) { @@ -2460,7 +2420,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http case 5: { - if ("Allow".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Allow".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 1024L) != 0)) { @@ -2471,7 +2431,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http return; } - if ("Range".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Range".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 137438953472L) != 0)) { @@ -2486,7 +2446,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http case 14: { - if ("Content-Length".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Content-Length".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 2048L) != 0)) { @@ -2497,7 +2457,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http return; } - if ("Accept-Charset".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Accept-Charset".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 2097152L) != 0)) { @@ -2512,7 +2472,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http case 12: { - if ("Content-Type".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Content-Type".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 4096L) != 0)) { @@ -2523,7 +2483,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http return; } - if ("Max-Forwards".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Max-Forwards".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 17179869184L) != 0)) { @@ -2538,7 +2498,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http case 16: { - if ("Content-Encoding".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Content-Encoding".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 8192L) != 0)) { @@ -2549,7 +2509,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http return; } - if ("Content-Language".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Content-Language".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 16384L) != 0)) { @@ -2560,7 +2520,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http return; } - if ("Content-Location".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Content-Location".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 32768L) != 0)) { @@ -2575,7 +2535,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http case 11: { - if ("Content-MD5".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Content-MD5".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 65536L) != 0)) { @@ -2590,7 +2550,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http case 15: { - if ("Accept-Encoding".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Accept-Encoding".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 4194304L) != 0)) { @@ -2601,7 +2561,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http return; } - if ("Accept-Language".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Accept-Language".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 8388608L) != 0)) { @@ -2616,7 +2576,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http case 8: { - if ("If-Match".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("If-Match".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 536870912L) != 0)) { @@ -2627,7 +2587,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http return; } - if ("If-Range".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("If-Range".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 4294967296L) != 0)) { @@ -2642,7 +2602,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http case 19: { - if ("If-Unmodified-Since".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("If-Unmodified-Since".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 8589934592L) != 0)) { @@ -2653,7 +2613,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http return; } - if ("Proxy-Authorization".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Proxy-Authorization".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 34359738368L) != 0)) { @@ -2668,7 +2628,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http case 2: { - if ("TE".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("TE".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 274877906944L) != 0)) { @@ -2683,7 +2643,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http case 9: { - if ("Translate".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Translate".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 549755813888L) != 0)) { @@ -2698,7 +2658,6 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } Unknown.Add(key, value); } - protected override bool RemoveFast(string key) { switch(key.Length) @@ -3347,7 +3306,6 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } return MaybeUnknown?.Remove(key) ?? false; } - protected override void ClearFast() { _bits = 0; @@ -3393,6 +3351,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http _TE = StringValues.Empty; _Translate = StringValues.Empty; _UserAgent = StringValues.Empty; + MaybeUnknown?.Clear(); } @@ -3402,7 +3361,6 @@ namespace Microsoft.AspNet.Server.Kestrel.Http { throw new ArgumentException(); } - if (((_bits & 1L) != 0)) { @@ -3857,7 +3815,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http ((ICollection>)MaybeUnknown)?.CopyTo(array, arrayIndex); } - + public unsafe void Append(byte[] keyBytes, int keyOffset, int keyLength, string value) { fixed(byte* ptr = keyBytes) { var pUB = ptr + keyOffset; var pUL = (ulong*)pUB; var pUI = (uint*)pUB; var pUS = (ushort*)pUB; @@ -4510,7 +4468,6 @@ namespace Microsoft.AspNet.Server.Kestrel.Http Unknown.TryGetValue(key, out existing); Unknown[key] = AppendValue(existing, value); } - public partial struct Enumerator { public bool MoveNext() @@ -4985,8 +4942,13 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } - public partial class FrameResponseHeaders + public partial class FrameResponseHeaders { + private static byte[] _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,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,76,101,110,103,116,104,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,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,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, + }; + private long _bits = 0; private StringValues _CacheControl; @@ -5020,6 +4982,12 @@ namespace Microsoft.AspNet.Server.Kestrel.Http private StringValues _Vary; private StringValues _WWWAuthenticate; + private byte[] _rawConnection; + private byte[] _rawDate; + private byte[] _rawTransferEncoding; + private byte[] _rawContentLength; + private byte[] _rawServer; + public StringValues HeaderCacheControl { get @@ -5029,10 +4997,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 1L; - _CacheControl = value; + _CacheControl = value; } } - public StringValues HeaderConnection { get @@ -5042,10 +5009,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 2L; - _Connection = value; + _Connection = value; + _rawConnection = null; } } - public StringValues HeaderDate { get @@ -5055,10 +5022,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 4L; - _Date = value; + _Date = value; + _rawDate = null; } } - public StringValues HeaderKeepAlive { get @@ -5068,10 +5035,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 8L; - _KeepAlive = value; + _KeepAlive = value; } } - public StringValues HeaderPragma { get @@ -5081,10 +5047,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 16L; - _Pragma = value; + _Pragma = value; } } - public StringValues HeaderTrailer { get @@ -5094,10 +5059,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 32L; - _Trailer = value; + _Trailer = value; } } - public StringValues HeaderTransferEncoding { get @@ -5107,10 +5071,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 64L; - _TransferEncoding = value; + _TransferEncoding = value; + _rawTransferEncoding = null; } } - public StringValues HeaderUpgrade { get @@ -5120,10 +5084,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 128L; - _Upgrade = value; + _Upgrade = value; } } - public StringValues HeaderVia { get @@ -5133,10 +5096,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 256L; - _Via = value; + _Via = value; } } - public StringValues HeaderWarning { get @@ -5146,10 +5108,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 512L; - _Warning = value; + _Warning = value; } } - public StringValues HeaderAllow { get @@ -5159,10 +5120,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 1024L; - _Allow = value; + _Allow = value; } } - public StringValues HeaderContentLength { get @@ -5172,10 +5132,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 2048L; - _ContentLength = value; + _ContentLength = value; + _rawContentLength = null; } } - public StringValues HeaderContentType { get @@ -5185,10 +5145,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 4096L; - _ContentType = value; + _ContentType = value; } } - public StringValues HeaderContentEncoding { get @@ -5198,10 +5157,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 8192L; - _ContentEncoding = value; + _ContentEncoding = value; } } - public StringValues HeaderContentLanguage { get @@ -5211,10 +5169,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 16384L; - _ContentLanguage = value; + _ContentLanguage = value; } } - public StringValues HeaderContentLocation { get @@ -5224,10 +5181,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 32768L; - _ContentLocation = value; + _ContentLocation = value; } } - public StringValues HeaderContentMD5 { get @@ -5237,10 +5193,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 65536L; - _ContentMD5 = value; + _ContentMD5 = value; } } - public StringValues HeaderContentRange { get @@ -5250,10 +5205,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 131072L; - _ContentRange = value; + _ContentRange = value; } } - public StringValues HeaderExpires { get @@ -5263,10 +5217,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 262144L; - _Expires = value; + _Expires = value; } } - public StringValues HeaderLastModified { get @@ -5276,10 +5229,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 524288L; - _LastModified = value; + _LastModified = value; } } - public StringValues HeaderAcceptRanges { get @@ -5289,10 +5241,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 1048576L; - _AcceptRanges = value; + _AcceptRanges = value; } } - public StringValues HeaderAge { get @@ -5302,10 +5253,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 2097152L; - _Age = value; + _Age = value; } } - public StringValues HeaderETag { get @@ -5315,10 +5265,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 4194304L; - _ETag = value; + _ETag = value; } } - public StringValues HeaderLocation { get @@ -5328,10 +5277,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 8388608L; - _Location = value; + _Location = value; } } - public StringValues HeaderProxyAutheticate { get @@ -5341,10 +5289,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 16777216L; - _ProxyAutheticate = value; + _ProxyAutheticate = value; } } - public StringValues HeaderRetryAfter { get @@ -5354,10 +5301,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 33554432L; - _RetryAfter = value; + _RetryAfter = value; } } - public StringValues HeaderServer { get @@ -5367,10 +5313,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 67108864L; - _Server = value; + _Server = value; + _rawServer = null; } } - public StringValues HeaderSetCookie { get @@ -5380,10 +5326,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 134217728L; - _SetCookie = value; + _SetCookie = value; } } - public StringValues HeaderVary { get @@ -5393,10 +5338,9 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 268435456L; - _Vary = value; + _Vary = value; } } - public StringValues HeaderWWWAuthenticate { get @@ -5406,22 +5350,51 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set { _bits |= 536870912L; - _WWWAuthenticate = value; + _WWWAuthenticate = value; } } + public void SetRawConnection(StringValues value, byte[] raw) + { + _bits |= 2L; + _Connection = value; + _rawConnection = raw; + } + public void SetRawDate(StringValues value, byte[] raw) + { + _bits |= 4L; + _Date = value; + _rawDate = raw; + } + public void SetRawTransferEncoding(StringValues value, byte[] raw) + { + _bits |= 64L; + _TransferEncoding = value; + _rawTransferEncoding = raw; + } + public void SetRawContentLength(StringValues value, byte[] raw) + { + _bits |= 2048L; + _ContentLength = value; + _rawContentLength = raw; + } + public void SetRawServer(StringValues value, byte[] raw) + { + _bits |= 67108864L; + _Server = value; + _rawServer = raw; + } protected override int GetCountFast() { return BitCount(_bits) + (MaybeUnknown?.Count ?? 0); } - protected override StringValues GetValueFast(string key) { switch(key.Length) { case 13: { - if ("Cache-Control".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Cache-Control".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 1L) != 0)) { @@ -5433,7 +5406,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } - if ("Content-Range".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Content-Range".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 131072L) != 0)) { @@ -5445,7 +5418,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } - if ("Last-Modified".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Last-Modified".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 524288L) != 0)) { @@ -5457,7 +5430,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } - if ("Accept-Ranges".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Accept-Ranges".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 1048576L) != 0)) { @@ -5470,10 +5443,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 10: { - if ("Connection".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Connection".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 2L) != 0)) { @@ -5485,7 +5458,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } - if ("Keep-Alive".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Keep-Alive".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 8L) != 0)) { @@ -5497,7 +5470,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } - if ("Set-Cookie".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Set-Cookie".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 134217728L) != 0)) { @@ -5510,10 +5483,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 4: { - if ("Date".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Date".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 4L) != 0)) { @@ -5525,7 +5498,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } - if ("ETag".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("ETag".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 4194304L) != 0)) { @@ -5537,7 +5510,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } - if ("Vary".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Vary".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 268435456L) != 0)) { @@ -5550,10 +5523,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 6: { - if ("Pragma".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Pragma".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 16L) != 0)) { @@ -5565,7 +5538,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } - if ("Server".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Server".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 67108864L) != 0)) { @@ -5578,10 +5551,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 7: { - if ("Trailer".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Trailer".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 32L) != 0)) { @@ -5593,7 +5566,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } - if ("Upgrade".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Upgrade".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 128L) != 0)) { @@ -5605,7 +5578,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } - if ("Warning".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Warning".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 512L) != 0)) { @@ -5617,7 +5590,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } - if ("Expires".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Expires".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 262144L) != 0)) { @@ -5630,10 +5603,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 17: { - if ("Transfer-Encoding".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Transfer-Encoding".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 64L) != 0)) { @@ -5645,7 +5618,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } - if ("Proxy-Autheticate".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Proxy-Autheticate".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 16777216L) != 0)) { @@ -5658,10 +5631,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 3: { - if ("Via".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Via".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 256L) != 0)) { @@ -5673,7 +5646,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } - if ("Age".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Age".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 2097152L) != 0)) { @@ -5686,10 +5659,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 5: { - if ("Allow".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Allow".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 1024L) != 0)) { @@ -5702,10 +5675,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 14: { - if ("Content-Length".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Content-Length".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 2048L) != 0)) { @@ -5718,10 +5691,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 12: { - if ("Content-Type".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Content-Type".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 4096L) != 0)) { @@ -5734,10 +5707,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 16: { - if ("Content-Encoding".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Content-Encoding".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 8192L) != 0)) { @@ -5749,7 +5722,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } - if ("Content-Language".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Content-Language".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 16384L) != 0)) { @@ -5761,7 +5734,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } - if ("Content-Location".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Content-Location".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 32768L) != 0)) { @@ -5773,7 +5746,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } - if ("WWW-Authenticate".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("WWW-Authenticate".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 536870912L) != 0)) { @@ -5786,10 +5759,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 11: { - if ("Content-MD5".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Content-MD5".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 65536L) != 0)) { @@ -5801,7 +5774,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } - if ("Retry-After".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Retry-After".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 33554432L) != 0)) { @@ -5814,10 +5787,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 8: { - if ("Location".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Location".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 8388608L) != 0)) { @@ -5830,14 +5803,13 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - } +} if (MaybeUnknown == null) { throw new System.Collections.Generic.KeyNotFoundException(); } return MaybeUnknown[key]; } - protected override bool TryGetValueFast(string key, out StringValues value) { switch(key.Length) @@ -5901,7 +5873,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 10: { if ("Connection".Equals(key, StringComparison.OrdinalIgnoreCase)) @@ -5947,7 +5919,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 4: { if ("Date".Equals(key, StringComparison.OrdinalIgnoreCase)) @@ -5993,7 +5965,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 6: { if ("Pragma".Equals(key, StringComparison.OrdinalIgnoreCase)) @@ -6025,7 +5997,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 7: { if ("Trailer".Equals(key, StringComparison.OrdinalIgnoreCase)) @@ -6085,7 +6057,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 17: { if ("Transfer-Encoding".Equals(key, StringComparison.OrdinalIgnoreCase)) @@ -6117,7 +6089,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 3: { if ("Via".Equals(key, StringComparison.OrdinalIgnoreCase)) @@ -6149,7 +6121,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 5: { if ("Allow".Equals(key, StringComparison.OrdinalIgnoreCase)) @@ -6167,7 +6139,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 14: { if ("Content-Length".Equals(key, StringComparison.OrdinalIgnoreCase)) @@ -6185,7 +6157,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 12: { if ("Content-Type".Equals(key, StringComparison.OrdinalIgnoreCase)) @@ -6203,7 +6175,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 16: { if ("Content-Encoding".Equals(key, StringComparison.OrdinalIgnoreCase)) @@ -6263,7 +6235,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 11: { if ("Content-MD5".Equals(key, StringComparison.OrdinalIgnoreCase)) @@ -6295,7 +6267,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 8: { if ("Location".Equals(key, StringComparison.OrdinalIgnoreCase)) @@ -6313,11 +6285,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - } +} value = StringValues.Empty; return MaybeUnknown?.TryGetValue(key, out value) ?? false; } - protected override void SetValueFast(string key, StringValues value) { switch(key.Length) @@ -6353,13 +6324,14 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 10: { if ("Connection".Equals(key, StringComparison.OrdinalIgnoreCase)) { _bits |= 2L; _Connection = value; + _rawConnection = null; return; } @@ -6378,13 +6350,14 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 4: { if ("Date".Equals(key, StringComparison.OrdinalIgnoreCase)) { _bits |= 4L; _Date = value; + _rawDate = null; return; } @@ -6403,7 +6376,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 6: { if ("Pragma".Equals(key, StringComparison.OrdinalIgnoreCase)) @@ -6417,11 +6390,12 @@ namespace Microsoft.AspNet.Server.Kestrel.Http { _bits |= 67108864L; _Server = value; + _rawServer = null; return; } } break; - + case 7: { if ("Trailer".Equals(key, StringComparison.OrdinalIgnoreCase)) @@ -6453,13 +6427,14 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 17: { if ("Transfer-Encoding".Equals(key, StringComparison.OrdinalIgnoreCase)) { _bits |= 64L; _TransferEncoding = value; + _rawTransferEncoding = null; return; } @@ -6471,7 +6446,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 3: { if ("Via".Equals(key, StringComparison.OrdinalIgnoreCase)) @@ -6489,7 +6464,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 5: { if ("Allow".Equals(key, StringComparison.OrdinalIgnoreCase)) @@ -6500,18 +6475,19 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 14: { if ("Content-Length".Equals(key, StringComparison.OrdinalIgnoreCase)) { _bits |= 2048L; _ContentLength = value; + _rawContentLength = null; return; } } break; - + case 12: { if ("Content-Type".Equals(key, StringComparison.OrdinalIgnoreCase)) @@ -6522,7 +6498,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 16: { if ("Content-Encoding".Equals(key, StringComparison.OrdinalIgnoreCase)) @@ -6554,7 +6530,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 11: { if ("Content-MD5".Equals(key, StringComparison.OrdinalIgnoreCase)) @@ -6572,7 +6548,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - + case 8: { if ("Location".Equals(key, StringComparison.OrdinalIgnoreCase)) @@ -6583,17 +6559,16 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } break; - } +} Unknown[key] = value; } - protected override void AddValueFast(string key, StringValues value) { switch(key.Length) { case 13: { - if ("Cache-Control".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Cache-Control".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 1L) != 0)) { @@ -6604,7 +6579,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http return; } - if ("Content-Range".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Content-Range".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 131072L) != 0)) { @@ -6615,7 +6590,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http return; } - if ("Last-Modified".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Last-Modified".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 524288L) != 0)) { @@ -6626,7 +6601,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http return; } - if ("Accept-Ranges".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Accept-Ranges".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 1048576L) != 0)) { @@ -6641,7 +6616,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http case 10: { - if ("Connection".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Connection".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 2L) != 0)) { @@ -6649,10 +6624,11 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } _bits |= 2L; _Connection = value; + _rawConnection = null; return; } - if ("Keep-Alive".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Keep-Alive".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 8L) != 0)) { @@ -6663,7 +6639,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http return; } - if ("Set-Cookie".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Set-Cookie".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 134217728L) != 0)) { @@ -6678,7 +6654,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http case 4: { - if ("Date".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Date".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 4L) != 0)) { @@ -6686,10 +6662,11 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } _bits |= 4L; _Date = value; + _rawDate = null; return; } - if ("ETag".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("ETag".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 4194304L) != 0)) { @@ -6700,7 +6677,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http return; } - if ("Vary".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Vary".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 268435456L) != 0)) { @@ -6715,7 +6692,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http case 6: { - if ("Pragma".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Pragma".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 16L) != 0)) { @@ -6726,7 +6703,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http return; } - if ("Server".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Server".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 67108864L) != 0)) { @@ -6734,6 +6711,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } _bits |= 67108864L; _Server = value; + _rawServer = null; return; } } @@ -6741,7 +6719,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http case 7: { - if ("Trailer".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Trailer".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 32L) != 0)) { @@ -6752,7 +6730,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http return; } - if ("Upgrade".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Upgrade".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 128L) != 0)) { @@ -6763,7 +6741,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http return; } - if ("Warning".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Warning".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 512L) != 0)) { @@ -6774,7 +6752,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http return; } - if ("Expires".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Expires".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 262144L) != 0)) { @@ -6789,7 +6767,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http case 17: { - if ("Transfer-Encoding".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Transfer-Encoding".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 64L) != 0)) { @@ -6797,10 +6775,11 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } _bits |= 64L; _TransferEncoding = value; + _rawTransferEncoding = null; return; } - if ("Proxy-Autheticate".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Proxy-Autheticate".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 16777216L) != 0)) { @@ -6815,7 +6794,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http case 3: { - if ("Via".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Via".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 256L) != 0)) { @@ -6826,7 +6805,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http return; } - if ("Age".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Age".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 2097152L) != 0)) { @@ -6841,7 +6820,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http case 5: { - if ("Allow".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Allow".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 1024L) != 0)) { @@ -6856,7 +6835,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http case 14: { - if ("Content-Length".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Content-Length".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 2048L) != 0)) { @@ -6864,6 +6843,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } _bits |= 2048L; _ContentLength = value; + _rawContentLength = null; return; } } @@ -6871,7 +6851,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http case 12: { - if ("Content-Type".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Content-Type".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 4096L) != 0)) { @@ -6886,7 +6866,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http case 16: { - if ("Content-Encoding".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Content-Encoding".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 8192L) != 0)) { @@ -6897,7 +6877,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http return; } - if ("Content-Language".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Content-Language".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 16384L) != 0)) { @@ -6908,7 +6888,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http return; } - if ("Content-Location".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Content-Location".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 32768L) != 0)) { @@ -6919,7 +6899,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http return; } - if ("WWW-Authenticate".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("WWW-Authenticate".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 536870912L) != 0)) { @@ -6934,7 +6914,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http case 11: { - if ("Content-MD5".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Content-MD5".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 65536L) != 0)) { @@ -6945,7 +6925,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http return; } - if ("Retry-After".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Retry-After".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 33554432L) != 0)) { @@ -6960,7 +6940,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http case 8: { - if ("Location".Equals(key, StringComparison.OrdinalIgnoreCase)) + if ("Location".Equals(key, StringComparison.OrdinalIgnoreCase)) { if (((_bits & 8388608L) != 0)) { @@ -6975,7 +6955,6 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } Unknown.Add(key, value); } - protected override bool RemoveFast(string key) { switch(key.Length) @@ -7048,6 +7027,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http { _bits &= ~2L; _Connection = StringValues.Empty; + _rawConnection = null; return true; } else @@ -7094,6 +7074,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http { _bits &= ~4L; _Date = StringValues.Empty; + _rawDate = null; return true; } else @@ -7154,6 +7135,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http { _bits &= ~67108864L; _Server = StringValues.Empty; + _rawServer = null; return true; } else @@ -7232,6 +7214,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http { _bits &= ~64L; _TransferEncoding = StringValues.Empty; + _rawTransferEncoding = null; return true; } else @@ -7314,6 +7297,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http { _bits &= ~2048L; _ContentLength = StringValues.Empty; + _rawContentLength = null; return true; } else @@ -7454,7 +7438,6 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } return MaybeUnknown?.Remove(key) ?? false; } - protected override void ClearFast() { _bits = 0; @@ -7489,6 +7472,12 @@ namespace Microsoft.AspNet.Server.Kestrel.Http _SetCookie = StringValues.Empty; _Vary = StringValues.Empty; _WWWAuthenticate = StringValues.Empty; + + _rawConnection = null; + _rawDate = null; + _rawTransferEncoding = null; + _rawContentLength = null; + _rawServer = null; MaybeUnknown?.Clear(); } @@ -7498,7 +7487,6 @@ namespace Microsoft.AspNet.Server.Kestrel.Http { throw new ArgumentException(); } - if (((_bits & 1L) != 0)) { @@ -7832,7 +7820,301 @@ namespace Microsoft.AspNet.Server.Kestrel.Http ((ICollection>)MaybeUnknown)?.CopyTo(array, arrayIndex); } - + + protected void CopyToFast(ref MemoryPoolIterator2 output) + { + + if (((_bits & 1L) != 0)) + { + foreach(var value in _CacheControl) + { + output.CopyFrom(_headerBytes, 0, 17); + output.CopyFromAscii(value); + } + } + + if (((_bits & 2L) != 0)) + { + if (_rawConnection != null) + { + output.CopyFrom(_rawConnection, 0, _rawConnection.Length); + } else + foreach(var value in _Connection) + { + output.CopyFrom(_headerBytes, 17, 14); + output.CopyFromAscii(value); + } + } + + if (((_bits & 4L) != 0)) + { + if (_rawDate != null) + { + output.CopyFrom(_rawDate, 0, _rawDate.Length); + } else + foreach(var value in _Date) + { + output.CopyFrom(_headerBytes, 31, 8); + output.CopyFromAscii(value); + } + } + + if (((_bits & 8L) != 0)) + { + foreach(var value in _KeepAlive) + { + output.CopyFrom(_headerBytes, 39, 14); + output.CopyFromAscii(value); + } + } + + if (((_bits & 16L) != 0)) + { + foreach(var value in _Pragma) + { + output.CopyFrom(_headerBytes, 53, 10); + output.CopyFromAscii(value); + } + } + + if (((_bits & 32L) != 0)) + { + foreach(var value in _Trailer) + { + output.CopyFrom(_headerBytes, 63, 11); + output.CopyFromAscii(value); + } + } + + if (((_bits & 64L) != 0)) + { + if (_rawTransferEncoding != null) + { + output.CopyFrom(_rawTransferEncoding, 0, _rawTransferEncoding.Length); + } else + foreach(var value in _TransferEncoding) + { + output.CopyFrom(_headerBytes, 74, 21); + output.CopyFromAscii(value); + } + } + + if (((_bits & 128L) != 0)) + { + foreach(var value in _Upgrade) + { + output.CopyFrom(_headerBytes, 95, 11); + output.CopyFromAscii(value); + } + } + + if (((_bits & 256L) != 0)) + { + foreach(var value in _Via) + { + output.CopyFrom(_headerBytes, 106, 7); + output.CopyFromAscii(value); + } + } + + if (((_bits & 512L) != 0)) + { + foreach(var value in _Warning) + { + output.CopyFrom(_headerBytes, 113, 11); + output.CopyFromAscii(value); + } + } + + if (((_bits & 1024L) != 0)) + { + foreach(var value in _Allow) + { + output.CopyFrom(_headerBytes, 124, 9); + output.CopyFromAscii(value); + } + } + + if (((_bits & 2048L) != 0)) + { + if (_rawContentLength != null) + { + output.CopyFrom(_rawContentLength, 0, _rawContentLength.Length); + } else + foreach(var value in _ContentLength) + { + output.CopyFrom(_headerBytes, 133, 18); + output.CopyFromAscii(value); + } + } + + if (((_bits & 4096L) != 0)) + { + foreach(var value in _ContentType) + { + output.CopyFrom(_headerBytes, 151, 16); + output.CopyFromAscii(value); + } + } + + if (((_bits & 8192L) != 0)) + { + foreach(var value in _ContentEncoding) + { + output.CopyFrom(_headerBytes, 167, 20); + output.CopyFromAscii(value); + } + } + + if (((_bits & 16384L) != 0)) + { + foreach(var value in _ContentLanguage) + { + output.CopyFrom(_headerBytes, 187, 20); + output.CopyFromAscii(value); + } + } + + if (((_bits & 32768L) != 0)) + { + foreach(var value in _ContentLocation) + { + output.CopyFrom(_headerBytes, 207, 20); + output.CopyFromAscii(value); + } + } + + if (((_bits & 65536L) != 0)) + { + foreach(var value in _ContentMD5) + { + output.CopyFrom(_headerBytes, 227, 15); + output.CopyFromAscii(value); + } + } + + if (((_bits & 131072L) != 0)) + { + foreach(var value in _ContentRange) + { + output.CopyFrom(_headerBytes, 242, 17); + output.CopyFromAscii(value); + } + } + + if (((_bits & 262144L) != 0)) + { + foreach(var value in _Expires) + { + output.CopyFrom(_headerBytes, 259, 11); + output.CopyFromAscii(value); + } + } + + if (((_bits & 524288L) != 0)) + { + foreach(var value in _LastModified) + { + output.CopyFrom(_headerBytes, 270, 17); + output.CopyFromAscii(value); + } + } + + if (((_bits & 1048576L) != 0)) + { + foreach(var value in _AcceptRanges) + { + output.CopyFrom(_headerBytes, 287, 17); + output.CopyFromAscii(value); + } + } + + if (((_bits & 2097152L) != 0)) + { + foreach(var value in _Age) + { + output.CopyFrom(_headerBytes, 304, 7); + output.CopyFromAscii(value); + } + } + + if (((_bits & 4194304L) != 0)) + { + foreach(var value in _ETag) + { + output.CopyFrom(_headerBytes, 311, 8); + output.CopyFromAscii(value); + } + } + + if (((_bits & 8388608L) != 0)) + { + foreach(var value in _Location) + { + output.CopyFrom(_headerBytes, 319, 12); + output.CopyFromAscii(value); + } + } + + if (((_bits & 16777216L) != 0)) + { + foreach(var value in _ProxyAutheticate) + { + output.CopyFrom(_headerBytes, 331, 21); + output.CopyFromAscii(value); + } + } + + if (((_bits & 33554432L) != 0)) + { + foreach(var value in _RetryAfter) + { + output.CopyFrom(_headerBytes, 352, 15); + output.CopyFromAscii(value); + } + } + + if (((_bits & 67108864L) != 0)) + { + if (_rawServer != null) + { + output.CopyFrom(_rawServer, 0, _rawServer.Length); + } else + foreach(var value in _Server) + { + output.CopyFrom(_headerBytes, 367, 10); + output.CopyFromAscii(value); + } + } + + if (((_bits & 134217728L) != 0)) + { + foreach(var value in _SetCookie) + { + output.CopyFrom(_headerBytes, 377, 14); + output.CopyFromAscii(value); + } + } + + if (((_bits & 268435456L) != 0)) + { + foreach(var value in _Vary) + { + output.CopyFrom(_headerBytes, 391, 8); + output.CopyFromAscii(value); + } + } + + if (((_bits & 536870912L) != 0)) + { + foreach(var value in _WWWAuthenticate) + { + output.CopyFrom(_headerBytes, 399, 20); + output.CopyFromAscii(value); + } + } + + } public unsafe void Append(byte[] keyBytes, int keyOffset, int keyLength, string value) { fixed(byte* ptr = keyBytes) { var pUB = ptr + keyOffset; var pUL = (ulong*)pUB; var pUI = (uint*)pUB; var pUS = (ushort*)pUB; @@ -7910,6 +8192,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http { _bits |= 2L; _Connection = new StringValues(value); + _rawConnection = null; } return; } @@ -7956,6 +8239,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http { _bits |= 4L; _Date = new StringValues(value); + _rawDate = null; } return; } @@ -8016,6 +8300,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http { _bits |= 67108864L; _Server = new StringValues(value); + _rawServer = null; } return; } @@ -8094,6 +8379,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http { _bits |= 64L; _TransferEncoding = new StringValues(value); + _rawTransferEncoding = null; } return; } @@ -8176,6 +8462,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http { _bits |= 2048L; _ContentLength = new StringValues(value); + _rawContentLength = null; } return; } @@ -8315,7 +8602,6 @@ namespace Microsoft.AspNet.Server.Kestrel.Http Unknown.TryGetValue(key, out existing); Unknown[key] = AppendValue(existing, value); } - public partial struct Enumerator { public bool MoveNext() diff --git a/src/Microsoft.AspNet.Server.Kestrel/Http/FrameResponseHeaders.cs b/src/Microsoft.AspNet.Server.Kestrel/Http/FrameResponseHeaders.cs index 725a647567..86c2a18554 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Http/FrameResponseHeaders.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/Http/FrameResponseHeaders.cs @@ -1,14 +1,25 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using Microsoft.Extensions.Primitives; using System.Collections; using System.Collections.Generic; +using Microsoft.AspNet.Server.Kestrel.Infrastructure; +using Microsoft.Extensions.Primitives; namespace Microsoft.AspNet.Server.Kestrel.Http { public partial class FrameResponseHeaders : FrameHeaders { + private static byte[] _CRLF = new[] { (byte)'\r', (byte)'\n' }; + private static byte[] _colonSpace = new[] { (byte)':', (byte)' ' }; + + public bool HasConnection => HeaderConnection.Count != 0; + + public bool HasTransferEncoding => HeaderTransferEncoding.Count != 0; + + public bool HasContentLength => HeaderContentLength.Count != 0; + + public Enumerator GetEnumerator() { return new Enumerator(this); @@ -19,6 +30,24 @@ namespace Microsoft.AspNet.Server.Kestrel.Http return GetEnumerator(); } + public void CopyTo(ref MemoryPoolIterator2 output) + { + CopyToFast(ref output); + if (MaybeUnknown != null) + { + foreach (var kv in MaybeUnknown) + { + foreach (var value in kv.Value) + { + output.CopyFrom(_CRLF, 0, 2); + output.CopyFromAscii(kv.Key); + output.CopyFrom(_colonSpace, 0, 2); + output.CopyFromAscii(value); + } + } + } + } + public partial struct Enumerator : IEnumerator> { private FrameResponseHeaders _collection; diff --git a/src/Microsoft.AspNet.Server.Kestrel/Http/MemoryPool.cs b/src/Microsoft.AspNet.Server.Kestrel/Http/MemoryPool.cs deleted file mode 100644 index 0fc5c390e1..0000000000 --- a/src/Microsoft.AspNet.Server.Kestrel/Http/MemoryPool.cs +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Collections.Generic; - -namespace Microsoft.AspNet.Server.Kestrel.Http -{ - public class MemoryPool : IMemoryPool - { - private static readonly byte[] EmptyArray = new byte[0]; - - private readonly Pool _pool1 = new Pool(); - private readonly Pool _pool2 = new Pool(); - private readonly Pool _pool3 = new Pool(); - - public byte[] Empty - { - get - { - return EmptyArray; - } - } - - public byte[] AllocByte(int minimumSize) - { - if (minimumSize == 0) - { - return EmptyArray; - } - if (minimumSize <= 1024) - { - return _pool1.Alloc(1024); - } - if (minimumSize <= 2048) - { - return _pool2.Alloc(2048); - } - return new byte[minimumSize]; - } - - public void FreeByte(byte[] memory) - { - if (memory == null) - { - return; - } - switch (memory.Length) - { - case 1024: - _pool1.Free(memory, 256); - break; - case 2048: - _pool2.Free(memory, 64); - break; - } - } - - public char[] AllocChar(int minimumSize) - { - if (minimumSize == 0) - { - return new char[0]; - } - if (minimumSize <= 128) - { - return _pool3.Alloc(128); - } - return new char[minimumSize]; - } - - public void FreeChar(char[] memory) - { - if (memory == null) - { - return; - } - switch (memory.Length) - { - case 128: - _pool3.Free(memory, 256); - break; - } - } - - public ArraySegment AllocSegment(int minimumSize) - { - return new ArraySegment(AllocByte(minimumSize)); - } - - public void FreeSegment(ArraySegment segment) - { - FreeByte(segment.Array); - } - - class Pool - { - private readonly Stack _stack = new Stack(); - private readonly object _sync = new object(); - - public T[] Alloc(int size) - { - lock (_sync) - { - if (_stack.Count != 0) - { - return _stack.Pop(); - } - } - return new T[size]; - } - - public void Free(T[] value, int limit) - { - lock (_sync) - { - if (_stack.Count < limit) - { - _stack.Push(value); - } - } - } - } - } -} diff --git a/src/Microsoft.AspNet.Server.Kestrel/Http/MemoryPoolTextWriter.cs b/src/Microsoft.AspNet.Server.Kestrel/Http/MemoryPoolTextWriter.cs deleted file mode 100644 index 2f549dc157..0000000000 --- a/src/Microsoft.AspNet.Server.Kestrel/Http/MemoryPoolTextWriter.cs +++ /dev/null @@ -1,155 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.IO; -using System.Text; - -namespace Microsoft.AspNet.Server.Kestrel.Http -{ - public class MemoryPoolTextWriter : TextWriter - { - private readonly IMemoryPool _memory; - - private char[] _textArray; - private int _textBegin; - private int _textEnd; - // ReSharper disable InconsistentNaming - private const int _textLength = 128; - // ReSharper restore InconsistentNaming - - private byte[] _dataArray; - private int _dataEnd; - - private readonly Encoder _encoder; - - public MemoryPoolTextWriter(IMemoryPool memory) - { - _memory = memory; - _textArray = _memory.AllocChar(_textLength); - _dataArray = _memory.Empty; - _encoder = Encoding.UTF8.GetEncoder(); - } - - public ArraySegment Buffer - { - get - { - return new ArraySegment(_dataArray, 0, _dataEnd); - } - } - - public override Encoding Encoding - { - get - { - return Encoding.UTF8; - } - } - - protected override void Dispose(bool disposing) - { - try - { - if (disposing) - { - if (_textArray != null) - { - _memory.FreeChar(_textArray); - _textArray = null; - } - if (_dataArray != null) - { - _memory.FreeByte(_dataArray); - _dataArray = null; - } - } - } - finally - { - base.Dispose(disposing); - } - } - - private void Encode(bool flush) - { - var bytesNeeded = _encoder.GetByteCount( - _textArray, - _textBegin, - _textEnd - _textBegin, - flush); - - Grow(bytesNeeded); - - var bytesUsed = _encoder.GetBytes( - _textArray, - _textBegin, - _textEnd - _textBegin, - _dataArray, - _dataEnd, - flush); - - _textBegin = _textEnd = 0; - _dataEnd += bytesUsed; - } - - private void Grow(int minimumAvailable) - { - if (_dataArray.Length - _dataEnd >= minimumAvailable) - { - return; - } - - var newLength = _dataArray.Length + Math.Max(_dataArray.Length, minimumAvailable); - var newArray = _memory.AllocByte(newLength); - Array.Copy(_dataArray, 0, newArray, 0, _dataEnd); - _memory.FreeByte(_dataArray); - _dataArray = newArray; - } - - public override void Write(char value) - { - if (_textLength == _textEnd) - { - Encode(false); - if (_textLength == _textEnd) - { - throw new InvalidOperationException("Unexplainable failure to encode text"); - } - } - - _textArray[_textEnd++] = value; - } - - public override void Write(string value) - { - var sourceIndex = 0; - var sourceLength = value.Length; - while (sourceIndex < sourceLength) - { - if (_textLength == _textEnd) - { - Encode(false); - } - - var count = sourceLength - sourceIndex; - if (count > _textLength - _textEnd) - { - count = _textLength - _textEnd; - } - - value.CopyTo(sourceIndex, _textArray, _textEnd, count); - sourceIndex += count; - _textEnd += count; - } - } - - public override void Flush() - { - while (_textBegin != _textEnd) - { - Encode(true); - } - } - } -} diff --git a/src/Microsoft.AspNet.Server.Kestrel/Http/ReasonPhrases.cs b/src/Microsoft.AspNet.Server.Kestrel/Http/ReasonPhrases.cs index fe8fa6e19e..9afbe88d6c 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Http/ReasonPhrases.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/Http/ReasonPhrases.cs @@ -2,11 +2,65 @@ // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Globalization; +using System.Text; namespace Microsoft.AspNet.Server.Kestrel.Http { public static class ReasonPhrases { + private static readonly byte[] _bytesStatus100 = Encoding.ASCII.GetBytes("100 Continue"); + private static readonly byte[] _bytesStatus101 = Encoding.ASCII.GetBytes("101 Switching Protocols"); + private static readonly byte[] _bytesStatus102 = Encoding.ASCII.GetBytes("102 Processing"); + private static readonly byte[] _bytesStatus200 = Encoding.ASCII.GetBytes("200 OK"); + private static readonly byte[] _bytesStatus201 = Encoding.ASCII.GetBytes("201 Created"); + private static readonly byte[] _bytesStatus202 = Encoding.ASCII.GetBytes("202 Accepted"); + private static readonly byte[] _bytesStatus203 = Encoding.ASCII.GetBytes("203 Non-Authoritative Information"); + private static readonly byte[] _bytesStatus204 = Encoding.ASCII.GetBytes("204 No Content"); + private static readonly byte[] _bytesStatus205 = Encoding.ASCII.GetBytes("205 Reset Content"); + private static readonly byte[] _bytesStatus206 = Encoding.ASCII.GetBytes("206 Partial Content"); + private static readonly byte[] _bytesStatus207 = Encoding.ASCII.GetBytes("207 Multi-Status"); + private static readonly byte[] _bytesStatus226 = Encoding.ASCII.GetBytes("226 IM Used"); + private static readonly byte[] _bytesStatus300 = Encoding.ASCII.GetBytes("300 Multiple Choices"); + private static readonly byte[] _bytesStatus301 = Encoding.ASCII.GetBytes("301 Moved Permanently"); + private static readonly byte[] _bytesStatus302 = Encoding.ASCII.GetBytes("302 Found"); + private static readonly byte[] _bytesStatus303 = Encoding.ASCII.GetBytes("303 See Other"); + private static readonly byte[] _bytesStatus304 = Encoding.ASCII.GetBytes("304 Not Modified"); + private static readonly byte[] _bytesStatus305 = Encoding.ASCII.GetBytes("305 Use Proxy"); + private static readonly byte[] _bytesStatus306 = Encoding.ASCII.GetBytes("306 Reserved"); + private static readonly byte[] _bytesStatus307 = Encoding.ASCII.GetBytes("307 Temporary Redirect"); + private static readonly byte[] _bytesStatus400 = Encoding.ASCII.GetBytes("400 Bad Request"); + private static readonly byte[] _bytesStatus401 = Encoding.ASCII.GetBytes("401 Unauthorized"); + private static readonly byte[] _bytesStatus402 = Encoding.ASCII.GetBytes("402 Payment Required"); + private static readonly byte[] _bytesStatus403 = Encoding.ASCII.GetBytes("403 Forbidden"); + private static readonly byte[] _bytesStatus404 = Encoding.ASCII.GetBytes("404 Not Found"); + private static readonly byte[] _bytesStatus405 = Encoding.ASCII.GetBytes("405 Method Not Allowed"); + private static readonly byte[] _bytesStatus406 = Encoding.ASCII.GetBytes("406 Not Acceptable"); + private static readonly byte[] _bytesStatus407 = Encoding.ASCII.GetBytes("407 Proxy Authentication Required"); + private static readonly byte[] _bytesStatus408 = Encoding.ASCII.GetBytes("408 Request Timeout"); + private static readonly byte[] _bytesStatus409 = Encoding.ASCII.GetBytes("409 Conflict"); + private static readonly byte[] _bytesStatus410 = Encoding.ASCII.GetBytes("410 Gone"); + private static readonly byte[] _bytesStatus411 = Encoding.ASCII.GetBytes("411 Length Required"); + private static readonly byte[] _bytesStatus412 = Encoding.ASCII.GetBytes("412 Precondition Failed"); + private static readonly byte[] _bytesStatus413 = Encoding.ASCII.GetBytes("413 Request Entity Too Large"); + private static readonly byte[] _bytesStatus414 = Encoding.ASCII.GetBytes("414 Request-URI Too Long"); + private static readonly byte[] _bytesStatus415 = Encoding.ASCII.GetBytes("415 Unsupported Media Type"); + private static readonly byte[] _bytesStatus416 = Encoding.ASCII.GetBytes("416 Requested Range Not Satisfiable"); + private static readonly byte[] _bytesStatus417 = Encoding.ASCII.GetBytes("417 Expectation Failed"); + private static readonly byte[] _bytesStatus418 = Encoding.ASCII.GetBytes("418 I'm a Teapot"); + private static readonly byte[] _bytesStatus422 = Encoding.ASCII.GetBytes("422 Unprocessable Entity"); + private static readonly byte[] _bytesStatus423 = Encoding.ASCII.GetBytes("423 Locked"); + private static readonly byte[] _bytesStatus424 = Encoding.ASCII.GetBytes("424 Failed Dependency"); + private static readonly byte[] _bytesStatus426 = Encoding.ASCII.GetBytes("426 Upgrade Required"); + private static readonly byte[] _bytesStatus500 = Encoding.ASCII.GetBytes("500 Internal Server Error"); + private static readonly byte[] _bytesStatus501 = Encoding.ASCII.GetBytes("501 Not Implemented"); + private static readonly byte[] _bytesStatus502 = Encoding.ASCII.GetBytes("502 Bad Gateway"); + private static readonly byte[] _bytesStatus503 = Encoding.ASCII.GetBytes("503 Service Unavailable"); + private static readonly byte[] _bytesStatus504 = Encoding.ASCII.GetBytes("504 Gateway Timeout"); + private static readonly byte[] _bytesStatus505 = Encoding.ASCII.GetBytes("505 HTTP Version Not Supported"); + private static readonly byte[] _bytesStatus506 = Encoding.ASCII.GetBytes("506 Variant Also Negotiates"); + private static readonly byte[] _bytesStatus507 = Encoding.ASCII.GetBytes("507 Insufficient Storage"); + private static readonly byte[] _bytesStatus510 = Encoding.ASCII.GetBytes("510 Not Extended"); + public static string ToStatus(int statusCode, string reasonPhrase = null) { if (string.IsNullOrEmpty(reasonPhrase)) @@ -16,6 +70,123 @@ namespace Microsoft.AspNet.Server.Kestrel.Http return statusCode.ToString(CultureInfo.InvariantCulture) + " " + reasonPhrase; } + public static byte[] ToStatusBytes(int statusCode, string reasonPhrase = null) + { + if (string.IsNullOrEmpty(reasonPhrase)) + { + switch (statusCode) + { + case 100: + return _bytesStatus100; + case 101: + return _bytesStatus101; + case 102: + return _bytesStatus102; + case 200: + return _bytesStatus200; + case 201: + return _bytesStatus201; + case 202: + return _bytesStatus202; + case 203: + return _bytesStatus203; + case 204: + return _bytesStatus204; + case 205: + return _bytesStatus205; + case 206: + return _bytesStatus206; + case 207: + return _bytesStatus207; + case 226: + return _bytesStatus226; + case 300: + return _bytesStatus300; + case 301: + return _bytesStatus301; + case 302: + return _bytesStatus302; + case 303: + return _bytesStatus303; + case 304: + return _bytesStatus304; + case 305: + return _bytesStatus305; + case 306: + return _bytesStatus306; + case 307: + return _bytesStatus307; + case 400: + return _bytesStatus400; + case 401: + return _bytesStatus401; + case 402: + return _bytesStatus402; + case 403: + return _bytesStatus403; + case 404: + return _bytesStatus404; + case 405: + return _bytesStatus405; + case 406: + return _bytesStatus406; + case 407: + return _bytesStatus407; + case 408: + return _bytesStatus408; + case 409: + return _bytesStatus409; + case 410: + return _bytesStatus410; + case 411: + return _bytesStatus411; + case 412: + return _bytesStatus412; + case 413: + return _bytesStatus413; + case 414: + return _bytesStatus414; + case 415: + return _bytesStatus415; + case 416: + return _bytesStatus416; + case 417: + return _bytesStatus417; + case 418: + return _bytesStatus418; + case 422: + return _bytesStatus422; + case 423: + return _bytesStatus423; + case 424: + return _bytesStatus424; + case 426: + return _bytesStatus426; + case 500: + return _bytesStatus500; + case 501: + return _bytesStatus501; + case 502: + return _bytesStatus502; + case 503: + return _bytesStatus503; + case 504: + return _bytesStatus504; + case 505: + return _bytesStatus505; + case 506: + return _bytesStatus506; + case 507: + return _bytesStatus507; + case 510: + return _bytesStatus510; + default: + return Encoding.ASCII.GetBytes(statusCode.ToString(CultureInfo.InvariantCulture) + " Unknown"); + } + } + return Encoding.ASCII.GetBytes(statusCode.ToString(CultureInfo.InvariantCulture) + " " + reasonPhrase); + } + public static string ToReasonPhrase(int statusCode) { switch (statusCode) @@ -242,4 +413,4 @@ namespace Microsoft.AspNet.Server.Kestrel.Http } } } -} +} \ No newline at end of file diff --git a/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/MemoryPool2.cs b/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/MemoryPool2.cs index 446f03c2b3..5c9ce81f69 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/MemoryPool2.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/MemoryPool2.cs @@ -30,6 +30,12 @@ namespace Microsoft.AspNet.Server.Kestrel.Infrastructure /// 4096 - 64 gives you a blockLength of 4032 usable bytes per block. /// private const int _blockLength = _blockStride - _blockUnused; + + /// + /// Max allocation block size for pooled blocks, + /// larger values can be leased but they will be disposed after use rather than returned to the pool. + /// + public const int MaxPooledBlockLength = _blockLength; /// /// 4096 * 32 gives you a slabLength of 128k contiguous bytes allocated per slab @@ -59,7 +65,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Infrastructure /// The block returned must be at least this size. It may be larger than this minimum size, and if so, /// the caller may write to the block's entire size rather than being limited to the minumumSize requested. /// The block that is reserved for the called. It must be passed to Return when it is no longer being used. - public MemoryPoolBlock2 Lease(int minimumSize = _blockLength) + public MemoryPoolBlock2 Lease(int minimumSize = MaxPooledBlockLength) { if (minimumSize > _blockLength) { diff --git a/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/MemoryPoolIterator2.cs b/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/MemoryPoolIterator2.cs index 6c5c1f205a..a3b5e678c5 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/MemoryPoolIterator2.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/Infrastructure/MemoryPoolIterator2.cs @@ -572,5 +572,109 @@ namespace Microsoft.AspNet.Server.Kestrel.Infrastructure return new MemoryPoolIterator2(block, blockIndex); } + + public void CopyFrom(byte[] data) + { + CopyFrom(data, 0, data.Length); + } + + public void CopyFrom(byte[] data, int offset, int count) + { + Debug.Assert(_block.Next == null); + Debug.Assert(_block.End == _index); + + var block = _block; + + var sourceData = data; + var sourceStart = offset; + var sourceEnd = offset + count; + + var targetData = block.Array; + var targetStart = block.End; + var targetEnd = block.Data.Offset + block.Data.Count; + + while (true) + { + // actual count to copy is remaining data, or unused trailing space in the current block, whichever is smaller + var copyCount = Math.Min(sourceEnd - sourceStart, targetEnd - targetStart); + + Buffer.BlockCopy(sourceData, sourceStart, targetData, targetStart, copyCount); + sourceStart += copyCount; + targetStart += copyCount; + + // if this means all source data has been copied + if (sourceStart == sourceEnd) + { + // increase occupied space in the block, and adjust iterator at start of unused trailing space + block.End = targetStart; + _block = block; + _index = targetStart; + return; + } + + // otherwise another block needs to be allocated to follow this one + block.Next = block.Pool.Lease(); + block = block.Next; + + targetData = block.Array; + targetStart = block.End; + targetEnd = block.Data.Offset + block.Data.Count; + } + } + + public unsafe void CopyFromAscii(string data) + { + Debug.Assert(_block.Next == null); + Debug.Assert(_block.End == _index); + + var block = _block; + + var inputLength = data.Length; + var inputLengthMinusSpan = inputLength - 3; + + fixed (char* pData = data) + { + var input = pData; + var inputEnd = pData + data.Length; + var blockRemaining = block.Data.Offset + block.Data.Count - block.End; + var blockRemainingMinusSpan = blockRemaining - 3; + + while (input < inputEnd) + { + if (blockRemaining == 0) + { + block.Next = block.Pool.Lease(); + block = block.Next; + blockRemaining = block.Data.Count; + blockRemainingMinusSpan = blockRemaining - 3; + } + + fixed (byte* pOutput = block.Data.Array) + { + var output = pOutput + block.End; + + var copied = 0; + for (; copied < inputLengthMinusSpan && copied < blockRemainingMinusSpan; copied += 4) + { + *(output) = (byte)*(input); + *(output + 1) = (byte)*(input + 1); + *(output + 2) = (byte)*(input + 2); + *(output + 3) = (byte)*(input + 3); + output += 4; + input += 4; + blockRemainingMinusSpan -= 4; + } + for (; copied < inputLength && copied < blockRemaining; copied++) + { + *(output++) = (byte)*(input++); + blockRemaining--; + } + block.End += copied; + _block = block; + _index = block.End; + } + } + } + } } } diff --git a/src/Microsoft.AspNet.Server.Kestrel/ServiceContext.cs b/src/Microsoft.AspNet.Server.Kestrel/ServiceContext.cs index d3d1539a59..095f37f856 100644 --- a/src/Microsoft.AspNet.Server.Kestrel/ServiceContext.cs +++ b/src/Microsoft.AspNet.Server.Kestrel/ServiceContext.cs @@ -13,13 +13,11 @@ namespace Microsoft.AspNet.Server.Kestrel { public ServiceContext() { - Memory = new MemoryPool(); } public ServiceContext(ServiceContext context) { AppLifetime = context.AppLifetime; - Memory = context.Memory; Log = context.Log; HttpContextFactory = context.HttpContextFactory; DateHeaderValueManager = context.DateHeaderValueManager; @@ -29,8 +27,6 @@ namespace Microsoft.AspNet.Server.Kestrel public IApplicationLifetime AppLifetime { get; set; } - public IMemoryPool Memory { get; set; } - public IKestrelTrace Log { get; set; } public IHttpContextFactory HttpContextFactory { get; set; } diff --git a/test/Microsoft.AspNet.Server.KestrelTests/EngineTests.cs b/test/Microsoft.AspNet.Server.KestrelTests/EngineTests.cs index f19b2b3077..afc30af8a9 100644 --- a/test/Microsoft.AspNet.Server.KestrelTests/EngineTests.cs +++ b/test/Microsoft.AspNet.Server.KestrelTests/EngineTests.cs @@ -171,8 +171,8 @@ namespace Microsoft.AspNet.Server.KestrelTests "Content-Length: 0", "", "HTTP/1.1 200 OK", - "Content-Length: 7", "Connection: close", + "Content-Length: 7", "", "Goodbye"); } @@ -241,8 +241,8 @@ namespace Microsoft.AspNet.Server.KestrelTests "Goodbye"); await connection.Receive( "HTTP/1.0 200 OK", - "Content-Length: 0", "Connection: keep-alive", + "Content-Length: 0", "\r\n"); await connection.ReceiveEnd( "HTTP/1.0 200 OK", @@ -267,14 +267,14 @@ namespace Microsoft.AspNet.Server.KestrelTests "Connection: keep-alive", "", "POST / HTTP/1.0", - "Connection: keep-alive", "Content-Length: 7", + "Connection: keep-alive", "", "Goodbye"); await connection.Receive( "HTTP/1.0 200 OK", - "Content-Length: 0", "Connection: keep-alive", + "Content-Length: 0", "\r\n"); await connection.ReceiveEnd( "HTTP/1.0 200 OK", @@ -295,16 +295,16 @@ namespace Microsoft.AspNet.Server.KestrelTests { await connection.SendEnd( "POST / HTTP/1.0", - "Connection: keep-alive", "Content-Length: 11", + "Connection: keep-alive", "", "Hello WorldPOST / HTTP/1.0", "", "Goodbye"); await connection.Receive( "HTTP/1.0 200 OK", - "Content-Length: 11", "Connection: keep-alive", + "Content-Length: 11", "", "Hello World"); await connection.ReceiveEnd( @@ -336,8 +336,8 @@ namespace Microsoft.AspNet.Server.KestrelTests "Goodbye"); await connection.Receive( "HTTP/1.0 200 OK", - "Content-Length: 11", "Connection: keep-alive", + "Content-Length: 11", "", "Hello World"); await connection.ReceiveEnd( @@ -361,15 +361,15 @@ namespace Microsoft.AspNet.Server.KestrelTests await connection.Send( "POST / HTTP/1.1", "Expect: 100-continue", - "Content-Length: 11", "Connection: close", + "Content-Length: 11", "\r\n"); await connection.Receive("HTTP/1.1 100 Continue", "\r\n"); await connection.SendEnd("Hello World"); await connection.Receive( "HTTP/1.1 200 OK", - "Content-Length: 11", "Connection: close", + "Content-Length: 11", "", "Hello World"); } @@ -422,8 +422,8 @@ namespace Microsoft.AspNet.Server.KestrelTests "Content-Length: 0", "", "HTTP/1.0 200 OK", - "Content-Length: 0", "Connection: keep-alive", + "Content-Length: 0", "", ""); } @@ -584,11 +584,12 @@ namespace Microsoft.AspNet.Server.KestrelTests "", "HTTP/1.1 500 Internal Server Error", ""); + await connection.Receive("Connection: close", + ""); await connection.ReceiveStartsWith("Date:"); await connection.ReceiveEnd( "Content-Length: 0", "Server: Kestrel", - "Connection: close", "", ""); @@ -812,12 +813,12 @@ namespace Microsoft.AspNet.Server.KestrelTests "Server: Kestrel", "", "HTTP/1.1 500 Internal Server Error", + "Connection: close", ""); await connection.ReceiveStartsWith("Date:"); await connection.ReceiveEnd( "Content-Length: 0", "Server: Kestrel", - "Connection: close", "", ""); diff --git a/test/Microsoft.AspNet.Server.KestrelTests/TestInput.cs b/test/Microsoft.AspNet.Server.KestrelTests/TestInput.cs index 24cf1cdb77..a440ea0edf 100644 --- a/test/Microsoft.AspNet.Server.KestrelTests/TestInput.cs +++ b/test/Microsoft.AspNet.Server.KestrelTests/TestInput.cs @@ -13,12 +13,10 @@ namespace Microsoft.AspNet.Server.KestrelTests { public TestInput() { - var memory = new MemoryPool(); var memory2 = new MemoryPool2(); FrameContext = new FrameContext { SocketInput = new SocketInput(memory2), - Memory = memory, ConnectionControl = this, FrameControl = this }; diff --git a/tools/Microsoft.AspNet.Server.Kestrel.GeneratedCode/KnownHeaders.cs b/tools/Microsoft.AspNet.Server.Kestrel.GeneratedCode/KnownHeaders.cs index b2def16b46..ab20b6c2d9 100644 --- a/tools/Microsoft.AspNet.Server.Kestrel.GeneratedCode/KnownHeaders.cs +++ b/tools/Microsoft.AspNet.Server.Kestrel.GeneratedCode/KnownHeaders.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Linq; using Microsoft.Dnx.Compilation.CSharp; +using System.Text; namespace Microsoft.AspNet.Server.Kestrel.GeneratedCode { @@ -11,7 +12,7 @@ namespace Microsoft.AspNet.Server.Kestrel.GeneratedCode { static string Each(IEnumerable values, Func formatter) { - return values.Select(formatter).Aggregate((a, b) => a + b); + return values.Any() ? values.Select(formatter).Aggregate((a, b) => a + b) : ""; } class KnownHeader @@ -19,10 +20,14 @@ namespace Microsoft.AspNet.Server.Kestrel.GeneratedCode public string Name { get; set; } public int Index { get; set; } public string Identifier => Name.Replace("-", ""); + + public byte[] Bytes => Encoding.ASCII.GetBytes($"\r\n{Name}: "); + public int BytesOffset { get; set; } + public int BytesCount { get; set; } + public bool EnhancedSetter { get; set; } public string TestBit() => $"((_bits & {1L << Index}L) != 0)"; public string SetBit() => $"_bits |= {1L << Index}L"; public string ClearBit() => $"_bits &= ~{1L << Index}L"; - public string EqualIgnoreCaseBytes() { var result = ""; @@ -54,7 +59,6 @@ namespace Microsoft.AspNet.Server.Kestrel.GeneratedCode } return $"({result})"; } - protected string Term(string name, int offset, int count, string array, string suffix) { ulong mask = 0; @@ -69,13 +73,11 @@ namespace Microsoft.AspNet.Server.Kestrel.GeneratedCode return $"(({array}[{offset / count}] & {mask}{suffix}) == {comp}{suffix})"; } } - public virtual void BeforeCompile(BeforeCompileContext context) { var syntaxTree = Microsoft.CodeAnalysis.CSharp.CSharpSyntaxTree.ParseText(GeneratedFile()); context.Compilation = context.Compilation.AddSyntaxTrees(syntaxTree); } - public static string GeneratedFile() { var commonHeaders = new[] @@ -128,8 +130,15 @@ namespace Microsoft.AspNet.Server.Kestrel.GeneratedCode { Name = header, Index = index - }); - + }).ToArray(); + var enhancedHeaders = new[] + { + "Connection", + "Server", + "Date", + "Transfer-Encoding", + "Content-Length", + }; var responseHeaders = commonHeaders.Concat(new[] { "Accept-Ranges", @@ -145,38 +154,60 @@ namespace Microsoft.AspNet.Server.Kestrel.GeneratedCode }).Select((header, index) => new KnownHeader { Name = header, - Index = index - }); - + Index = index, + EnhancedSetter = enhancedHeaders.Contains(header) + }).ToArray(); var loops = new[] { new { Headers = requestHeaders, HeadersByLength = requestHeaders.GroupBy(x => x.Name.Length), - ClassName = "FrameRequestHeaders" + ClassName = "FrameRequestHeaders", + Bytes = default(byte[]) }, new { Headers = responseHeaders, HeadersByLength = responseHeaders.GroupBy(x => x.Name.Length), - ClassName = "FrameResponseHeaders" + ClassName = "FrameResponseHeaders", + Bytes = responseHeaders.SelectMany(header => header.Bytes).ToArray() } }; - + foreach (var loop in loops.Where(l => l.Bytes != null)) + { + var offset = 0; + foreach (var header in loop.Headers) + { + header.BytesOffset = offset; + header.BytesCount += header.Bytes.Length; + offset += header.BytesCount; + } + } return $@" using System; using System.Collections.Generic; +using System.Text; +using Microsoft.AspNet.Server.Kestrel.Infrastructure; using Microsoft.Extensions.Primitives; namespace Microsoft.AspNet.Server.Kestrel.Http {{ {Each(loops, loop => $@" - public partial class {loop.ClassName} - {{ + public partial class {loop.ClassName} + {{{(loop.Bytes != null ? + $@" + private static byte[] _headerBytes = new byte[] + {{ + {Each(loop.Bytes, b => $"{b},")} + }};" + : "")} + private long _bits = 0; {Each(loop.Headers, header => @" private StringValues _" + header.Identifier + ";")} + {Each(loop.Headers.Where(header => header.EnhancedSetter), header => @" + private byte[] _raw" + header.Identifier + ";")} {Each(loop.Headers, header => $@" public StringValues Header{header.Identifier} {{ @@ -187,22 +218,28 @@ namespace Microsoft.AspNet.Server.Kestrel.Http set {{ {header.SetBit()}; - _{header.Identifier} = value; + _{header.Identifier} = value; {(header.EnhancedSetter == false ? "" : $@" + _raw{header.Identifier} = null;")} }} - }} - ")} + }}")} + {Each(loop.Headers.Where(header => header.EnhancedSetter), header => $@" + public void SetRaw{header.Identifier}(StringValues value, byte[] raw) + {{ + {header.SetBit()}; + _{header.Identifier} = value; + _raw{header.Identifier} = raw; + }}")} protected override int GetCountFast() {{ return BitCount(_bits) + (MaybeUnknown?.Count ?? 0); }} - protected override StringValues GetValueFast(string key) {{ switch(key.Length) {{{Each(loop.HeadersByLength, byLength => $@" case {byLength.Key}: {{{Each(byLength, header => $@" - if (""{header.Name}"".Equals(key, StringComparison.OrdinalIgnoreCase)) + if (""{header.Name}"".Equals(key, StringComparison.OrdinalIgnoreCase)) {{ if ({header.TestBit()}) {{ @@ -215,14 +252,13 @@ namespace Microsoft.AspNet.Server.Kestrel.Http }} ")}}} break; - ")}}} +")}}} if (MaybeUnknown == null) {{ throw new System.Collections.Generic.KeyNotFoundException(); }} return MaybeUnknown[key]; }} - protected override bool TryGetValueFast(string key, out StringValues value) {{ switch(key.Length) @@ -244,11 +280,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http }} ")}}} break; - ")}}} +")}}} value = StringValues.Empty; return MaybeUnknown?.TryGetValue(key, out value) ?? false; }} - protected override void SetValueFast(string key, StringValues value) {{ switch(key.Length) @@ -258,29 +293,30 @@ namespace Microsoft.AspNet.Server.Kestrel.Http if (""{header.Name}"".Equals(key, StringComparison.OrdinalIgnoreCase)) {{ {header.SetBit()}; - _{header.Identifier} = value; + _{header.Identifier} = value;{(header.EnhancedSetter == false ? "" : $@" + _raw{header.Identifier} = null;")} return; }} ")}}} break; - ")}}} +")}}} Unknown[key] = value; }} - protected override void AddValueFast(string key, StringValues value) {{ switch(key.Length) {{{Each(loop.HeadersByLength, byLength => $@" case {byLength.Key}: {{{Each(byLength, header => $@" - if (""{header.Name}"".Equals(key, StringComparison.OrdinalIgnoreCase)) + if (""{header.Name}"".Equals(key, StringComparison.OrdinalIgnoreCase)) {{ if ({header.TestBit()}) {{ throw new ArgumentException(""An item with the same key has already been added.""); }} {header.SetBit()}; - _{header.Identifier} = value; + _{header.Identifier} = value;{(header.EnhancedSetter == false ? "" : $@" + _raw{header.Identifier} = null;")} return; }} ")}}} @@ -288,7 +324,6 @@ namespace Microsoft.AspNet.Server.Kestrel.Http ")}}} Unknown.Add(key, value); }} - protected override bool RemoveFast(string key) {{ switch(key.Length) @@ -300,7 +335,8 @@ namespace Microsoft.AspNet.Server.Kestrel.Http if ({header.TestBit()}) {{ {header.ClearBit()}; - _{header.Identifier} = StringValues.Empty; + _{header.Identifier} = StringValues.Empty;{(header.EnhancedSetter == false ? "" : $@" + _raw{header.Identifier} = null;")} return true; }} else @@ -313,12 +349,13 @@ namespace Microsoft.AspNet.Server.Kestrel.Http ")}}} return MaybeUnknown?.Remove(key) ?? false; }} - protected override void ClearFast() {{ _bits = 0; {Each(loop.Headers, header => $@" _{header.Identifier} = StringValues.Empty;")} + {Each(loop.Headers.Where(header => header.EnhancedSetter), header => $@" + _raw{header.Identifier} = null;")} MaybeUnknown?.Clear(); }} @@ -328,7 +365,6 @@ namespace Microsoft.AspNet.Server.Kestrel.Http {{ throw new ArgumentException(); }} - {Each(loop.Headers, header => $@" if ({header.TestBit()}) {{ @@ -343,7 +379,24 @@ namespace Microsoft.AspNet.Server.Kestrel.Http ")} ((ICollection>)MaybeUnknown)?.CopyTo(array, arrayIndex); }} - + {(loop.ClassName == "FrameResponseHeaders" ? $@" + protected void CopyToFast(ref MemoryPoolIterator2 output) + {{ + {Each(loop.Headers, header => $@" + if ({header.TestBit()}) + {{ {(header.EnhancedSetter == false ? "" : $@" + if (_raw{header.Identifier} != null) + {{ + output.CopyFromAscii(_raw{header.Identifier}, 0, _raw{header.Identifier}.Length); + }} else ")} + foreach(var value in _{header.Identifier}) + {{ + output.CopyFromAscii(_headerBytes, {header.BytesOffset}, {header.BytesCount}); + output.CopyFromAscii(value); + }} + }} + ")} + }}" : "")} public unsafe void Append(byte[] keyBytes, int keyOffset, int keyLength, string value) {{ fixed(byte* ptr = keyBytes) {{ var pUB = ptr + keyOffset; var pUL = (ulong*)pUB; var pUI = (uint*)pUB; var pUS = (ushort*)pUB; @@ -360,7 +413,8 @@ namespace Microsoft.AspNet.Server.Kestrel.Http else {{ {header.SetBit()}; - _{header.Identifier} = new StringValues(value); + _{header.Identifier} = new StringValues(value);{(header.EnhancedSetter == false ? "" : $@" + _raw{header.Identifier} = null;")} }} return; }} @@ -372,7 +426,6 @@ namespace Microsoft.AspNet.Server.Kestrel.Http Unknown.TryGetValue(key, out existing); Unknown[key] = AppendValue(existing, value); }} - public partial struct Enumerator {{ public bool MoveNext() @@ -409,9 +462,8 @@ namespace Microsoft.AspNet.Server.Kestrel.Http ")}}} "; } - public virtual void AfterCompile(AfterCompileContext context) { } } -} +} \ No newline at end of file