Moving PlatformBenchmarks from aspnet/benchmarks (#2457)
This commit is contained in:
parent
7e5104573e
commit
e411cbf7e2
|
|
@ -126,6 +126,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SystemdTestApp", "samples\S
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PlaintextApp", "samples\PlaintextApp\PlaintextApp.csproj", "{CE5523AE-6E38-4E20-998F-C64E02C5CC51}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PlatformBenchmarks", "benchmarkapps\PlatformBenchmarks\PlatformBenchmarks.csproj", "{7C24EAB8-57A9-4613-A8A6-4C21BB7D260D}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
|
@ -364,6 +366,18 @@ Global
|
|||
{CE5523AE-6E38-4E20-998F-C64E02C5CC51}.Release|x64.Build.0 = Release|Any CPU
|
||||
{CE5523AE-6E38-4E20-998F-C64E02C5CC51}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{CE5523AE-6E38-4E20-998F-C64E02C5CC51}.Release|x86.Build.0 = Release|Any CPU
|
||||
{7C24EAB8-57A9-4613-A8A6-4C21BB7D260D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7C24EAB8-57A9-4613-A8A6-4C21BB7D260D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7C24EAB8-57A9-4613-A8A6-4C21BB7D260D}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{7C24EAB8-57A9-4613-A8A6-4C21BB7D260D}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{7C24EAB8-57A9-4613-A8A6-4C21BB7D260D}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{7C24EAB8-57A9-4613-A8A6-4C21BB7D260D}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{7C24EAB8-57A9-4613-A8A6-4C21BB7D260D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7C24EAB8-57A9-4613-A8A6-4C21BB7D260D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{7C24EAB8-57A9-4613-A8A6-4C21BB7D260D}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{7C24EAB8-57A9-4613-A8A6-4C21BB7D260D}.Release|x64.Build.0 = Release|Any CPU
|
||||
{7C24EAB8-57A9-4613-A8A6-4C21BB7D260D}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{7C24EAB8-57A9-4613-A8A6-4C21BB7D260D}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
@ -390,6 +404,7 @@ Global
|
|||
{7BC22A4A-15D2-44C2-AB45-049F0FB562FA} = {8A3D00B8-1CCF-4BE6-A060-11104CE2D9CE}
|
||||
{A7994A41-CAF8-47A7-8975-F101F75B5BC1} = {8A3D00B8-1CCF-4BE6-A060-11104CE2D9CE}
|
||||
{CE5523AE-6E38-4E20-998F-C64E02C5CC51} = {8A3D00B8-1CCF-4BE6-A060-11104CE2D9CE}
|
||||
{7C24EAB8-57A9-4613-A8A6-4C21BB7D260D} = {A95C3BE1-B850-4265-97A0-777ADCCD437F}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {2D10D020-6770-47CA-BB8D-2C23FE3AE071}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,50 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Text;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure;
|
||||
|
||||
namespace PlatformBenchmarks
|
||||
{
|
||||
public struct AsciiString : IEquatable<AsciiString>
|
||||
{
|
||||
private readonly byte[] _data;
|
||||
|
||||
public AsciiString(string s) => _data = Encoding.ASCII.GetBytes(s);
|
||||
|
||||
public int Length => _data.Length;
|
||||
|
||||
public ReadOnlySpan<byte> AsSpan() => _data;
|
||||
|
||||
public static implicit operator ReadOnlySpan<byte>(AsciiString str) => str._data;
|
||||
public static implicit operator byte[] (AsciiString str) => str._data;
|
||||
|
||||
public static implicit operator AsciiString(string str) => new AsciiString(str);
|
||||
|
||||
public override string ToString() => HttpUtilities.GetAsciiStringNonNullCharacters(_data);
|
||||
public static explicit operator string(AsciiString str) => str.ToString();
|
||||
|
||||
public bool Equals(AsciiString other) => ReferenceEquals(_data, other._data) || SequenceEqual(_data, other._data);
|
||||
private bool SequenceEqual(byte[] data1, byte[] data2) => new Span<byte>(data1).SequenceEqual(data2);
|
||||
|
||||
public static bool operator ==(AsciiString a, AsciiString b) => a.Equals(b);
|
||||
public static bool operator !=(AsciiString a, AsciiString b) => !a.Equals(b);
|
||||
public override bool Equals(object other) => (other is AsciiString) && Equals((AsciiString)other);
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
// Copied from x64 version of string.GetLegacyNonRandomizedHashCode()
|
||||
// https://github.com/dotnet/coreclr/blob/master/src/mscorlib/src/System/String.Comparison.cs
|
||||
var data = _data;
|
||||
int hash1 = 5381;
|
||||
int hash2 = hash1;
|
||||
foreach (int b in data)
|
||||
{
|
||||
hash1 = ((hash1 << 5) + hash1) ^ b;
|
||||
}
|
||||
return hash1 + (hash2 * 1566083941);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,156 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.IO.Pipelines;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
|
||||
using Utf8Json;
|
||||
|
||||
namespace PlatformBenchmarks
|
||||
{
|
||||
public class BenchmarkApplication : HttpConnection
|
||||
{
|
||||
private static AsciiString _crlf = "\r\n";
|
||||
private static AsciiString _eoh = "\r\n\r\n"; // End Of Headers
|
||||
private static AsciiString _http11OK = "HTTP/1.1 200 OK\r\n";
|
||||
private static AsciiString _headerServer = "Server: Custom";
|
||||
private static AsciiString _headerContentLength = "Content-Length: ";
|
||||
private static AsciiString _headerContentLengthZero = "Content-Length: 0\r\n";
|
||||
private static AsciiString _headerContentTypeText = "Content-Type: text/plain\r\n";
|
||||
private static AsciiString _headerContentTypeJson = "Content-Type: application/json\r\n";
|
||||
|
||||
|
||||
private static AsciiString _plainTextBody = "Hello, World!";
|
||||
|
||||
private static class Paths
|
||||
{
|
||||
public static AsciiString Plaintext = "/plaintext";
|
||||
public static AsciiString Json = "/json";
|
||||
}
|
||||
|
||||
private bool _isPlainText;
|
||||
private bool _isJson;
|
||||
|
||||
public override void OnStartLine(HttpMethod method, HttpVersion version, Span<byte> target, Span<byte> path, Span<byte> query, Span<byte> customMethod, bool pathEncoded)
|
||||
{
|
||||
if (path.StartsWith(Paths.Plaintext) && method == HttpMethod.Get)
|
||||
{
|
||||
_isPlainText = true;
|
||||
}
|
||||
else if (path.StartsWith(Paths.Json) && method == HttpMethod.Get)
|
||||
{
|
||||
_isJson = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_isPlainText = false;
|
||||
_isJson = false;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnHeader(Span<byte> name, Span<byte> value)
|
||||
{
|
||||
}
|
||||
|
||||
public override ValueTask ProcessRequestAsync()
|
||||
{
|
||||
if (_isPlainText)
|
||||
{
|
||||
PlainText(Writer);
|
||||
}
|
||||
else if (_isJson)
|
||||
{
|
||||
Json(Writer);
|
||||
}
|
||||
else
|
||||
{
|
||||
Default(Writer);
|
||||
}
|
||||
|
||||
return default;
|
||||
}
|
||||
|
||||
public override async ValueTask OnReadCompletedAsync()
|
||||
{
|
||||
await Writer.FlushAsync();
|
||||
}
|
||||
private static void PlainText(PipeWriter pipeWriter)
|
||||
{
|
||||
var writer = new BufferWriter<PipeWriter>(pipeWriter);
|
||||
// HTTP 1.1 OK
|
||||
writer.Write(_http11OK);
|
||||
|
||||
// Server headers
|
||||
writer.Write(_headerServer);
|
||||
|
||||
// Date header
|
||||
writer.Write(DateHeader.HeaderBytes);
|
||||
|
||||
// Content-Type header
|
||||
writer.Write(_headerContentTypeText);
|
||||
|
||||
// Content-Length header
|
||||
writer.Write(_headerContentLength);
|
||||
writer.WriteNumeric((ulong)_plainTextBody.Length);
|
||||
|
||||
// End of headers
|
||||
writer.Write(_eoh);
|
||||
|
||||
// Body
|
||||
writer.Write(_plainTextBody);
|
||||
writer.Commit();
|
||||
}
|
||||
|
||||
private static void Json(PipeWriter pipeWriter)
|
||||
{
|
||||
var writer = new BufferWriter<PipeWriter>(pipeWriter);
|
||||
|
||||
// HTTP 1.1 OK
|
||||
writer.Write(_http11OK);
|
||||
|
||||
// Server headers
|
||||
writer.Write(_headerServer);
|
||||
|
||||
// Date header
|
||||
writer.Write(DateHeader.HeaderBytes);
|
||||
|
||||
// Content-Type header
|
||||
writer.Write(_headerContentTypeJson);
|
||||
|
||||
// Content-Length header
|
||||
writer.Write(_headerContentLength);
|
||||
var jsonPayload = JsonSerializer.SerializeUnsafe(new { message = "Hello, World!" });
|
||||
writer.WriteNumeric((ulong)jsonPayload.Count);
|
||||
|
||||
// End of headers
|
||||
writer.Write(_eoh);
|
||||
|
||||
// Body
|
||||
writer.Write(jsonPayload);
|
||||
writer.Commit();
|
||||
}
|
||||
|
||||
private static void Default(PipeWriter pipeWriter)
|
||||
{
|
||||
var writer = new BufferWriter<PipeWriter>(pipeWriter);
|
||||
|
||||
// HTTP 1.1 OK
|
||||
writer.Write(_http11OK);
|
||||
|
||||
// Server headers
|
||||
writer.Write(_headerServer);
|
||||
|
||||
// Date header
|
||||
writer.Write(DateHeader.HeaderBytes);
|
||||
|
||||
// Content-Length 0
|
||||
writer.Write(_headerContentLengthZero);
|
||||
|
||||
// End of headers
|
||||
writer.Write(_crlf);
|
||||
writer.Commit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Net;
|
||||
using Microsoft.AspNetCore;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Core;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
||||
namespace PlatformBenchmarks
|
||||
{
|
||||
public static class BenchmarkConfigurationHelpers
|
||||
{
|
||||
public static IWebHostBuilder UseBenchmarksConfiguration(this IWebHostBuilder builder, IConfiguration configuration)
|
||||
{
|
||||
builder.UseConfiguration(configuration);
|
||||
|
||||
// Handle the transport type
|
||||
var webHost = builder.GetSetting("KestrelTransport");
|
||||
|
||||
// Handle the thread count
|
||||
var threadCountRaw = builder.GetSetting("threadCount");
|
||||
int? theadCount = null;
|
||||
|
||||
if (!string.IsNullOrEmpty(threadCountRaw) &&
|
||||
Int32.TryParse(threadCountRaw, out var value))
|
||||
{
|
||||
theadCount = value;
|
||||
}
|
||||
|
||||
if (string.Equals(webHost, "Libuv", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
builder.UseLibuv(options =>
|
||||
{
|
||||
if (theadCount.HasValue)
|
||||
{
|
||||
options.ThreadCount = theadCount.Value;
|
||||
}
|
||||
});
|
||||
}
|
||||
else if (string.Equals(webHost, "Sockets", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
builder.UseSockets(options =>
|
||||
{
|
||||
if (theadCount.HasValue)
|
||||
{
|
||||
options.IOQueueCount = theadCount.Value;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static IPEndPoint CreateIPEndPoint(this IConfiguration config)
|
||||
{
|
||||
var url = config["server.urls"] ?? config["urls"];
|
||||
|
||||
if (string.IsNullOrEmpty(url))
|
||||
{
|
||||
return new IPEndPoint(IPAddress.Loopback, 8080);
|
||||
}
|
||||
|
||||
var address = ServerAddress.FromUrl(url);
|
||||
|
||||
IPAddress ip;
|
||||
|
||||
if (string.Equals(address.Host, "localhost", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
ip = IPAddress.Loopback;
|
||||
}
|
||||
else if (!IPAddress.TryParse(address.Host, out ip))
|
||||
{
|
||||
ip = IPAddress.IPv6Any;
|
||||
}
|
||||
|
||||
return new IPEndPoint(ip, address.Port);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
// 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.Text;
|
||||
using System.Diagnostics;
|
||||
using System.IO.Pipelines;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace System.Buffers
|
||||
{
|
||||
internal static class BufferWriterExtensions
|
||||
{
|
||||
private const int MaxULongByteLength = 20;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal static void WriteNumeric(ref this BufferWriter<PipeWriter> buffer, ulong number)
|
||||
{
|
||||
// Try to format directly
|
||||
if (Utf8Formatter.TryFormat(number, buffer.Span, out int bytesWritten))
|
||||
{
|
||||
buffer.Advance(bytesWritten);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Ask for at least 20 bytes
|
||||
buffer.Ensure(MaxULongByteLength);
|
||||
|
||||
Debug.Assert(buffer.Span.Length >= 20, "Buffer is < 20 bytes");
|
||||
|
||||
// Try again
|
||||
if (Utf8Formatter.TryFormat(number, buffer.Span, out bytesWritten))
|
||||
{
|
||||
buffer.Advance(bytesWritten);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Buffers.Text;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
||||
{
|
||||
/// <summary>
|
||||
/// Manages the generation of the date header value.
|
||||
/// </summary>
|
||||
internal static class DateHeader
|
||||
{
|
||||
const int prefixLength = 8; // "\r\nDate: ".Length
|
||||
const int dateTimeRLength = 29; // Wed, 14 Mar 2018 14:20:00 GMT
|
||||
const int suffixLength = 2; // crlf
|
||||
const int suffixIndex = dateTimeRLength + prefixLength;
|
||||
|
||||
private static readonly Timer s_timer = new Timer((s) => {
|
||||
SetDateValues(DateTimeOffset.UtcNow);
|
||||
}, null, 1000, 1000);
|
||||
|
||||
private static byte[] s_headerBytesMaster = new byte[prefixLength + dateTimeRLength + suffixLength];
|
||||
private static byte[] s_headerBytesScratch = new byte[prefixLength + dateTimeRLength + suffixLength];
|
||||
|
||||
static DateHeader()
|
||||
{
|
||||
var utf8 = Encoding.ASCII.GetBytes("\r\nDate: ").AsSpan();
|
||||
utf8.CopyTo(s_headerBytesMaster);
|
||||
utf8.CopyTo(s_headerBytesScratch);
|
||||
s_headerBytesMaster[suffixIndex] = (byte)'\r';
|
||||
s_headerBytesMaster[suffixIndex + 1] = (byte)'\n';
|
||||
s_headerBytesScratch[suffixIndex] = (byte)'\r';
|
||||
s_headerBytesScratch[suffixIndex + 1] = (byte)'\n';
|
||||
SetDateValues(DateTimeOffset.UtcNow);
|
||||
}
|
||||
|
||||
public static ReadOnlySpan<byte> HeaderBytes => s_headerBytesMaster;
|
||||
|
||||
private static void SetDateValues(DateTimeOffset value)
|
||||
{
|
||||
lock (s_headerBytesScratch)
|
||||
{
|
||||
if (!Utf8Formatter.TryFormat(value, s_headerBytesScratch.AsSpan().Slice(prefixLength), out int written, 'R'))
|
||||
{
|
||||
throw new Exception("date time format failed");
|
||||
}
|
||||
Debug.Assert(written == dateTimeRLength);
|
||||
var temp = s_headerBytesMaster;
|
||||
s_headerBytesMaster = s_headerBytesScratch;
|
||||
s_headerBytesScratch = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,161 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.IO.Pipelines;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Connections;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
|
||||
|
||||
namespace PlatformBenchmarks
|
||||
{
|
||||
public static class HttpApplicationConnectionBuilderExtensions
|
||||
{
|
||||
public static IConnectionBuilder UseHttpApplication<TConnection>(this IConnectionBuilder builder) where TConnection : HttpConnection, new()
|
||||
{
|
||||
return builder.Use(next => new HttpApplication<TConnection>().ExecuteAsync);
|
||||
}
|
||||
}
|
||||
|
||||
public class HttpApplication<TConnection> where TConnection : HttpConnection, new()
|
||||
{
|
||||
public Task ExecuteAsync(ConnectionContext connection)
|
||||
{
|
||||
var parser = new HttpParser<HttpConnection>();
|
||||
|
||||
var httpConnection = new TConnection
|
||||
{
|
||||
Parser = parser,
|
||||
Reader = connection.Transport.Input,
|
||||
Writer = connection.Transport.Output
|
||||
};
|
||||
return httpConnection.ExecuteAsync();
|
||||
}
|
||||
}
|
||||
|
||||
public class HttpConnection : IHttpHeadersHandler, IHttpRequestLineHandler
|
||||
{
|
||||
private State _state;
|
||||
|
||||
public PipeReader Reader { get; set; }
|
||||
public PipeWriter Writer { get; set; }
|
||||
|
||||
internal HttpParser<HttpConnection> Parser { get; set; }
|
||||
|
||||
public virtual void OnHeader(Span<byte> name, Span<byte> value)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual void OnStartLine(HttpMethod method, HttpVersion version, Span<byte> target, Span<byte> path, Span<byte> query, Span<byte> customMethod, bool pathEncoded)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual ValueTask ProcessRequestAsync()
|
||||
{
|
||||
return default;
|
||||
}
|
||||
|
||||
public virtual ValueTask OnReadCompletedAsync()
|
||||
{
|
||||
return default;
|
||||
}
|
||||
|
||||
public async Task ExecuteAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
await ProcessRequestsAsync();
|
||||
|
||||
Reader.Complete();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Reader.Complete(ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Writer.Complete();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ProcessRequestsAsync()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
var task = Reader.ReadAsync();
|
||||
|
||||
if (!task.IsCompleted)
|
||||
{
|
||||
// No more data in the input
|
||||
await OnReadCompletedAsync();
|
||||
}
|
||||
|
||||
var result = await task;
|
||||
var buffer = result.Buffer;
|
||||
var consumed = buffer.Start;
|
||||
var examined = buffer.End;
|
||||
|
||||
if (!buffer.IsEmpty)
|
||||
{
|
||||
ParseHttpRequest(buffer, out consumed, out examined);
|
||||
|
||||
if (_state != State.Body && result.IsCompleted)
|
||||
{
|
||||
ThrowUnexpectedEndOfData();
|
||||
}
|
||||
}
|
||||
else if (result.IsCompleted)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
Reader.AdvanceTo(consumed, examined);
|
||||
|
||||
if (_state == State.Body)
|
||||
{
|
||||
await ProcessRequestAsync();
|
||||
|
||||
_state = State.StartLine;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ParseHttpRequest(in ReadOnlySequence<byte> buffer, out SequencePosition consumed, out SequencePosition examined)
|
||||
{
|
||||
consumed = buffer.Start;
|
||||
examined = buffer.End;
|
||||
|
||||
var parsingStartLine = _state == State.StartLine;
|
||||
if (parsingStartLine)
|
||||
{
|
||||
if (Parser.ParseRequestLine(this, buffer, out consumed, out examined))
|
||||
{
|
||||
_state = State.Headers;
|
||||
}
|
||||
}
|
||||
|
||||
if (_state == State.Headers)
|
||||
{
|
||||
if (Parser.ParseHeaders(this, parsingStartLine ? buffer.Slice(consumed) : buffer, out consumed, out examined, out int consumedBytes))
|
||||
{
|
||||
_state = State.Body;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void ThrowUnexpectedEndOfData()
|
||||
{
|
||||
throw new InvalidOperationException("Unexpected end of data!");
|
||||
}
|
||||
|
||||
private enum State
|
||||
{
|
||||
StartLine,
|
||||
Headers,
|
||||
Body
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||
<OutputType>Exe</OutputType>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Utf8Json" Version="$(Utf8JsonPackageVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- These references are used when running locally -->
|
||||
<ItemGroup Condition="'$(BenchmarksTargetFramework)' == ''">
|
||||
<ProjectReference Include="..\..\src\Kestrel\Kestrel.csproj" />
|
||||
<ProjectReference Include="..\..\src\Kestrel.Transport.Libuv\Kestrel.Transport.Libuv.csproj" />
|
||||
|
||||
<PackageReference Include="Microsoft.Extensions.Buffers.Sources" PrivateAssets="All" Version="$(MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.CommandLine" Version="$(MicrosoftExtensionsConfigurationCommandLinePackageVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- These references are used when running on the Benchmarks Server -->
|
||||
<ItemGroup Condition="'$(BenchmarksTargetFramework)' != ''">
|
||||
<PackageReference Include="Microsoft.AspNetCore.All" Version="$(MicrosoftAspNetCoreAllPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Buffers.Sources" Version="$(MicrosoftAspNetCoreAllPackageVersion)" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Net;
|
||||
using Microsoft.AspNetCore;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Core;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions.Internal;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace PlatformBenchmarks
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
BuildWebHost(args).Run();
|
||||
}
|
||||
|
||||
public static IWebHost BuildWebHost(string[] args)
|
||||
{
|
||||
var config = new ConfigurationBuilder()
|
||||
.AddEnvironmentVariables(prefix: "ASPNETCORE_")
|
||||
.AddCommandLine(args)
|
||||
.Build();
|
||||
|
||||
var host = new WebHostBuilder()
|
||||
.UseBenchmarksConfiguration(config)
|
||||
.UseKestrel((context, options) =>
|
||||
{
|
||||
IPEndPoint endPoint = context.Configuration.CreateIPEndPoint();
|
||||
|
||||
options.Listen(endPoint, builder =>
|
||||
{
|
||||
builder.UseHttpApplication<BenchmarkApplication>();
|
||||
});
|
||||
})
|
||||
.UseStartup<Startup>()
|
||||
.Build();
|
||||
|
||||
return host;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Net.WebSockets;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
|
||||
namespace PlatformBenchmarks
|
||||
{
|
||||
public class Startup
|
||||
{
|
||||
public void Configure(IApplicationBuilder app)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"Default": {
|
||||
"Client": "Wrk",
|
||||
"PresetHeaders": "Json",
|
||||
|
||||
"Source": {
|
||||
"Repository": "https://github.com/aspnet/KestrelHttpServer.git",
|
||||
"BranchOrCommit": "dev",
|
||||
"Project": "benchmarkapps/PlatformBenchmarks/PlatformBenchmarks.csproj"
|
||||
}
|
||||
},
|
||||
"JsonPlatform": {
|
||||
"Path": "/json"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"Default": {
|
||||
"Client": "Wrk",
|
||||
"PresetHeaders": "Plaintext",
|
||||
"ClientProperties": {
|
||||
"ScriptName": "pipeline",
|
||||
"PipelineDepth": 16
|
||||
},
|
||||
"Source": {
|
||||
"Repository": "https://github.com/aspnet/KestrelHttpServer.git",
|
||||
"BranchOrCommit": "dev",
|
||||
"Project": "benchmarkapps/PlatformBenchmarks/PlatformBenchmarks.csproj"
|
||||
},
|
||||
"Port": 8080
|
||||
},
|
||||
"PlaintextPlatform": {
|
||||
"Path": "/plaintext"
|
||||
},
|
||||
"PlaintextNonPipelinedPlatform": {
|
||||
"Path": "/plaintext",
|
||||
"ClientProperties": {
|
||||
"ScriptName": "",
|
||||
"PipelineDepth": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,6 +7,7 @@
|
|||
<BenchmarkDotNetPackageVersion>0.10.13</BenchmarkDotNetPackageVersion>
|
||||
<InternalAspNetCoreSdkPackageVersion>2.1.0-preview3-17002</InternalAspNetCoreSdkPackageVersion>
|
||||
<LibuvPackageVersion>1.10.0</LibuvPackageVersion>
|
||||
<MicrosoftAspNetCoreAllPackageVersion>2.1.0-preview3-32110</MicrosoftAspNetCoreAllPackageVersion>
|
||||
<MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion>2.1.0-preview3-32110</MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion>
|
||||
<MicrosoftAspNetCoreCertificatesGenerationSourcesPackageVersion>2.1.0-preview3-32110</MicrosoftAspNetCoreCertificatesGenerationSourcesPackageVersion>
|
||||
<MicrosoftAspNetCoreHostingAbstractionsPackageVersion>2.1.0-preview3-32110</MicrosoftAspNetCoreHostingAbstractionsPackageVersion>
|
||||
|
|
@ -20,6 +21,7 @@
|
|||
<MicrosoftExtensionsBuffersSourcesPackageVersion>2.1.0-preview3-32110</MicrosoftExtensionsBuffersSourcesPackageVersion>
|
||||
<MicrosoftExtensionsBuffersTestingSourcesPackageVersion>2.1.0-preview3-32110</MicrosoftExtensionsBuffersTestingSourcesPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationBinderPackageVersion>2.1.0-preview3-32110</MicrosoftExtensionsConfigurationBinderPackageVersion>
|
||||
<MicrosoftExtensionsConfigurationCommandLinePackageVersion>2.1.0-preview3-32037</MicrosoftExtensionsConfigurationCommandLinePackageVersion>
|
||||
<MicrosoftExtensionsConfigurationJsonPackageVersion>2.1.0-preview3-32110</MicrosoftExtensionsConfigurationJsonPackageVersion>
|
||||
<MicrosoftExtensionsDependencyInjectionPackageVersion>2.1.0-preview3-32110</MicrosoftExtensionsDependencyInjectionPackageVersion>
|
||||
<MicrosoftExtensionsLoggingAbstractionsPackageVersion>2.1.0-preview3-32110</MicrosoftExtensionsLoggingAbstractionsPackageVersion>
|
||||
|
|
@ -40,6 +42,7 @@
|
|||
<SystemRuntimeCompilerServicesUnsafePackageVersion>4.5.0-preview3-26331-02</SystemRuntimeCompilerServicesUnsafePackageVersion>
|
||||
<SystemSecurityCryptographyCngPackageVersion>4.5.0-preview3-26331-02</SystemSecurityCryptographyCngPackageVersion>
|
||||
<SystemThreadingTasksExtensionsPackageVersion>4.5.0-preview3-26331-02</SystemThreadingTasksExtensionsPackageVersion>
|
||||
<Utf8JsonPackageVersion>1.3.7</Utf8JsonPackageVersion>
|
||||
<XunitAnalyzersPackageVersion>0.8.0</XunitAnalyzersPackageVersion>
|
||||
<XunitPackageVersion>2.3.1</XunitPackageVersion>
|
||||
<XunitRunnerVisualStudioPackageVersion>2.4.0-beta.1.build3945</XunitRunnerVisualStudioPackageVersion>
|
||||
|
|
|
|||
Loading…
Reference in New Issue