Reacting to Hosting changes

This commit is contained in:
John Luo 2015-10-29 14:18:34 -07:00
parent af2c32f612
commit b466c3b7d7
19 changed files with 212 additions and 142 deletions

View File

@ -206,9 +206,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
ResponseBody = new FrameResponseStream(this);
DuplexStream = new FrameDuplexStream(RequestBody, ResponseBody);
var httpContext = HttpContextFactory.Create(this);
try
{
await Application.Invoke(this).ConfigureAwait(false);
await Application.Invoke(httpContext).ConfigureAwait(false);
}
catch (Exception ex)
{
@ -227,6 +228,8 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
await FireOnCompleted();
HttpContextFactory.Dispose(httpContext);
await ProduceEnd();
while (await RequestBody.ReadAsync(_nullBuffer, 0, _nullBuffer.Length) != 0)

View File

@ -3,6 +3,7 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Server.Kestrel.Networking;
using Microsoft.Extensions.Logging;
@ -23,7 +24,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
public Task StartAsync(
ServerAddress address,
KestrelThread thread,
Func<Frame, Task> application)
RequestDelegate application)
{
ServerAddress = address;
Thread = thread;

View File

@ -1,8 +1,7 @@
// 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.Threading.Tasks;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Server.Kestrel.Infrastructure;
namespace Microsoft.AspNet.Server.Kestrel.Http
@ -34,7 +33,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
public KestrelThread Thread { get; set; }
public Func<Frame, Task> Application { get; set; }
public RequestDelegate Application { get; set; }
public MemoryPool2 Memory2 { get; set; }
}

View File

