From d29e4d4cf09bc5dc75a706f96ecb5edb1ea118b7 Mon Sep 17 00:00:00 2001 From: Ben Adams Date: Tue, 11 Apr 2017 03:30:18 +0100 Subject: [PATCH] Specialized struct generics rather than interface (#1640) Changed the IHttpParser interface to be generic. This lets use a struct to get better code generation and also should allow us to inline calls back into the handler from the parser. --- .../Adapter/Internal/StreamSocketOutput.cs | 2 +- .../Internal/Http/Frame.cs | 17 +++++++------- .../Internal/Http/FrameAdapter.cs | 23 +++++++++++++++++++ .../Internal/Http/HttpParser.cs | 10 ++++---- .../Internal/Http/IHttpParser.cs | 6 ++--- .../Internal/Http/ISocketOutput.cs | 2 +- .../Internal/ServiceContext.cs | 2 +- .../KestrelServer.cs | 2 +- .../FrameResponseHeadersTests.cs | 23 ------------------- .../HttpParserTests.cs | 3 +-- .../OutputProducerTests.cs | 4 ++-- .../FrameFeatureCollection.cs | 2 +- .../FrameParsingOverheadBenchmark.cs | 2 +- .../FrameWritingBenchmark.cs | 2 +- .../KestrelHttpParserBenchmark.cs | 22 +++++++++++++++--- .../Mocks/NullParser.cs | 8 +++---- .../RequestParsingBenchmark.cs | 2 +- .../ResponseHeaderCollectionBenchmark.cs | 2 +- .../ResponseHeadersWritingBenchmark.cs | 2 +- test/shared/MockSocketOutput.cs | 2 +- test/shared/TestServiceContext.cs | 2 +- 21 files changed, 78 insertions(+), 62 deletions(-) create mode 100644 src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/Http/FrameAdapter.cs diff --git a/src/Microsoft.AspNetCore.Server.Kestrel.Core/Adapter/Internal/StreamSocketOutput.cs b/src/Microsoft.AspNetCore.Server.Kestrel.Core/Adapter/Internal/StreamSocketOutput.cs index d7e7529f6d..926f0d1cc1 100644 --- a/src/Microsoft.AspNetCore.Server.Kestrel.Core/Adapter/Internal/StreamSocketOutput.cs +++ b/src/Microsoft.AspNetCore.Server.Kestrel.Core/Adapter/Internal/StreamSocketOutput.cs @@ -83,7 +83,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Adapter.Internal return WriteAsync(default(ArraySegment), chunk: false, cancellationToken: cancellationToken); } - public void Write(Action callback, T state) + public void Write(Action callback, T state) where T : struct { lock (_sync) { diff --git a/src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/Http/Frame.cs b/src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/Http/Frame.cs index d21c4c5563..9c4035ff8e 100644 --- a/src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/Http/Frame.cs +++ b/src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/Http/Frame.cs @@ -26,7 +26,7 @@ using Microsoft.Extensions.Primitives; namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { - public abstract partial class Frame : IFrameControl, IHttpRequestLineHandler, IHttpHeadersHandler + public abstract partial class Frame : IFrameControl { private const byte ByteAsterisk = (byte)'*'; private const byte ByteForwardSlash = (byte)'/'; @@ -34,7 +34,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http private static readonly ArraySegment _endChunkedResponseBytes = CreateAsciiByteArraySegment("0\r\n\r\n"); private static readonly ArraySegment _continueBytes = CreateAsciiByteArraySegment("HTTP/1.1 100 Continue\r\n\r\n"); - private static readonly Action _writeHeaders = WriteResponseHeaders; + private static readonly Action _writeHeaders = WriteResponseHeaders; private static readonly byte[] _bytesConnectionClose = Encoding.ASCII.GetBytes("\r\nConnection: close"); private static readonly byte[] _bytesConnectionKeepAlive = Encoding.ASCII.GetBytes("\r\nConnection: keep-alive"); @@ -80,7 +80,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http protected long _responseBytesWritten; private readonly FrameContext _frameContext; - private readonly IHttpParser _parser; + private readonly IHttpParser _parser; public Frame(FrameContext frameContext) { @@ -88,7 +88,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http ServerOptions = ServiceContext.ServerOptions; - _parser = ServiceContext.HttpParserFactory(this); + _parser = ServiceContext.HttpParserFactory(new FrameAdapter(this)); FrameControl = this; _keepAliveMilliseconds = (long)ServerOptions.Limits.KeepAliveTimeout.TotalMilliseconds; @@ -988,11 +988,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http responseHeaders.SetRawDate(dateHeaderValues.String, dateHeaderValues.Bytes); } - Output.Write(_writeHeaders, this); + Output.Write(_writeHeaders, new FrameAdapter(this)); } - private static void WriteResponseHeaders(WritableBuffer writableBuffer, Frame frame) + private static void WriteResponseHeaders(WritableBuffer writableBuffer, FrameAdapter frameAdapter) { + var frame = frameAdapter.Frame; var writer = new WritableBufferWriter(writableBuffer); var responseHeaders = frame.FrameResponseHeaders; @@ -1050,7 +1051,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http overLength = true; } - var result = _parser.ParseRequestLine(this, buffer, out consumed, out examined); + var result = _parser.ParseRequestLine(new FrameAdapter(this), buffer, out consumed, out examined); if (!result && overLength) { RejectRequest(RequestRejectionReason.RequestLineTooLong); @@ -1072,7 +1073,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http overLength = true; } - var result = _parser.ParseHeaders(this, buffer, out consumed, out examined, out var consumedBytes); + var result = _parser.ParseHeaders(new FrameAdapter(this), buffer, out consumed, out examined, out var consumedBytes); _remainingRequestHeadersBytesAllowed -= consumedBytes; if (!result && overLength) diff --git a/src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/Http/FrameAdapter.cs b/src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/Http/FrameAdapter.cs new file mode 100644 index 0000000000..6659b83bf8 --- /dev/null +++ b/src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/Http/FrameAdapter.cs @@ -0,0 +1,23 @@ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.AspNetCore.Server.Kestrel.Internal.System; + +namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http +{ + public struct FrameAdapter : IHttpRequestLineHandler, IHttpHeadersHandler + { + public Frame Frame; + + public FrameAdapter(Frame frame) + { + Frame = frame; + } + + public void OnHeader(Span name, Span value) + => Frame.OnHeader(name, value); + + public void OnStartLine(HttpMethod method, HttpVersion version, Span target, Span path, Span query, Span customMethod, bool pathEncoded) + => Frame.OnStartLine(method, version, target, path, query, customMethod, pathEncoded); + } +} diff --git a/src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/Http/HttpParser.cs b/src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/Http/HttpParser.cs index 9b253fb20a..43a7d94990 100644 --- a/src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/Http/HttpParser.cs +++ b/src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/Http/HttpParser.cs @@ -9,7 +9,7 @@ using Microsoft.Extensions.Logging; namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { - public class HttpParser : IHttpParser + public class HttpParser : IHttpParser where TRequestHandler : IHttpHeadersHandler, IHttpRequestLineHandler { public HttpParser(IKestrelTrace log) { @@ -27,7 +27,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http private const byte ByteQuestionMark = (byte)'?'; private const byte BytePercentage = (byte)'%'; - public unsafe bool ParseRequestLine(IHttpRequestLineHandler handler, ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined) + public unsafe bool ParseRequestLine(TRequestHandler handler, ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined) { consumed = buffer.Start; examined = buffer.End; @@ -66,7 +66,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http return true; } - private unsafe void ParseRequestLine(IHttpRequestLineHandler handler, byte* data, int length) + private unsafe void ParseRequestLine(TRequestHandler handler, byte* data, int length) { int offset; Span customMethod = default(Span); @@ -183,7 +183,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http handler.OnStartLine(method, httpVersion, targetBuffer, pathBuffer, query, customMethod, pathEncoded); } - public unsafe bool ParseHeaders(IHttpHeadersHandler handler, ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined, out int consumedBytes) + public unsafe bool ParseHeaders(TRequestHandler handler, ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined, out int consumedBytes) { consumed = buffer.Start; examined = buffer.End; @@ -346,7 +346,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private unsafe void TakeSingleHeader(byte* headerLine, int length, IHttpHeadersHandler handler) + private unsafe void TakeSingleHeader(byte* headerLine, int length, TRequestHandler handler) { // Skip CR, LF from end position var valueEnd = length - 3; diff --git a/src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/Http/IHttpParser.cs b/src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/Http/IHttpParser.cs index 8473fc4cc3..46dfc1b34b 100644 --- a/src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/Http/IHttpParser.cs +++ b/src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/Http/IHttpParser.cs @@ -5,11 +5,11 @@ using Microsoft.AspNetCore.Server.Kestrel.Internal.System.IO.Pipelines; namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http { - public interface IHttpParser + public interface IHttpParser where TRequestHandler : IHttpHeadersHandler, IHttpRequestLineHandler { - bool ParseRequestLine(IHttpRequestLineHandler handler, ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined); + bool ParseRequestLine(TRequestHandler handler, ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined); - bool ParseHeaders(IHttpHeadersHandler handler, ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined, out int consumedBytes); + bool ParseHeaders(TRequestHandler handler, ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined, out int consumedBytes); void Reset(); } diff --git a/src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/Http/ISocketOutput.cs b/src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/Http/ISocketOutput.cs index d12bd67310..139a5000a0 100644 --- a/src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/Http/ISocketOutput.cs +++ b/src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/Http/ISocketOutput.cs @@ -17,6 +17,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http Task WriteAsync(ArraySegment buffer, bool chunk = false, CancellationToken cancellationToken = default(CancellationToken)); void Flush(); Task FlushAsync(CancellationToken cancellationToken = default(CancellationToken)); - void Write(Action write, T state); + void Write(Action write, T state) where T : struct; } } diff --git a/src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/ServiceContext.cs b/src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/ServiceContext.cs index 41a37f2fe5..4df0cb751f 100644 --- a/src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/ServiceContext.cs +++ b/src/Microsoft.AspNetCore.Server.Kestrel.Core/Internal/ServiceContext.cs @@ -13,7 +13,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal public IThreadPool ThreadPool { get; set; } - public Func HttpParserFactory { get; set; } + public Func> HttpParserFactory { get; set; } public DateHeaderValueManager DateHeaderValueManager { get; set; } diff --git a/src/Microsoft.AspNetCore.Server.Kestrel.Core/KestrelServer.cs b/src/Microsoft.AspNetCore.Server.Kestrel.Core/KestrelServer.cs index 8cb36edf33..d5962ee0a1 100644 --- a/src/Microsoft.AspNetCore.Server.Kestrel.Core/KestrelServer.cs +++ b/src/Microsoft.AspNetCore.Server.Kestrel.Core/KestrelServer.cs @@ -101,7 +101,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core var serviceContext = new ServiceContext { Log = trace, - HttpParserFactory = frame => new HttpParser(frame.ServiceContext.Log), + HttpParserFactory = frameParser => new HttpParser(frameParser.Frame.ServiceContext.Log), ThreadPool = threadPool, DateHeaderValueManager = _dateHeaderValueManager, ServerOptions = Options diff --git a/test/Microsoft.AspNetCore.Server.Kestrel.Core.Tests/FrameResponseHeadersTests.cs b/test/Microsoft.AspNetCore.Server.Kestrel.Core.Tests/FrameResponseHeadersTests.cs index c36da4188f..2d6f6bb706 100644 --- a/test/Microsoft.AspNetCore.Server.Kestrel.Core.Tests/FrameResponseHeadersTests.cs +++ b/test/Microsoft.AspNetCore.Server.Kestrel.Core.Tests/FrameResponseHeadersTests.cs @@ -256,28 +256,5 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests "42,000", "42.000", }; - - private class NoopHttpParser : IHttpParser - { - public bool ParseHeaders(IHttpHeadersHandler handler, ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined, out int consumedBytes) - { - consumed = buffer.Start; - examined = buffer.End; - consumedBytes = 0; - return false; - } - - public bool ParseRequestLine(IHttpRequestLineHandler handler, ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined) - { - consumed = buffer.Start; - examined = buffer.End; - return false; - } - - public void Reset() - { - - } - } } } \ No newline at end of file diff --git a/test/Microsoft.AspNetCore.Server.Kestrel.Core.Tests/HttpParserTests.cs b/test/Microsoft.AspNetCore.Server.Kestrel.Core.Tests/HttpParserTests.cs index 3600be4c40..2a953005cc 100644 --- a/test/Microsoft.AspNetCore.Server.Kestrel.Core.Tests/HttpParserTests.cs +++ b/test/Microsoft.AspNetCore.Server.Kestrel.Core.Tests/HttpParserTests.cs @@ -5,7 +5,6 @@ using System.Collections.Generic; using System.Linq; using System.Text; using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Server.Kestrel.Core; using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http; using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Infrastructure; using Microsoft.AspNetCore.Server.Kestrel.Internal.System; @@ -418,7 +417,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests Assert.Equal(buffer.End, examined); } - private IHttpParser CreateParser(IKestrelTrace log) => new HttpParser(log); + private IHttpParser CreateParser(IKestrelTrace log) => new HttpParser(log); public static IEnumerable RequestLineValidData => HttpParsingData.RequestLineValidData; diff --git a/test/Microsoft.AspNetCore.Server.Kestrel.Core.Tests/OutputProducerTests.cs b/test/Microsoft.AspNetCore.Server.Kestrel.Core.Tests/OutputProducerTests.cs index ff5591b109..e96126d087 100644 --- a/test/Microsoft.AspNetCore.Server.Kestrel.Core.Tests/OutputProducerTests.cs +++ b/test/Microsoft.AspNetCore.Server.Kestrel.Core.Tests/OutputProducerTests.cs @@ -38,11 +38,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests var called = false; - ((ISocketOutput)socketOutput).Write((buffer, state) => + ((ISocketOutput)socketOutput).Write((buffer, state) => { called = true; }, - null); + 0); Assert.False(called); } diff --git a/test/Microsoft.AspNetCore.Server.Kestrel.Performance/FrameFeatureCollection.cs b/test/Microsoft.AspNetCore.Server.Kestrel.Performance/FrameFeatureCollection.cs index 4115934774..bd4ec5ae97 100644 --- a/test/Microsoft.AspNetCore.Server.Kestrel.Performance/FrameFeatureCollection.cs +++ b/test/Microsoft.AspNetCore.Server.Kestrel.Performance/FrameFeatureCollection.cs @@ -78,7 +78,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance { var serviceContext = new ServiceContext { - HttpParserFactory = _ => NullParser.Instance, + HttpParserFactory = _ => NullParser.Instance, ServerOptions = new KestrelServerOptions() }; var frameContext = new FrameContext diff --git a/test/Microsoft.AspNetCore.Server.Kestrel.Performance/FrameParsingOverheadBenchmark.cs b/test/Microsoft.AspNetCore.Server.Kestrel.Performance/FrameParsingOverheadBenchmark.cs index ac7f6869bf..bb01a4fc01 100644 --- a/test/Microsoft.AspNetCore.Server.Kestrel.Performance/FrameParsingOverheadBenchmark.cs +++ b/test/Microsoft.AspNetCore.Server.Kestrel.Performance/FrameParsingOverheadBenchmark.cs @@ -22,7 +22,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance { var serviceContext = new ServiceContext { - HttpParserFactory = _ => NullParser.Instance, + HttpParserFactory = _ => NullParser.Instance, ServerOptions = new KestrelServerOptions() }; var frameContext = new FrameContext diff --git a/test/Microsoft.AspNetCore.Server.Kestrel.Performance/FrameWritingBenchmark.cs b/test/Microsoft.AspNetCore.Server.Kestrel.Performance/FrameWritingBenchmark.cs index 01f1b008fa..3755e5df5c 100644 --- a/test/Microsoft.AspNetCore.Server.Kestrel.Performance/FrameWritingBenchmark.cs +++ b/test/Microsoft.AspNetCore.Server.Kestrel.Performance/FrameWritingBenchmark.cs @@ -94,7 +94,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance DateHeaderValueManager = new DateHeaderValueManager(), ServerOptions = new KestrelServerOptions(), Log = new MockTrace(), - HttpParserFactory = f => new HttpParser(log: null) + HttpParserFactory = f => new HttpParser(log: null) }; var frameContext = new FrameContext { diff --git a/test/Microsoft.AspNetCore.Server.Kestrel.Performance/KestrelHttpParserBenchmark.cs b/test/Microsoft.AspNetCore.Server.Kestrel.Performance/KestrelHttpParserBenchmark.cs index d7e3e89511..c19bd6ddec 100644 --- a/test/Microsoft.AspNetCore.Server.Kestrel.Performance/KestrelHttpParserBenchmark.cs +++ b/test/Microsoft.AspNetCore.Server.Kestrel.Performance/KestrelHttpParserBenchmark.cs @@ -12,7 +12,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance public class KestrelHttpParserBenchmark : IHttpRequestLineHandler, IHttpHeadersHandler { - private readonly HttpParser _parser = new HttpParser(log: null); + private readonly HttpParser _parser = new HttpParser(log: null); private ReadableBuffer _buffer; @@ -53,14 +53,14 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance private void ParseData() { - if (!_parser.ParseRequestLine(this, _buffer, out var consumed, out var examined)) + if (!_parser.ParseRequestLine(new Adapter(this), _buffer, out var consumed, out var examined)) { ErrorUtilities.ThrowInvalidRequestHeaders(); } _buffer = _buffer.Slice(consumed, _buffer.End); - if (!_parser.ParseHeaders(this, _buffer, out consumed, out examined, out var consumedBytes)) + if (!_parser.ParseHeaders(new Adapter(this), _buffer, out consumed, out examined, out var consumedBytes)) { ErrorUtilities.ThrowInvalidRequestHeaders(); } @@ -73,5 +73,21 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance public void OnHeader(Span name, Span value) { } + + private struct Adapter : IHttpRequestLineHandler, IHttpHeadersHandler + { + public KestrelHttpParserBenchmark RequestHandler; + + public Adapter(KestrelHttpParserBenchmark requestHandler) + { + RequestHandler = requestHandler; + } + + public void OnHeader(Span name, Span value) + => RequestHandler.OnHeader(name, value); + + public void OnStartLine(HttpMethod method, HttpVersion version, Span target, Span path, Span query, Span customMethod, bool pathEncoded) + => RequestHandler.OnStartLine(method, version, target, path, query, customMethod, pathEncoded); + } } } diff --git a/test/Microsoft.AspNetCore.Server.Kestrel.Performance/Mocks/NullParser.cs b/test/Microsoft.AspNetCore.Server.Kestrel.Performance/Mocks/NullParser.cs index d27bfc1f2b..54d71cf795 100644 --- a/test/Microsoft.AspNetCore.Server.Kestrel.Performance/Mocks/NullParser.cs +++ b/test/Microsoft.AspNetCore.Server.Kestrel.Performance/Mocks/NullParser.cs @@ -8,7 +8,7 @@ using Microsoft.AspNetCore.Server.Kestrel.Internal.System.IO.Pipelines; namespace Microsoft.AspNetCore.Server.Kestrel.Performance { - public class NullParser : IHttpParser + public class NullParser : IHttpParser where TRequestHandler : struct, IHttpHeadersHandler, IHttpRequestLineHandler { private readonly byte[] _startLine = Encoding.ASCII.GetBytes("GET /plaintext HTTP/1.1\r\n"); private readonly byte[] _target = Encoding.ASCII.GetBytes("/plaintext"); @@ -19,9 +19,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance private readonly byte[] _connectionHeaderName = Encoding.ASCII.GetBytes("Connection"); private readonly byte[] _connectionHeaderValue = Encoding.ASCII.GetBytes("keep-alive"); - public static readonly NullParser Instance = new NullParser(); + public static readonly NullParser Instance = new NullParser(); - public bool ParseHeaders(IHttpHeadersHandler handler, ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined, out int consumedBytes) + public bool ParseHeaders(TRequestHandler handler, ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined, out int consumedBytes) { handler.OnHeader(new Span(_hostHeaderName), new Span(_hostHeaderValue)); handler.OnHeader(new Span(_acceptHeaderName), new Span(_acceptHeaderValue)); @@ -34,7 +34,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance return true; } - public bool ParseRequestLine(IHttpRequestLineHandler handler, ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined) + public bool ParseRequestLine(TRequestHandler handler, ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined) { handler.OnStartLine(HttpMethod.Get, HttpVersion.Http11, diff --git a/test/Microsoft.AspNetCore.Server.Kestrel.Performance/RequestParsingBenchmark.cs b/test/Microsoft.AspNetCore.Server.Kestrel.Performance/RequestParsingBenchmark.cs index d759bccc02..593b4b8d46 100644 --- a/test/Microsoft.AspNetCore.Server.Kestrel.Performance/RequestParsingBenchmark.cs +++ b/test/Microsoft.AspNetCore.Server.Kestrel.Performance/RequestParsingBenchmark.cs @@ -23,7 +23,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance { var serviceContext = new ServiceContext { - HttpParserFactory = f => new HttpParser(f.ServiceContext.Log), + HttpParserFactory = f => new HttpParser(f.Frame.ServiceContext.Log), ServerOptions = new KestrelServerOptions() }; var frameContext = new FrameContext diff --git a/test/Microsoft.AspNetCore.Server.Kestrel.Performance/ResponseHeaderCollectionBenchmark.cs b/test/Microsoft.AspNetCore.Server.Kestrel.Performance/ResponseHeaderCollectionBenchmark.cs index 0d32ed7079..9aaf5a61f5 100644 --- a/test/Microsoft.AspNetCore.Server.Kestrel.Performance/ResponseHeaderCollectionBenchmark.cs +++ b/test/Microsoft.AspNetCore.Server.Kestrel.Performance/ResponseHeaderCollectionBenchmark.cs @@ -170,7 +170,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance { var serviceContext = new ServiceContext { - HttpParserFactory = f => new HttpParser(f.ServiceContext.Log), + HttpParserFactory = f => new HttpParser(f.Frame.ServiceContext.Log), ServerOptions = new KestrelServerOptions() }; var frameContext = new FrameContext diff --git a/test/Microsoft.AspNetCore.Server.Kestrel.Performance/ResponseHeadersWritingBenchmark.cs b/test/Microsoft.AspNetCore.Server.Kestrel.Performance/ResponseHeadersWritingBenchmark.cs index da56c4cc0b..5d5db64188 100644 --- a/test/Microsoft.AspNetCore.Server.Kestrel.Performance/ResponseHeadersWritingBenchmark.cs +++ b/test/Microsoft.AspNetCore.Server.Kestrel.Performance/ResponseHeadersWritingBenchmark.cs @@ -120,7 +120,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance DateHeaderValueManager = new DateHeaderValueManager(), ServerOptions = new KestrelServerOptions(), Log = new MockTrace(), - HttpParserFactory = f => new HttpParser(log: null) + HttpParserFactory = f => new HttpParser(log: null) }; var frameContext = new FrameContext diff --git a/test/shared/MockSocketOutput.cs b/test/shared/MockSocketOutput.cs index f213514434..9089bca83d 100644 --- a/test/shared/MockSocketOutput.cs +++ b/test/shared/MockSocketOutput.cs @@ -34,7 +34,7 @@ namespace Microsoft.AspNetCore.Testing return TaskCache.CompletedTask; } - public void Write(Action write, T state) + public void Write(Action write, T state) where T : struct { } diff --git a/test/shared/TestServiceContext.cs b/test/shared/TestServiceContext.cs index bf8e8eed40..808a03998d 100644 --- a/test/shared/TestServiceContext.cs +++ b/test/shared/TestServiceContext.cs @@ -18,7 +18,7 @@ namespace Microsoft.AspNetCore.Testing ThreadPool = new LoggingThreadPool(Log); DateHeaderValueManager = new DateHeaderValueManager(systemClock: new MockSystemClock()); DateHeaderValue = DateHeaderValueManager.GetDateHeaderValues().String; - HttpParserFactory = frame => new HttpParser(frame.ServiceContext.Log); + HttpParserFactory = frameAdapter => new HttpParser(frameAdapter.Frame.ServiceContext.Log); ServerOptions = new KestrelServerOptions { AddServerHeader = false