Kestrel code tidyups (#11896)

This commit is contained in:
Ben Adams 2019-07-22 20:57:52 +01:00 committed by Stephen Halter
parent 7ca234607a
commit 2e0d7889ad
26 changed files with 137 additions and 257 deletions

View File

@ -255,7 +255,6 @@ namespace System.Buffers
{ {
char ch = *(input + i); char ch = *(input + i);
*(output + i) = (byte)ch; // Cast convert *(output + i) = (byte)ch; // Cast convert
i = length;
} }
} }
} }

View File

@ -27,7 +27,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
private Mode _mode = Mode.Prefix; private Mode _mode = Mode.Prefix;
private volatile bool _canceled; private volatile bool _canceled;
private Task _pumpTask; private Task _pumpTask;
private Pipe _requestBodyPipe; private readonly Pipe _requestBodyPipe;
private ReadResult _readResult; private ReadResult _readResult;
public Http1ChunkedEncodingMessageBody(bool keepAlive, Http1Connection context) public Http1ChunkedEncodingMessageBody(bool keepAlive, Http1Connection context)

View File

@ -287,13 +287,13 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
// origin-form. // origin-form.
// The most common form of request-target. // The most common form of request-target.
// https://tools.ietf.org/html/rfc7230#section-5.3.1 // 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) else if (ch == ByteAsterisk && target.Length == 1)
{ {
OnAsteriskFormTarget(method); OnAsteriskFormTarget(method);
} }
else if (target.GetKnownHttpScheme(out var scheme)) else if (target.GetKnownHttpScheme(out _))
{ {
OnAbsoluteFormTarget(target, query); OnAbsoluteFormTarget(target, query);
} }
@ -321,7 +321,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
} }
// Compare with Http2Stream.TryValidatePseudoHeaders // Compare with Http2Stream.TryValidatePseudoHeaders
private void OnOriginFormTarget(HttpMethod method, HttpVersion version, Span<byte> target, Span<byte> path, Span<byte> query, Span<byte> customMethod, bool pathEncoded) private void OnOriginFormTarget(bool pathEncoded, Span<byte> target, Span<byte> path, Span<byte> query)
{ {
Debug.Assert(target[0] == ByteForwardSlash, "Should only be called when path starts with /"); Debug.Assert(target[0] == ByteForwardSlash, "Should only be called when path starts with /");

View File

@ -171,7 +171,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
return _flusher.FlushAsync(_minResponseDataRateFeature.MinDataRate, bytesWritten, this, cancellationToken); return _flusher.FlushAsync(_minResponseDataRateFeature.MinDataRate, bytesWritten, this, cancellationToken);
} }
ValueTask<FlushResult> FlushAsyncChunked(Http1OutputProducer producer, CancellationToken token) static ValueTask<FlushResult> 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. // Local function so in the common-path the stack space for BufferWriter isn't reserved and cleared when it isn't used.

View File

