Make the HttpParser a singleton (#2203)

- It's completely stateless so make it a singleton
- Fixed tests
This commit is contained in:
David Fowler 2017-12-03 13:27:36 -08:00 committed by GitHub
parent a08707f133
commit b8a1c04ffb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 26 additions and 15 deletions

View File

@ -29,7 +29,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance
var serviceContext = new ServiceContext var serviceContext = new ServiceContext
{ {
ServerOptions = new KestrelServerOptions(), ServerOptions = new KestrelServerOptions(),
HttpParserFactory = f => NullParser<Http1ParsingHandler>.Instance HttpParser = NullParser<Http1ParsingHandler>.Instance
}; };
var http1Connection = new Http1Connection<object>(application: null, context: new Http1ConnectionContext var http1Connection = new Http1Connection<object>(application: null, context: new Http1ConnectionContext

View File

@ -104,7 +104,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 HttpParser<Http1ParsingHandler>() HttpParser = new HttpParser<Http1ParsingHandler>()
}; };
var http1Connection = new TestHttp1Connection<object>( var http1Connection = new TestHttp1Connection<object>(

View File

@ -86,7 +86,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 HttpParser<Http1ParsingHandler>() HttpParser = new HttpParser<Http1ParsingHandler>()
}; };
var http1Connection = new Http1Connection<object>(application: null, context: new Http1ConnectionContext var http1Connection = new Http1Connection<object>(application: null, context: new Http1ConnectionContext

View File

@ -30,7 +30,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 HttpParser<Http1ParsingHandler>() HttpParser = new HttpParser<Http1ParsingHandler>()
}; };
var http1Connection = new Http1Connection<object>(application: null, context: new Http1ConnectionContext var http1Connection = new Http1Connection<object>(application: null, context: new Http1ConnectionContext

View File

@ -179,7 +179,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 HttpParser<Http1ParsingHandler>() HttpParser = new HttpParser<Http1ParsingHandler>()
}; };
var http1Connection = new Http1Connection<object>(application: null, context: new Http1ConnectionContext var http1Connection = new Http1Connection<object>(application: null, context: new Http1ConnectionContext

View File

@ -119,7 +119,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 HttpParser<Http1ParsingHandler>() HttpParser = new HttpParser<Http1ParsingHandler>()
}; };
var http1Connection = new TestHttp1Connection<object>( var http1Connection = new TestHttp1Connection<object>(

View File

@ -35,7 +35,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
: base(context) : base(context)
{ {
_context = context; _context = context;
_parser = ServiceContext.HttpParserFactory(new Http1ParsingHandler(this)); _parser = ServiceContext.HttpParser;
_keepAliveTicks = ServerOptions.Limits.KeepAliveTimeout.Ticks; _keepAliveTicks = ServerOptions.Limits.KeepAliveTimeout.Ticks;
_requestHeadersTimeoutTicks = ServerOptions.Limits.RequestHeadersTimeout.Ticks; _requestHeadersTimeoutTicks = ServerOptions.Limits.RequestHeadersTimeout.Ticks;

View File

@ -13,7 +13,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal
public IThreadPool ThreadPool { get; set; } public IThreadPool ThreadPool { get; set; }
public Func<Http1ParsingHandler, IHttpParser<Http1ParsingHandler>> HttpParserFactory { get; set; } public IHttpParser<Http1ParsingHandler> HttpParser { get; set; }
public ISystemClock SystemClock { get; set; } public ISystemClock SystemClock { get; set; }

View File

@ -101,7 +101,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core
return new ServiceContext return new ServiceContext
{ {
Log = trace, Log = trace,
HttpParserFactory = handler => new HttpParser<Http1ParsingHandler>(handler.Connection.ServiceContext.Log.IsEnabled(LogLevel.Information)), HttpParser = new HttpParser<Http1ParsingHandler>(trace.IsEnabled(LogLevel.Information)),
ThreadPool = threadPool, ThreadPool = threadPool,
SystemClock = systemClock, SystemClock = systemClock,
DateHeaderValueManager = dateHeaderValueManager, DateHeaderValueManager = dateHeaderValueManager,

View File

@ -188,6 +188,8 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
public void LoggerCategoryNameIsKestrelServerNamespace() public void LoggerCategoryNameIsKestrelServerNamespace()
{ {
var mockLoggerFactory = new Mock<ILoggerFactory>(); var mockLoggerFactory = new Mock<ILoggerFactory>();
var mockLogger = new Mock<ILogger>();
mockLoggerFactory.Setup(m => m.CreateLogger(It.IsAny<string>())).Returns(mockLogger.Object);
new KestrelServer(Options.Create<KestrelServerOptions>(null), Mock.Of<ITransportFactory>(), mockLoggerFactory.Object); new KestrelServer(Options.Create<KestrelServerOptions>(null), Mock.Of<ITransportFactory>(), mockLoggerFactory.Object);
mockLoggerFactory.Verify(factory => factory.CreateLogger("Microsoft.AspNetCore.Server.Kestrel")); mockLoggerFactory.Verify(factory => factory.CreateLogger("Microsoft.AspNetCore.Server.Kestrel"));
} }
@ -195,8 +197,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
[Fact] [Fact]
public void StartWithNoTransportFactoryThrows() public void StartWithNoTransportFactoryThrows()
{ {
var mockLoggerFactory = new Mock<ILoggerFactory>();
var mockLogger = new Mock<ILogger>();
mockLoggerFactory.Setup(m => m.CreateLogger(It.IsAny<string>())).Returns(mockLogger.Object);
var exception = Assert.Throws<ArgumentNullException>(() => var exception = Assert.Throws<ArgumentNullException>(() =>
new KestrelServer(Options.Create<KestrelServerOptions>(null), null, Mock.Of<ILoggerFactory>())); new KestrelServer(Options.Create<KestrelServerOptions>(null), null, mockLoggerFactory.Object));
Assert.Equal("transportFactory", exception.ParamName); Assert.Equal("transportFactory", exception.ParamName);
} }
@ -231,7 +236,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
.Setup(transportFactory => transportFactory.Create(It.IsAny<IEndPointInformation>(), It.IsAny<IConnectionHandler>())) .Setup(transportFactory => transportFactory.Create(It.IsAny<IEndPointInformation>(), It.IsAny<IConnectionHandler>()))
.Returns(mockTransport.Object); .Returns(mockTransport.Object);
var server = new KestrelServer(Options.Create(options), mockTransportFactory.Object, Mock.Of<LoggerFactory>()); var mockLoggerFactory = new Mock<ILoggerFactory>();
var mockLogger = new Mock<ILogger>();
mockLoggerFactory.Setup(m => m.CreateLogger(It.IsAny<string>())).Returns(mockLogger.Object);
var server = new KestrelServer(Options.Create(options), mockTransportFactory.Object, mockLoggerFactory.Object);
await server.StartAsync(new DummyApplication(), CancellationToken.None); await server.StartAsync(new DummyApplication(), CancellationToken.None);
var stopTask1 = server.StopAsync(default(CancellationToken)); var stopTask1 = server.StopAsync(default(CancellationToken));
@ -285,7 +293,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Tests
.Setup(transportFactory => transportFactory.Create(It.IsAny<IEndPointInformation>(), It.IsAny<IConnectionHandler>())) .Setup(transportFactory => transportFactory.Create(It.IsAny<IEndPointInformation>(), It.IsAny<IConnectionHandler>()))
.Returns(mockTransport.Object); .Returns(mockTransport.Object);
var server = new KestrelServer(Options.Create(options), mockTransportFactory.Object, Mock.Of<LoggerFactory>()); var mockLoggerFactory = new Mock<ILoggerFactory>();
var mockLogger = new Mock<ILogger>();
mockLoggerFactory.Setup(m => m.CreateLogger(It.IsAny<string>())).Returns(mockLogger.Object);
var server = new KestrelServer(Options.Create(options), mockTransportFactory.Object, mockLoggerFactory.Object);
await server.StartAsync(new DummyApplication(), CancellationToken.None); await server.StartAsync(new DummyApplication(), CancellationToken.None);
var stopTask1 = server.StopAsync(default(CancellationToken)); var stopTask1 = server.StopAsync(default(CancellationToken));

View File

@ -110,7 +110,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Tests
DateHeaderValueManager = serviceContextPrimary.DateHeaderValueManager, DateHeaderValueManager = serviceContextPrimary.DateHeaderValueManager,
ServerOptions = serviceContextPrimary.ServerOptions, ServerOptions = serviceContextPrimary.ServerOptions,
ThreadPool = serviceContextPrimary.ThreadPool, ThreadPool = serviceContextPrimary.ThreadPool,
HttpParserFactory = serviceContextPrimary.HttpParserFactory, HttpParser = serviceContextPrimary.HttpParser,
}; };
var builderSecondary = new ConnectionBuilder(); var builderSecondary = new ConnectionBuilder();
builderSecondary.UseHttpServer(serviceContextSecondary, new DummyApplication(c => c.Response.WriteAsync("Secondary")), HttpProtocols.Http1); builderSecondary.UseHttpServer(serviceContextSecondary, new DummyApplication(c => c.Response.WriteAsync("Secondary")), HttpProtocols.Http1);
@ -221,7 +221,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Tests
DateHeaderValueManager = serviceContextPrimary.DateHeaderValueManager, DateHeaderValueManager = serviceContextPrimary.DateHeaderValueManager,
ServerOptions = serviceContextPrimary.ServerOptions, ServerOptions = serviceContextPrimary.ServerOptions,
ThreadPool = serviceContextPrimary.ThreadPool, ThreadPool = serviceContextPrimary.ThreadPool,
HttpParserFactory = serviceContextPrimary.HttpParserFactory, HttpParser = serviceContextPrimary.HttpParser,
}; };
var builderSecondary = new ConnectionBuilder(); var builderSecondary = new ConnectionBuilder();
builderSecondary.UseHttpServer(serviceContextSecondary, new DummyApplication(c => c.Response.WriteAsync("Secondary")), HttpProtocols.Http1); builderSecondary.UseHttpServer(serviceContextSecondary, new DummyApplication(c => c.Response.WriteAsync("Secondary")), HttpProtocols.Http1);

View File

@ -39,7 +39,7 @@ namespace Microsoft.AspNetCore.Testing
SystemClock = new MockSystemClock(); SystemClock = new MockSystemClock();
DateHeaderValueManager = new DateHeaderValueManager(SystemClock); DateHeaderValueManager = new DateHeaderValueManager(SystemClock);
ConnectionManager = new HttpConnectionManager(Log, ResourceCounter.Unlimited); ConnectionManager = new HttpConnectionManager(Log, ResourceCounter.Unlimited);
HttpParserFactory = handler => new HttpParser<Http1ParsingHandler>(handler.Connection.ServiceContext.Log.IsEnabled(LogLevel.Information)); HttpParser = new HttpParser<Http1ParsingHandler>(Log.IsEnabled(LogLevel.Information));
ServerOptions = new KestrelServerOptions ServerOptions = new KestrelServerOptions
{ {
AddServerHeader = false AddServerHeader = false