@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Server.Kestrel.Infrastructure;
using Microsoft.AspNet.Server.Kestrel.Networking;
using Microsoft.Extensions.Logging;
@ -33,7 +34,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
string pipeName,
ServerAddress address,
KestrelThread thread,
Func<Frame, Task> application)
RequestDelegate application)
{
await StartAsync(address, thread, application).ConfigureAwait(false);

View File

@ -4,6 +4,7 @@
using System;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Server.Kestrel.Infrastructure;
using Microsoft.AspNet.Server.Kestrel.Networking;
using Microsoft.Extensions.Logging;
@ -26,7 +27,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
string pipeName,
ServerAddress address,
KestrelThread thread,
Func<Frame, Task> application)
RequestDelegate application)
{
ServerAddress = address;
Thread = thread;

View File

@ -3,8 +3,7 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNet.Http.Features;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Server.Kestrel.Http;
using Microsoft.AspNet.Server.Kestrel.Networking;
@ -49,7 +48,7 @@ namespace Microsoft.AspNet.Server.Kestrel
Threads.Clear();
}
public IDisposable CreateServer(ServerAddress address, Func<IFeatureCollection, Task> application)
public IDisposable CreateServer(ServerAddress address, RequestDelegate application)
{
var listeners = new List<IDisposable>();

View File

@ -0,0 +1,128 @@
// 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.Collections.Generic;
using Microsoft.AspNet.Hosting;
using Microsoft.AspNet.Hosting.Server;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Http.Features;
using Microsoft.AspNet.Server.Kestrel.Http;
using Microsoft.Extensions.Logging;
namespace Microsoft.AspNet.Server.Kestrel
{
public class KestrelServer : IServer
{
private Stack<IDisposable> _disposables;
private readonly IApplicationLifetime _applicationLifetime;
private readonly ILogger _logger;
private readonly IHttpContextFactory _httpContextFactory;
public KestrelServer(IFeatureCollection features, IApplicationLifetime applicationLifetime, ILogger logger, IHttpContextFactory httpContextFactory)
{
if (features == null)
{
throw new ArgumentNullException(nameof(features));
}
if (applicationLifetime == null)
{
throw new ArgumentNullException(nameof(applicationLifetime));
}
if (logger == null)
{
throw new ArgumentNullException(nameof(logger));
}
if (httpContextFactory == null)
{
throw new ArgumentNullException(nameof(httpContextFactory));
}
_applicationLifetime = applicationLifetime;
_logger = logger;
Features = features;
_httpContextFactory = httpContextFactory;
}
public IFeatureCollection Features { get; }
public void Start(RequestDelegate requestDelegate)
{
if (_disposables != null)
{
// The server has already started and/or has not been cleaned up yet
throw new InvalidOperationException("Server has already started.");
}
_disposables = new Stack<IDisposable>();
try
{
var information = (KestrelServerInformation)Features.Get<IKestrelServerInformation>();
var dateHeaderValueManager = new DateHeaderValueManager();
var engine = new KestrelEngine(new ServiceContext
{
AppLifetime = _applicationLifetime,
Log = new KestrelTrace(_logger),
HttpContextFactory = _httpContextFactory,
DateHeaderValueManager = dateHeaderValueManager,
ConnectionFilter = information.ConnectionFilter,
NoDelay = information.NoDelay
});
_disposables.Push(engine);
_disposables.Push(dateHeaderValueManager);
if (information.ThreadCount < 0)
{
throw new ArgumentOutOfRangeException(nameof(information.ThreadCount),
information.ThreadCount,
"ThreadCount cannot be negative");
}
engine.Start(information.ThreadCount == 0 ? 1 : information.ThreadCount);
var atLeastOneListener = false;
foreach (var address in information.Addresses)
{
var parsedAddress = ServerAddress.FromUrl(address);
if (parsedAddress == null)
{
throw new FormatException("Unrecognized listening address: " + address);
}
else
{
atLeastOneListener = true;
_disposables.Push(engine.CreateServer(
parsedAddress,
requestDelegate));
}
}
if (!atLeastOneListener)
{
throw new InvalidOperationException("No recognized listening addresses were configured.");
}
}
catch
{
Dispose();
throw;
}
}
public void Dispose()
{
if (_disposables != null)
{
while (_disposables.Count > 0)
{
_disposables.Pop().Dispose();
}
_disposables = null;
}
}
}
}

View File

@ -1,14 +1,11 @@
// 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.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNet.Hosting;
using Microsoft.AspNet.Hosting.Server;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Http.Features;
using Microsoft.AspNet.Server.Features;
using Microsoft.AspNet.Server.Kestrel.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
@ -20,89 +17,24 @@ namespace Microsoft.AspNet.Server.Kestrel
public class ServerFactory : IServerFactory
{
private readonly IApplicationLifetime _appLifetime;
private readonly ILogger _logger;
private readonly ILoggerFactory _loggerFactory;
private readonly IHttpContextFactory _httpContextFactory;
public ServerFactory(IApplicationLifetime appLifetime, ILoggerFactory loggerFactory)
public ServerFactory(IApplicationLifetime appLifetime, ILoggerFactory loggerFactory, IHttpContextFactory httpContextFactory)
{
_appLifetime = appLifetime;
_logger = loggerFactory.CreateLogger("Microsoft.AspNet.Server.Kestrel");
_loggerFactory = loggerFactory;
_httpContextFactory = httpContextFactory;
}
public IFeatureCollection Initialize(IConfiguration configuration)
public IServer CreateServer(IConfiguration configuration)
{
var information = new KestrelServerInformation();
information.Initialize(configuration);
var serverFeatures = new FeatureCollection();
serverFeatures.Set<IKestrelServerInformation>(information);
serverFeatures.Set<IServerAddressesFeature>(information);
return serverFeatures;
}
public IDisposable Start(IFeatureCollection serverFeatures, Func<IFeatureCollection, Task> application)
{
var disposables = new Stack<IDisposable>();
var disposer = new Disposable(() =>
{
foreach (var disposable in disposables)
{
disposable.Dispose();
}
});
try
{
var information = (KestrelServerInformation)serverFeatures.Get<IKestrelServerInformation>();
var dateHeaderValueManager = new DateHeaderValueManager();
var engine = new KestrelEngine(new ServiceContext
{
AppLifetime = _appLifetime,
Log = new KestrelTrace(_logger),
DateHeaderValueManager = dateHeaderValueManager,
ConnectionFilter = information.ConnectionFilter,
NoDelay = information.NoDelay
});
disposables.Push(engine);
disposables.Push(dateHeaderValueManager);
if (information.ThreadCount < 0)
{
throw new ArgumentOutOfRangeException(nameof(information.ThreadCount),
information.ThreadCount,
"ThreadCount cannot be negative");
}
engine.Start(information.ThreadCount == 0 ? 1 : information.ThreadCount);
bool atLeastOneListener = false;
foreach (var address in information.Addresses)
{
var parsedAddress = ServerAddress.FromUrl(address);
if (parsedAddress == null)
{
throw new FormatException("Unrecognized listening address: " + address);
}
else
{
atLeastOneListener = true;
disposables.Push(engine.CreateServer(
parsedAddress,
application));
}
}
if (!atLeastOneListener)
{
throw new InvalidOperationException("No recognized listening addresses were configured.");
}
return disposer;
}
catch
{
disposer.Dispose();
throw;
}
return new KestrelServer(serverFeatures, _appLifetime, _loggerFactory.CreateLogger("Microsoft.AspNet.Server.Kestrel"), _httpContextFactory);
}
}
}

