parent
b57ac72431
commit
1fa001e7db
|
|
@ -16,7 +16,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance
|
|||
{
|
||||
private const int InnerLoopCount = 512;
|
||||
|
||||
public ReadableBuffer _buffer;
|
||||
public ReadOnlyBuffer _buffer;
|
||||
public Http1Connection _http1Connection;
|
||||
|
||||
[IterationSetup]
|
||||
|
|
|
|||
|
|
@ -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.Buffers;
|
||||
using System.IO.Pipelines;
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
|
||||
|
|
@ -12,7 +13,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance
|
|||
{
|
||||
private readonly HttpParser<Adapter> _parser = new HttpParser<Adapter>();
|
||||
|
||||
private ReadableBuffer _buffer;
|
||||
private ReadOnlyBuffer _buffer;
|
||||
|
||||
[Benchmark(Baseline = true, OperationsPerInvoke = RequestParsingData.InnerLoopCount)]
|
||||
public void PlaintextTechEmpower()
|
||||
|
|
@ -46,7 +47,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance
|
|||
|
||||
private void InsertData(byte[] data)
|
||||
{
|
||||
_buffer = ReadableBuffer.Create(data);
|
||||
_buffer = new ReadOnlyBuffer(data);
|
||||
}
|
||||
|
||||
private void ParseData()
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.Collections.Sequences;
|
||||
using System.IO.Pipelines;
|
||||
using System.Text;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
|
||||
|
|
@ -21,7 +23,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance
|
|||
|
||||
public static readonly NullParser<Http1ParsingHandler> Instance = new NullParser<Http1ParsingHandler>();
|
||||
|
||||
public bool ParseHeaders(TRequestHandler handler, ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined, out int consumedBytes)
|
||||
public bool ParseHeaders(TRequestHandler handler, ReadOnlyBuffer buffer, out Position consumed, out Position examined, out int consumedBytes)
|
||||
{
|
||||
handler.OnHeader(new Span<byte>(_hostHeaderName), new Span<byte>(_hostHeaderValue));
|
||||
handler.OnHeader(new Span<byte>(_acceptHeaderName), new Span<byte>(_acceptHeaderValue));
|
||||
|
|
@ -34,7 +36,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance
|
|||
return true;
|
||||
}
|
||||
|
||||
public bool ParseRequestLine(TRequestHandler handler, ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined)
|
||||
public bool ParseRequestLine(TRequestHandler handler, ReadOnlyBuffer buffer, out Position consumed, out Position examined)
|
||||
{
|
||||
handler.OnStartLine(HttpMethod.Get,
|
||||
HttpVersion.Http11,
|
||||
|
|
|
|||
|
|
@ -25,20 +25,21 @@
|
|||
<MicrosoftExtensionsLoggingTestingPackageVersion>2.1.0-preview1-27965</MicrosoftExtensionsLoggingTestingPackageVersion>
|
||||
<MicrosoftExtensionsOptionsPackageVersion>2.1.0-preview1-27965</MicrosoftExtensionsOptionsPackageVersion>
|
||||
<MicrosoftNETCoreApp20PackageVersion>2.0.0</MicrosoftNETCoreApp20PackageVersion>
|
||||
<MicrosoftNETCoreApp21PackageVersion>2.1.0-preview1-26016-05</MicrosoftNETCoreApp21PackageVersion>
|
||||
<MicrosoftNETCoreApp21PackageVersion>2.1.0-preview1-26102-01</MicrosoftNETCoreApp21PackageVersion>
|
||||
<MicrosoftNetHttpHeadersPackageVersion>2.1.0-preview1-27965</MicrosoftNetHttpHeadersPackageVersion>
|
||||
<MicrosoftNETTestSdkPackageVersion>15.3.0</MicrosoftNETTestSdkPackageVersion>
|
||||
<MoqPackageVersion>4.7.49</MoqPackageVersion>
|
||||
<NewtonsoftJsonPackageVersion>10.0.1</NewtonsoftJsonPackageVersion>
|
||||
<SystemBuffersPackageVersion>4.5.0-preview1-26016-05</SystemBuffersPackageVersion>
|
||||
<SystemIOPipelinesPackageVersion>0.1.0-e171215-1</SystemIOPipelinesPackageVersion>
|
||||
<SystemIOPipelinesTestingPackageVersion>0.1.0-e171215-1</SystemIOPipelinesTestingPackageVersion>
|
||||
<SystemMemoryPackageVersion>4.5.0-preview1-26016-05</SystemMemoryPackageVersion>
|
||||
<SystemNumericsVectorsPackageVersion>4.5.0-preview1-26016-05</SystemNumericsVectorsPackageVersion>
|
||||
<SystemRuntimeCompilerServicesUnsafePackageVersion>4.5.0-preview1-26016-05</SystemRuntimeCompilerServicesUnsafePackageVersion>
|
||||
<SystemSecurityCryptographyCngPackageVersion>4.5.0-preview1-26016-05</SystemSecurityCryptographyCngPackageVersion>
|
||||
<SystemTextEncodingsWebUtf8PackageVersion>0.1.0-e171215-1</SystemTextEncodingsWebUtf8PackageVersion>
|
||||
<SystemThreadingTasksExtensionsPackageVersion>4.5.0-preview2-25707-02</SystemThreadingTasksExtensionsPackageVersion>
|
||||
<SystemBuffersPackageVersion>4.5.0-preview1-26102-01</SystemBuffersPackageVersion>
|
||||
<SystemBuffersPrimitivesPackageVersion>0.1.0-e180104-2</SystemBuffersPrimitivesPackageVersion>
|
||||
<SystemIOPipelinesPackageVersion>0.1.0-e180104-2</SystemIOPipelinesPackageVersion>
|
||||
<SystemIOPipelinesTestingPackageVersion>0.1.0-e180104-2</SystemIOPipelinesTestingPackageVersion>
|
||||
<SystemMemoryPackageVersion>4.5.0-preview1-26102-01</SystemMemoryPackageVersion>
|
||||
<SystemNumericsVectorsPackageVersion>4.5.0-preview1-26102-01</SystemNumericsVectorsPackageVersion>
|
||||
<SystemRuntimeCompilerServicesUnsafePackageVersion>4.5.0-preview1-26102-01</SystemRuntimeCompilerServicesUnsafePackageVersion>
|
||||
<SystemSecurityCryptographyCngPackageVersion>4.5.0-preview1-26102-01</SystemSecurityCryptographyCngPackageVersion>
|
||||
<SystemTextEncodingsWebUtf8PackageVersion>0.1.0-e180104-2</SystemTextEncodingsWebUtf8PackageVersion>
|
||||
<SystemThreadingTasksExtensionsPackageVersion>4.5.0-preview1-26102-01</SystemThreadingTasksExtensionsPackageVersion>
|
||||
<XunitAnalyzersPackageVersion>0.8.0</XunitAnalyzersPackageVersion>
|
||||
<XunitPackageVersion>2.3.1</XunitPackageVersion>
|
||||
<XunitRunnerVisualStudioPackageVersion>2.3.1</XunitRunnerVisualStudioPackageVersion>
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ using System.IO;
|
|||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
|
||||
using System.IO.Pipelines;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Adapter.Internal
|
||||
{
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal
|
|||
}
|
||||
|
||||
// Internal for testing
|
||||
internal static PipeOptions GetInputPipeOptions(ServiceContext serviceContext, MemoryPool memoryPool, IScheduler writerScheduler) => new PipeOptions
|
||||
internal static PipeOptions GetInputPipeOptions(ServiceContext serviceContext, MemoryPool memoryPool, Scheduler writerScheduler) => new PipeOptions
|
||||
(
|
||||
pool: memoryPool,
|
||||
readerScheduler: serviceContext.ThreadPool,
|
||||
|
|
@ -92,7 +92,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal
|
|||
maximumSizeLow: serviceContext.ServerOptions.Limits.MaxRequestBufferSize ?? 0
|
||||
);
|
||||
|
||||
internal static PipeOptions GetOutputPipeOptions(ServiceContext serviceContext, MemoryPool memoryPool, IScheduler readerScheduler) => new PipeOptions
|
||||
internal static PipeOptions GetOutputPipeOptions(ServiceContext serviceContext, MemoryPool memoryPool, Scheduler readerScheduler) => new PipeOptions
|
||||
(
|
||||
pool: memoryPool,
|
||||
readerScheduler: readerScheduler,
|
||||
|
|
|
|||
|
|
@ -2,11 +2,14 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.Collections.Sequences;
|
||||
using System.Diagnostics;
|
||||
using System.IO.Pipelines;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Text.Encodings.Web.Utf8;
|
||||
using System.Threading;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure;
|
||||
|
||||
|
|
@ -66,7 +69,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
Input.CancelPendingRead();
|
||||
}
|
||||
|
||||
public void ParseRequest(ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined)
|
||||
public void ParseRequest(ReadOnlyBuffer buffer, out Position consumed, out Position examined)
|
||||
{
|
||||
consumed = buffer.Start;
|
||||
examined = buffer.End;
|
||||
|
|
@ -104,7 +107,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
}
|
||||
}
|
||||
|
||||
public bool TakeStartLine(ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined)
|
||||
public bool TakeStartLine(ReadOnlyBuffer buffer, out Position consumed, out Position examined)
|
||||
{
|
||||
var overLength = false;
|
||||
if (buffer.Length >= ServerOptions.Limits.MaxRequestLineSize)
|
||||
|
|
@ -122,7 +125,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
return result;
|
||||
}
|
||||
|
||||
public bool TakeMessageHeaders(ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined)
|
||||
public bool TakeMessageHeaders(ReadOnlyBuffer buffer, out Position consumed, out Position examined)
|
||||
{
|
||||
// Make sure the buffer is limited
|
||||
bool overLength = false;
|
||||
|
|
@ -424,7 +427,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
TimeoutControl.SetTimeout(_keepAliveTicks, TimeoutAction.StopProcessingNextRequest);
|
||||
}
|
||||
|
||||
protected override bool BeginRead(out ReadableBufferAwaitable awaitable)
|
||||
protected override bool BeginRead(out ValueAwaiter<ReadResult> awaitable)
|
||||
{
|
||||
awaitable = Input.ReadAsync();
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.Collections.Sequences;
|
||||
using System.IO;
|
||||
using System.IO.Pipelines;
|
||||
using System.Threading.Tasks;
|
||||
|
|
@ -149,7 +151,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
}
|
||||
}
|
||||
|
||||
protected void Copy(ReadableBuffer readableBuffer, WritableBuffer writableBuffer)
|
||||
protected void Copy(ReadOnlyBuffer readableBuffer, WritableBuffer writableBuffer)
|
||||
{
|
||||
_context.TimeoutControl.BytesRead(readableBuffer.Length);
|
||||
|
||||
|
|
@ -171,7 +173,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
_pumpTask = PumpAsync();
|
||||
}
|
||||
|
||||
protected virtual bool Read(ReadableBuffer readableBuffer, WritableBuffer writableBuffer, out ReadCursor consumed, out ReadCursor examined)
|
||||
protected virtual bool Read(ReadOnlyBuffer readableBuffer, WritableBuffer writableBuffer, out Position consumed, out Position examined)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
|
@ -296,7 +298,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
RequestUpgrade = true;
|
||||
}
|
||||
|
||||
protected override bool Read(ReadableBuffer readableBuffer, WritableBuffer writableBuffer, out ReadCursor consumed, out ReadCursor examined)
|
||||
protected override bool Read(ReadOnlyBuffer readableBuffer, WritableBuffer writableBuffer, out Position consumed, out Position examined)
|
||||
{
|
||||
Copy(readableBuffer, writableBuffer);
|
||||
consumed = readableBuffer.End;
|
||||
|
|
@ -318,7 +320,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
_inputLength = _contentLength;
|
||||
}
|
||||
|
||||
protected override bool Read(ReadableBuffer readableBuffer, WritableBuffer writableBuffer, out ReadCursor consumed, out ReadCursor examined)
|
||||
protected override bool Read(ReadOnlyBuffer readableBuffer, WritableBuffer writableBuffer, out Position consumed, out Position examined)
|
||||
{
|
||||
if (_inputLength == 0)
|
||||
{
|
||||
|
|
@ -366,10 +368,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
RequestKeepAlive = keepAlive;
|
||||
}
|
||||
|
||||
protected override bool Read(ReadableBuffer readableBuffer, WritableBuffer writableBuffer, out ReadCursor consumed, out ReadCursor examined)
|
||||
protected override bool Read(ReadOnlyBuffer readableBuffer, WritableBuffer writableBuffer, out Position consumed, out Position examined)
|
||||
{
|
||||
consumed = default(ReadCursor);
|
||||
examined = default(ReadCursor);
|
||||
consumed = default(Position);
|
||||
examined = default(Position);
|
||||
|
||||
while (_mode < Mode.Trailer)
|
||||
{
|
||||
|
|
@ -457,17 +459,17 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
}
|
||||
}
|
||||
|
||||
private void ParseChunkedPrefix(ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined)
|
||||
private void ParseChunkedPrefix(ReadOnlyBuffer buffer, out Position consumed, out Position examined)
|
||||
{
|
||||
consumed = buffer.Start;
|
||||
examined = buffer.Start;
|
||||
var reader = new ReadableBufferReader(buffer);
|
||||
var reader = BufferReader.Create(buffer);
|
||||
var ch1 = reader.Take();
|
||||
var ch2 = reader.Take();
|
||||
|
||||
if (ch1 == -1 || ch2 == -1)
|
||||
{
|
||||
examined = reader.Cursor;
|
||||
examined = reader.Position;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -478,8 +480,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
{
|
||||
if (ch1 == ';')
|
||||
{
|
||||
consumed = reader.Cursor;
|
||||
examined = reader.Cursor;
|
||||
consumed = reader.Position;
|
||||
examined = reader.Position;
|
||||
|
||||
AddAndCheckConsumedBytes(reader.ConsumedBytes);
|
||||
_inputLength = chunkSize;
|
||||
|
|
@ -490,14 +492,14 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
ch2 = reader.Take();
|
||||
if (ch2 == -1)
|
||||
{
|
||||
examined = reader.Cursor;
|
||||
examined = reader.Position;
|
||||
return;
|
||||
}
|
||||
|
||||
if (ch1 == '\r' && ch2 == '\n')
|
||||
{
|
||||
consumed = reader.Cursor;
|
||||
examined = reader.Cursor;
|
||||
consumed = reader.Position;
|
||||
examined = reader.Position;
|
||||
|
||||
AddAndCheckConsumedBytes(reader.ConsumedBytes);
|
||||
_inputLength = chunkSize;
|
||||
|
|
@ -513,7 +515,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
_context.ThrowRequestRejected(RequestRejectionReason.BadChunkSizeData);
|
||||
}
|
||||
|
||||
private void ParseExtension(ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined)
|
||||
private void ParseExtension(ReadOnlyBuffer buffer, out Position consumed, out Position examined)
|
||||
{
|
||||
// Chunk-extensions not currently parsed
|
||||
// Just drain the data
|
||||
|
|
@ -522,8 +524,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
|
||||
do
|
||||
{
|
||||
ReadCursor extensionCursor;
|
||||
if (ReadCursorOperations.Seek(buffer.Start, buffer.End, out extensionCursor, ByteCR) == -1)
|
||||
Position extensionCursor;
|
||||
if (ReadOnlyBuffer.Seek(buffer.Start, buffer.End, out extensionCursor, ByteCR) == -1)
|
||||
{
|
||||
// End marker not found yet
|
||||
consumed = buffer.End;
|
||||
|
|
@ -565,7 +567,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
} while (_mode == Mode.Extension);
|
||||
}
|
||||
|
||||
private void ReadChunkedData(ReadableBuffer buffer, WritableBuffer writableBuffer, out ReadCursor consumed, out ReadCursor examined)
|
||||
private void ReadChunkedData(ReadOnlyBuffer buffer, WritableBuffer writableBuffer, out Position consumed, out Position examined)
|
||||
{
|
||||
var actual = Math.Min(buffer.Length, _inputLength);
|
||||
consumed = buffer.Move(buffer.Start, actual);
|
||||
|
|
@ -582,7 +584,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
}
|
||||
}
|
||||
|
||||
private void ParseChunkedSuffix(ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined)
|
||||
private void ParseChunkedSuffix(ReadOnlyBuffer buffer, out Position consumed, out Position examined)
|
||||
{
|
||||
consumed = buffer.Start;
|
||||
examined = buffer.Start;
|
||||
|
|
@ -608,7 +610,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
}
|
||||
}
|
||||
|
||||
private void ParseChunkedTrailer(ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined)
|
||||
private void ParseChunkedTrailer(ReadOnlyBuffer buffer, out Position consumed, out Position examined)
|
||||
{
|
||||
consumed = buffer.Start;
|
||||
examined = buffer.Start;
|
||||
|
|
|
|||
|
|
@ -203,7 +203,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
return FlushAsyncAwaited(awaitable, bytesWritten, cancellationToken);
|
||||
}
|
||||
|
||||
private async Task FlushAsyncAwaited(WritableBufferAwaitable awaitable, long count, CancellationToken cancellationToken)
|
||||
private async Task FlushAsyncAwaited(ValueAwaiter<FlushResult> awaitable, long count, CancellationToken cancellationToken)
|
||||
{
|
||||
// https://github.com/dotnet/corefxlab/issues/1334
|
||||
// Since the flush awaitable doesn't currently support multiple awaiters
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.Collections.Sequences;
|
||||
using System.IO.Pipelines;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
|
@ -31,7 +33,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
private const byte ByteQuestionMark = (byte)'?';
|
||||
private const byte BytePercentage = (byte)'%';
|
||||
|
||||
public unsafe bool ParseRequestLine(TRequestHandler handler, ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined)
|
||||
public unsafe bool ParseRequestLine(TRequestHandler handler, ReadOnlyBuffer buffer, out Position consumed, out Position examined)
|
||||
{
|
||||
consumed = buffer.Start;
|
||||
examined = buffer.End;
|
||||
|
|
@ -186,7 +188,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
handler.OnStartLine(method, httpVersion, targetBuffer, pathBuffer, query, customMethod, pathEncoded);
|
||||
}
|
||||
|
||||
public unsafe bool ParseHeaders(TRequestHandler handler, ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined, out int consumedBytes)
|
||||
public unsafe bool ParseHeaders(TRequestHandler handler, ReadOnlyBuffer buffer, out Position consumed, out Position examined, out int consumedBytes)
|
||||
{
|
||||
consumed = buffer.Start;
|
||||
examined = buffer.End;
|
||||
|
|
@ -194,8 +196,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
|
||||
var bufferEnd = buffer.End;
|
||||
|
||||
var reader = new ReadableBufferReader(buffer);
|
||||
var start = default(ReadableBufferReader);
|
||||
var reader = BufferReader.Create(buffer);
|
||||
var start = default(BufferReader<ReadOnlyBuffer>);
|
||||
var done = false;
|
||||
|
||||
try
|
||||
|
|
@ -276,10 +278,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
}
|
||||
else
|
||||
{
|
||||
var current = reader.Cursor;
|
||||
var current = reader.Position;
|
||||
|
||||
// Split buffers
|
||||
if (ReadCursorOperations.Seek(current, bufferEnd, out var lineEnd, ByteLF) == -1)
|
||||
if (ReadOnlyBuffer.Seek(current, bufferEnd, out var lineEnd, ByteLF) == -1)
|
||||
{
|
||||
// Not there
|
||||
return false;
|
||||
|
|
@ -312,7 +314,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
}
|
||||
finally
|
||||
{
|
||||
consumed = reader.Cursor;
|
||||
consumed = reader.Position;
|
||||
consumedBytes = reader.ConsumedBytes;
|
||||
|
||||
if (done)
|
||||
|
|
@ -412,10 +414,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
private static bool TryGetNewLine(ref ReadableBuffer buffer, out ReadCursor found)
|
||||
private static bool TryGetNewLine(ref ReadOnlyBuffer buffer, out Position found)
|
||||
{
|
||||
var start = buffer.Start;
|
||||
if (ReadCursorOperations.Seek(start, buffer.End, out found, ByteLF) != -1)
|
||||
if (ReadOnlyBuffer.Seek(start, buffer.End, out found, ByteLF) != -1)
|
||||
{
|
||||
// Move 1 byte past the \n
|
||||
found = buffer.Move(found, 1);
|
||||
|
|
|
|||
|
|
@ -380,7 +380,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
{
|
||||
}
|
||||
|
||||
protected virtual bool BeginRead(out ReadableBufferAwaitable awaitable)
|
||||
protected virtual bool BeginRead(out ValueAwaiter<ReadResult> awaitable)
|
||||
{
|
||||
awaitable = default;
|
||||
return false;
|
||||
|
|
@ -1302,7 +1302,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
(
|
||||
pool: _context.MemoryPool,
|
||||
readerScheduler: ServiceContext.ThreadPool,
|
||||
writerScheduler: InlineScheduler.Default,
|
||||
writerScheduler: Scheduler.Inline,
|
||||
maximumSizeHigh: 1,
|
||||
maximumSizeLow: 1
|
||||
));
|
||||
|
|
|
|||
|
|
@ -1,14 +1,16 @@
|
|||
// 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.Buffers;
|
||||
using System.Collections.Sequences;
|
||||
using System.IO.Pipelines;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||
{
|
||||
public interface IHttpParser<TRequestHandler> where TRequestHandler : IHttpHeadersHandler, IHttpRequestLineHandler
|
||||
{
|
||||
bool ParseRequestLine(TRequestHandler handler, ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined);
|
||||
bool ParseRequestLine(TRequestHandler handler, ReadOnlyBuffer buffer, out Position consumed, out Position examined);
|
||||
|
||||
bool ParseHeaders(TRequestHandler handler, ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined, out int consumedBytes);
|
||||
bool ParseHeaders(TRequestHandler handler, ReadOnlyBuffer buffer, out Position consumed, out Position examined, out int consumedBytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.Buffers;
|
||||
using System.IO.Pipelines;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
|
@ -16,7 +17,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
private static byte[] _numericBytesScratch;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static Span<byte> ToSpan(this ReadableBuffer buffer)
|
||||
public static ReadOnlySpan<byte> ToSpan(this ReadOnlyBuffer buffer)
|
||||
{
|
||||
if (buffer.IsSingleSpan)
|
||||
{
|
||||
|
|
@ -35,6 +36,15 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
return result;
|
||||
}
|
||||
|
||||
public static ArraySegment<byte> GetArray(this ReadOnlyMemory<byte> memory)
|
||||
{
|
||||
if (!MemoryMarshal.TryGetArray(memory, out var result))
|
||||
{
|
||||
throw new InvalidOperationException("Buffer backed by array was expected");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public unsafe static void WriteAsciiNoValidation(ref this WritableBufferWriter buffer, string data)
|
||||
{
|
||||
if (string.IsNullOrEmpty(data))
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.Collections.Sequences;
|
||||
using System.Collections.Concurrent;
|
||||
using System.IO.Pipelines;
|
||||
using System.Text;
|
||||
|
|
@ -214,7 +216,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2
|
|||
}
|
||||
}
|
||||
|
||||
private bool ParsePreface(ReadableBuffer readableBuffer, out ReadCursor consumed, out ReadCursor examined)
|
||||
private bool ParsePreface(ReadOnlyBuffer readableBuffer, out Position consumed, out Position examined)
|
||||
{
|
||||
consumed = readableBuffer.Start;
|
||||
examined = readableBuffer.End;
|
||||
|
|
|
|||
|
|
@ -1,13 +1,15 @@
|
|||
// 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.Buffers;
|
||||
using System.Collections.Sequences;
|
||||
using System.IO.Pipelines;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2
|
||||
{
|
||||
public static class Http2FrameReader
|
||||
{
|
||||
public static bool ReadFrame(ReadableBuffer readableBuffer, Http2Frame frame, out ReadCursor consumed, out ReadCursor examined)
|
||||
public static bool ReadFrame(ReadOnlyBuffer readableBuffer, Http2Frame frame, out Position consumed, out Position examined)
|
||||
{
|
||||
consumed = readableBuffer.Start;
|
||||
examined = readableBuffer.End;
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal
|
|||
(
|
||||
pool: MemoryPool,
|
||||
readerScheduler: _context.ServiceContext.ThreadPool,
|
||||
writerScheduler: InlineScheduler.Default,
|
||||
writerScheduler: Scheduler.Inline,
|
||||
maximumSizeHigh: _context.ServiceContext.ServerOptions.Limits.MaxRequestBufferSize ?? 0,
|
||||
maximumSizeLow: _context.ServiceContext.ServerOptions.Limits.MaxRequestBufferSize ?? 0
|
||||
);
|
||||
|
|
@ -81,8 +81,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal
|
|||
internal PipeOptions AdaptedOutputPipeOptions => new PipeOptions
|
||||
(
|
||||
pool: MemoryPool,
|
||||
readerScheduler: InlineScheduler.Default,
|
||||
writerScheduler: InlineScheduler.Default,
|
||||
readerScheduler: Scheduler.Inline,
|
||||
writerScheduler: Scheduler.Inline,
|
||||
maximumSizeHigh: _context.ServiceContext.ServerOptions.Limits.MaxResponseBufferSize ?? 0,
|
||||
maximumSizeLow: _context.ServiceContext.ServerOptions.Limits.MaxResponseBufferSize ?? 0
|
||||
);
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ using Microsoft.Extensions.Logging;
|
|||
|
||||
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure
|
||||
{
|
||||
public class InlineLoggingThreadPool : IThreadPool
|
||||
public class InlineLoggingThreadPool : KestrelThreadPool
|
||||
{
|
||||
private readonly IKestrelTrace _log;
|
||||
|
||||
|
|
@ -16,7 +16,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure
|
|||
_log = log;
|
||||
}
|
||||
|
||||
public void Run(Action action)
|
||||
public override void Run(Action action)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
@ -28,12 +28,17 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure
|
|||
}
|
||||
}
|
||||
|
||||
public void UnsafeRun(WaitCallback action, object state)
|
||||
public override void UnsafeRun(WaitCallback action, object state)
|
||||
{
|
||||
action(state);
|
||||
}
|
||||
|
||||
public void Schedule(Action<object> action, object state)
|
||||
public override void Schedule(Action action)
|
||||
{
|
||||
Run(action);
|
||||
}
|
||||
|
||||
public override void Schedule(Action<object> action, object state)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@ using System.Threading;
|
|||
|
||||
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure
|
||||
{
|
||||
public interface IThreadPool : IScheduler
|
||||
public abstract class KestrelThreadPool: Scheduler
|
||||
{
|
||||
void Run(Action action);
|
||||
void UnsafeRun(WaitCallback action, object state);
|
||||
public abstract void Run(Action action);
|
||||
public abstract void UnsafeRun(WaitCallback action, object state);
|
||||
}
|
||||
}
|
||||
|
|
@ -7,7 +7,7 @@ using Microsoft.Extensions.Logging;
|
|||
|
||||
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure
|
||||
{
|
||||
public class LoggingThreadPool : IThreadPool
|
||||
public class LoggingThreadPool : KestrelThreadPool
|
||||
{
|
||||
private readonly IKestrelTrace _log;
|
||||
|
||||
|
|
@ -40,17 +40,22 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure
|
|||
};
|
||||
}
|
||||
|
||||
public void Run(Action action)
|
||||
public override void Run(Action action)
|
||||
{
|
||||
ThreadPool.QueueUserWorkItem(_runAction, action);
|
||||
}
|
||||
|
||||
public void UnsafeRun(WaitCallback action, object state)
|
||||
public override void UnsafeRun(WaitCallback action, object state)
|
||||
{
|
||||
ThreadPool.QueueUserWorkItem(action, state);
|
||||
}
|
||||
|
||||
public void Schedule(Action<object> action, object state)
|
||||
public override void Schedule(Action action)
|
||||
{
|
||||
Run(action);
|
||||
}
|
||||
|
||||
public override void Schedule(Action<object> action, object state)
|
||||
{
|
||||
Run(() => action(state));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal
|
|||
{
|
||||
public IKestrelTrace Log { get; set; }
|
||||
|
||||
public IThreadPool ThreadPool { get; set; }
|
||||
public KestrelThreadPool ThreadPool { get; set; }
|
||||
|
||||
public IHttpParser<Http1ParsingHandler> HttpParser { get; set; }
|
||||
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core
|
|||
|
||||
// TODO: This logic will eventually move into the IConnectionHandler<T> and off
|
||||
// the service context once we get to https://github.com/aspnet/KestrelHttpServer/issues/1662
|
||||
IThreadPool threadPool = null;
|
||||
KestrelThreadPool threadPool = null;
|
||||
switch (serverOptions.ApplicationSchedulingMode)
|
||||
{
|
||||
case SchedulingMode.Default:
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions.Internal
|
|||
public string ConnectionId { get; set; }
|
||||
|
||||
public virtual MemoryPool MemoryPool { get; }
|
||||
public virtual IScheduler InputWriterScheduler { get; }
|
||||
public virtual IScheduler OutputReaderScheduler { get; }
|
||||
public virtual Scheduler InputWriterScheduler { get; }
|
||||
public virtual Scheduler OutputReaderScheduler { get; }
|
||||
|
||||
public IPipeConnection Transport { get; set; }
|
||||
public IPipeConnection Application { get; set; }
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ using System.Buffers;
|
|||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.IO.Pipelines;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Protocols;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions.Internal;
|
||||
|
|
@ -183,7 +184,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Internal
|
|||
_bufferHandle.Dispose();
|
||||
}
|
||||
|
||||
private async Task ApplyBackpressureAsync(WritableBufferAwaitable flushTask)
|
||||
private async Task ApplyBackpressureAsync(ValueAwaiter<FlushResult> flushTask)
|
||||
{
|
||||
Log.ConnectionPause(ConnectionId);
|
||||
_socket.ReadStop();
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Internal
|
|||
public ListenerContext ListenerContext { get; set; }
|
||||
|
||||
public override MemoryPool MemoryPool => ListenerContext.Thread.MemoryPool;
|
||||
public override IScheduler InputWriterScheduler => ListenerContext.Thread;
|
||||
public override IScheduler OutputReaderScheduler => ListenerContext.Thread;
|
||||
public override Scheduler InputWriterScheduler => ListenerContext.Thread;
|
||||
public override Scheduler OutputReaderScheduler => ListenerContext.Thread;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ using Microsoft.Extensions.Logging;
|
|||
|
||||
namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Internal
|
||||
{
|
||||
public class LibuvThread : IScheduler
|
||||
public class LibuvThread : Scheduler
|
||||
{
|
||||
// maximum times the work queues swapped and are processed in a single pass
|
||||
// as completing a task may immediately have write data to put on the network
|
||||
|
|
@ -390,7 +390,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Internal
|
|||
return await Task.WhenAny(task, Task.Delay(timeout)).ConfigureAwait(false) == task;
|
||||
}
|
||||
|
||||
public void Schedule(Action<object> action, object state)
|
||||
public override void Schedule(Action action)
|
||||
{
|
||||
Post(state => state(), action);
|
||||
}
|
||||
|
||||
public override void Schedule(Action<object> action, object state)
|
||||
{
|
||||
Post(action, state);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Internal.Networkin
|
|||
_bufs = handle + requestSize;
|
||||
}
|
||||
|
||||
public LibuvAwaitable<UvWriteReq> WriteAsync(UvStreamHandle handle, ReadableBuffer buffer)
|
||||
public LibuvAwaitable<UvWriteReq> WriteAsync(UvStreamHandle handle, ReadOnlyBuffer buffer)
|
||||
{
|
||||
Write(handle, buffer, LibuvAwaitable<UvWriteReq>.Callback, _awaitable);
|
||||
return _awaitable;
|
||||
|
|
@ -63,7 +63,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Internal.Networkin
|
|||
|
||||
private unsafe void Write(
|
||||
UvStreamHandle handle,
|
||||
ReadableBuffer buffer,
|
||||
ReadOnlyBuffer buffer,
|
||||
Action<UvWriteReq, int, UvException, object> callback,
|
||||
object state)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2,15 +2,24 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.Internal
|
||||
{
|
||||
public static class BufferExtensions
|
||||
{
|
||||
public static ArraySegment<byte> GetArray(this Memory<byte> buffer)
|
||||
public static ArraySegment<byte> GetArray(this Memory<byte> memory)
|
||||
{
|
||||
ArraySegment<byte> result;
|
||||
if (!buffer.TryGetArray(out result))
|
||||
if (!memory.TryGetArray(out var result))
|
||||
{
|
||||
throw new InvalidOperationException("Buffer backed by array was expected");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static ArraySegment<byte> GetArray(this ReadOnlyMemory<byte> memory)
|
||||
{
|
||||
if (!MemoryMarshal.TryGetArray(memory, out var result))
|
||||
{
|
||||
throw new InvalidOperationException("Buffer backed by array was expected");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,8 +52,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.Internal
|
|||
}
|
||||
|
||||
public override MemoryPool MemoryPool { get; }
|
||||
public override IScheduler InputWriterScheduler => InlineScheduler.Default;
|
||||
public override IScheduler OutputReaderScheduler => TaskRunScheduler.Default;
|
||||
public override Scheduler InputWriterScheduler => Scheduler.Inline;
|
||||
public override Scheduler OutputReaderScheduler => Scheduler.TaskRun;
|
||||
|
||||
public async Task StartAsync(IConnectionHandler connectionHandler)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2,10 +2,12 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO.Pipelines;
|
||||
using System.Net.Sockets;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.Internal
|
||||
{
|
||||
|
|
@ -24,7 +26,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.Internal
|
|||
_eventArgs.Completed += (_, e) => ((SocketAwaitable)e.UserToken).Complete(e.BytesTransferred, e.SocketError);
|
||||
}
|
||||
|
||||
public SocketAwaitable SendAsync(ReadableBuffer buffers)
|
||||
public SocketAwaitable SendAsync(ReadOnlyBuffer buffers)
|
||||
{
|
||||
if (buffers.IsSingleSpan)
|
||||
{
|
||||
|
|
@ -50,7 +52,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.Internal
|
|||
return _awaitable;
|
||||
}
|
||||
|
||||
private SocketAwaitable SendAsync(Memory<byte> buffer)
|
||||
private SocketAwaitable SendAsync(ReadOnlyMemory<byte> memory)
|
||||
{
|
||||
// The BufferList getter is much less expensive then the setter.
|
||||
if (_eventArgs.BufferList != null)
|
||||
|
|
@ -59,9 +61,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.Internal
|
|||
}
|
||||
|
||||
#if NETCOREAPP2_1
|
||||
_eventArgs.SetBuffer(buffer);
|
||||
_eventArgs.SetBuffer(MemoryMarshal.AsMemory(memory));
|
||||
#else
|
||||
var segment = buffer.GetArray();
|
||||
var segment = memory.GetArray();
|
||||
|
||||
_eventArgs.SetBuffer(segment.Array, segment.Offset, segment.Count);
|
||||
#endif
|
||||
|
|
@ -73,7 +75,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.Internal
|
|||
return _awaitable;
|
||||
}
|
||||
|
||||
private List<ArraySegment<byte>> GetBufferList(ReadableBuffer buffer)
|
||||
private List<ArraySegment<byte>> GetBufferList(ReadOnlyBuffer buffer)
|
||||
{
|
||||
Debug.Assert(!buffer.IsEmpty);
|
||||
Debug.Assert(!buffer.IsSingleSpan);
|
||||
|
|
|
|||
|
|
@ -12,8 +12,8 @@ namespace Microsoft.AspNetCore.Protocols.Features
|
|||
|
||||
IPipeConnection Application { get; set; }
|
||||
|
||||
IScheduler InputWriterScheduler { get; }
|
||||
Scheduler InputWriterScheduler { get; }
|
||||
|
||||
IScheduler OutputReaderScheduler { get; }
|
||||
Scheduler OutputReaderScheduler { get; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,9 +58,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
public IPipeConnection Transport { get; set; }
|
||||
public IPipeConnection Application { get; set; }
|
||||
|
||||
public IScheduler InputWriterScheduler => TaskRunScheduler.Default;
|
||||
public Scheduler InputWriterScheduler => Scheduler.TaskRun;
|
||||
|
||||
public IScheduler OutputReaderScheduler => TaskRunScheduler.Default;
|
||||
public Scheduler OutputReaderScheduler => Scheduler.TaskRun;
|
||||
|
||||
public string ConnectionId { get; set; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ using System;
|
|||
using System.Buffers;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Sequences;
|
||||
using System.IO;
|
||||
using System.IO.Pipelines;
|
||||
using System.Linq;
|
||||
|
|
@ -33,8 +34,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
private readonly ServiceContext _serviceContext;
|
||||
private readonly Http1ConnectionContext _http1ConnectionContext;
|
||||
private readonly MemoryPool _pipelineFactory;
|
||||
private ReadCursor _consumed;
|
||||
private ReadCursor _examined;
|
||||
private Position _consumed;
|
||||
private Position _examined;
|
||||
private Mock<ITimeoutControl> _timeoutControl;
|
||||
|
||||
public Http1ConnectionTests()
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.IO.Pipelines;
|
||||
using System.IO.Pipelines.Testing;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
|
@ -35,7 +35,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
string expectedVersion)
|
||||
{
|
||||
var parser = CreateParser(Mock.Of<IKestrelTrace>());
|
||||
var buffer = ReadableBuffer.Create(Encoding.ASCII.GetBytes(requestLine));
|
||||
var buffer = new ReadOnlyBuffer(Encoding.ASCII.GetBytes(requestLine));
|
||||
var requestHandler = new RequestHandler();
|
||||
|
||||
Assert.True(parser.ParseRequestLine(requestHandler, buffer, out var consumed, out var examined));
|
||||
|
|
@ -54,7 +54,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
public void ParseRequestLineReturnsFalseWhenGivenIncompleteRequestLines(string requestLine)
|
||||
{
|
||||
var parser = CreateParser(Mock.Of<IKestrelTrace>());
|
||||
var buffer = ReadableBuffer.Create(Encoding.ASCII.GetBytes(requestLine));
|
||||
var buffer = new ReadOnlyBuffer(Encoding.ASCII.GetBytes(requestLine));
|
||||
var requestHandler = new RequestHandler();
|
||||
|
||||
Assert.False(parser.ParseRequestLine(requestHandler, buffer, out var consumed, out var examined));
|
||||
|
|
@ -65,7 +65,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
public void ParseRequestLineDoesNotConsumeIncompleteRequestLine(string requestLine)
|
||||
{
|
||||
var parser = CreateParser(Mock.Of<IKestrelTrace>());
|
||||
var buffer = ReadableBuffer.Create(Encoding.ASCII.GetBytes(requestLine));
|
||||
var buffer = new ReadOnlyBuffer(Encoding.ASCII.GetBytes(requestLine));
|
||||
var requestHandler = new RequestHandler();
|
||||
|
||||
Assert.False(parser.ParseRequestLine(requestHandler, buffer, out var consumed, out var examined));
|
||||
|
|
@ -84,7 +84,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
.Returns(true);
|
||||
|
||||
var parser = CreateParser(mockTrace.Object);
|
||||
var buffer = ReadableBuffer.Create(Encoding.ASCII.GetBytes(requestLine));
|
||||
var buffer = new ReadOnlyBuffer(Encoding.ASCII.GetBytes(requestLine));
|
||||
var requestHandler = new RequestHandler();
|
||||
|
||||
var exception = Assert.Throws<BadHttpRequestException>(() =>
|
||||
|
|
@ -106,7 +106,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
.Returns(true);
|
||||
|
||||
var parser = CreateParser(mockTrace.Object);
|
||||
var buffer = ReadableBuffer.Create(Encoding.ASCII.GetBytes(requestLine));
|
||||
var buffer = new ReadOnlyBuffer(Encoding.ASCII.GetBytes(requestLine));
|
||||
var requestHandler = new RequestHandler();
|
||||
|
||||
var exception = Assert.Throws<BadHttpRequestException>(() =>
|
||||
|
|
@ -128,7 +128,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
.Returns(true);
|
||||
|
||||
var parser = CreateParser(mockTrace.Object);
|
||||
var buffer = ReadableBuffer.Create(Encoding.ASCII.GetBytes(requestLine));
|
||||
var buffer = new ReadOnlyBuffer(Encoding.ASCII.GetBytes(requestLine));
|
||||
var requestHandler = new RequestHandler();
|
||||
|
||||
var exception = Assert.Throws<BadHttpRequestException>(() =>
|
||||
|
|
@ -179,7 +179,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
{
|
||||
var parser = CreateParser(Mock.Of<IKestrelTrace>());
|
||||
|
||||
var buffer = ReadableBuffer.Create(Encoding.ASCII.GetBytes(rawHeaders));
|
||||
var buffer = new ReadOnlyBuffer(Encoding.ASCII.GetBytes(rawHeaders));
|
||||
var requestHandler = new RequestHandler();
|
||||
Assert.False(parser.ParseHeaders(requestHandler, buffer, out var consumed, out var examined, out var consumedBytes));
|
||||
}
|
||||
|
|
@ -204,7 +204,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
{
|
||||
var parser = CreateParser(Mock.Of<IKestrelTrace>());
|
||||
|
||||
var buffer = ReadableBuffer.Create(Encoding.ASCII.GetBytes(rawHeaders));
|
||||
var buffer = new ReadOnlyBuffer(Encoding.ASCII.GetBytes(rawHeaders));
|
||||
var requestHandler = new RequestHandler();
|
||||
parser.ParseHeaders(requestHandler, buffer, out var consumed, out var examined, out var consumedBytes);
|
||||
|
||||
|
|
@ -294,7 +294,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
var parser = CreateParser(Mock.Of<IKestrelTrace>());
|
||||
|
||||
const string headerLine = "Header: value\r\n\r";
|
||||
var buffer1 = ReadableBuffer.Create(Encoding.ASCII.GetBytes(headerLine));
|
||||
var buffer1 = new ReadOnlyBuffer(Encoding.ASCII.GetBytes(headerLine));
|
||||
var requestHandler = new RequestHandler();
|
||||
Assert.False(parser.ParseHeaders(requestHandler, buffer1, out var consumed, out var examined, out var consumedBytes));
|
||||
|
||||
|
|
@ -302,7 +302,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
Assert.Equal(buffer1.End, examined);
|
||||
Assert.Equal(headerLine.Length - 1, consumedBytes);
|
||||
|
||||
var buffer2 = ReadableBuffer.Create(Encoding.ASCII.GetBytes("\r\n"));
|
||||
var buffer2 = new ReadOnlyBuffer(Encoding.ASCII.GetBytes("\r\n"));
|
||||
Assert.True(parser.ParseHeaders(requestHandler, buffer2, out consumed, out examined, out consumedBytes));
|
||||
|
||||
Assert.Equal(buffer2.End, consumed);
|
||||
|
|
@ -320,7 +320,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
.Returns(true);
|
||||
|
||||
var parser = CreateParser(mockTrace.Object);
|
||||
var buffer = ReadableBuffer.Create(Encoding.ASCII.GetBytes(rawHeaders));
|
||||
var buffer = new ReadOnlyBuffer(Encoding.ASCII.GetBytes(rawHeaders));
|
||||
var requestHandler = new RequestHandler();
|
||||
|
||||
var exception = Assert.Throws<BadHttpRequestException>(() =>
|
||||
|
|
@ -341,7 +341,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
var parser = CreateParser(mockTrace.Object);
|
||||
|
||||
// Invalid request line
|
||||
var buffer = ReadableBuffer.Create(Encoding.ASCII.GetBytes("GET % HTTP/1.1\r\n"));
|
||||
var buffer = new ReadOnlyBuffer(Encoding.ASCII.GetBytes("GET % HTTP/1.1\r\n"));
|
||||
var requestHandler = new RequestHandler();
|
||||
|
||||
var exception = Assert.Throws<BadHttpRequestException>(() =>
|
||||
|
|
@ -351,7 +351,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
Assert.Equal(StatusCodes.Status400BadRequest, (exception as BadHttpRequestException).StatusCode);
|
||||
|
||||
// Unrecognized HTTP version
|
||||
buffer = ReadableBuffer.Create(Encoding.ASCII.GetBytes("GET / HTTP/1.2\r\n"));
|
||||
buffer = new ReadOnlyBuffer(Encoding.ASCII.GetBytes("GET / HTTP/1.2\r\n"));
|
||||
|
||||
exception = Assert.Throws<BadHttpRequestException>(() =>
|
||||
parser.ParseRequestLine(requestHandler, buffer, out var consumed, out var examined));
|
||||
|
|
@ -360,7 +360,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
Assert.Equal(StatusCodes.Status505HttpVersionNotsupported, (exception as BadHttpRequestException).StatusCode);
|
||||
|
||||
// Invalid request header
|
||||
buffer = ReadableBuffer.Create(Encoding.ASCII.GetBytes("Header: value\n\r\n"));
|
||||
buffer = new ReadOnlyBuffer(Encoding.ASCII.GetBytes("Header: value\n\r\n"));
|
||||
|
||||
exception = Assert.Throws<BadHttpRequestException>(() =>
|
||||
parser.ParseHeaders(requestHandler, buffer, out var consumed, out var examined, out var consumedBytes));
|
||||
|
|
@ -369,27 +369,13 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
Assert.Equal(StatusCodes.Status400BadRequest, exception.StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ParseRequestLineSplitBufferWithoutNewLineDoesNotUpdateConsumed()
|
||||
{
|
||||
var parser = CreateParser(Mock.Of<IKestrelTrace>());
|
||||
var buffer = BufferUtilities.CreateBuffer("GET ", "/");
|
||||
|
||||
var requestHandler = new RequestHandler();
|
||||
var result = parser.ParseRequestLine(requestHandler, buffer, out var consumed, out var examined);
|
||||
|
||||
Assert.False(result);
|
||||
Assert.Equal(buffer.Start, consumed);
|
||||
Assert.Equal(buffer.End, examined);
|
||||
}
|
||||
|
||||
private void VerifyHeader(
|
||||
string headerName,
|
||||
string rawHeaderValue,
|
||||
string expectedHeaderValue)
|
||||
{
|
||||
var parser = CreateParser(Mock.Of<IKestrelTrace>());
|
||||
var buffer = ReadableBuffer.Create(Encoding.ASCII.GetBytes($"{headerName}:{rawHeaderValue}\r\n"));
|
||||
var buffer = new ReadOnlyBuffer(Encoding.ASCII.GetBytes($"{headerName}:{rawHeaderValue}\r\n"));
|
||||
|
||||
var requestHandler = new RequestHandler();
|
||||
parser.ParseHeaders(requestHandler, buffer, out var consumed, out var examined, out var consumedBytes);
|
||||
|
|
@ -407,7 +393,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
Assert.True(expectedHeaderNames.Count() == expectedHeaderValues.Count(), $"{nameof(expectedHeaderNames)} and {nameof(expectedHeaderValues)} sizes must match");
|
||||
|
||||
var parser = CreateParser(Mock.Of<IKestrelTrace>());
|
||||
var buffer = ReadableBuffer.Create(Encoding.ASCII.GetBytes(rawHeaders));
|
||||
var buffer = new ReadOnlyBuffer(Encoding.ASCII.GetBytes(rawHeaders));
|
||||
|
||||
var requestHandler = new RequestHandler();
|
||||
parser.ParseHeaders(requestHandler, buffer, out var consumed, out var examined, out var consumedBytes);
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
var pipeOptions = new PipeOptions
|
||||
(
|
||||
pool: _memoryPool,
|
||||
readerScheduler: Mock.Of<IScheduler>()
|
||||
readerScheduler: Mock.Of<Scheduler>()
|
||||
);
|
||||
|
||||
using (var socketOutput = CreateOutputProducer(pipeOptions))
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
serviceContext.ServerOptions.Limits.MaxResponseBufferSize = maxResponseBufferSize;
|
||||
serviceContext.ThreadPool = new LoggingThreadPool(null);
|
||||
|
||||
var mockScheduler = Mock.Of<IScheduler>();
|
||||
var mockScheduler = Mock.Of<Scheduler>();
|
||||
var outputPipeOptions = ConnectionHandler.GetOutputPipeOptions(serviceContext, new MemoryPool(), readerScheduler: mockScheduler);
|
||||
|
||||
Assert.Equal(expectedMaximumSizeLow, outputPipeOptions.MaximumSizeLow);
|
||||
|
|
@ -44,7 +44,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
serviceContext.ServerOptions.Limits.MaxRequestBufferSize = maxRequestBufferSize;
|
||||
serviceContext.ThreadPool = new LoggingThreadPool(null);
|
||||
|
||||
var mockScheduler = Mock.Of<IScheduler>();
|
||||
var mockScheduler = Mock.Of<Scheduler>();
|
||||
var inputPipeOptions = ConnectionHandler.GetInputPipeOptions(serviceContext, new MemoryPool(), writerScheduler: mockScheduler);
|
||||
|
||||
Assert.Equal(expectedMaximumSizeLow, inputPipeOptions.MaximumSizeLow);
|
||||
|
|
@ -69,7 +69,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
Assert.Equal(expectedMaximumSizeLow, connectionLifetime.AdaptedInputPipeOptions.MaximumSizeLow);
|
||||
Assert.Equal(expectedMaximumSizeHigh, connectionLifetime.AdaptedInputPipeOptions.MaximumSizeHigh);
|
||||
Assert.Same(serviceContext.ThreadPool, connectionLifetime.AdaptedInputPipeOptions.ReaderScheduler);
|
||||
Assert.Same(InlineScheduler.Default, connectionLifetime.AdaptedInputPipeOptions.WriterScheduler);
|
||||
Assert.Same(Scheduler.Inline, connectionLifetime.AdaptedInputPipeOptions.WriterScheduler);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
|
|
@ -87,8 +87,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
|
|||
|
||||
Assert.Equal(expectedMaximumSizeLow, connectionLifetime.AdaptedOutputPipeOptions.MaximumSizeLow);
|
||||
Assert.Equal(expectedMaximumSizeHigh, connectionLifetime.AdaptedOutputPipeOptions.MaximumSizeHigh);
|
||||
Assert.Same(InlineScheduler.Default, connectionLifetime.AdaptedOutputPipeOptions.ReaderScheduler);
|
||||
Assert.Same(InlineScheduler.Default, connectionLifetime.AdaptedOutputPipeOptions.WriterScheduler);
|
||||
Assert.Same(Scheduler.Inline, connectionLifetime.AdaptedOutputPipeOptions.ReaderScheduler);
|
||||
Assert.Same(Scheduler.Inline, connectionLifetime.AdaptedOutputPipeOptions.WriterScheduler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -117,11 +117,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Tests
|
|||
var transportContext = new TestLibuvTransportContext() { ConnectionHandler = mockConnectionHandler };
|
||||
var transport = new LibuvTransport(mockLibuv, transportContext, null);
|
||||
var thread = new LibuvThread(transport);
|
||||
var mockScheduler = new Mock<IScheduler>();
|
||||
var mockScheduler = new Mock<Scheduler>();
|
||||
Action backPressure = null;
|
||||
mockScheduler.Setup(m => m.Schedule(It.IsAny<Action<object>>(), It.IsAny<object>())).Callback<Action<object>, object>((a, o) =>
|
||||
mockScheduler.Setup(m => m.Schedule(It.IsAny<Action>())).Callback<Action>(a =>
|
||||
{
|
||||
backPressure = () => a(o);
|
||||
backPressure = a;
|
||||
});
|
||||
mockConnectionHandler.InputOptions = pool =>
|
||||
new PipeOptions(
|
||||
|
|
|
|||
|
|
@ -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.Buffers;
|
||||
using System.IO.Pipelines;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
|
|
@ -68,7 +69,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Tests
|
|||
|
||||
await writeRequest.WriteAsync(
|
||||
serverConnectionPipe,
|
||||
ReadableBuffer.Create(new byte[] { 1, 2, 3, 4 }));
|
||||
new ReadOnlyBuffer(new byte[] { 1, 2, 3, 4 }));
|
||||
|
||||
writeRequest.Dispose();
|
||||
serverConnectionPipe.Dispose();
|
||||
|
|
|
|||
|
|
@ -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.Buffers;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Runtime.InteropServices;
|
||||
|
|
@ -161,7 +162,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Tests
|
|||
{
|
||||
var req = new UvWriteReq(_logger);
|
||||
req.DangerousInit(loop);
|
||||
var block = ReadableBuffer.Create(new byte[] { 65, 66, 67, 68, 69 });
|
||||
var block = new ReadOnlyBuffer(new byte[] { 65, 66, 67, 68, 69 });
|
||||
|
||||
await req.WriteAsync(
|
||||
tcp2,
|
||||
|
|
|
|||
Loading…
Reference in New Issue