@ -5,6 +5,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Buffers; using System.Buffers;
using System.IO.Pipelines; using System.IO.Pipelines;
using System.Numerics;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using Microsoft.Extensions.Primitives; using Microsoft.Extensions.Primitives;
@ -875,7 +876,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
protected override int GetCountFast() 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) 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() 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) protected override bool TryGetValueFast(string key, out StringValues value)
@ -10275,7 +10276,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
_contentLength = null; _contentLength = null;
var tempBits = _bits; var tempBits = _bits;
_bits = 0; _bits = 0;
if(HttpHeaders.BitCount(tempBits) > 12) if(BitOperations.PopCount((ulong)tempBits) > 12)
{ {
_headers = default(HeaderReferences); _headers = default(HeaderReferences);
return; return;
@ -11848,7 +11849,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
protected override int GetCountFast() 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) protected override bool TryGetValueFast(string key, out StringValues value)
@ -11985,7 +11986,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
_contentLength = null; _contentLength = null;
var tempBits = _bits; var tempBits = _bits;
_bits = 0; _bits = 0;
if(HttpHeaders.BitCount(tempBits) > 12) if(BitOperations.PopCount((ulong)tempBits) > 12)
{ {
_headers = default(HeaderReferences); _headers = default(HeaderReferences);
return; return;

View File

@ -133,31 +133,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
[MethodImpl(MethodImplOptions.NoInlining)] [MethodImpl(MethodImplOptions.NoInlining)]
protected bool RemoveUnknown(string key) => MaybeUnknown?.Remove(key) ?? false; 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() protected virtual int GetCountFast()
{ throw new NotImplementedException(); } { throw new NotImplementedException(); }
@ -222,8 +197,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
bool IDictionary<string, StringValues>.ContainsKey(string key) bool IDictionary<string, StringValues>.ContainsKey(string key)
{ {
StringValues value; return TryGetValueFast(key, out _);
return TryGetValueFast(key, out value);
} }
void ICollection<KeyValuePair<string, StringValues>>.CopyTo(KeyValuePair<string, StringValues>[] array, int arrayIndex) void ICollection<KeyValuePair<string, StringValues>>.CopyTo(KeyValuePair<string, StringValues>[] array, int arrayIndex)

View File

@ -12,7 +12,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
{ {
public class HttpParser<TRequestHandler> : IHttpParser<TRequestHandler> where TRequestHandler : IHttpHeadersHandler, IHttpRequestLineHandler public class HttpParser<TRequestHandler> : IHttpParser<TRequestHandler> where TRequestHandler : IHttpHeadersHandler, IHttpRequestLineHandler
{ {
private bool _showErrorDetails; private readonly bool _showErrorDetails;
public HttpParser() : this(showErrorDetails: true) public HttpParser() : this(showErrorDetails: true)
{ {

View File

@ -36,7 +36,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
private Stack<KeyValuePair<Func<object, Task>, object>> _onStarting; private Stack<KeyValuePair<Func<object, Task>, object>> _onStarting;
private Stack<KeyValuePair<Func<object, Task>, object>> _onCompleted; private Stack<KeyValuePair<Func<object, Task>, object>> _onCompleted;
private object _abortLock = new object(); private readonly object _abortLock = new object();
private volatile bool _connectionAborted; private volatile bool _connectionAborted;
private bool _preventRequestAbortedCancellation; private bool _preventRequestAbortedCancellation;
private CancellationTokenSource _abortedCts; 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) private void VerifyAndUpdateWrite(int count)
{ {
var responseHeaders = HttpResponseHeaders; var responseHeaders = HttpResponseHeaders;
@ -1554,7 +1548,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
return await Output.FlushAsync(cancellationToken); return await Output.FlushAsync(cancellationToken);
} }
public Task WriteAsync(ReadOnlyMemory<byte> data, CancellationToken cancellationToken = default(CancellationToken)) public Task WriteAsync(ReadOnlyMemory<byte> data, CancellationToken cancellationToken = default)
{ {
return WritePipeAsync(data, cancellationToken).GetAsTask(); return WritePipeAsync(data, cancellationToken).GetAsTask();
} }

View File

@ -132,11 +132,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
_collection = collection; _collection = collection;
_bits = collection._bits; _bits = collection._bits;
_next = 0; _next = 0;
_current = default(KeyValuePair<string, StringValues>); _current = default;
_hasUnknown = collection.MaybeUnknown != null; _hasUnknown = collection.MaybeUnknown != null;
_unknownEnumerator = _hasUnknown _unknownEnumerator = _hasUnknown
? collection.MaybeUnknown.GetEnumerator() ? collection.MaybeUnknown.GetEnumerator()
: default(Dictionary<string, StringValues>.Enumerator); : default;
} }
public KeyValuePair<string, StringValues> Current => _current; public KeyValuePair<string, StringValues> Current => _current;

View File

@ -123,8 +123,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
} }
} }
void ThrowObjectDisposedException() => throw new ObjectDisposedException(nameof(HttpRequestStream)); static void ThrowObjectDisposedException() => throw new ObjectDisposedException(nameof(HttpRequestStream));
void ThrowTaskCanceledException() => throw new TaskCanceledException(); static void ThrowTaskCanceledException() => throw new TaskCanceledException();
} }
} }
} }