View File

@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNet.Hosting;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Server.Kestrel.Filter;
using Microsoft.AspNet.Server.Kestrel.Http;
using Microsoft.AspNet.Server.Kestrel.Infrastructure;
@ -20,6 +21,7 @@ namespace Microsoft.AspNet.Server.Kestrel
AppLifetime = context.AppLifetime;
Memory = context.Memory;
Log = context.Log;
HttpContextFactory = context.HttpContextFactory;
DateHeaderValueManager = context.DateHeaderValueManager;
ConnectionFilter = context.ConnectionFilter;
NoDelay = context.NoDelay;
@ -31,6 +33,8 @@ namespace Microsoft.AspNet.Server.Kestrel
public IKestrelTrace Log { get; set; }
public IHttpContextFactory HttpContextFactory { get; set; }
public DateHeaderValueManager DateHeaderValueManager { get; set; }
public IConnectionFilter ConnectionFilter { get; set; }

View File

@ -26,7 +26,7 @@ namespace Microsoft.AspNet.Server.Kestrel.FunctionalTests
.Build();
var hostBuilder = new WebHostBuilder(config);
hostBuilder.UseServer("Microsoft.AspNet.Server.Kestrel");
hostBuilder.UseServerFactory("Microsoft.AspNet.Server.Kestrel");
hostBuilder.UseStartup(ConfigureEchoAddress);
using (var app = hostBuilder.Build().Start())

View File

