A few HttpParser changes (#1624)

- Renamed KestrelHttpParser to HttpParser
- Removed the generic virtual dispatch as it turns out to be an
order of magnitude slower than regular virtual dispatch. This change
means we also lose the inlining of Frame.OnStartLine and Frame.OnHeader.
This commit is contained in:
David Fowler 2017-04-07 08:35:53 -07:00 committed by GitHub
parent f253dbc0c0
commit 239b691ff5
12 changed files with 20 additions and 20 deletions

View File

@ -10,9 +10,9 @@ using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
{ {
public class KestrelHttpParser : IHttpParser public class HttpParser : IHttpParser
{ {
public KestrelHttpParser(IKestrelTrace log) public HttpParser(IKestrelTrace log)
{ {
Log = log; Log = log;
} }
@ -28,7 +28,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
private const byte ByteQuestionMark = (byte)'?'; private const byte ByteQuestionMark = (byte)'?';
private const byte BytePercentage = (byte)'%'; private const byte BytePercentage = (byte)'%';
public unsafe bool ParseRequestLine<T>(T handler, ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined) where T : IHttpRequestLineHandler public unsafe bool ParseRequestLine(IHttpRequestLineHandler handler, ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined)
{ {
consumed = buffer.Start; consumed = buffer.Start;
examined = buffer.End; examined = buffer.End;
@ -67,7 +67,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
return true; return true;
} }
private unsafe void ParseRequestLine<T>(T handler, byte* data, int length) where T : IHttpRequestLineHandler private unsafe void ParseRequestLine(IHttpRequestLineHandler handler, byte* data, int length)
{ {
int offset; int offset;
Span<byte> customMethod = default(Span<byte>); Span<byte> customMethod = default(Span<byte>);
@ -184,7 +184,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
handler.OnStartLine(method, httpVersion, targetBuffer, pathBuffer, query, customMethod, pathEncoded); handler.OnStartLine(method, httpVersion, targetBuffer, pathBuffer, query, customMethod, pathEncoded);
} }
public unsafe bool ParseHeaders<T>(T handler, ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined, out int consumedBytes) where T : IHttpHeadersHandler public unsafe bool ParseHeaders(IHttpHeadersHandler handler, ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined, out int consumedBytes)
{ {
consumed = buffer.Start; consumed = buffer.Start;
examined = buffer.End; examined = buffer.End;
@ -347,7 +347,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
private unsafe void TakeSingleHeader<T>(byte* headerLine, int length, T handler) where T : IHttpHeadersHandler private unsafe void TakeSingleHeader(byte* headerLine, int length, IHttpHeadersHandler handler)
{ {
// Skip CR, LF from end position // Skip CR, LF from end position
var valueEnd = length - 3; var valueEnd = length - 3;

View File

@ -7,9 +7,9 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
{ {
public interface IHttpParser public interface IHttpParser
{ {
bool ParseRequestLine<T>(T handler, ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined) where T : IHttpRequestLineHandler; bool ParseRequestLine(IHttpRequestLineHandler handler, ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined);
bool ParseHeaders<T>(T handler, ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined, out int consumedBytes) where T : IHttpHeadersHandler; bool ParseHeaders(IHttpHeadersHandler handler, ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined, out int consumedBytes);
void Reset(); void Reset();
} }

View File

@ -101,7 +101,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core
var serviceContext = new ServiceContext var serviceContext = new ServiceContext
{ {
Log = trace, Log = trace,
HttpParserFactory = frame => new KestrelHttpParser(frame.ServiceContext.Log), HttpParserFactory = frame => new HttpParser(frame.ServiceContext.Log),
ThreadPool = threadPool, ThreadPool = threadPool,
DateHeaderValueManager = _dateHeaderValueManager, DateHeaderValueManager = _dateHeaderValueManager,
ServerOptions = Options ServerOptions = Options

View File

@ -259,7 +259,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
private class NoopHttpParser : IHttpParser private class NoopHttpParser : IHttpParser
{ {
public bool ParseHeaders<T>(T handler, ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined, out int consumedBytes) where T : IHttpHeadersHandler public bool ParseHeaders(IHttpHeadersHandler handler, ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined, out int consumedBytes)
{ {
consumed = buffer.Start; consumed = buffer.Start;
examined = buffer.End; examined = buffer.End;
@ -267,7 +267,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
return false; return false;
} }
public bool ParseRequestLine<T>(T handler, ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined) where T : IHttpRequestLineHandler public bool ParseRequestLine(IHttpRequestLineHandler handler, ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined)
{ {
consumed = buffer.Start; consumed = buffer.Start;
examined = buffer.End; examined = buffer.End;

View File

@ -418,7 +418,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
Assert.Equal(buffer.End, examined); Assert.Equal(buffer.End, examined);
} }
private IHttpParser CreateParser(IKestrelTrace log) => new KestrelHttpParser(log); private IHttpParser CreateParser(IKestrelTrace log) => new HttpParser(log);
public static IEnumerable<string[]> RequestLineValidData => HttpParsingData.RequestLineValidData; public static IEnumerable<string[]> RequestLineValidData => HttpParsingData.RequestLineValidData;

View File

@ -114,7 +114,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance
public static readonly NullParser Instance = new NullParser(); public static readonly NullParser Instance = new NullParser();
public bool ParseHeaders<T>(T handler, ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined, out int consumedBytes) where T : IHttpHeadersHandler public bool ParseHeaders(IHttpHeadersHandler handler, ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined, out int consumedBytes)
{ {
handler.OnHeader(new Span<byte>(_hostHeaderName), new Span<byte>(_hostHeaderValue)); handler.OnHeader(new Span<byte>(_hostHeaderName), new Span<byte>(_hostHeaderValue));
handler.OnHeader(new Span<byte>(_acceptHeaderName), new Span<byte>(_acceptHeaderValue)); handler.OnHeader(new Span<byte>(_acceptHeaderName), new Span<byte>(_acceptHeaderValue));
@ -127,7 +127,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance
return true; return true;
} }
public bool ParseRequestLine<T>(T handler, ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined) where T : IHttpRequestLineHandler public bool ParseRequestLine(IHttpRequestLineHandler handler, ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined)
{ {
handler.OnStartLine(HttpMethod.Get, handler.OnStartLine(HttpMethod.Get,
HttpVersion.Http11, HttpVersion.Http11,

View File

@ -94,7 +94,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance
DateHeaderValueManager = new DateHeaderValueManager(), DateHeaderValueManager = new DateHeaderValueManager(),
ServerOptions = new KestrelServerOptions(), ServerOptions = new KestrelServerOptions(),
Log = new MockTrace(), Log = new MockTrace(),
HttpParserFactory = f => new KestrelHttpParser(log: null) HttpParserFactory = f => new HttpParser(log: null)
}; };
var frameContext = new FrameContext var frameContext = new FrameContext
{ {

View File

@ -12,7 +12,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance
public class KestrelHttpParserBenchmark : IHttpRequestLineHandler, IHttpHeadersHandler public class KestrelHttpParserBenchmark : IHttpRequestLineHandler, IHttpHeadersHandler
{ {
private readonly KestrelHttpParser _parser = new KestrelHttpParser(log: null); private readonly HttpParser _parser = new HttpParser(log: null);
private ReadableBuffer _buffer; private ReadableBuffer _buffer;

View File

@ -23,7 +23,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance
{ {
var serviceContext = new ServiceContext var serviceContext = new ServiceContext
{ {
HttpParserFactory = f => new KestrelHttpParser(f.ServiceContext.Log), HttpParserFactory = f => new HttpParser(f.ServiceContext.Log),
ServerOptions = new KestrelServerOptions() ServerOptions = new KestrelServerOptions()
}; };
var frameContext = new FrameContext var frameContext = new FrameContext

View File

@ -170,7 +170,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance
{ {
var serviceContext = new ServiceContext var serviceContext = new ServiceContext
{ {
HttpParserFactory = f => new KestrelHttpParser(f.ServiceContext.Log), HttpParserFactory = f => new HttpParser(f.ServiceContext.Log),
ServerOptions = new KestrelServerOptions() ServerOptions = new KestrelServerOptions()
}; };
var frameContext = new FrameContext var frameContext = new FrameContext

View File

@ -120,7 +120,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance
DateHeaderValueManager = new DateHeaderValueManager(), DateHeaderValueManager = new DateHeaderValueManager(),
ServerOptions = new KestrelServerOptions(), ServerOptions = new KestrelServerOptions(),
Log = new MockTrace(), Log = new MockTrace(),
HttpParserFactory = f => new KestrelHttpParser(log: null) HttpParserFactory = f => new HttpParser(log: null)
}; };
var frameContext = new FrameContext var frameContext = new FrameContext

View File

@ -18,7 +18,7 @@ namespace Microsoft.AspNetCore.Testing
ThreadPool = new LoggingThreadPool(Log); ThreadPool = new LoggingThreadPool(Log);
DateHeaderValueManager = new DateHeaderValueManager(systemClock: new MockSystemClock()); DateHeaderValueManager = new DateHeaderValueManager(systemClock: new MockSystemClock());
DateHeaderValue = DateHeaderValueManager.GetDateHeaderValues().String; DateHeaderValue = DateHeaderValueManager.GetDateHeaderValues().String;
HttpParserFactory = frame => new KestrelHttpParser(frame.ServiceContext.Log); HttpParserFactory = frame => new HttpParser(frame.ServiceContext.Log);
ServerOptions = new KestrelServerOptions ServerOptions = new KestrelServerOptions
{ {
AddServerHeader = false AddServerHeader = false