View File

@ -4,7 +4,6 @@
using System; using System;
using System.Buffers; using System.Buffers;
using System.IO; using System.IO;
using System.IO.Pipelines;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Connections; using Microsoft.AspNetCore.Connections;
@ -14,7 +13,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
{ {
internal sealed class HttpRequestStream : Stream internal sealed class HttpRequestStream : Stream
{ {
private HttpRequestPipeReader _pipeReader; private readonly HttpRequestPipeReader _pipeReader;
private readonly IHttpBodyControlFeature _bodyControl; private readonly IHttpBodyControlFeature _bodyControl;
public HttpRequestStream(IHttpBodyControlFeature bodyControl, HttpRequestPipeReader pipeReader) public HttpRequestStream(IHttpBodyControlFeature bodyControl, HttpRequestPipeReader pipeReader)
@ -155,12 +154,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
var readableBufferLength = readableBuffer.Length; var readableBufferLength = readableBuffer.Length;
var consumed = readableBuffer.End; var consumed = readableBuffer.End;
var actual = 0;
try try
{ {
if (readableBufferLength != 0) 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); var slice = actual == readableBufferLength ? readableBuffer : readableBuffer.Slice(0, actual);
consumed = slice.End; consumed = slice.End;

View File

@ -14,8 +14,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
{ {
internal sealed partial class HttpResponseHeaders : HttpHeaders internal sealed partial class HttpResponseHeaders : HttpHeaders
{ {
private static ReadOnlySpan<byte> _CrLf => new[] { (byte)'\r', (byte)'\n' }; private static ReadOnlySpan<byte> CrLf => new[] { (byte)'\r', (byte)'\n' };
private static ReadOnlySpan<byte> _colonSpace => new[] { (byte)':', (byte)' ' }; private static ReadOnlySpan<byte> ColonSpace => new[] { (byte)':', (byte)' ' };
public Enumerator GetEnumerator() public Enumerator GetEnumerator()
{ {
@ -46,9 +46,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
{ {
if (value != null) if (value != null)
{ {
buffer.Write(_CrLf); buffer.Write(CrLf);
buffer.WriteAsciiNoValidation(kv.Key); buffer.WriteAsciiNoValidation(kv.Key);
buffer.Write(_colonSpace); buffer.Write(ColonSpace);
buffer.WriteAsciiNoValidation(value); buffer.WriteAsciiNoValidation(value);
} }
} }

View File

@ -104,7 +104,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
ThrowObjectDisposedException(); ThrowObjectDisposedException();
} }
void ThrowObjectDisposedException() static void ThrowObjectDisposedException()
{ {
throw new ObjectDisposedException(nameof(HttpResponseStream), CoreStrings.WritingToResponseBodyAfterResponseCompleted); throw new ObjectDisposedException(nameof(HttpResponseStream), CoreStrings.WritingToResponseBodyAfterResponseCompleted);
} }

View File

@ -187,8 +187,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
public static unsafe bool ContainsDotSegments(byte* start, byte* end) public static unsafe bool ContainsDotSegments(byte* start, byte* end)
{ {
var src = start; var src = start;
var dst = start;
while (src < end) while (src < end)
{ {
var ch1 = *src; var ch1 = *src;

View File

@ -18,7 +18,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
public override bool IsEmpty => true; public override bool IsEmpty => true;
public override ValueTask<ReadResult> ReadAsync(CancellationToken cancellationToken = default(CancellationToken)) => new ValueTask<ReadResult>(new ReadResult(default, isCanceled: false, isCompleted: true)); public override ValueTask<ReadResult> ReadAsync(CancellationToken cancellationToken = default) => new ValueTask<ReadResult>(new ReadResult(default, isCanceled: false, isCompleted: true));
public override Task ConsumeAsync() => Task.CompletedTask; public override Task ConsumeAsync() => Task.CompletedTask;

View File

@ -36,17 +36,18 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack
return false; return false;
} }
i = i - ((1 << n) - 1); i -= ((1 << n) - 1);
while (i >= 128) 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) if (j >= buffer.Length)
{ {
return false; 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; buffer[j++] = (byte)i;
} }

View File

@ -82,141 +82,77 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.HPack
public static byte[] ToStatusBytes(int statusCode) public static byte[] ToStatusBytes(int statusCode)
{ {
switch (statusCode) return statusCode switch
{ {
case Microsoft.AspNetCore.Http.StatusCodes.Status100Continue: Microsoft.AspNetCore.Http.StatusCodes.Status100Continue => _bytesStatus100,
return _bytesStatus100; Microsoft.AspNetCore.Http.StatusCodes.Status101SwitchingProtocols => _bytesStatus101,
case Microsoft.AspNetCore.Http.StatusCodes.Status101SwitchingProtocols: Microsoft.AspNetCore.Http.StatusCodes.Status102Processing => _bytesStatus102,
return _bytesStatus101;
case Microsoft.AspNetCore.Http.StatusCodes.Status102Processing:
return _bytesStatus102;
case Microsoft.AspNetCore.Http.StatusCodes.Status200OK: Microsoft.AspNetCore.Http.StatusCodes.Status200OK => _bytesStatus200,
return _bytesStatus200; Microsoft.AspNetCore.Http.StatusCodes.Status201Created => _bytesStatus201,
case Microsoft.AspNetCore.Http.StatusCodes.Status201Created: Microsoft.AspNetCore.Http.StatusCodes.Status202Accepted => _bytesStatus202,
return _bytesStatus201; Microsoft.AspNetCore.Http.StatusCodes.Status203NonAuthoritative => _bytesStatus203,
case Microsoft.AspNetCore.Http.StatusCodes.Status202Accepted: Microsoft.AspNetCore.Http.StatusCodes.Status204NoContent => _bytesStatus204,
return _bytesStatus202; Microsoft.AspNetCore.Http.StatusCodes.Status205ResetContent => _bytesStatus205,
case Microsoft.AspNetCore.Http.StatusCodes.Status203NonAuthoritative: Microsoft.AspNetCore.Http.StatusCodes.Status206PartialContent => _bytesStatus206,
return _bytesStatus203; Microsoft.AspNetCore.Http.StatusCodes.Status207MultiStatus => _bytesStatus207,
case Microsoft.AspNetCore.Http.StatusCodes.Status204NoContent: Microsoft.AspNetCore.Http.StatusCodes.Status208AlreadyReported => _bytesStatus208,
return _bytesStatus204; Microsoft.AspNetCore.Http.StatusCodes.Status226IMUsed => _bytesStatus226,
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;
case Microsoft.AspNetCore.Http.StatusCodes.Status300MultipleChoices: Microsoft.AspNetCore.Http.StatusCodes.Status300MultipleChoices => _bytesStatus300,
return _bytesStatus300; Microsoft.AspNetCore.Http.StatusCodes.Status301MovedPermanently => _bytesStatus301,
case Microsoft.AspNetCore.Http.StatusCodes.Status301MovedPermanently: Microsoft.AspNetCore.Http.StatusCodes.Status302Found => _bytesStatus302,
return _bytesStatus301; Microsoft.AspNetCore.Http.StatusCodes.Status303SeeOther => _bytesStatus303,
case Microsoft.AspNetCore.Http.StatusCodes.Status302Found: Microsoft.AspNetCore.Http.StatusCodes.Status304NotModified => _bytesStatus304,
return _bytesStatus302; Microsoft.AspNetCore.Http.StatusCodes.Status305UseProxy => _bytesStatus305,
case Microsoft.AspNetCore.Http.StatusCodes.Status303SeeOther: Microsoft.AspNetCore.Http.StatusCodes.Status306SwitchProxy => _bytesStatus306,
return _bytesStatus303; Microsoft.AspNetCore.Http.StatusCodes.Status307TemporaryRedirect => _bytesStatus307,
case Microsoft.AspNetCore.Http.StatusCodes.Status304NotModified: Microsoft.AspNetCore.Http.StatusCodes.Status308PermanentRedirect => _bytesStatus308,
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;
case Microsoft.AspNetCore.Http.StatusCodes.Status400BadRequest: Microsoft.AspNetCore.Http.StatusCodes.Status400BadRequest => _bytesStatus400,
return _bytesStatus400; Microsoft.AspNetCore.Http.StatusCodes.Status401Unauthorized => _bytesStatus401,
case Microsoft.AspNetCore.Http.StatusCodes.Status401Unauthorized: Microsoft.AspNetCore.Http.StatusCodes.Status402PaymentRequired => _bytesStatus402,
return _bytesStatus401; Microsoft.AspNetCore.Http.StatusCodes.Status403Forbidden => _bytesStatus403,
case Microsoft.AspNetCore.Http.StatusCodes.Status402PaymentRequired: Microsoft.AspNetCore.Http.StatusCodes.Status404NotFound => _bytesStatus404,
return _bytesStatus402; Microsoft.AspNetCore.Http.StatusCodes.Status405MethodNotAllowed => _bytesStatus405,
case Microsoft.AspNetCore.Http.StatusCodes.Status403Forbidden: Microsoft.AspNetCore.Http.StatusCodes.Status406NotAcceptable => _bytesStatus406,
return _bytesStatus403; Microsoft.AspNetCore.Http.StatusCodes.Status407ProxyAuthenticationRequired => _bytesStatus407,
case Microsoft.AspNetCore.Http.StatusCodes.Status404NotFound: Microsoft.AspNetCore.Http.StatusCodes.Status408RequestTimeout => _bytesStatus408,
return _bytesStatus404; Microsoft.AspNetCore.Http.StatusCodes.Status409Conflict => _bytesStatus409,
case Microsoft.AspNetCore.Http.StatusCodes.Status405MethodNotAllowed: Microsoft.AspNetCore.Http.StatusCodes.Status410Gone => _bytesStatus410,
return _bytesStatus405; Microsoft.AspNetCore.Http.StatusCodes.Status411LengthRequired => _bytesStatus411,
case Microsoft.AspNetCore.Http.StatusCodes.Status406NotAcceptable: Microsoft.AspNetCore.Http.StatusCodes.Status412PreconditionFailed => _bytesStatus412,
return _bytesStatus406; Microsoft.AspNetCore.Http.StatusCodes.Status413PayloadTooLarge => _bytesStatus413,
case Microsoft.AspNetCore.Http.StatusCodes.Status407ProxyAuthenticationRequired: Microsoft.AspNetCore.Http.StatusCodes.Status414UriTooLong => _bytesStatus414,
return _bytesStatus407; Microsoft.AspNetCore.Http.StatusCodes.Status415UnsupportedMediaType => _bytesStatus415,
case Microsoft.AspNetCore.Http.StatusCodes.Status408RequestTimeout: Microsoft.AspNetCore.Http.StatusCodes.Status416RangeNotSatisfiable => _bytesStatus416,
return _bytesStatus408; Microsoft.AspNetCore.Http.StatusCodes.Status417ExpectationFailed => _bytesStatus417,
case Microsoft.AspNetCore.Http.StatusCodes.Status409Conflict: Microsoft.AspNetCore.Http.StatusCodes.Status418ImATeapot => _bytesStatus418,
return _bytesStatus409; Microsoft.AspNetCore.Http.StatusCodes.Status419AuthenticationTimeout => _bytesStatus419,
case Microsoft.AspNetCore.Http.StatusCodes.Status410Gone: Microsoft.AspNetCore.Http.StatusCodes.Status421MisdirectedRequest => _bytesStatus421,
return _bytesStatus410; Microsoft.AspNetCore.Http.StatusCodes.Status422UnprocessableEntity => _bytesStatus422,
case Microsoft.AspNetCore.Http.StatusCodes.Status411LengthRequired: Microsoft.AspNetCore.Http.StatusCodes.Status423Locked => _bytesStatus423,
return _bytesStatus411; Microsoft.AspNetCore.Http.StatusCodes.Status424FailedDependency => _bytesStatus424,
case Microsoft.AspNetCore.Http.StatusCodes.Status412PreconditionFailed: Microsoft.AspNetCore.Http.StatusCodes.Status426UpgradeRequired => _bytesStatus426,
return _bytesStatus412; Microsoft.AspNetCore.Http.StatusCodes.Status428PreconditionRequired => _bytesStatus428,
case Microsoft.AspNetCore.Http.StatusCodes.Status413PayloadTooLarge: Microsoft.AspNetCore.Http.StatusCodes.Status429TooManyRequests => _bytesStatus429,
return _bytesStatus413; Microsoft.AspNetCore.Http.StatusCodes.Status431RequestHeaderFieldsTooLarge => _bytesStatus431,
case Microsoft.AspNetCore.Http.StatusCodes.Status414UriTooLong: Microsoft.AspNetCore.Http.StatusCodes.Status451UnavailableForLegalReasons => _bytesStatus451,
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;
case Microsoft.AspNetCore.Http.StatusCodes.Status500InternalServerError: Microsoft.AspNetCore.Http.StatusCodes.Status500InternalServerError => _bytesStatus500,
return _bytesStatus500; Microsoft.AspNetCore.Http.StatusCodes.Status501NotImplemented => _bytesStatus501,
case Microsoft.AspNetCore.Http.StatusCodes.Status501NotImplemented: Microsoft.AspNetCore.Http.StatusCodes.Status502BadGateway => _bytesStatus502,
return _bytesStatus501; Microsoft.AspNetCore.Http.StatusCodes.Status503ServiceUnavailable => _bytesStatus503,
case Microsoft.AspNetCore.Http.StatusCodes.Status502BadGateway: Microsoft.AspNetCore.Http.StatusCodes.Status504GatewayTimeout => _bytesStatus504,
return _bytesStatus502; Microsoft.AspNetCore.Http.StatusCodes.Status505HttpVersionNotsupported => _bytesStatus505,
case Microsoft.AspNetCore.Http.StatusCodes.Status503ServiceUnavailable: Microsoft.AspNetCore.Http.StatusCodes.Status506VariantAlsoNegotiates => _bytesStatus506,
return _bytesStatus503; Microsoft.AspNetCore.Http.StatusCodes.Status507InsufficientStorage => _bytesStatus507,
case Microsoft.AspNetCore.Http.StatusCodes.Status504GatewayTimeout: Microsoft.AspNetCore.Http.StatusCodes.Status508LoopDetected => _bytesStatus508,
return _bytesStatus504; Microsoft.AspNetCore.Http.StatusCodes.Status510NotExtended => _bytesStatus510,
case Microsoft.AspNetCore.Http.StatusCodes.Status505HttpVersionNotsupported: Microsoft.AspNetCore.Http.StatusCodes.Status511NetworkAuthenticationRequired => _bytesStatus511,
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;
default: _ => CreateStatusBytes(statusCode)
return Encoding.ASCII.GetBytes(statusCode.ToString(CultureInfo.InvariantCulture)); };
}
} }
} }
} }

View File

@ -396,31 +396,20 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2
throw new Http2ConnectionErrorException(CoreStrings.FormatHttp2ErrorStreamIdEven(_incomingFrame.Type, _incomingFrame.StreamId), Http2ErrorCode.PROTOCOL_ERROR); throw new Http2ConnectionErrorException(CoreStrings.FormatHttp2ErrorStreamIdEven(_incomingFrame.Type, _incomingFrame.StreamId), Http2ErrorCode.PROTOCOL_ERROR);
} }
switch (_incomingFrame.Type) return _incomingFrame.Type switch
{ {
case Http2FrameType.DATA: Http2FrameType.DATA => ProcessDataFrameAsync(payload),
return ProcessDataFrameAsync(payload); Http2FrameType.HEADERS => ProcessHeadersFrameAsync(application, payload),
case Http2FrameType.HEADERS: Http2FrameType.PRIORITY => ProcessPriorityFrameAsync(),
return ProcessHeadersFrameAsync(application, payload); Http2FrameType.RST_STREAM => ProcessRstStreamFrameAsync(),
case Http2FrameType.PRIORITY: Http2FrameType.SETTINGS => ProcessSettingsFrameAsync(payload),
return ProcessPriorityFrameAsync(); Http2FrameType.PUSH_PROMISE => throw new Http2ConnectionErrorException(CoreStrings.Http2ErrorPushPromiseReceived, Http2ErrorCode.PROTOCOL_ERROR),
case Http2FrameType.RST_STREAM: Http2FrameType.PING => ProcessPingFrameAsync(payload),
return ProcessRstStreamFrameAsync(); Http2FrameType.GOAWAY => ProcessGoAwayFrameAsync(),
case Http2FrameType.SETTINGS: Http2FrameType.WINDOW_UPDATE => ProcessWindowUpdateFrameAsync(),
return ProcessSettingsFrameAsync(payload); Http2FrameType.CONTINUATION => ProcessContinuationFrameAsync(payload),
case Http2FrameType.PUSH_PROMISE: _ => ProcessUnknownFrameAsync(),
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();
}
} }
private Task ProcessDataFrameAsync(in ReadOnlySequence<byte> payload) private Task ProcessDataFrameAsync(in ReadOnlySequence<byte> payload)

View File

@ -22,7 +22,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2
internal class Http2FrameWriter internal class Http2FrameWriter
{ {
// Literal Header Field without Indexing - Indexed Name (Index 8 - :status) // Literal Header Field without Indexing - Indexed Name (Index 8 - :status)
private static ReadOnlySpan<byte> _continueBytes => new byte[] { 0x08, 0x03, (byte)'1', (byte)'0', (byte)'0' }; private static ReadOnlySpan<byte> ContinueBytes => new byte[] { 0x08, 0x03, (byte)'1', (byte)'0', (byte)'0' };
private readonly object _writeLock = new object(); private readonly object _writeLock = new object();
private readonly Http2Frame _outgoingFrame; private readonly Http2Frame _outgoingFrame;
@ -138,9 +138,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2
} }
_outgoingFrame.PrepareHeaders(Http2HeadersFrameFlags.END_HEADERS, streamId); _outgoingFrame.PrepareHeaders(Http2HeadersFrameFlags.END_HEADERS, streamId);
_outgoingFrame.PayloadLength = _continueBytes.Length; _outgoingFrame.PayloadLength = ContinueBytes.Length;
WriteHeaderUnsynchronized(); WriteHeaderUnsynchronized();
_outputWriter.Write(_continueBytes); _outputWriter.Write(ContinueBytes);
return TimeFlushUnsynchronizedAsync(); return TimeFlushUnsynchronizedAsync();
} }
} }
@ -545,7 +545,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2
return default; return default;
} }
_outgoingFrame.PreparePing(Http2PingFrameFlags.ACK); _outgoingFrame.PreparePing(flags);
Debug.Assert(payload.Length == _outgoingFrame.PayloadLength); // 8 Debug.Assert(payload.Length == _outgoingFrame.PayloadLength); // 8
WriteHeaderUnsynchronized(); WriteHeaderUnsynchronized();
foreach (var segment in payload) foreach (var segment in payload)