@ -28,7 +28,7 @@ namespace Microsoft.AspNet.Server.Kestrel.FunctionalTests
.Build();
var hostBuilder = new WebHostBuilder(config);
hostBuilder.UseServer("Microsoft.AspNet.Server.Kestrel");
hostBuilder.UseServerFactory("Microsoft.AspNet.Server.Kestrel");
hostBuilder.UseStartup(app =>
{
app.Run(async context =>

View File

@ -24,7 +24,7 @@ namespace Microsoft.AspNet.Server.Kestrel.FunctionalTests
.Build();
var hostBuilder = new WebHostBuilder(config);
hostBuilder.UseServer("Microsoft.AspNet.Server.Kestrel");
hostBuilder.UseServerFactory("Microsoft.AspNet.Server.Kestrel");
hostBuilder.UseStartup(app =>
{
app.Run(async context =>

View File

@ -26,7 +26,7 @@ namespace Microsoft.AspNet.Server.Kestrel.FunctionalTests
.Build();
var hostBuilder = new WebHostBuilder(config);
hostBuilder.UseServer("Microsoft.AspNet.Server.Kestrel");
hostBuilder.UseServerFactory("Microsoft.AspNet.Server.Kestrel");
hostBuilder.UseStartup(app =>
{
var serverInfo = app.ServerFeatures.Get<IKestrelServerInformation>();

View File

@ -4,7 +4,6 @@
using System;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNet.Http.Features;
using Xunit;
namespace Microsoft.AspNet.Server.KestrelTests
@ -14,9 +13,9 @@ namespace Microsoft.AspNet.Server.KestrelTests
[Fact]
public async Task ResponsesAreChunkedAutomatically()
{
using (var server = new TestServer(async frame =>
using (var server = new TestServer(async httpContext =>
{
var response = frame.Get<IHttpResponseFeature>();
var response = httpContext.Response;
response.Headers.Clear();
await response.Body.WriteAsync(Encoding.ASCII.GetBytes("Hello "), 0, 6);
await response.Body.WriteAsync(Encoding.ASCII.GetBytes("World!"), 0, 6);
@ -46,9 +45,9 @@ namespace Microsoft.AspNet.Server.KestrelTests
[Fact]
public async Task ZeroLengthWritesAreIgnored()
{
using (var server = new TestServer(async frame =>
using (var server = new TestServer(async httpContext =>
{
var response = frame.Get<IHttpResponseFeature>();
var response = httpContext.Response;
response.Headers.Clear();
await response.Body.WriteAsync(Encoding.ASCII.GetBytes("Hello "), 0, 6);
await response.Body.WriteAsync(new byte[0], 0, 0);
@ -79,9 +78,9 @@ namespace Microsoft.AspNet.Server.KestrelTests
[Fact]
public async Task EmptyResponseBodyHandledCorrectlyWithZeroLengthWrite()
{
using (var server = new TestServer(async frame =>
using (var server = new TestServer(async httpContext =>
{
var response = frame.Get<IHttpResponseFeature>();
var response = httpContext.Response;
response.Headers.Clear();
await response.Body.WriteAsync(new byte[0], 0, 0);
}))
@ -106,9 +105,9 @@ namespace Microsoft.AspNet.Server.KestrelTests
[Fact]
public async Task ConnectionClosedIfExeptionThrownAfterWrite()
{
using (var server = new TestServer(async frame =>
using (var server = new TestServer(async httpContext =>
{
var response = frame.Get<IHttpResponseFeature>();
var response = httpContext.Response;
response.Headers.Clear();
await response.Body.WriteAsync(Encoding.ASCII.GetBytes("Hello World!"), 0, 12);
throw new Exception();
@ -136,9 +135,9 @@ namespace Microsoft.AspNet.Server.KestrelTests
[Fact]
public async Task ConnectionClosedIfExeptionThrownAfterZeroLengthWrite()
{
using (var server = new TestServer(async frame =>
using (var server = new TestServer(async httpContext =>
{
var response = frame.Get<IHttpResponseFeature>();
var response = httpContext.Response;
response.Headers.Clear();
await response.Body.WriteAsync(new byte[0], 0, 0);
throw new Exception();

View File

@ -4,7 +4,7 @@
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNet.Server.Kestrel.Filter;
using Microsoft.AspNet.Server.Kestrel.Http;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Http.Features;
using Xunit;
@ -12,10 +12,10 @@ namespace Microsoft.AspNet.Server.KestrelTests
{
public class ConnectionFilterTests
{
private async Task App(IFeatureCollection frame)
private async Task App(HttpContext httpContext)
{
var request = frame.Get<IHttpRequestFeature>();
var response = frame.Get<IHttpResponseFeature>();
var request = httpContext.Request;
var response = httpContext.Response;
response.Headers.Clear();
while (true)
{

View File

@ -7,7 +7,7 @@ using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNet.Http.Features;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Server.Kestrel;
using Microsoft.AspNet.Server.Kestrel.Filter;
using Microsoft.Extensions.Logging;
@ -39,10 +39,10 @@ namespace Microsoft.AspNet.Server.KestrelTests
}
}
private async Task App(IFeatureCollection frame)
private async Task App(HttpContext httpContext)
{
var request = frame.Get<IHttpRequestFeature>();
var response = frame.Get<IHttpResponseFeature>();
var request = httpContext.Request;
var response = httpContext.Response;
response.Headers.Clear();
while (true)
{
@ -56,10 +56,10 @@ namespace Microsoft.AspNet.Server.KestrelTests
}
}
private async Task AppChunked(IFeatureCollection frame)
private async Task AppChunked(HttpContext httpContext)
{
var request = frame.Get<IHttpRequestFeature>();
var response = frame.Get<IHttpResponseFeature>();
var request = httpContext.Request;
var response = httpContext.Response;
var data = new MemoryStream();
await request.Body.CopyToAsync(data);
var bytes = data.ToArray();
@ -69,9 +69,9 @@ namespace Microsoft.AspNet.Server.KestrelTests
await response.Body.WriteAsync(bytes, 0, bytes.Length);
}
private Task EmptyApp(IFeatureCollection frame)
private Task EmptyApp(HttpContext httpContext)
{
frame.Get<IHttpResponseFeature>().Headers.Clear();
httpContext.Response.Headers.Clear();
return Task.FromResult<object>(null);
}
@ -471,10 +471,10 @@ namespace Microsoft.AspNet.Server.KestrelTests
[MemberData(nameof(ConnectionFilterData))]
public async Task ZeroContentLengthNotSetAutomaticallyForCertainStatusCodes(ServiceContext testContext)
{
using (var server = new TestServer(async frame =>
using (var server = new TestServer(async httpContext =>
{
var request = frame.Get<IHttpRequestFeature>();
var response = frame.Get<IHttpResponseFeature>();
var request = httpContext.Request;
var response = httpContext.Response;
response.Headers.Clear();
using (var reader = new StreamReader(request.Body, Encoding.ASCII))
@ -529,9 +529,9 @@ namespace Microsoft.AspNet.Server.KestrelTests
var testLogger = new TestApplicationErrorLogger();
testContext.Log = new KestrelTrace(testLogger);
using (var server = new TestServer(frame =>
using (var server = new TestServer(httpContext =>
{
var response = frame.Get<IHttpResponseFeature>();
var response = httpContext.Response;
response.OnStarting(_ =>
{
onStartingCalled = true;
@ -586,9 +586,9 @@ namespace Microsoft.AspNet.Server.KestrelTests
var testLogger = new TestApplicationErrorLogger();
testContext.Log = new KestrelTrace(testLogger);
using (var server = new TestServer(async frame =>
using (var server = new TestServer(async httpContext =>
{
var response = frame.Get<IHttpResponseFeature>();
var response = httpContext.Response;
response.OnStarting(_ =>
{
onStartingCalled = true;
@ -628,9 +628,9 @@ namespace Microsoft.AspNet.Server.KestrelTests
var testLogger = new TestApplicationErrorLogger();
testContext.Log = new KestrelTrace(testLogger);
using (var server = new TestServer(async frame =>
using (var server = new TestServer(async httpContext =>
{
var response = frame.Get<IHttpResponseFeature>();
var response = httpContext.Response;
response.OnStarting(_ =>
{
onStartingCalled = true;
@ -741,11 +741,11 @@ namespace Microsoft.AspNet.Server.KestrelTests
var testLogger = new TestApplicationErrorLogger();
testContext.Log = new KestrelTrace(testLogger);
using (var server = new TestServer(async frame =>
using (var server = new TestServer(async httpContext =>
{
var onStartingException = new Exception();
var response = frame.Get<IHttpResponseFeature>();
var response = httpContext.Response;
response.OnStarting(_ =>
{
onStartingCallCount1++;
@ -812,9 +812,9 @@ namespace Microsoft.AspNet.Server.KestrelTests
var testLogger = new TestApplicationErrorLogger();
testContext.Log = new KestrelTrace(testLogger);
using (var server = new TestServer(async frame =>
using (var server = new TestServer(async httpContext =>
{
var response = frame.Get<IHttpResponseFeature>();
var response = httpContext.Response;
response.OnCompleted(_ =>
{
onCompletedCalled1 = true;
@ -856,10 +856,10 @@ namespace Microsoft.AspNet.Server.KestrelTests
[MemberData(nameof(ConnectionFilterData))]
public async Task RequestBodyIsConsumedAutomaticallyIfAppDoesntConsumeItFully(ServiceContext testContext)
{
using (var server = new TestServer(async frame =>
using (var server = new TestServer(async httpContext =>
{
var response = frame.Get<IHttpResponseFeature>();
var request = frame.Get<IHttpRequestFeature>();
var response = httpContext.Response;
var request = httpContext.Request;
Assert.Equal("POST", request.Method);

View File

@ -8,21 +8,20 @@ using System.Net.Http;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Threading.Tasks;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Server.Kestrel.Filter;
using Microsoft.AspNet.Server.Kestrel.Http;
using Microsoft.AspNet.Server.Kestrel.Https;
using Microsoft.AspNet.Testing.xunit;
using Xunit;
using Microsoft.AspNet.Http.Features;
namespace Microsoft.AspNet.Server.KestrelTests
{
public class HttpsConnectionFilterTests
{
private async Task App(IFeatureCollection frame)
private async Task App(HttpContext httpContext)
{
var request = frame.Get<IHttpRequestFeature>();
var response = frame.Get<IHttpResponseFeature>();
var request = httpContext.Request;
var response = httpContext.Response;
response.Headers.Clear();
while (true)
{

View File

@ -2,9 +2,8 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Threading.Tasks;
using Microsoft.AspNet.Http;
using Microsoft.AspNet.Server.Kestrel;
using Microsoft.AspNet.Http.Features;
namespace Microsoft.AspNet.Server.KestrelTests
{
@ -16,22 +15,22 @@ namespace Microsoft.AspNet.Server.KestrelTests
private KestrelEngine _engine;
private IDisposable _server;
public TestServer(Func<IFeatureCollection, Task> app)
public TestServer(RequestDelegate app)
: this(app, new TestServiceContext())
{
}
public TestServer(Func<IFeatureCollection, Task> app, ServiceContext context)
public TestServer(RequestDelegate app, ServiceContext context)
: this(app, context, "http://localhost:54321/")
{
}
public TestServer(Func<IFeatureCollection, Task> app, ServiceContext context, string serverAddress)
public TestServer(RequestDelegate app, ServiceContext context, string serverAddress)
{
Create(app, context, serverAddress);
}
public void Create(Func<IFeatureCollection, Task> app, ServiceContext context, string serverAddress)
public void Create(RequestDelegate app, ServiceContext context, string serverAddress)
{
_engine = new KestrelEngine(context);
_engine.Start(1);

View File

@ -1,4 +1,8 @@
using Microsoft.AspNet.Server.Kestrel;
// 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.AspNet.Http.Internal;
using Microsoft.AspNet.Server.Kestrel;
namespace Microsoft.AspNet.Server.KestrelTests
{
@ -8,6 +12,7 @@ namespace Microsoft.AspNet.Server.KestrelTests
{
AppLifetime = new LifetimeNotImplemented();
Log = new TestKestrelTrace();
HttpContextFactory = new HttpContextFactory(new HttpContextAccessor());
DateHeaderValueManager = new TestDateHeaderValueManager();
}
}