Reacting to Hosting changes
This commit is contained in:
parent
af2c32f612
commit
b466c3b7d7
|
|
@ -206,9 +206,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
ResponseBody = new FrameResponseStream(this);
|
ResponseBody = new FrameResponseStream(this);
|
||||||
DuplexStream = new FrameDuplexStream(RequestBody, ResponseBody);
|
DuplexStream = new FrameDuplexStream(RequestBody, ResponseBody);
|
||||||
|
|
||||||
|
var httpContext = HttpContextFactory.Create(this);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await Application.Invoke(this).ConfigureAwait(false);
|
await Application.Invoke(httpContext).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|
@ -227,6 +228,8 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
|
|
||||||
await FireOnCompleted();
|
await FireOnCompleted();
|
||||||
|
|
||||||
|
HttpContextFactory.Dispose(httpContext);
|
||||||
|
|
||||||
await ProduceEnd();
|
await ProduceEnd();
|
||||||
|
|
||||||
while (await RequestBody.ReadAsync(_nullBuffer, 0, _nullBuffer.Length) != 0)
|
while (await RequestBody.ReadAsync(_nullBuffer, 0, _nullBuffer.Length) != 0)
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNet.Http;
|
||||||
using Microsoft.AspNet.Server.Kestrel.Networking;
|
using Microsoft.AspNet.Server.Kestrel.Networking;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
|
@ -23,7 +24,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
public Task StartAsync(
|
public Task StartAsync(
|
||||||
ServerAddress address,
|
ServerAddress address,
|
||||||
KestrelThread thread,
|
KestrelThread thread,
|
||||||
Func<Frame, Task> application)
|
RequestDelegate application)
|
||||||
{
|
{
|
||||||
ServerAddress = address;
|
ServerAddress = address;
|
||||||
Thread = thread;
|
Thread = thread;
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// 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.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using Microsoft.AspNet.Http;
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.AspNet.Server.Kestrel.Infrastructure;
|
using Microsoft.AspNet.Server.Kestrel.Infrastructure;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Server.Kestrel.Http
|
namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
|
|
@ -34,7 +33,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
|
|
||||||
public KestrelThread Thread { get; set; }
|
public KestrelThread Thread { get; set; }
|
||||||
|
|
||||||
public Func<Frame, Task> Application { get; set; }
|
public RequestDelegate Application { get; set; }
|
||||||
|
|
||||||
public MemoryPool2 Memory2 { get; set; }
|
public MemoryPool2 Memory2 { get; set; }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNet.Http;
|
||||||
using Microsoft.AspNet.Server.Kestrel.Infrastructure;
|
using Microsoft.AspNet.Server.Kestrel.Infrastructure;
|
||||||
using Microsoft.AspNet.Server.Kestrel.Networking;
|
using Microsoft.AspNet.Server.Kestrel.Networking;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
@ -33,7 +34,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
string pipeName,
|
string pipeName,
|
||||||
ServerAddress address,
|
ServerAddress address,
|
||||||
KestrelThread thread,
|
KestrelThread thread,
|
||||||
Func<Frame, Task> application)
|
RequestDelegate application)
|
||||||
{
|
{
|
||||||
await StartAsync(address, thread, application).ConfigureAwait(false);
|
await StartAsync(address, thread, application).ConfigureAwait(false);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNet.Http;
|
||||||
using Microsoft.AspNet.Server.Kestrel.Infrastructure;
|
using Microsoft.AspNet.Server.Kestrel.Infrastructure;
|
||||||
using Microsoft.AspNet.Server.Kestrel.Networking;
|
using Microsoft.AspNet.Server.Kestrel.Networking;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
@ -26,7 +27,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
string pipeName,
|
string pipeName,
|
||||||
ServerAddress address,
|
ServerAddress address,
|
||||||
KestrelThread thread,
|
KestrelThread thread,
|
||||||
Func<Frame, Task> application)
|
RequestDelegate application)
|
||||||
{
|
{
|
||||||
ServerAddress = address;
|
ServerAddress = address;
|
||||||
Thread = thread;
|
Thread = thread;
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading.Tasks;
|
using Microsoft.AspNet.Http;
|
||||||
using Microsoft.AspNet.Http.Features;
|
|
||||||
using Microsoft.AspNet.Server.Kestrel.Http;
|
using Microsoft.AspNet.Server.Kestrel.Http;
|
||||||
using Microsoft.AspNet.Server.Kestrel.Networking;
|
using Microsoft.AspNet.Server.Kestrel.Networking;
|
||||||
|
|
||||||
|
|
@ -49,7 +48,7 @@ namespace Microsoft.AspNet.Server.Kestrel
|
||||||
Threads.Clear();
|
Threads.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public IDisposable CreateServer(ServerAddress address, Func<IFeatureCollection, Task> application)
|
public IDisposable CreateServer(ServerAddress address, RequestDelegate application)
|
||||||
{
|
{
|
||||||
var listeners = new List<IDisposable>();
|
var listeners = new List<IDisposable>();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,14 +1,11 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// 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.
|
// 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;
|
||||||
using Microsoft.AspNet.Hosting.Server;
|
using Microsoft.AspNet.Hosting.Server;
|
||||||
|
using Microsoft.AspNet.Http;
|
||||||
using Microsoft.AspNet.Http.Features;
|
using Microsoft.AspNet.Http.Features;
|
||||||
using Microsoft.AspNet.Server.Features;
|
using Microsoft.AspNet.Server.Features;
|
||||||
using Microsoft.AspNet.Server.Kestrel.Http;
|
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
|
@ -20,89 +17,24 @@ namespace Microsoft.AspNet.Server.Kestrel
|
||||||
public class ServerFactory : IServerFactory
|
public class ServerFactory : IServerFactory
|
||||||
{
|
{
|
||||||
private readonly IApplicationLifetime _appLifetime;
|
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;
|
_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();
|
var information = new KestrelServerInformation();
|
||||||
information.Initialize(configuration);
|
information.Initialize(configuration);
|
||||||
var serverFeatures = new FeatureCollection();
|
var serverFeatures = new FeatureCollection();
|
||||||
serverFeatures.Set<IKestrelServerInformation>(information);
|
serverFeatures.Set<IKestrelServerInformation>(information);
|
||||||
serverFeatures.Set<IServerAddressesFeature>(information);
|
serverFeatures.Set<IServerAddressesFeature>(information);
|
||||||
return serverFeatures;
|
return new KestrelServer(serverFeatures, _appLifetime, _loggerFactory.CreateLogger("Microsoft.AspNet.Server.Kestrel"), _httpContextFactory);
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// 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.Hosting;
|
||||||
|
using Microsoft.AspNet.Http;
|
||||||
using Microsoft.AspNet.Server.Kestrel.Filter;
|
using Microsoft.AspNet.Server.Kestrel.Filter;
|
||||||
using Microsoft.AspNet.Server.Kestrel.Http;
|
using Microsoft.AspNet.Server.Kestrel.Http;
|
||||||
using Microsoft.AspNet.Server.Kestrel.Infrastructure;
|
using Microsoft.AspNet.Server.Kestrel.Infrastructure;
|
||||||
|
|
@ -20,6 +21,7 @@ namespace Microsoft.AspNet.Server.Kestrel
|
||||||
AppLifetime = context.AppLifetime;
|
AppLifetime = context.AppLifetime;
|
||||||
Memory = context.Memory;
|
Memory = context.Memory;
|
||||||
Log = context.Log;
|
Log = context.Log;
|
||||||
|
HttpContextFactory = context.HttpContextFactory;
|
||||||
DateHeaderValueManager = context.DateHeaderValueManager;
|
DateHeaderValueManager = context.DateHeaderValueManager;
|
||||||
ConnectionFilter = context.ConnectionFilter;
|
ConnectionFilter = context.ConnectionFilter;
|
||||||
NoDelay = context.NoDelay;
|
NoDelay = context.NoDelay;
|
||||||
|
|
@ -31,6 +33,8 @@ namespace Microsoft.AspNet.Server.Kestrel
|
||||||
|
|
||||||
public IKestrelTrace Log { get; set; }
|
public IKestrelTrace Log { get; set; }
|
||||||
|
|
||||||
|
public IHttpContextFactory HttpContextFactory { get; set; }
|
||||||
|
|
||||||
public DateHeaderValueManager DateHeaderValueManager { get; set; }
|
public DateHeaderValueManager DateHeaderValueManager { get; set; }
|
||||||
|
|
||||||
public IConnectionFilter ConnectionFilter { get; set; }
|
public IConnectionFilter ConnectionFilter { get; set; }
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ namespace Microsoft.AspNet.Server.Kestrel.FunctionalTests
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
var hostBuilder = new WebHostBuilder(config);
|
var hostBuilder = new WebHostBuilder(config);
|
||||||
hostBuilder.UseServer("Microsoft.AspNet.Server.Kestrel");
|
hostBuilder.UseServerFactory("Microsoft.AspNet.Server.Kestrel");
|
||||||
hostBuilder.UseStartup(ConfigureEchoAddress);
|
hostBuilder.UseStartup(ConfigureEchoAddress);
|
||||||
|
|
||||||
using (var app = hostBuilder.Build().Start())
|
using (var app = hostBuilder.Build().Start())
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ namespace Microsoft.AspNet.Server.Kestrel.FunctionalTests
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
var hostBuilder = new WebHostBuilder(config);
|
var hostBuilder = new WebHostBuilder(config);
|
||||||
hostBuilder.UseServer("Microsoft.AspNet.Server.Kestrel");
|
hostBuilder.UseServerFactory("Microsoft.AspNet.Server.Kestrel");
|
||||||
hostBuilder.UseStartup(app =>
|
hostBuilder.UseStartup(app =>
|
||||||
{
|
{
|
||||||
app.Run(async context =>
|
app.Run(async context =>
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ namespace Microsoft.AspNet.Server.Kestrel.FunctionalTests
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
var hostBuilder = new WebHostBuilder(config);
|
var hostBuilder = new WebHostBuilder(config);
|
||||||
hostBuilder.UseServer("Microsoft.AspNet.Server.Kestrel");
|
hostBuilder.UseServerFactory("Microsoft.AspNet.Server.Kestrel");
|
||||||
hostBuilder.UseStartup(app =>
|
hostBuilder.UseStartup(app =>
|
||||||
{
|
{
|
||||||
app.Run(async context =>
|
app.Run(async context =>
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ namespace Microsoft.AspNet.Server.Kestrel.FunctionalTests
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
var hostBuilder = new WebHostBuilder(config);
|
var hostBuilder = new WebHostBuilder(config);
|
||||||
hostBuilder.UseServer("Microsoft.AspNet.Server.Kestrel");
|
hostBuilder.UseServerFactory("Microsoft.AspNet.Server.Kestrel");
|
||||||
hostBuilder.UseStartup(app =>
|
hostBuilder.UseStartup(app =>
|
||||||
{
|
{
|
||||||
var serverInfo = app.ServerFeatures.Get<IKestrelServerInformation>();
|
var serverInfo = app.ServerFeatures.Get<IKestrelServerInformation>();
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.Http.Features;
|
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Server.KestrelTests
|
namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
|
|
@ -14,9 +13,9 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task ResponsesAreChunkedAutomatically()
|
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();
|
response.Headers.Clear();
|
||||||
await response.Body.WriteAsync(Encoding.ASCII.GetBytes("Hello "), 0, 6);
|
await response.Body.WriteAsync(Encoding.ASCII.GetBytes("Hello "), 0, 6);
|
||||||
await response.Body.WriteAsync(Encoding.ASCII.GetBytes("World!"), 0, 6);
|
await response.Body.WriteAsync(Encoding.ASCII.GetBytes("World!"), 0, 6);
|
||||||
|
|
@ -46,9 +45,9 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task ZeroLengthWritesAreIgnored()
|
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();
|
response.Headers.Clear();
|
||||||
await response.Body.WriteAsync(Encoding.ASCII.GetBytes("Hello "), 0, 6);
|
await response.Body.WriteAsync(Encoding.ASCII.GetBytes("Hello "), 0, 6);
|
||||||
await response.Body.WriteAsync(new byte[0], 0, 0);
|
await response.Body.WriteAsync(new byte[0], 0, 0);
|
||||||
|
|
@ -79,9 +78,9 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task EmptyResponseBodyHandledCorrectlyWithZeroLengthWrite()
|
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();
|
response.Headers.Clear();
|
||||||
await response.Body.WriteAsync(new byte[0], 0, 0);
|
await response.Body.WriteAsync(new byte[0], 0, 0);
|
||||||
}))
|
}))
|
||||||
|
|
@ -106,9 +105,9 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task ConnectionClosedIfExeptionThrownAfterWrite()
|
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();
|
response.Headers.Clear();
|
||||||
await response.Body.WriteAsync(Encoding.ASCII.GetBytes("Hello World!"), 0, 12);
|
await response.Body.WriteAsync(Encoding.ASCII.GetBytes("Hello World!"), 0, 12);
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
|
|
@ -136,9 +135,9 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task ConnectionClosedIfExeptionThrownAfterZeroLengthWrite()
|
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();
|
response.Headers.Clear();
|
||||||
await response.Body.WriteAsync(new byte[0], 0, 0);
|
await response.Body.WriteAsync(new byte[0], 0, 0);
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.Server.Kestrel.Filter;
|
using Microsoft.AspNet.Server.Kestrel.Filter;
|
||||||
using Microsoft.AspNet.Server.Kestrel.Http;
|
using Microsoft.AspNet.Http;
|
||||||
using Microsoft.AspNet.Http.Features;
|
using Microsoft.AspNet.Http.Features;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
|
|
@ -12,10 +12,10 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
{
|
{
|
||||||
public class ConnectionFilterTests
|
public class ConnectionFilterTests
|
||||||
{
|
{
|
||||||
private async Task App(IFeatureCollection frame)
|
private async Task App(HttpContext httpContext)
|
||||||
{
|
{
|
||||||
var request = frame.Get<IHttpRequestFeature>();
|
var request = httpContext.Request;
|
||||||
var response = frame.Get<IHttpResponseFeature>();
|
var response = httpContext.Response;
|
||||||
response.Headers.Clear();
|
response.Headers.Clear();
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ using System.Net;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.Http.Features;
|
using Microsoft.AspNet.Http;
|
||||||
using Microsoft.AspNet.Server.Kestrel;
|
using Microsoft.AspNet.Server.Kestrel;
|
||||||
using Microsoft.AspNet.Server.Kestrel.Filter;
|
using Microsoft.AspNet.Server.Kestrel.Filter;
|
||||||
using Microsoft.Extensions.Logging;
|
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 request = httpContext.Request;
|
||||||
var response = frame.Get<IHttpResponseFeature>();
|
var response = httpContext.Response;
|
||||||
response.Headers.Clear();
|
response.Headers.Clear();
|
||||||
while (true)
|
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 request = httpContext.Request;
|
||||||
var response = frame.Get<IHttpResponseFeature>();
|
var response = httpContext.Response;
|
||||||
var data = new MemoryStream();
|
var data = new MemoryStream();
|
||||||
await request.Body.CopyToAsync(data);
|
await request.Body.CopyToAsync(data);
|
||||||
var bytes = data.ToArray();
|
var bytes = data.ToArray();
|
||||||
|
|
@ -69,9 +69,9 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
await response.Body.WriteAsync(bytes, 0, bytes.Length);
|
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);
|
return Task.FromResult<object>(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -471,10 +471,10 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
[MemberData(nameof(ConnectionFilterData))]
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
public async Task ZeroContentLengthNotSetAutomaticallyForCertainStatusCodes(ServiceContext testContext)
|
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 request = httpContext.Request;
|
||||||
var response = frame.Get<IHttpResponseFeature>();
|
var response = httpContext.Response;
|
||||||
response.Headers.Clear();
|
response.Headers.Clear();
|
||||||
|
|
||||||
using (var reader = new StreamReader(request.Body, Encoding.ASCII))
|
using (var reader = new StreamReader(request.Body, Encoding.ASCII))
|
||||||
|
|
@ -529,9 +529,9 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
var testLogger = new TestApplicationErrorLogger();
|
var testLogger = new TestApplicationErrorLogger();
|
||||||
testContext.Log = new KestrelTrace(testLogger);
|
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(_ =>
|
response.OnStarting(_ =>
|
||||||
{
|
{
|
||||||
onStartingCalled = true;
|
onStartingCalled = true;
|
||||||
|
|
@ -586,9 +586,9 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
var testLogger = new TestApplicationErrorLogger();
|
var testLogger = new TestApplicationErrorLogger();
|
||||||
testContext.Log = new KestrelTrace(testLogger);
|
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(_ =>
|
response.OnStarting(_ =>
|
||||||
{
|
{
|
||||||
onStartingCalled = true;
|
onStartingCalled = true;
|
||||||
|
|
@ -628,9 +628,9 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
var testLogger = new TestApplicationErrorLogger();
|
var testLogger = new TestApplicationErrorLogger();
|
||||||
testContext.Log = new KestrelTrace(testLogger);
|
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(_ =>
|
response.OnStarting(_ =>
|
||||||
{
|
{
|
||||||
onStartingCalled = true;
|
onStartingCalled = true;
|
||||||
|
|
@ -741,11 +741,11 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
var testLogger = new TestApplicationErrorLogger();
|
var testLogger = new TestApplicationErrorLogger();
|
||||||
testContext.Log = new KestrelTrace(testLogger);
|
testContext.Log = new KestrelTrace(testLogger);
|
||||||
|
|
||||||
using (var server = new TestServer(async frame =>
|
using (var server = new TestServer(async httpContext =>
|
||||||
{
|
{
|
||||||
var onStartingException = new Exception();
|
var onStartingException = new Exception();
|
||||||
|
|
||||||
var response = frame.Get<IHttpResponseFeature>();
|
var response = httpContext.Response;
|
||||||
response.OnStarting(_ =>
|
response.OnStarting(_ =>
|
||||||
{
|
{
|
||||||
onStartingCallCount1++;
|
onStartingCallCount1++;
|
||||||
|
|
@ -812,9 +812,9 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
var testLogger = new TestApplicationErrorLogger();
|
var testLogger = new TestApplicationErrorLogger();
|
||||||
testContext.Log = new KestrelTrace(testLogger);
|
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(_ =>
|
response.OnCompleted(_ =>
|
||||||
{
|
{
|
||||||
onCompletedCalled1 = true;
|
onCompletedCalled1 = true;
|
||||||
|
|
@ -856,10 +856,10 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
[MemberData(nameof(ConnectionFilterData))]
|
[MemberData(nameof(ConnectionFilterData))]
|
||||||
public async Task RequestBodyIsConsumedAutomaticallyIfAppDoesntConsumeItFully(ServiceContext testContext)
|
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 response = httpContext.Response;
|
||||||
var request = frame.Get<IHttpRequestFeature>();
|
var request = httpContext.Request;
|
||||||
|
|
||||||
Assert.Equal("POST", request.Method);
|
Assert.Equal("POST", request.Method);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,21 +8,20 @@ using System.Net.Http;
|
||||||
using System.Net.Security;
|
using System.Net.Security;
|
||||||
using System.Security.Cryptography.X509Certificates;
|
using System.Security.Cryptography.X509Certificates;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNet.Http;
|
||||||
using Microsoft.AspNet.Server.Kestrel.Filter;
|
using Microsoft.AspNet.Server.Kestrel.Filter;
|
||||||
using Microsoft.AspNet.Server.Kestrel.Http;
|
|
||||||
using Microsoft.AspNet.Server.Kestrel.Https;
|
using Microsoft.AspNet.Server.Kestrel.Https;
|
||||||
using Microsoft.AspNet.Testing.xunit;
|
using Microsoft.AspNet.Testing.xunit;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
using Microsoft.AspNet.Http.Features;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Server.KestrelTests
|
namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
{
|
{
|
||||||
public class HttpsConnectionFilterTests
|
public class HttpsConnectionFilterTests
|
||||||
{
|
{
|
||||||
private async Task App(IFeatureCollection frame)
|
private async Task App(HttpContext httpContext)
|
||||||
{
|
{
|
||||||
var request = frame.Get<IHttpRequestFeature>();
|
var request = httpContext.Request;
|
||||||
var response = frame.Get<IHttpResponseFeature>();
|
var response = httpContext.Response;
|
||||||
response.Headers.Clear();
|
response.Headers.Clear();
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,8 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Threading.Tasks;
|
using Microsoft.AspNet.Http;
|
||||||
using Microsoft.AspNet.Server.Kestrel;
|
using Microsoft.AspNet.Server.Kestrel;
|
||||||
using Microsoft.AspNet.Http.Features;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Server.KestrelTests
|
namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
{
|
{
|
||||||
|
|
@ -16,22 +15,22 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
private KestrelEngine _engine;
|
private KestrelEngine _engine;
|
||||||
private IDisposable _server;
|
private IDisposable _server;
|
||||||
|
|
||||||
public TestServer(Func<IFeatureCollection, Task> app)
|
public TestServer(RequestDelegate app)
|
||||||
: this(app, new TestServiceContext())
|
: this(app, new TestServiceContext())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public TestServer(Func<IFeatureCollection, Task> app, ServiceContext context)
|
public TestServer(RequestDelegate app, ServiceContext context)
|
||||||
: this(app, context, "http://localhost:54321/")
|
: 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);
|
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 = new KestrelEngine(context);
|
||||||
_engine.Start(1);
|
_engine.Start(1);
|
||||||
|
|
|
||||||
|
|
@ -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
|
namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
{
|
{
|
||||||
|
|
@ -8,6 +12,7 @@ namespace Microsoft.AspNet.Server.KestrelTests
|
||||||
{
|
{
|
||||||
AppLifetime = new LifetimeNotImplemented();
|
AppLifetime = new LifetimeNotImplemented();
|
||||||
Log = new TestKestrelTrace();
|
Log = new TestKestrelTrace();
|
||||||
|
HttpContextFactory = new HttpContextFactory(new HttpContextAccessor());
|
||||||
DateHeaderValueManager = new TestDateHeaderValueManager();
|
DateHeaderValueManager = new TestDateHeaderValueManager();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue