diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/BufferExtensions.cs b/src/Servers/Kestrel/Core/src/Internal/Http/BufferExtensions.cs index 72d19d94fb..f94d422062 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/BufferExtensions.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/BufferExtensions.cs @@ -255,7 +255,6 @@ namespace System.Buffers { char ch = *(input + i); *(output + i) = (byte)ch; // Cast convert - i = length; } } } diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/Http1ChunkedEncodingMessageBody.cs b/src/Servers/Kestrel/Core/src/Internal/Http/Http1ChunkedEncodingMessageBody.cs index 727c3663e3..b2c255c3df 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/Http1ChunkedEncodingMessageBody.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/Http1ChunkedEncodingMessageBody.cs @@ -27,7 +27,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http private Mode _mode = Mode.Prefix; private volatile bool _canceled; private Task _pumpTask; - private Pipe _requestBodyPipe; + private readonly Pipe _requestBodyPipe; private ReadResult _readResult; public Http1ChunkedEncodingMessageBody(bool keepAlive, Http1Connection context) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/Http1Connection.cs b/src/Servers/Kestrel/Core/src/Internal/Http/Http1Connection.cs index 165be2add9..8cf1bd068b 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/Http1Connection.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/Http1Connection.cs @@ -287,13 +287,13 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http // origin-form. // The most common form of request-target. // https://tools.ietf.org/html/rfc7230#section-5.3.1 - OnOriginFormTarget(method, version, target, path, query, customMethod, pathEncoded); + OnOriginFormTarget(pathEncoded, target, path, query); } else if (ch == ByteAsterisk && target.Length == 1) { OnAsteriskFormTarget(method); } - else if (target.GetKnownHttpScheme(out var scheme)) + else if (target.GetKnownHttpScheme(out _)) { OnAbsoluteFormTarget(target, query); } @@ -321,7 +321,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } // Compare with Http2Stream.TryValidatePseudoHeaders - private void OnOriginFormTarget(HttpMethod method, HttpVersion version, Span target, Span path, Span query, Span customMethod, bool pathEncoded) + private void OnOriginFormTarget(bool pathEncoded, Span target, Span path, Span query) { Debug.Assert(target[0] == ByteForwardSlash, "Should only be called when path starts with /"); diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/Http1OutputProducer.cs b/src/Servers/Kestrel/Core/src/Internal/Http/Http1OutputProducer.cs index b3c0248838..2d818c49ed 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/Http1OutputProducer.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/Http1OutputProducer.cs @@ -171,7 +171,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http return _flusher.FlushAsync(_minResponseDataRateFeature.MinDataRate, bytesWritten, this, cancellationToken); } - ValueTask FlushAsyncChunked(Http1OutputProducer producer, CancellationToken token) + static ValueTask FlushAsyncChunked(Http1OutputProducer producer, CancellationToken token) { // Local function so in the common-path the stack space for BufferWriter isn't reserved and cleared when it isn't used. diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/HttpHeaders.Generated.cs b/src/Servers/Kestrel/Core/src/Internal/Http/HttpHeaders.Generated.cs index 6c85c81a68..e626a19d9c 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/HttpHeaders.Generated.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/HttpHeaders.Generated.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Buffers; using System.IO.Pipelines; +using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Microsoft.Extensions.Primitives; @@ -875,7 +876,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http protected override int GetCountFast() { - return (_contentLength.HasValue ? 1 : 0 ) + BitCount(_bits) + (MaybeUnknown?.Count ?? 0); + return (_contentLength.HasValue ? 1 : 0 ) + BitOperations.PopCount((ulong)_bits) + (MaybeUnknown?.Count ?? 0); } protected override bool TryGetValueFast(string key, out StringValues value) @@ -7310,7 +7311,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } protected override int GetCountFast() { - return (_contentLength.HasValue ? 1 : 0 ) + BitCount(_bits) + (MaybeUnknown?.Count ?? 0); + return (_contentLength.HasValue ? 1 : 0 ) + BitOperations.PopCount((ulong)_bits) + (MaybeUnknown?.Count ?? 0); } protected override bool TryGetValueFast(string key, out StringValues value) @@ -10275,7 +10276,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http _contentLength = null; var tempBits = _bits; _bits = 0; - if(HttpHeaders.BitCount(tempBits) > 12) + if(BitOperations.PopCount((ulong)tempBits) > 12) { _headers = default(HeaderReferences); return; @@ -11848,7 +11849,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http protected override int GetCountFast() { - return (_contentLength.HasValue ? 1 : 0 ) + BitCount(_bits) + (MaybeUnknown?.Count ?? 0); + return (_contentLength.HasValue ? 1 : 0 ) + BitOperations.PopCount((ulong)_bits) + (MaybeUnknown?.Count ?? 0); } protected override bool TryGetValueFast(string key, out StringValues value) @@ -11985,7 +11986,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http _contentLength = null; var tempBits = _bits; _bits = 0; - if(HttpHeaders.BitCount(tempBits) > 12) + if(BitOperations.PopCount((ulong)tempBits) > 12) { _headers = default(HeaderReferences); return; diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/HttpHeaders.cs b/src/Servers/Kestrel/Core/src/Internal/Http/HttpHeaders.cs index efc935d202..d041705a19 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/HttpHeaders.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/HttpHeaders.cs @@ -133,31 +133,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http [MethodImpl(MethodImplOptions.NoInlining)] protected bool RemoveUnknown(string key) => MaybeUnknown?.Remove(key) ?? false; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - protected static int BitCount(long value) - { - int SoftwareFallback(ulong v) - { - // see https://github.com/dotnet/corefx/blob/5965fd3756bc9dd9c89a27621eb10c6931126de2/src/System.Reflection.Metadata/src/System/Reflection/Internal/Utilities/BitArithmetic.cs - - const ulong Mask01010101 = 0x5555555555555555UL; - const ulong Mask00110011 = 0x3333333333333333UL; - const ulong Mask00001111 = 0x0F0F0F0F0F0F0F0FUL; - const ulong Mask00000001 = 0x0101010101010101UL; - - v = v - ((v >> 1) & Mask01010101); - v = (v & Mask00110011) + ((v >> 2) & Mask00110011); - return (int)(unchecked(((v + (v >> 4)) & Mask00001111) * Mask00000001) >> 56); - } - - if (Popcnt.X64.IsSupported) - { - return (int)Popcnt.X64.PopCount((ulong)value); - } - - return SoftwareFallback((ulong)value); - } - protected virtual int GetCountFast() { throw new NotImplementedException(); } @@ -222,8 +197,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http bool IDictionary.ContainsKey(string key) { - StringValues value; - return TryGetValueFast(key, out value); + return TryGetValueFast(key, out _); } void ICollection>.CopyTo(KeyValuePair[] array, int arrayIndex) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/HttpParser.cs b/src/Servers/Kestrel/Core/src/Internal/Http/HttpParser.cs index b8486621db..2fe5dfdb36 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/HttpParser.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/HttpParser.cs @@ -12,7 +12,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { public class HttpParser : IHttpParser where TRequestHandler : IHttpHeadersHandler, IHttpRequestLineHandler { - private bool _showErrorDetails; + private readonly bool _showErrorDetails; public HttpParser() : this(showErrorDetails: true) { diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/HttpProtocol.cs b/src/Servers/Kestrel/Core/src/Internal/Http/HttpProtocol.cs index 80424d9568..9320980de2 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/HttpProtocol.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/HttpProtocol.cs @@ -36,7 +36,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http private Stack, object>> _onStarting; private Stack, object>> _onCompleted; - private object _abortLock = new object(); + private readonly object _abortLock = new object(); private volatile bool _connectionAborted; private bool _preventRequestAbortedCancellation; private CancellationTokenSource _abortedCts; @@ -839,12 +839,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } } - [MethodImpl(MethodImplOptions.NoInlining)] - private Task FlushAsyncInternal() - { - return Output.FlushAsync(default).GetAsTask(); - } - private void VerifyAndUpdateWrite(int count) { var responseHeaders = HttpResponseHeaders; @@ -1554,7 +1548,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http return await Output.FlushAsync(cancellationToken); } - public Task WriteAsync(ReadOnlyMemory data, CancellationToken cancellationToken = default(CancellationToken)) + public Task WriteAsync(ReadOnlyMemory data, CancellationToken cancellationToken = default) { return WritePipeAsync(data, cancellationToken).GetAsTask(); } diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/HttpRequestHeaders.cs b/src/Servers/Kestrel/Core/src/Internal/Http/HttpRequestHeaders.cs index a6bf25ecbb..32e9e41d84 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/HttpRequestHeaders.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/HttpRequestHeaders.cs @@ -132,11 +132,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http _collection = collection; _bits = collection._bits; _next = 0; - _current = default(KeyValuePair); + _current = default; _hasUnknown = collection.MaybeUnknown != null; _unknownEnumerator = _hasUnknown ? collection.MaybeUnknown.GetEnumerator() - : default(Dictionary.Enumerator); + : default; } public KeyValuePair Current => _current; diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/HttpRequestPipeReader.cs b/src/Servers/Kestrel/Core/src/Internal/Http/HttpRequestPipeReader.cs index 262e79f602..da624c8208 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/HttpRequestPipeReader.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/HttpRequestPipeReader.cs @@ -123,8 +123,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } } - void ThrowObjectDisposedException() => throw new ObjectDisposedException(nameof(HttpRequestStream)); - void ThrowTaskCanceledException() => throw new TaskCanceledException(); + static void ThrowObjectDisposedException() => throw new ObjectDisposedException(nameof(HttpRequestStream)); + static void ThrowTaskCanceledException() => throw new TaskCanceledException(); } } } diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/HttpRequestStream.cs b/src/Servers/Kestrel/Core/src/Internal/Http/HttpRequestStream.cs index d84dfd6b90..4d5513293e 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/HttpRequestStream.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/HttpRequestStream.cs @@ -4,7 +4,6 @@ using System; using System.Buffers; using System.IO; -using System.IO.Pipelines; using System.Threading; using System.Threading.Tasks; using Microsoft.AspNetCore.Connections; @@ -14,7 +13,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { internal sealed class HttpRequestStream : Stream { - private HttpRequestPipeReader _pipeReader; + private readonly HttpRequestPipeReader _pipeReader; private readonly IHttpBodyControlFeature _bodyControl; public HttpRequestStream(IHttpBodyControlFeature bodyControl, HttpRequestPipeReader pipeReader) @@ -155,12 +154,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http var readableBufferLength = readableBuffer.Length; var consumed = readableBuffer.End; - var actual = 0; try { if (readableBufferLength != 0) { - actual = (int)Math.Min(readableBufferLength, buffer.Length); + var actual = (int)Math.Min(readableBufferLength, buffer.Length); var slice = actual == readableBufferLength ? readableBuffer : readableBuffer.Slice(0, actual); consumed = slice.End; diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/HttpResponseHeaders.cs b/src/Servers/Kestrel/Core/src/Internal/Http/HttpResponseHeaders.cs index 6dff25ae5d..0af675600f 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/HttpResponseHeaders.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/HttpResponseHeaders.cs @@ -14,8 +14,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { internal sealed partial class HttpResponseHeaders : HttpHeaders { - private static ReadOnlySpan _CrLf => new[] { (byte)'\r', (byte)'\n' }; - private static ReadOnlySpan _colonSpace => new[] { (byte)':', (byte)' ' }; + private static ReadOnlySpan CrLf => new[] { (byte)'\r', (byte)'\n' }; + private static ReadOnlySpan ColonSpace => new[] { (byte)':', (byte)' ' }; public Enumerator GetEnumerator() { @@ -46,9 +46,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { if (value != null) { - buffer.Write(_CrLf); + buffer.Write(CrLf); buffer.WriteAsciiNoValidation(kv.Key); - buffer.Write(_colonSpace); + buffer.Write(ColonSpace); buffer.WriteAsciiNoValidation(value); } } diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/HttpResponsePipeWriter.cs b/src/Servers/Kestrel/Core/src/Internal/Http/HttpResponsePipeWriter.cs index b6b6674103..6ccb84b66c 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/HttpResponsePipeWriter.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/HttpResponsePipeWriter.cs @@ -104,7 +104,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http ThrowObjectDisposedException(); } - void ThrowObjectDisposedException() + static void ThrowObjectDisposedException() { throw new ObjectDisposedException(nameof(HttpResponseStream), CoreStrings.WritingToResponseBodyAfterResponseCompleted); } diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/PathNormalizer.cs b/src/Servers/Kestrel/Core/src/Internal/Http/PathNormalizer.cs index a7ea4ce366..0ba8df24d1 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/PathNormalizer.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/PathNormalizer.cs @@ -187,8 +187,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http public static unsafe bool ContainsDotSegments(byte* start, byte* end) { var src = start; - var dst = start; - while (src < end) { var ch1 = *src; diff --git a/src/Servers/Kestrel/Core/src/Internal/Http/ZeroContentLengthMessageBody.cs b/src/Servers/Kestrel/Core/src/Internal/Http/ZeroContentLengthMessageBody.cs index 2329321b1b..1090832858 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http/ZeroContentLengthMessageBody.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http/ZeroContentLengthMessageBody.cs @@ -18,7 +18,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http public override bool IsEmpty => true; - public override ValueTask ReadAsync(CancellationToken cancellationToken = default(CancellationToken)) => new ValueTask(new ReadResult(default, isCanceled: false, isCompleted: true)); + public override ValueTask ReadAsync(CancellationToken cancellationToken = default) => new ValueTask(new ReadResult(default, isCanceled: false, isCompleted: true)); public override Task ConsumeAsync() => Task.CompletedTask; diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/HPack/IntegerEncoder.cs b/src/Servers/Kestrel/Core/src/Internal/Http2/HPack/IntegerEncoder.cs index 15beb845f7..600d032176 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http2/HPack/IntegerEncoder.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http2/HPack/IntegerEncoder.cs @@ -36,17 +36,18 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack return false; } - i = i - ((1 << n) - 1); + i -= ((1 << n) - 1); while (i >= 128) { - buffer[j++] = (byte)(i % 128 + 128); + var ui = (uint)i; // Use unsigned for optimizations + buffer[j++] = (byte)((ui % 128) + 128); if (j >= buffer.Length) { return false; } - i = i / 128; + i = (int)(ui / 128); // Jit converts unsigned divide by power-of-2 constant to clean shift } buffer[j++] = (byte)i; } diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/HPack/StatusCodes.cs b/src/Servers/Kestrel/Core/src/Internal/Http2/HPack/StatusCodes.cs index 35d90e796c..e00afa1d28 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http2/HPack/StatusCodes.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http2/HPack/StatusCodes.cs @@ -82,141 +82,77 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack public static byte[] ToStatusBytes(int statusCode) { - switch (statusCode) + return statusCode switch { - case Microsoft.AspNetCore.Http.StatusCodes.Status100Continue: - return _bytesStatus100; - case Microsoft.AspNetCore.Http.StatusCodes.Status101SwitchingProtocols: - return _bytesStatus101; - case Microsoft.AspNetCore.Http.StatusCodes.Status102Processing: - return _bytesStatus102; + Microsoft.AspNetCore.Http.StatusCodes.Status100Continue => _bytesStatus100, + Microsoft.AspNetCore.Http.StatusCodes.Status101SwitchingProtocols => _bytesStatus101, + Microsoft.AspNetCore.Http.StatusCodes.Status102Processing => _bytesStatus102, - case Microsoft.AspNetCore.Http.StatusCodes.Status200OK: - return _bytesStatus200; - case Microsoft.AspNetCore.Http.StatusCodes.Status201Created: - return _bytesStatus201; - case Microsoft.AspNetCore.Http.StatusCodes.Status202Accepted: - return _bytesStatus202; - case Microsoft.AspNetCore.Http.StatusCodes.Status203NonAuthoritative: - return _bytesStatus203; - case Microsoft.AspNetCore.Http.StatusCodes.Status204NoContent: - return _bytesStatus204; - case Microsoft.AspNetCore.Http.StatusCodes.Status205ResetContent: - return _bytesStatus205; - case Microsoft.AspNetCore.Http.StatusCodes.Status206PartialContent: - return _bytesStatus206; - case Microsoft.AspNetCore.Http.StatusCodes.Status207MultiStatus: - return _bytesStatus207; - case Microsoft.AspNetCore.Http.StatusCodes.Status208AlreadyReported: - return _bytesStatus208; - case Microsoft.AspNetCore.Http.StatusCodes.Status226IMUsed: - return _bytesStatus226; + Microsoft.AspNetCore.Http.StatusCodes.Status200OK => _bytesStatus200, + Microsoft.AspNetCore.Http.StatusCodes.Status201Created => _bytesStatus201, + Microsoft.AspNetCore.Http.StatusCodes.Status202Accepted => _bytesStatus202, + Microsoft.AspNetCore.Http.StatusCodes.Status203NonAuthoritative => _bytesStatus203, + Microsoft.AspNetCore.Http.StatusCodes.Status204NoContent => _bytesStatus204, + Microsoft.AspNetCore.Http.StatusCodes.Status205ResetContent => _bytesStatus205, + Microsoft.AspNetCore.Http.StatusCodes.Status206PartialContent => _bytesStatus206, + Microsoft.AspNetCore.Http.StatusCodes.Status207MultiStatus => _bytesStatus207, + Microsoft.AspNetCore.Http.StatusCodes.Status208AlreadyReported => _bytesStatus208, + Microsoft.AspNetCore.Http.StatusCodes.Status226IMUsed => _bytesStatus226, - case Microsoft.AspNetCore.Http.StatusCodes.Status300MultipleChoices: - return _bytesStatus300; - case Microsoft.AspNetCore.Http.StatusCodes.Status301MovedPermanently: - return _bytesStatus301; - case Microsoft.AspNetCore.Http.StatusCodes.Status302Found: - return _bytesStatus302; - case Microsoft.AspNetCore.Http.StatusCodes.Status303SeeOther: - return _bytesStatus303; - case Microsoft.AspNetCore.Http.StatusCodes.Status304NotModified: - return _bytesStatus304; - case Microsoft.AspNetCore.Http.StatusCodes.Status305UseProxy: - return _bytesStatus305; - case Microsoft.AspNetCore.Http.StatusCodes.Status306SwitchProxy: - return _bytesStatus306; - case Microsoft.AspNetCore.Http.StatusCodes.Status307TemporaryRedirect: - return _bytesStatus307; - case Microsoft.AspNetCore.Http.StatusCodes.Status308PermanentRedirect: - return _bytesStatus308; + Microsoft.AspNetCore.Http.StatusCodes.Status300MultipleChoices => _bytesStatus300, + Microsoft.AspNetCore.Http.StatusCodes.Status301MovedPermanently => _bytesStatus301, + Microsoft.AspNetCore.Http.StatusCodes.Status302Found => _bytesStatus302, + Microsoft.AspNetCore.Http.StatusCodes.Status303SeeOther => _bytesStatus303, + Microsoft.AspNetCore.Http.StatusCodes.Status304NotModified => _bytesStatus304, + Microsoft.AspNetCore.Http.StatusCodes.Status305UseProxy => _bytesStatus305, + Microsoft.AspNetCore.Http.StatusCodes.Status306SwitchProxy => _bytesStatus306, + Microsoft.AspNetCore.Http.StatusCodes.Status307TemporaryRedirect => _bytesStatus307, + Microsoft.AspNetCore.Http.StatusCodes.Status308PermanentRedirect => _bytesStatus308, - case Microsoft.AspNetCore.Http.StatusCodes.Status400BadRequest: - return _bytesStatus400; - case Microsoft.AspNetCore.Http.StatusCodes.Status401Unauthorized: - return _bytesStatus401; - case Microsoft.AspNetCore.Http.StatusCodes.Status402PaymentRequired: - return _bytesStatus402; - case Microsoft.AspNetCore.Http.StatusCodes.Status403Forbidden: - return _bytesStatus403; - case Microsoft.AspNetCore.Http.StatusCodes.Status404NotFound: - return _bytesStatus404; - case Microsoft.AspNetCore.Http.StatusCodes.Status405MethodNotAllowed: - return _bytesStatus405; - case Microsoft.AspNetCore.Http.StatusCodes.Status406NotAcceptable: - return _bytesStatus406; - case Microsoft.AspNetCore.Http.StatusCodes.Status407ProxyAuthenticationRequired: - return _bytesStatus407; - case Microsoft.AspNetCore.Http.StatusCodes.Status408RequestTimeout: - return _bytesStatus408; - case Microsoft.AspNetCore.Http.StatusCodes.Status409Conflict: - return _bytesStatus409; - case Microsoft.AspNetCore.Http.StatusCodes.Status410Gone: - return _bytesStatus410; - case Microsoft.AspNetCore.Http.StatusCodes.Status411LengthRequired: - return _bytesStatus411; - case Microsoft.AspNetCore.Http.StatusCodes.Status412PreconditionFailed: - return _bytesStatus412; - case Microsoft.AspNetCore.Http.StatusCodes.Status413PayloadTooLarge: - return _bytesStatus413; - case Microsoft.AspNetCore.Http.StatusCodes.Status414UriTooLong: - return _bytesStatus414; - case Microsoft.AspNetCore.Http.StatusCodes.Status415UnsupportedMediaType: - return _bytesStatus415; - case Microsoft.AspNetCore.Http.StatusCodes.Status416RangeNotSatisfiable: - return _bytesStatus416; - case Microsoft.AspNetCore.Http.StatusCodes.Status417ExpectationFailed: - return _bytesStatus417; - case Microsoft.AspNetCore.Http.StatusCodes.Status418ImATeapot: - return _bytesStatus418; - case Microsoft.AspNetCore.Http.StatusCodes.Status419AuthenticationTimeout: - return _bytesStatus419; - case Microsoft.AspNetCore.Http.StatusCodes.Status421MisdirectedRequest: - return _bytesStatus421; - case Microsoft.AspNetCore.Http.StatusCodes.Status422UnprocessableEntity: - return _bytesStatus422; - case Microsoft.AspNetCore.Http.StatusCodes.Status423Locked: - return _bytesStatus423; - case Microsoft.AspNetCore.Http.StatusCodes.Status424FailedDependency: - return _bytesStatus424; - case Microsoft.AspNetCore.Http.StatusCodes.Status426UpgradeRequired: - return _bytesStatus426; - case Microsoft.AspNetCore.Http.StatusCodes.Status428PreconditionRequired: - return _bytesStatus428; - case Microsoft.AspNetCore.Http.StatusCodes.Status429TooManyRequests: - return _bytesStatus429; - case Microsoft.AspNetCore.Http.StatusCodes.Status431RequestHeaderFieldsTooLarge: - return _bytesStatus431; - case Microsoft.AspNetCore.Http.StatusCodes.Status451UnavailableForLegalReasons: - return _bytesStatus451; + Microsoft.AspNetCore.Http.StatusCodes.Status400BadRequest => _bytesStatus400, + Microsoft.AspNetCore.Http.StatusCodes.Status401Unauthorized => _bytesStatus401, + Microsoft.AspNetCore.Http.StatusCodes.Status402PaymentRequired => _bytesStatus402, + Microsoft.AspNetCore.Http.StatusCodes.Status403Forbidden => _bytesStatus403, + Microsoft.AspNetCore.Http.StatusCodes.Status404NotFound => _bytesStatus404, + Microsoft.AspNetCore.Http.StatusCodes.Status405MethodNotAllowed => _bytesStatus405, + Microsoft.AspNetCore.Http.StatusCodes.Status406NotAcceptable => _bytesStatus406, + Microsoft.AspNetCore.Http.StatusCodes.Status407ProxyAuthenticationRequired => _bytesStatus407, + Microsoft.AspNetCore.Http.StatusCodes.Status408RequestTimeout => _bytesStatus408, + Microsoft.AspNetCore.Http.StatusCodes.Status409Conflict => _bytesStatus409, + Microsoft.AspNetCore.Http.StatusCodes.Status410Gone => _bytesStatus410, + Microsoft.AspNetCore.Http.StatusCodes.Status411LengthRequired => _bytesStatus411, + Microsoft.AspNetCore.Http.StatusCodes.Status412PreconditionFailed => _bytesStatus412, + Microsoft.AspNetCore.Http.StatusCodes.Status413PayloadTooLarge => _bytesStatus413, + Microsoft.AspNetCore.Http.StatusCodes.Status414UriTooLong => _bytesStatus414, + Microsoft.AspNetCore.Http.StatusCodes.Status415UnsupportedMediaType => _bytesStatus415, + Microsoft.AspNetCore.Http.StatusCodes.Status416RangeNotSatisfiable => _bytesStatus416, + Microsoft.AspNetCore.Http.StatusCodes.Status417ExpectationFailed => _bytesStatus417, + Microsoft.AspNetCore.Http.StatusCodes.Status418ImATeapot => _bytesStatus418, + Microsoft.AspNetCore.Http.StatusCodes.Status419AuthenticationTimeout => _bytesStatus419, + Microsoft.AspNetCore.Http.StatusCodes.Status421MisdirectedRequest => _bytesStatus421, + Microsoft.AspNetCore.Http.StatusCodes.Status422UnprocessableEntity => _bytesStatus422, + Microsoft.AspNetCore.Http.StatusCodes.Status423Locked => _bytesStatus423, + Microsoft.AspNetCore.Http.StatusCodes.Status424FailedDependency => _bytesStatus424, + Microsoft.AspNetCore.Http.StatusCodes.Status426UpgradeRequired => _bytesStatus426, + Microsoft.AspNetCore.Http.StatusCodes.Status428PreconditionRequired => _bytesStatus428, + Microsoft.AspNetCore.Http.StatusCodes.Status429TooManyRequests => _bytesStatus429, + Microsoft.AspNetCore.Http.StatusCodes.Status431RequestHeaderFieldsTooLarge => _bytesStatus431, + Microsoft.AspNetCore.Http.StatusCodes.Status451UnavailableForLegalReasons => _bytesStatus451, - case Microsoft.AspNetCore.Http.StatusCodes.Status500InternalServerError: - return _bytesStatus500; - case Microsoft.AspNetCore.Http.StatusCodes.Status501NotImplemented: - return _bytesStatus501; - case Microsoft.AspNetCore.Http.StatusCodes.Status502BadGateway: - return _bytesStatus502; - case Microsoft.AspNetCore.Http.StatusCodes.Status503ServiceUnavailable: - return _bytesStatus503; - case Microsoft.AspNetCore.Http.StatusCodes.Status504GatewayTimeout: - return _bytesStatus504; - case Microsoft.AspNetCore.Http.StatusCodes.Status505HttpVersionNotsupported: - return _bytesStatus505; - case Microsoft.AspNetCore.Http.StatusCodes.Status506VariantAlsoNegotiates: - return _bytesStatus506; - case Microsoft.AspNetCore.Http.StatusCodes.Status507InsufficientStorage: - return _bytesStatus507; - case Microsoft.AspNetCore.Http.StatusCodes.Status508LoopDetected: - return _bytesStatus508; - case Microsoft.AspNetCore.Http.StatusCodes.Status510NotExtended: - return _bytesStatus510; - case Microsoft.AspNetCore.Http.StatusCodes.Status511NetworkAuthenticationRequired: - return _bytesStatus511; + Microsoft.AspNetCore.Http.StatusCodes.Status500InternalServerError => _bytesStatus500, + Microsoft.AspNetCore.Http.StatusCodes.Status501NotImplemented => _bytesStatus501, + Microsoft.AspNetCore.Http.StatusCodes.Status502BadGateway => _bytesStatus502, + Microsoft.AspNetCore.Http.StatusCodes.Status503ServiceUnavailable => _bytesStatus503, + Microsoft.AspNetCore.Http.StatusCodes.Status504GatewayTimeout => _bytesStatus504, + Microsoft.AspNetCore.Http.StatusCodes.Status505HttpVersionNotsupported => _bytesStatus505, + Microsoft.AspNetCore.Http.StatusCodes.Status506VariantAlsoNegotiates => _bytesStatus506, + Microsoft.AspNetCore.Http.StatusCodes.Status507InsufficientStorage => _bytesStatus507, + Microsoft.AspNetCore.Http.StatusCodes.Status508LoopDetected => _bytesStatus508, + Microsoft.AspNetCore.Http.StatusCodes.Status510NotExtended => _bytesStatus510, + Microsoft.AspNetCore.Http.StatusCodes.Status511NetworkAuthenticationRequired => _bytesStatus511, - default: - return Encoding.ASCII.GetBytes(statusCode.ToString(CultureInfo.InvariantCulture)); - - } + _ => CreateStatusBytes(statusCode) + }; } } } diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.cs b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.cs index 91c3d04557..481f869acc 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Connection.cs @@ -396,31 +396,20 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2 throw new Http2ConnectionErrorException(CoreStrings.FormatHttp2ErrorStreamIdEven(_incomingFrame.Type, _incomingFrame.StreamId), Http2ErrorCode.PROTOCOL_ERROR); } - switch (_incomingFrame.Type) + return _incomingFrame.Type switch { - case Http2FrameType.DATA: - return ProcessDataFrameAsync(payload); - case Http2FrameType.HEADERS: - return ProcessHeadersFrameAsync(application, payload); - case Http2FrameType.PRIORITY: - return ProcessPriorityFrameAsync(); - case Http2FrameType.RST_STREAM: - return ProcessRstStreamFrameAsync(); - case Http2FrameType.SETTINGS: - return ProcessSettingsFrameAsync(payload); - case Http2FrameType.PUSH_PROMISE: - throw new Http2ConnectionErrorException(CoreStrings.Http2ErrorPushPromiseReceived, Http2ErrorCode.PROTOCOL_ERROR); - case Http2FrameType.PING: - return ProcessPingFrameAsync(payload); - case Http2FrameType.GOAWAY: - return ProcessGoAwayFrameAsync(); - case Http2FrameType.WINDOW_UPDATE: - return ProcessWindowUpdateFrameAsync(); - case Http2FrameType.CONTINUATION: - return ProcessContinuationFrameAsync(payload); - default: - return ProcessUnknownFrameAsync(); - } + Http2FrameType.DATA => ProcessDataFrameAsync(payload), + Http2FrameType.HEADERS => ProcessHeadersFrameAsync(application, payload), + Http2FrameType.PRIORITY => ProcessPriorityFrameAsync(), + Http2FrameType.RST_STREAM => ProcessRstStreamFrameAsync(), + Http2FrameType.SETTINGS => ProcessSettingsFrameAsync(payload), + Http2FrameType.PUSH_PROMISE => throw new Http2ConnectionErrorException(CoreStrings.Http2ErrorPushPromiseReceived, Http2ErrorCode.PROTOCOL_ERROR), + Http2FrameType.PING => ProcessPingFrameAsync(payload), + Http2FrameType.GOAWAY => ProcessGoAwayFrameAsync(), + Http2FrameType.WINDOW_UPDATE => ProcessWindowUpdateFrameAsync(), + Http2FrameType.CONTINUATION => ProcessContinuationFrameAsync(payload), + _ => ProcessUnknownFrameAsync(), + }; } private Task ProcessDataFrameAsync(in ReadOnlySequence payload) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2FrameWriter.cs b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2FrameWriter.cs index 294c524272..7555b9f223 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2FrameWriter.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2FrameWriter.cs @@ -22,7 +22,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2 internal class Http2FrameWriter { // Literal Header Field without Indexing - Indexed Name (Index 8 - :status) - private static ReadOnlySpan _continueBytes => new byte[] { 0x08, 0x03, (byte)'1', (byte)'0', (byte)'0' }; + private static ReadOnlySpan ContinueBytes => new byte[] { 0x08, 0x03, (byte)'1', (byte)'0', (byte)'0' }; private readonly object _writeLock = new object(); private readonly Http2Frame _outgoingFrame; @@ -138,9 +138,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2 } _outgoingFrame.PrepareHeaders(Http2HeadersFrameFlags.END_HEADERS, streamId); - _outgoingFrame.PayloadLength = _continueBytes.Length; + _outgoingFrame.PayloadLength = ContinueBytes.Length; WriteHeaderUnsynchronized(); - _outputWriter.Write(_continueBytes); + _outputWriter.Write(ContinueBytes); return TimeFlushUnsynchronizedAsync(); } } @@ -545,7 +545,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2 return default; } - _outgoingFrame.PreparePing(Http2PingFrameFlags.ACK); + _outgoingFrame.PreparePing(flags); Debug.Assert(payload.Length == _outgoingFrame.PayloadLength); // 8 WriteHeaderUnsynchronized(); foreach (var segment in payload) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2OutputProducer.cs b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2OutputProducer.cs index 6d08b0555d..ac647b4db7 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2OutputProducer.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2OutputProducer.cs @@ -95,11 +95,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2 _stream.ResetAndAbort(abortReason, Http2ErrorCode.INTERNAL_ERROR); } - public Task WriteChunkAsync(ReadOnlySpan span, CancellationToken cancellationToken) - { - throw new NotImplementedException(); - } - public ValueTask FlushAsync(CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) diff --git a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Stream.cs b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Stream.cs index caab64c029..752a70fe4b 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Stream.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Http2/Http2Stream.cs @@ -94,8 +94,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2 { Log.RequestBodyNotEntirelyRead(ConnectionIdFeature, TraceIdentifier); - var states = ApplyCompletionFlag(StreamCompletionFlags.Aborted); - if (states.OldState != states.NewState) + var (oldState, newState) = ApplyCompletionFlag(StreamCompletionFlags.Aborted); + if (oldState != newState) { // Don't block on IO. This never faults. _ = _http2Output.WriteRstStreamAsync(Http2ErrorCode.NO_ERROR); @@ -425,9 +425,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2 public void Abort(IOException abortReason) { - var states = ApplyCompletionFlag(StreamCompletionFlags.Aborted); + var (oldState, newState) = ApplyCompletionFlag(StreamCompletionFlags.Aborted); - if (states.OldState == states.NewState) + if (oldState == newState) { return; } @@ -451,9 +451,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2 internal void ResetAndAbort(ConnectionAbortedException abortReason, Http2ErrorCode error) { // Future incoming frames will drain for a default grace period to avoid destabilizing the connection. - var states = ApplyCompletionFlag(StreamCompletionFlags.Aborted); + var (oldState, newState) = ApplyCompletionFlag(StreamCompletionFlags.Aborted); - if (states.OldState == states.NewState) + if (oldState == newState) { return; } diff --git a/src/Servers/Kestrel/Core/src/Internal/Infrastructure/HttpUtilities.cs b/src/Servers/Kestrel/Core/src/Internal/Infrastructure/HttpUtilities.cs index 3f3013aeab..f57c296e1e 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Infrastructure/HttpUtilities.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Infrastructure/HttpUtilities.cs @@ -422,15 +422,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure public static string VersionToString(HttpVersion httpVersion) { - switch (httpVersion) + return httpVersion switch { - case HttpVersion.Http10: - return Http10Version; - case HttpVersion.Http11: - return Http11Version; - default: - return null; - } + HttpVersion.Http10 => Http10Version, + HttpVersion.Http11 => Http11Version, + _ => null, + }; } public static string MethodToString(HttpMethod method) { @@ -445,15 +442,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure public static string SchemeToString(HttpScheme scheme) { - switch (scheme) + return scheme switch { - case HttpScheme.Http: - return HttpUriScheme; - case HttpScheme.Https: - return HttpsUriScheme; - default: - return null; - } + HttpScheme.Http => HttpUriScheme, + HttpScheme.Https => HttpsUriScheme, + _ => null, + }; } public static bool IsHostHeaderValid(string hostText) diff --git a/src/Servers/Kestrel/Core/src/Internal/Infrastructure/PipeWriterHelpers/TimingPipeFlusher.cs b/src/Servers/Kestrel/Core/src/Internal/Infrastructure/PipeWriterHelpers/TimingPipeFlusher.cs index a1d16d3cc1..2f71f821c4 100644 --- a/src/Servers/Kestrel/Core/src/Internal/Infrastructure/PipeWriterHelpers/TimingPipeFlusher.cs +++ b/src/Servers/Kestrel/Core/src/Internal/Infrastructure/PipeWriterHelpers/TimingPipeFlusher.cs @@ -60,10 +60,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure.PipeW return new ValueTask(pipeFlushTask.Result); } - return TimeFlushAsyncAwaited(pipeFlushTask, minRate, count, outputAborter, cancellationToken); + return TimeFlushAsyncAwaited(pipeFlushTask, minRate, outputAborter, cancellationToken); } - private async ValueTask TimeFlushAsyncAwaited(ValueTask pipeFlushTask, MinDataRate minRate, long count, IHttpOutputAborter outputAborter, CancellationToken cancellationToken) + private async ValueTask TimeFlushAsyncAwaited(ValueTask pipeFlushTask, MinDataRate minRate, IHttpOutputAborter outputAborter, CancellationToken cancellationToken) { if (minRate != null) { diff --git a/src/Servers/Kestrel/Core/src/Middleware/Internal/DuplexPipeStream.cs b/src/Servers/Kestrel/Core/src/Middleware/Internal/DuplexPipeStream.cs index 1cdde16313..b81a5e8869 100644 --- a/src/Servers/Kestrel/Core/src/Middleware/Internal/DuplexPipeStream.cs +++ b/src/Servers/Kestrel/Core/src/Middleware/Internal/DuplexPipeStream.cs @@ -152,7 +152,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state) { - var task = ReadAsync(buffer, offset, count, default(CancellationToken), state); + var task = ReadAsync(buffer, offset, count, default, state); if (callback != null) { task.ContinueWith(t => callback.Invoke(t)); @@ -190,7 +190,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state) { - var task = WriteAsync(buffer, offset, count, default(CancellationToken), state); + var task = WriteAsync(buffer, offset, count, default, state); if (callback != null) { task.ContinueWith(t => callback.Invoke(t)); diff --git a/src/Servers/Kestrel/Transport.Sockets/src/Internal/SocketAwaitableEventArgs.cs b/src/Servers/Kestrel/Transport.Sockets/src/Internal/SocketAwaitableEventArgs.cs index c9f4da86e8..9c8f2aef9d 100644 --- a/src/Servers/Kestrel/Transport.Sockets/src/Internal/SocketAwaitableEventArgs.cs +++ b/src/Servers/Kestrel/Transport.Sockets/src/Internal/SocketAwaitableEventArgs.cs @@ -40,7 +40,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.Internal return BytesTransferred; - void ThrowSocketException(SocketError e) + static void ThrowSocketException(SocketError e) { throw new SocketException((int)e); } diff --git a/src/Servers/Kestrel/shared/KnownHeaders.cs b/src/Servers/Kestrel/shared/KnownHeaders.cs index acc03a08c1..e38dfb19a9 100644 --- a/src/Servers/Kestrel/shared/KnownHeaders.cs +++ b/src/Servers/Kestrel/shared/KnownHeaders.cs @@ -579,6 +579,7 @@ using System; using System.Collections.Generic; using System.Buffers; using System.IO.Pipelines; +using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Microsoft.Extensions.Primitives; @@ -642,7 +643,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http }}")} protected override int GetCountFast() {{ - return (_contentLength.HasValue ? 1 : 0 ) + BitCount(_bits) + (MaybeUnknown?.Count ?? 0); + return (_contentLength.HasValue ? 1 : 0 ) + BitOperations.PopCount((ulong)_bits) + (MaybeUnknown?.Count ?? 0); }} protected override bool TryGetValueFast(string key, out StringValues value) @@ -824,7 +825,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http _contentLength = null; var tempBits = _bits; _bits = 0; - if(HttpHeaders.BitCount(tempBits) > 12) + if(BitOperations.PopCount((ulong)tempBits) > 12) {{ _headers = default(HeaderReferences); return;