View File

@ -95,11 +95,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2
_stream.ResetAndAbort(abortReason, Http2ErrorCode.INTERNAL_ERROR); _stream.ResetAndAbort(abortReason, Http2ErrorCode.INTERNAL_ERROR);
} }
public Task WriteChunkAsync(ReadOnlySpan<byte> span, CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
public ValueTask<FlushResult> FlushAsync(CancellationToken cancellationToken) public ValueTask<FlushResult> FlushAsync(CancellationToken cancellationToken)
{ {
if (cancellationToken.IsCancellationRequested) if (cancellationToken.IsCancellationRequested)

View File

@ -94,8 +94,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2
{ {
Log.RequestBodyNotEntirelyRead(ConnectionIdFeature, TraceIdentifier); Log.RequestBodyNotEntirelyRead(ConnectionIdFeature, TraceIdentifier);
var states = ApplyCompletionFlag(StreamCompletionFlags.Aborted); var (oldState, newState) = ApplyCompletionFlag(StreamCompletionFlags.Aborted);
if (states.OldState != states.NewState) if (oldState != newState)
{ {
// Don't block on IO. This never faults. // Don't block on IO. This never faults.
_ = _http2Output.WriteRstStreamAsync(Http2ErrorCode.NO_ERROR); _ = _http2Output.WriteRstStreamAsync(Http2ErrorCode.NO_ERROR);
@ -425,9 +425,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2
public void Abort(IOException abortReason) 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; return;
} }
@ -451,9 +451,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2
internal void ResetAndAbort(ConnectionAbortedException abortReason, Http2ErrorCode error) internal void ResetAndAbort(ConnectionAbortedException abortReason, Http2ErrorCode error)
{ {
// Future incoming frames will drain for a default grace period to avoid destabilizing the connection. // 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; return;
} }

View File

@ -422,15 +422,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure
public static string VersionToString(HttpVersion httpVersion) public static string VersionToString(HttpVersion httpVersion)
{ {
switch (httpVersion) return httpVersion switch
{ {
case HttpVersion.Http10: HttpVersion.Http10 => Http10Version,
return Http10Version; HttpVersion.Http11 => Http11Version,
case HttpVersion.Http11: _ => null,
return Http11Version; };
default:
return null;
}
} }
public static string MethodToString(HttpMethod method) public static string MethodToString(HttpMethod method)
{ {
@ -445,15 +442,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure
public static string SchemeToString(HttpScheme scheme) public static string SchemeToString(HttpScheme scheme)
{ {
switch (scheme) return scheme switch
{ {
case HttpScheme.Http: HttpScheme.Http => HttpUriScheme,
return HttpUriScheme; HttpScheme.Https => HttpsUriScheme,
case HttpScheme.Https: _ => null,
return HttpsUriScheme; };
default:
return null;
}
} }
public static bool IsHostHeaderValid(string hostText) public static bool IsHostHeaderValid(string hostText)

View File

@ -60,10 +60,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure.PipeW
return new ValueTask<FlushResult>(pipeFlushTask.Result); return new ValueTask<FlushResult>(pipeFlushTask.Result);
} }
return TimeFlushAsyncAwaited(pipeFlushTask, minRate, count, outputAborter, cancellationToken); return TimeFlushAsyncAwaited(pipeFlushTask, minRate, outputAborter, cancellationToken);
} }
private async ValueTask<FlushResult> TimeFlushAsyncAwaited(ValueTask<FlushResult> pipeFlushTask, MinDataRate minRate, long count, IHttpOutputAborter outputAborter, CancellationToken cancellationToken) private async ValueTask<FlushResult> TimeFlushAsyncAwaited(ValueTask<FlushResult> pipeFlushTask, MinDataRate minRate, IHttpOutputAborter outputAborter, CancellationToken cancellationToken)
{ {
if (minRate != null) if (minRate != null)
{ {

View File

@ -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) 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) if (callback != null)
{ {
task.ContinueWith(t => callback.Invoke(t)); 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) 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) if (callback != null)
{ {
task.ContinueWith(t => callback.Invoke(t)); task.ContinueWith(t => callback.Invoke(t));

View File

@ -40,7 +40,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.Internal
return BytesTransferred; return BytesTransferred;
void ThrowSocketException(SocketError e) static void ThrowSocketException(SocketError e)
{ {
throw new SocketException((int)e); throw new SocketException((int)e);
} }

View File

@ -579,6 +579,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Buffers; using System.Buffers;
using System.IO.Pipelines; using System.IO.Pipelines;
using System.Numerics;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using Microsoft.Extensions.Primitives; using Microsoft.Extensions.Primitives;
@ -642,7 +643,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
}}")} }}")}
protected override int GetCountFast() 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) protected override bool TryGetValueFast(string key, out StringValues value)
@ -824,7 +825,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
_contentLength = null; _contentLength = null;
var tempBits = _bits; var tempBits = _bits;
_bits = 0; _bits = 0;
if(HttpHeaders.BitCount(tempBits) > 12) if(BitOperations.PopCount((ulong)tempBits) > 12)
{{ {{
_headers = default(HeaderReferences); _headers = default(HeaderReferences);
return; return;