#283 Update naming, merge options

This commit is contained in:
Chris R 2016-12-15 14:38:59 -08:00
parent 4c388e89ce
commit d7ce8d8103
32 changed files with 152 additions and 212 deletions

View File

@ -15,19 +15,19 @@ namespace HotAddSample
{ {
public void ConfigureServices(IServiceCollection services) public void ConfigureServices(IServiceCollection services)
{ {
services.Configure<WebListenerOptions>(options => services.Configure<HttpSysOptions>(options =>
{ {
ListenerSettings = options.ListenerSettings; ServerOptions = options;
}); });
} }
public WebListenerSettings ListenerSettings { get; set; } public HttpSysOptions ServerOptions { get; set; }
public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory) public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory)
{ {
loggerfactory.AddConsole(LogLevel.Information); loggerfactory.AddConsole(LogLevel.Information);
var addresses = ListenerSettings.UrlPrefixes; var addresses = ServerOptions.UrlPrefixes;
addresses.Add("http://localhost:12346/pathBase/"); addresses.Add("http://localhost:12346/pathBase/");
app.Use(async (context, next) => app.Use(async (context, next) =>
@ -102,7 +102,7 @@ namespace HotAddSample
{ {
var host = new WebHostBuilder() var host = new WebHostBuilder()
.UseStartup<Startup>() .UseStartup<Startup>()
.UseWebListener() .UseHttpSys()
.Build(); .Build();
host.Run(); host.Run();

View File

@ -16,10 +16,10 @@ namespace SelfHostServer
public void ConfigureServices(IServiceCollection services) public void ConfigureServices(IServiceCollection services)
{ {
// Server options can be configured here instead of in Main. // Server options can be configured here instead of in Main.
services.Configure<WebListenerOptions>(options => services.Configure<HttpSysOptions>(options =>
{ {
options.ListenerSettings.Authentication.Schemes = AuthenticationSchemes.None; options.Authentication.Schemes = AuthenticationSchemes.None;
options.ListenerSettings.Authentication.AllowAnonymous = true; options.Authentication.AllowAnonymous = true;
}); });
} }
@ -49,10 +49,10 @@ namespace SelfHostServer
{ {
var host = new WebHostBuilder() var host = new WebHostBuilder()
.UseStartup<Startup>() .UseStartup<Startup>()
.UseWebListener(options => .UseHttpSys(options =>
{ {
options.ListenerSettings.Authentication.Schemes = AuthenticationSchemes.None; options.Authentication.Schemes = AuthenticationSchemes.None;
options.ListenerSettings.Authentication.AllowAnonymous = true; options.Authentication.AllowAnonymous = true;
}) })
.Build(); .Build();

View File

@ -14,10 +14,10 @@ namespace Microsoft.AspNetCore.Server.HttpSys
internal static readonly IOCompletionCallback IOCallback = new IOCompletionCallback(IOWaitCallback); internal static readonly IOCompletionCallback IOCallback = new IOCompletionCallback(IOWaitCallback);
private TaskCompletionSource<RequestContext> _tcs; private TaskCompletionSource<RequestContext> _tcs;
private WebListener _server; private HttpSysListener _server;
private NativeRequestContext _nativeRequestContext; private NativeRequestContext _nativeRequestContext;
internal AsyncAcceptContext(WebListener server) internal AsyncAcceptContext(HttpSysListener server)
{ {
_server = server; _server = server;
_tcs = new TaskCompletionSource<RequestContext>(); _tcs = new TaskCompletionSource<RequestContext>();
@ -40,7 +40,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
} }
} }
internal WebListener Server internal HttpSysListener Server
{ {
get get
{ {
@ -58,12 +58,12 @@ namespace Microsoft.AspNetCore.Server.HttpSys
if (errorCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS && if (errorCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS &&
errorCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_MORE_DATA) errorCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_MORE_DATA)
{ {
asyncResult.Tcs.TrySetException(new WebListenerException((int)errorCode)); asyncResult.Tcs.TrySetException(new HttpSysException((int)errorCode));
complete = true; complete = true;
} }
else else
{ {
WebListener server = asyncResult.Server; HttpSysListener server = asyncResult.Server;
if (errorCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS) if (errorCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS)
{ {
// at this point we have received an unmanaged HTTP_REQUEST and memoryBlob // at this point we have received an unmanaged HTTP_REQUEST and memoryBlob
@ -106,7 +106,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
{ {
// someother bad error, possible(?) return values are: // someother bad error, possible(?) return values are:
// ERROR_INVALID_HANDLE, ERROR_INSUFFICIENT_BUFFER, ERROR_OPERATION_ABORTED // ERROR_INVALID_HANDLE, ERROR_INSUFFICIENT_BUFFER, ERROR_OPERATION_ABORTED
asyncResult.Tcs.TrySetException(new WebListenerException((int)statusCode)); asyncResult.Tcs.TrySetException(new HttpSysException((int)statusCode));
complete = true; complete = true;
} }
} }
@ -169,7 +169,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
retry = true; retry = true;
} }
else if (statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS else if (statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS
&& WebListener.SkipIOCPCallbackOnSuccess) && HttpSysListener.SkipIOCPCallbackOnSuccess)
{ {
// IO operation completed synchronously - callback won't be called to signal completion. // IO operation completed synchronously - callback won't be called to signal completion.
IOCompleted(this, statusCode, bytesTransferred); IOCompleted(this, statusCode, bytesTransferred);

View File

@ -9,19 +9,19 @@ using System.Runtime.InteropServices;
namespace Microsoft.AspNetCore.Server.HttpSys namespace Microsoft.AspNetCore.Server.HttpSys
{ {
[SuppressMessage("Microsoft.Usage", "CA2237:MarkISerializableTypesWithSerializable")] [SuppressMessage("Microsoft.Usage", "CA2237:MarkISerializableTypesWithSerializable")]
public class WebListenerException : Win32Exception public class HttpSysException : Win32Exception
{ {
internal WebListenerException() internal HttpSysException()
: base(Marshal.GetLastWin32Error()) : base(Marshal.GetLastWin32Error())
{ {
} }
internal WebListenerException(int errorCode) internal HttpSysException(int errorCode)
: base(errorCode) : base(errorCode)
{ {
} }
internal WebListenerException(int errorCode, string message) internal HttpSysException(int errorCode, string message)
: base(errorCode, message) : base(errorCode, message)
{ {
} }

View File

@ -14,7 +14,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
/// <summary> /// <summary>
/// An HTTP server wrapping the Http.Sys APIs that accepts requests. /// An HTTP server wrapping the Http.Sys APIs that accepts requests.
/// </summary> /// </summary>
public sealed class WebListener : IDisposable public sealed class HttpSysListener : IDisposable
{ {
// Win8# 559317 fixed a bug in Http.sys's HttpReceiveClientCertificate method. // Win8# 559317 fixed a bug in Http.sys's HttpReceiveClientCertificate method.
// Without this fix IOCP callbacks were not being called although ERROR_IO_PENDING was // Without this fix IOCP callbacks were not being called although ERROR_IO_PENDING was
@ -40,16 +40,15 @@ namespace Microsoft.AspNetCore.Server.HttpSys
private object _internalLock; private object _internalLock;
public WebListener() public HttpSysListener(HttpSysOptions options, ILoggerFactory loggerFactory)
: this(new WebListenerSettings())
{ {
} if (options == null)
public WebListener(WebListenerSettings settings)
{
if (settings == null)
{ {
throw new ArgumentNullException(nameof(settings)); throw new ArgumentNullException(nameof(options));
}
if (loggerFactory == null)
{
throw new ArgumentNullException(nameof(loggerFactory));
} }
if (!HttpApi.Supported) if (!HttpApi.Supported)
@ -59,7 +58,9 @@ namespace Microsoft.AspNetCore.Server.HttpSys
Debug.Assert(HttpApi.ApiVersion == HttpApi.HTTP_API_VERSION.Version20, "Invalid Http api version"); Debug.Assert(HttpApi.ApiVersion == HttpApi.HTTP_API_VERSION.Version20, "Invalid Http api version");
Settings = settings; Options = options;
Logger = LogHelper.CreateLogger(loggerFactory, typeof(HttpSysListener));
_state = State.Stopped; _state = State.Stopped;
_internalLock = new object(); _internalLock = new object();
@ -99,10 +100,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
Disposed, Disposed,
} }
internal ILogger Logger internal ILogger Logger { get; private set; }
{
get { return Settings.Logger; }
}
internal UrlGroup UrlGroup internal UrlGroup UrlGroup
{ {
@ -119,7 +117,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
get { return _disconnectListener; } get { return _disconnectListener; }
} }
public WebListenerSettings Settings { get; } public HttpSysOptions Options { get; }
public bool IsListening public bool IsListening
{ {
@ -148,18 +146,18 @@ namespace Microsoft.AspNetCore.Server.HttpSys
return; return;
} }
Settings.Authentication.SetUrlGroupSecurity(UrlGroup); Options.Authentication.SetUrlGroupSecurity(UrlGroup);
Settings.Timeouts.SetUrlGroupTimeouts(UrlGroup); Options.Timeouts.SetUrlGroupTimeouts(UrlGroup);
Settings.SetRequestQueueLimit(RequestQueue); Options.SetRequestQueueLimit(RequestQueue);
_requestQueue.AttachToUrlGroup(); _requestQueue.AttachToUrlGroup();
// All resources are set up correctly. Now add all prefixes. // All resources are set up correctly. Now add all prefixes.
try try
{ {
Settings.UrlPrefixes.RegisterAllPrefixes(UrlGroup); Options.UrlPrefixes.RegisterAllPrefixes(UrlGroup);
} }
catch (WebListenerException) catch (HttpSysException)
{ {
// If an error occurred while adding prefixes, free all resources allocated by previous steps. // If an error occurred while adding prefixes, free all resources allocated by previous steps.
_requestQueue.DetachFromUrlGroup(); _requestQueue.DetachFromUrlGroup();
@ -191,7 +189,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
return; return;
} }
Settings.UrlPrefixes.UnregisterAllPrefixes(); Options.UrlPrefixes.UnregisterAllPrefixes();
_state = State.Stopped; _state = State.Stopped;
@ -285,7 +283,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
// some other bad error, possible(?) return values are: // some other bad error, possible(?) return values are:
// ERROR_INVALID_HANDLE, ERROR_INSUFFICIENT_BUFFER, ERROR_OPERATION_ABORTED // ERROR_INVALID_HANDLE, ERROR_INSUFFICIENT_BUFFER, ERROR_OPERATION_ABORTED
asyncResult.Dispose(); asyncResult.Dispose();
throw new WebListenerException((int)statusCode); throw new HttpSysException((int)statusCode);
} }
} }
catch (Exception exception) catch (Exception exception)
@ -310,10 +308,10 @@ namespace Microsoft.AspNetCore.Server.HttpSys
internal unsafe bool ValidateAuth(NativeRequestContext requestMemory) internal unsafe bool ValidateAuth(NativeRequestContext requestMemory)
{ {
if (!Settings.Authentication.AllowAnonymous && !requestMemory.CheckAuthenticated()) if (!Options.Authentication.AllowAnonymous && !requestMemory.CheckAuthenticated())
{ {
SendError(requestMemory.RequestId, StatusCodes.Status401Unauthorized, SendError(requestMemory.RequestId, StatusCodes.Status401Unauthorized,
AuthenticationManager.GenerateChallenges(Settings.Authentication.Schemes)); AuthenticationManager.GenerateChallenges(Options.Authentication.Schemes));
return false; return false;
} }
return true; return true;

View File

@ -7,35 +7,31 @@ using Microsoft.Extensions.Logging.Abstractions;
namespace Microsoft.AspNetCore.Server.HttpSys namespace Microsoft.AspNetCore.Server.HttpSys
{ {
public class WebListenerSettings public class HttpSysOptions
{ {
private const long DefaultRequestQueueLength = 1000; // Http.sys default. private const long DefaultRequestQueueLength = 1000; // Http.sys default.
internal static readonly int DefaultMaxAccepts = 5 * Environment.ProcessorCount;
// The native request queue // The native request queue
private long _requestQueueLength = DefaultRequestQueueLength; private long _requestQueueLength = DefaultRequestQueueLength;
private RequestQueue _requestQueue; private RequestQueue _requestQueue;
private ILogger _logger = NullLogger.Instance; private ILogger _logger = NullLogger.Instance;
public WebListenerSettings() public HttpSysOptions()
{ {
} }
/// <summary> /// <summary>
/// The logger that will be used to create the WebListener instance. This should not be changed /// The maximum number of concurrent accepts.
/// after creating the listener.
/// </summary> /// </summary>
public ILogger Logger public int MaxAccepts { get; set; } = DefaultMaxAccepts;
{
get { return _logger; } /// <summary>
set /// Attempts kernel mode caching for responses with eligible headers. The response may not include
{ /// Set-Cookie, Vary, or Pragma headers. It must include a Cache-Control header with Public and
if (value == null) /// either a Shared-Max-Age or Max-Age value, or an Expires header.
{ /// </summary>
throw new ArgumentNullException(nameof(value)); public bool EnableResponseCaching { get; set; } = true;
}
_logger = value;
}
}
/// <summary> /// <summary>
/// The url prefixes to register with Http.Sys. These may be modified at any time prior to disposing /// The url prefixes to register with Http.Sys. These may be modified at any time prior to disposing

View File

@ -1,23 +0,0 @@
// 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.Extensions.Logging;
using Microsoft.Extensions.Options;
namespace Microsoft.AspNetCore.Server.HttpSys.Internal
{
public class WebListenerOptionsSetup : IConfigureOptions<WebListenerOptions>
{
private ILoggerFactory _loggerFactory;
public WebListenerOptionsSetup(ILoggerFactory loggerFactory)
{
_loggerFactory = loggerFactory;
}
public void Configure(WebListenerOptions options)
{
options.ListenerSettings.Logger = _loggerFactory.CreateLogger<WebListener>();
}
}
}

View File

@ -16,7 +16,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
{ {
internal class MessagePump : IServer internal class MessagePump : IServer
{ {
private readonly WebListener _listener; private readonly HttpSysListener _listener;
private readonly ILogger _logger; private readonly ILogger _logger;
private IHttpApplication<object> _application; private IHttpApplication<object> _application;
@ -31,7 +31,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
private readonly ServerAddressesFeature _serverAddresses; private readonly ServerAddressesFeature _serverAddresses;
public MessagePump(IOptions<WebListenerOptions> options, ILoggerFactory loggerFactory) public MessagePump(IOptions<HttpSysOptions> options, ILoggerFactory loggerFactory)
{ {
if (options == null) if (options == null)
{ {
@ -43,7 +43,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
} }
var optionsInstance = options.Value; var optionsInstance = options.Value;
_listener = new WebListener(optionsInstance.ListenerSettings); _listener = new HttpSysListener(optionsInstance, loggerFactory);
_logger = LogHelper.CreateLogger(loggerFactory, typeof(MessagePump)); _logger = LogHelper.CreateLogger(loggerFactory, typeof(MessagePump));
Features = new FeatureCollection(); Features = new FeatureCollection();
_serverAddresses = new ServerAddressesFeature(); _serverAddresses = new ServerAddressesFeature();
@ -55,7 +55,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
_shutdownSignal = new ManualResetEvent(false); _shutdownSignal = new ManualResetEvent(false);
} }
internal WebListener Listener internal HttpSysListener Listener
{ {
get { return _listener; } get { return _listener; }
} }
@ -80,7 +80,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
_application = new ApplicationWrapper<TContext>(application); _application = new ApplicationWrapper<TContext>(application);
if (_listener.Settings.UrlPrefixes.Count == 0) if (_listener.Options.UrlPrefixes.Count == 0)
{ {
throw new InvalidOperationException("No address prefixes were defined."); throw new InvalidOperationException("No address prefixes were defined.");
} }
@ -206,11 +206,11 @@ namespace Microsoft.AspNetCore.Server.HttpSys
context.Dispose(); context.Dispose();
} }
private void ParseAddresses(ICollection<string> addresses, WebListener listener) private void ParseAddresses(ICollection<string> addresses, HttpSysListener listener)
{ {
foreach (var value in addresses) foreach (var value in addresses)
{ {
listener.Settings.UrlPrefixes.Add(UrlPrefix.Create(value)); listener.Options.UrlPrefixes.Add(UrlPrefix.Create(value));
} }
} }

View File

@ -111,7 +111,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
cts.Cancel(); cts.Cancel();
} }
if (statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS && WebListener.SkipIOCPCallbackOnSuccess) if (statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS && HttpSysListener.SkipIOCPCallbackOnSuccess)
{ {
// IO operation completed synchronously - callback won't be called to signal completion // IO operation completed synchronously - callback won't be called to signal completion
nativeOverlapped.Dispose(); nativeOverlapped.Dispose();

View File

@ -28,17 +28,17 @@ namespace Microsoft.AspNetCore.Server.HttpSys
if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS) if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS)
{ {
throw new WebListenerException((int)statusCode); throw new HttpSysException((int)statusCode);
} }
// Disabling callbacks when IO operation completes synchronously (returns ErrorCodes.ERROR_SUCCESS) // Disabling callbacks when IO operation completes synchronously (returns ErrorCodes.ERROR_SUCCESS)
if (WebListener.SkipIOCPCallbackOnSuccess && if (HttpSysListener.SkipIOCPCallbackOnSuccess &&
!UnsafeNclNativeMethods.SetFileCompletionNotificationModes( !UnsafeNclNativeMethods.SetFileCompletionNotificationModes(
requestQueueHandle, requestQueueHandle,
UnsafeNclNativeMethods.FileCompletionNotificationModes.SkipCompletionPortOnSuccess | UnsafeNclNativeMethods.FileCompletionNotificationModes.SkipCompletionPortOnSuccess |
UnsafeNclNativeMethods.FileCompletionNotificationModes.SkipSetEventOnHandle)) UnsafeNclNativeMethods.FileCompletionNotificationModes.SkipSetEventOnHandle))
{ {
throw new WebListenerException(Marshal.GetLastWin32Error()); throw new HttpSysException(Marshal.GetLastWin32Error());
} }
Handle = requestQueueHandle; Handle = requestQueueHandle;
@ -94,7 +94,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
if (result != 0) if (result != 0)
{ {
throw new WebListenerException((int)result); throw new HttpSysException((int)result);
} }
} }

View File

@ -16,7 +16,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS) if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS)
{ {
throw new WebListenerException((int)statusCode); throw new HttpSysException((int)statusCode);
} }
Debug.Assert(serverSessionId != 0, "Invalid id returned by HttpCreateServerSession"); Debug.Assert(serverSessionId != 0, "Invalid id returned by HttpCreateServerSession");

View File

@ -24,7 +24,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS) if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS)
{ {
throw new WebListenerException((int)statusCode); throw new HttpSysException((int)statusCode);
} }
Debug.Assert(urlGroupId != 0, "Invalid id returned by HttpCreateUrlGroup"); Debug.Assert(urlGroupId != 0, "Invalid id returned by HttpCreateUrlGroup");
@ -42,7 +42,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS) if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS)
{ {
var exception = new WebListenerException((int)statusCode); var exception = new HttpSysException((int)statusCode);
LogHelper.LogException(_logger, "SetUrlGroupProperty", exception); LogHelper.LogException(_logger, "SetUrlGroupProperty", exception);
if (throwOnError) if (throwOnError)
{ {
@ -62,11 +62,11 @@ namespace Microsoft.AspNetCore.Server.HttpSys
{ {
if (statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_ALREADY_EXISTS) if (statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_ALREADY_EXISTS)
{ {
throw new WebListenerException((int)statusCode, string.Format(Resources.Exception_PrefixAlreadyRegistered, uriPrefix)); throw new HttpSysException((int)statusCode, string.Format(Resources.Exception_PrefixAlreadyRegistered, uriPrefix));
} }
else else
{ {
throw new WebListenerException((int)statusCode); throw new HttpSysException((int)statusCode);
} }
} }
} }

View File

@ -187,7 +187,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
Complete(0, null); Complete(0, null);
} }
else if (statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS && else if (statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS &&
WebListener.SkipIOCPCallbackOnSuccess) HttpSysListener.SkipIOCPCallbackOnSuccess)
{ {
IOCompleted(statusCode, bytesReceived); IOCompleted(statusCode, bytesReceived);
} }
@ -197,7 +197,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
// Some other bad error, possible(?) return values are: // Some other bad error, possible(?) return values are:
// ERROR_INVALID_HANDLE, ERROR_INSUFFICIENT_BUFFER, ERROR_OPERATION_ABORTED // ERROR_INVALID_HANDLE, ERROR_INSUFFICIENT_BUFFER, ERROR_OPERATION_ABORTED
// Also ERROR_BAD_DATA if we got it twice or it reported smaller size buffer required. // Also ERROR_BAD_DATA if we got it twice or it reported smaller size buffer required.
Fail(new WebListenerException((int)statusCode)); Fail(new HttpSysException((int)statusCode));
} }
} }
while (retry); while (retry);
@ -254,7 +254,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
asyncResult._overlapped); asyncResult._overlapped);
if (errorCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_IO_PENDING || if (errorCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_IO_PENDING ||
(errorCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS && !WebListener.SkipIOCPCallbackOnSuccess)) (errorCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS && !HttpSysListener.SkipIOCPCallbackOnSuccess))
{ {
return; return;
} }
@ -267,7 +267,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
} }
else if (errorCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS) else if (errorCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS)
{ {
asyncResult.Fail(new WebListenerException((int)errorCode)); asyncResult.Fail(new HttpSysException((int)errorCode));
} }
else else
{ {
@ -405,7 +405,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
else else
{ {
// It's up to the consumer to fail if the missing ChannelBinding matters to them. // It's up to the consumer to fail if the missing ChannelBinding matters to them.
LogHelper.LogException(logger, "GetChannelBindingFromTls", new WebListenerException((int)statusCode)); LogHelper.LogException(logger, "GetChannelBindingFromTls", new HttpSysException((int)statusCode));
break; break;
} }
} }

View File

@ -49,7 +49,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
var cookedUrl = nativeRequestContext.GetCookedUrl(); var cookedUrl = nativeRequestContext.GetCookedUrl();
QueryString = cookedUrl.GetQueryString() ?? string.Empty; QueryString = cookedUrl.GetQueryString() ?? string.Empty;
var prefix = requestContext.Server.Settings.UrlPrefixes.GetPrefix((int)nativeRequestContext.UrlContext); var prefix = requestContext.Server.Options.UrlPrefixes.GetPrefix((int)nativeRequestContext.UrlContext);
var rawUrlInBytes = _nativeRequestContext.GetRawUrlInBytes(); var rawUrlInBytes = _nativeRequestContext.GetRawUrlInBytes();
var originalPath = RequestUriBuilder.DecodeAndUnescapePath(rawUrlInBytes); var originalPath = RequestUriBuilder.DecodeAndUnescapePath(rawUrlInBytes);

View File

@ -22,7 +22,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
private CancellationToken? _disconnectToken; private CancellationToken? _disconnectToken;
private bool _disposed; private bool _disposed;
internal RequestContext(WebListener server, NativeRequestContext memoryBlob) internal RequestContext(HttpSysListener server, NativeRequestContext memoryBlob)
{ {
// TODO: Verbose log // TODO: Verbose log
Server = server; Server = server;
@ -31,7 +31,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
Response = new Response(this); Response = new Response(this);
} }
internal WebListener Server { get; } internal HttpSysListener Server { get; }
internal ILogger Logger => Server.Logger; internal ILogger Logger => Server.Logger;

View File

@ -170,7 +170,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
} }
if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS && statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_HANDLE_EOF) if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS && statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_HANDLE_EOF)
{ {
Exception exception = new IOException(string.Empty, new WebListenerException((int)statusCode)); Exception exception = new IOException(string.Empty, new HttpSysException((int)statusCode));
LogHelper.LogException(Logger, "Read", exception); LogHelper.LogException(Logger, "Read", exception);
Abort(); Abort();
throw exception; throw exception;
@ -265,14 +265,14 @@ namespace Microsoft.AspNetCore.Server.HttpSys
} }
else else
{ {
Exception exception = new IOException(string.Empty, new WebListenerException((int)statusCode)); Exception exception = new IOException(string.Empty, new HttpSysException((int)statusCode));
LogHelper.LogException(Logger, "BeginRead", exception); LogHelper.LogException(Logger, "BeginRead", exception);
Abort(); Abort();
throw exception; throw exception;
} }
} }
else if (statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS && else if (statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS &&
WebListener.SkipIOCPCallbackOnSuccess) HttpSysListener.SkipIOCPCallbackOnSuccess)
{ {
// IO operation completed synchronously - callback won't be called to signal completion. // IO operation completed synchronously - callback won't be called to signal completion.
asyncResult.IOCompleted(statusCode, bytesReturned); asyncResult.IOCompleted(statusCode, bytesReturned);
@ -391,14 +391,14 @@ namespace Microsoft.AspNetCore.Server.HttpSys
} }
else else
{ {
Exception exception = new IOException(string.Empty, new WebListenerException((int)statusCode)); Exception exception = new IOException(string.Empty, new HttpSysException((int)statusCode));
LogHelper.LogException(Logger, "ReadAsync", exception); LogHelper.LogException(Logger, "ReadAsync", exception);
Abort(); Abort();
throw exception; throw exception;
} }
} }
else if (statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS && else if (statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS &&
WebListener.SkipIOCPCallbackOnSuccess) HttpSysListener.SkipIOCPCallbackOnSuccess)
{ {
// IO operation completed synchronously - callback won't be called to signal completion. // IO operation completed synchronously - callback won't be called to signal completion.
asyncResult.Dispose(); asyncResult.Dispose();

View File

@ -90,7 +90,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
{ {
if (errorCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS && errorCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_HANDLE_EOF) if (errorCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS && errorCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_HANDLE_EOF)
{ {
asyncResult.Fail(new IOException(string.Empty, new WebListenerException((int)errorCode))); asyncResult.Fail(new IOException(string.Empty, new HttpSysException((int)errorCode)));
} }
else else
{ {

View File

@ -45,7 +45,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
_expectedBodyLength = 0; _expectedBodyLength = 0;
_nativeStream = null; _nativeStream = null;
_cacheTtl = null; _cacheTtl = null;
_authChallenges = RequestContext.Server.Settings.Authentication.Schemes; _authChallenges = RequestContext.Server.Options.Authentication.Schemes;
} }
private enum ResponseState private enum ResponseState
@ -375,7 +375,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
if (asyncResult != null && if (asyncResult != null &&
statusCode == ErrorCodes.ERROR_SUCCESS && statusCode == ErrorCodes.ERROR_SUCCESS &&
WebListener.SkipIOCPCallbackOnSuccess) HttpSysListener.SkipIOCPCallbackOnSuccess)
{ {
asyncResult.BytesSent = bytesSent; asyncResult.BytesSent = bytesSent;
// The caller will invoke IOCompleted // The caller will invoke IOCompleted
@ -394,7 +394,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
{ {
if (StatusCode == (ushort)StatusCodes.Status401Unauthorized) if (StatusCode == (ushort)StatusCodes.Status401Unauthorized)
{ {
RequestContext.Server.Settings.Authentication.SetAuthenticationChallenge(RequestContext); RequestContext.Server.Options.Authentication.SetAuthenticationChallenge(RequestContext);
} }
var flags = HttpApi.HTTP_FLAGS.NONE; var flags = HttpApi.HTTP_FLAGS.NONE;
@ -662,7 +662,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
if (errorCode != ErrorCodes.ERROR_SUCCESS) if (errorCode != ErrorCodes.ERROR_SUCCESS)
{ {
throw new WebListenerException((int)errorCode); throw new HttpSysException((int)errorCode);
} }
} }

View File

@ -40,7 +40,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
private ILogger Logger => RequestContext.Server.Logger; private ILogger Logger => RequestContext.Server.Logger;
internal bool ThrowWriteExceptions => RequestContext.Server.Settings.ThrowWriteExceptions; internal bool ThrowWriteExceptions => RequestContext.Server.Options.ThrowWriteExceptions;
internal bool IsDisposed => _disposed; internal bool IsDisposed => _disposed;
@ -163,7 +163,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
{ {
if (ThrowWriteExceptions) if (ThrowWriteExceptions)
{ {
var exception = new IOException(string.Empty, new WebListenerException((int)statusCode)); var exception = new IOException(string.Empty, new HttpSysException((int)statusCode));
LogHelper.LogException(Logger, "Flush", exception); LogHelper.LogException(Logger, "Flush", exception);
Abort(); Abort();
throw exception; throw exception;
@ -329,7 +329,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
else if (ThrowWriteExceptions) else if (ThrowWriteExceptions)
{ {
asyncResult.Dispose(); asyncResult.Dispose();
Exception exception = new IOException(string.Empty, new WebListenerException((int)statusCode)); Exception exception = new IOException(string.Empty, new HttpSysException((int)statusCode));
LogHelper.LogException(Logger, "FlushAsync", exception); LogHelper.LogException(Logger, "FlushAsync", exception);
Abort(); Abort();
throw exception; throw exception;
@ -342,7 +342,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
} }
} }
if (statusCode == ErrorCodes.ERROR_SUCCESS && WebListener.SkipIOCPCallbackOnSuccess) if (statusCode == ErrorCodes.ERROR_SUCCESS && HttpSysListener.SkipIOCPCallbackOnSuccess)
{ {
// IO operation completed synchronously - callback won't be called to signal completion. // IO operation completed synchronously - callback won't be called to signal completion.
asyncResult.IOCompleted(statusCode, bytesSent); asyncResult.IOCompleted(statusCode, bytesSent);
@ -624,7 +624,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
else if (ThrowWriteExceptions) else if (ThrowWriteExceptions)
{ {
asyncResult.Dispose(); asyncResult.Dispose();
var exception = new IOException(string.Empty, new WebListenerException((int)statusCode)); var exception = new IOException(string.Empty, new HttpSysException((int)statusCode));
LogHelper.LogException(Logger, "SendFileAsync", exception); LogHelper.LogException(Logger, "SendFileAsync", exception);
Abort(); Abort();
throw exception; throw exception;
@ -637,7 +637,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
} }
} }
if (statusCode == ErrorCodes.ERROR_SUCCESS && WebListener.SkipIOCPCallbackOnSuccess) if (statusCode == ErrorCodes.ERROR_SUCCESS && HttpSysListener.SkipIOCPCallbackOnSuccess)
{ {
// IO operation completed synchronously - callback won't be called to signal completion. // IO operation completed synchronously - callback won't be called to signal completion.
asyncResult.IOCompleted(statusCode, bytesSent); asyncResult.IOCompleted(statusCode, bytesSent);

View File

@ -237,7 +237,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
} }
else if (asyncResult._responseStream.ThrowWriteExceptions) else if (asyncResult._responseStream.ThrowWriteExceptions)
{ {
var exception = new IOException(string.Empty, new WebListenerException((int)errorCode)); var exception = new IOException(string.Empty, new HttpSysException((int)errorCode));
LogHelper.LogException(logger, "FlushAsync.IOCompleted", exception); LogHelper.LogException(logger, "FlushAsync.IOCompleted", exception);
asyncResult.Fail(exception); asyncResult.Fail(exception);
} }

View File

@ -4,16 +4,14 @@
using System; using System;
using Microsoft.AspNetCore.Hosting.Server; using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.AspNetCore.Server.HttpSys; using Microsoft.AspNetCore.Server.HttpSys;
using Microsoft.AspNetCore.Server.HttpSys.Internal;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
namespace Microsoft.AspNetCore.Hosting namespace Microsoft.AspNetCore.Hosting
{ {
public static class WebHostBuilderWebListenerExtensions public static class WebHostBuilderHttpSysExtensions
{ {
/// <summary> /// <summary>
/// Specify WebListener as the server to be used by the web host. /// Specify HttpSys as the server to be used by the web host.
/// </summary> /// </summary>
/// <param name="hostBuilder"> /// <param name="hostBuilder">
/// The Microsoft.AspNetCore.Hosting.IWebHostBuilder to configure. /// The Microsoft.AspNetCore.Hosting.IWebHostBuilder to configure.
@ -21,29 +19,28 @@ namespace Microsoft.AspNetCore.Hosting
/// <returns> /// <returns>
/// The Microsoft.AspNetCore.Hosting.IWebHostBuilder. /// The Microsoft.AspNetCore.Hosting.IWebHostBuilder.
/// </returns> /// </returns>
public static IWebHostBuilder UseWebListener(this IWebHostBuilder hostBuilder) public static IWebHostBuilder UseHttpSys(this IWebHostBuilder hostBuilder)
{ {
return hostBuilder.ConfigureServices(services => { return hostBuilder.ConfigureServices(services => {
services.AddTransient<IConfigureOptions<WebListenerOptions>, WebListenerOptionsSetup>();
services.AddSingleton<IServer, MessagePump>(); services.AddSingleton<IServer, MessagePump>();
}); });
} }
/// <summary> /// <summary>
/// Specify WebListener as the server to be used by the web host. /// Specify HttpSys as the server to be used by the web host.
/// </summary> /// </summary>
/// <param name="hostBuilder"> /// <param name="hostBuilder">
/// The Microsoft.AspNetCore.Hosting.IWebHostBuilder to configure. /// The Microsoft.AspNetCore.Hosting.IWebHostBuilder to configure.
/// </param> /// </param>
/// <param name="options"> /// <param name="options">
/// A callback to configure WebListener options. /// A callback to configure HttpSys options.
/// </param> /// </param>
/// <returns> /// <returns>
/// The Microsoft.AspNetCore.Hosting.IWebHostBuilder. /// The Microsoft.AspNetCore.Hosting.IWebHostBuilder.
/// </returns> /// </returns>
public static IWebHostBuilder UseWebListener(this IWebHostBuilder hostBuilder, Action<WebListenerOptions> options) public static IWebHostBuilder UseHttpSys(this IWebHostBuilder hostBuilder, Action<HttpSysOptions> options)
{ {
return hostBuilder.UseWebListener().ConfigureServices(services => return hostBuilder.UseHttpSys().ConfigureServices(services =>
{ {
services.Configure(options); services.Configure(options);
}); });

View File

@ -1,29 +0,0 @@
// 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;
namespace Microsoft.AspNetCore.Server.HttpSys
{
public class WebListenerOptions
{
internal static readonly int DefaultMaxAccepts = 5 * Environment.ProcessorCount;
/// <summary>
/// Settings for the underlying WebListener instance.
/// </summary>
public WebListenerSettings ListenerSettings { get; } = new WebListenerSettings();
/// <summary>
/// The maximum number of concurrent calls to WebListener.AcceptAsync().
/// </summary>
public int MaxAccepts { get; set; } = DefaultMaxAccepts;
/// <summary>
/// Attempts kernel mode caching for responses with eligible headers. The response may not include
/// Set-Cookie, Vary, or Pragma headers. It must include a Cache-Control header with Public and
/// either a Shared-Max-Age or Max-Age value, or an Expires header.
/// </summary>
public bool EnableResponseCaching { get; set; } = true;
}
}

View File

@ -4,7 +4,8 @@
"packOptions": { "packOptions": {
"tags": [ "tags": [
"aspnetcore", "aspnetcore",
"weblistener" "weblistener",
"httpsys"
] ]
}, },
"dependencies": { "dependencies": {

View File

@ -8,6 +8,7 @@ using System.Net.Sockets;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Testing.xunit; using Microsoft.AspNetCore.Testing.xunit;
using Microsoft.Extensions.Logging;
using Xunit; using Xunit;
namespace Microsoft.AspNetCore.Server.HttpSys.Listener namespace Microsoft.AspNetCore.Server.HttpSys.Listener
@ -147,13 +148,13 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
string root; string root;
var server = Utilities.CreateHttpServerReturnRoot("/", out root); var server = Utilities.CreateHttpServerReturnRoot("/", out root);
server.Dispose(); server.Dispose();
server = new WebListener(); server = new HttpSysListener(new HttpSysOptions(), new LoggerFactory());
using (server) using (server)
{ {
var uriBuilder = new UriBuilder(root); var uriBuilder = new UriBuilder(root);
foreach (string path in new[] { "/", "/11", "/2/3", "/2", "/11/2" }) foreach (string path in new[] { "/", "/11", "/2/3", "/2", "/11/2" })
{ {
server.Settings.UrlPrefixes.Add(UrlPrefix.Create(uriBuilder.Scheme, uriBuilder.Host, uriBuilder.Port, path)); server.Options.UrlPrefixes.Add(UrlPrefix.Create(uriBuilder.Scheme, uriBuilder.Host, uriBuilder.Port, path));
} }
server.Start(); server.Start();

View File

@ -272,7 +272,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
string address; string address;
using (var server = Utilities.CreateHttpServer(out address)) using (var server = Utilities.CreateHttpServer(out address))
{ {
server.Settings.ThrowWriteExceptions = true; server.Options.ThrowWriteExceptions = true;
var responseTask = SendRequestAsync(address); var responseTask = SendRequestAsync(address);
var context = await server.AcceptAsync(Utilities.DefaultTimeout); var context = await server.AcceptAsync(Utilities.DefaultTimeout);
@ -331,7 +331,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
string address; string address;
using (var server = Utilities.CreateHttpServer(out address)) using (var server = Utilities.CreateHttpServer(out address))
{ {
server.Settings.ThrowWriteExceptions = true; server.Options.ThrowWriteExceptions = true;
var responseTask = SendRequestAsync(address); var responseTask = SendRequestAsync(address);
var context = await server.AcceptAsync(Utilities.DefaultTimeout); var context = await server.AcceptAsync(Utilities.DefaultTimeout);
@ -374,7 +374,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
string address; string address;
using (var server = Utilities.CreateHttpServer(out address)) using (var server = Utilities.CreateHttpServer(out address))
{ {
server.Settings.ThrowWriteExceptions = true; server.Options.ThrowWriteExceptions = true;
var cts = new CancellationTokenSource(); var cts = new CancellationTokenSource();
var responseTask = SendRequestAsync(address, cts.Token); var responseTask = SendRequestAsync(address, cts.Token);
@ -404,7 +404,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
string address; string address;
using (var server = Utilities.CreateHttpServer(out address)) using (var server = Utilities.CreateHttpServer(out address))
{ {
server.Settings.ThrowWriteExceptions = true; server.Options.ThrowWriteExceptions = true;
var cts = new CancellationTokenSource(); var cts = new CancellationTokenSource();
var responseTask = SendRequestAsync(address, cts.Token); var responseTask = SendRequestAsync(address, cts.Token);
@ -482,7 +482,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
string address; string address;
using (var server = Utilities.CreateHttpServer(out address)) using (var server = Utilities.CreateHttpServer(out address))
{ {
server.Settings.ThrowWriteExceptions = true; server.Options.ThrowWriteExceptions = true;
RequestContext context; RequestContext context;
using (var client = new HttpClient()) using (var client = new HttpClient())
{ {
@ -516,7 +516,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
string address; string address;
using (var server = Utilities.CreateHttpServer(out address)) using (var server = Utilities.CreateHttpServer(out address))
{ {
server.Settings.ThrowWriteExceptions = true; server.Options.ThrowWriteExceptions = true;
RequestContext context; RequestContext context;
using (var client = new HttpClient()) using (var client = new HttpClient())
{ {

View File

@ -352,7 +352,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
string address; string address;
using (var server = Utilities.CreateHttpServer(out address)) using (var server = Utilities.CreateHttpServer(out address))
{ {
server.Settings.ThrowWriteExceptions = true; server.Options.ThrowWriteExceptions = true;
var responseTask = SendRequestAsync(address); var responseTask = SendRequestAsync(address);
var context = await server.AcceptAsync(Utilities.DefaultTimeout); var context = await server.AcceptAsync(Utilities.DefaultTimeout);
@ -411,7 +411,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
string address; string address;
using (var server = Utilities.CreateHttpServer(out address)) using (var server = Utilities.CreateHttpServer(out address))
{ {
server.Settings.ThrowWriteExceptions = true; server.Options.ThrowWriteExceptions = true;
var responseTask = SendRequestAsync(address); var responseTask = SendRequestAsync(address);
var context = await server.AcceptAsync(Utilities.DefaultTimeout); var context = await server.AcceptAsync(Utilities.DefaultTimeout);
@ -454,7 +454,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
string address; string address;
using (var server = Utilities.CreateHttpServer(out address)) using (var server = Utilities.CreateHttpServer(out address))
{ {
server.Settings.ThrowWriteExceptions = true; server.Options.ThrowWriteExceptions = true;
var cts = new CancellationTokenSource(); var cts = new CancellationTokenSource();
var responseTask = SendRequestAsync(address, cts.Token); var responseTask = SendRequestAsync(address, cts.Token);
@ -510,7 +510,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
string address; string address;
using (var server = Utilities.CreateHttpServer(out address)) using (var server = Utilities.CreateHttpServer(out address))
{ {
server.Settings.ThrowWriteExceptions = true; server.Options.ThrowWriteExceptions = true;
RequestContext context; RequestContext context;
using (var client = new HttpClient()) using (var client = new HttpClient())
{ {

View File

@ -234,7 +234,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
string address; string address;
using (var server = Utilities.CreateHttpServer(out address)) using (var server = Utilities.CreateHttpServer(out address))
{ {
server.Settings.RequestQueueLimit = 1001; server.Options.RequestQueueLimit = 1001;
var responseTask = SendRequestAsync(address); var responseTask = SendRequestAsync(address);
var context = await server.AcceptAsync(Utilities.DefaultTimeout); var context = await server.AcceptAsync(Utilities.DefaultTimeout);
@ -262,7 +262,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
Assert.Equal(string.Empty, response); Assert.Equal(string.Empty, response);
address += "pathbase/"; address += "pathbase/";
server.Settings.UrlPrefixes.Add(address); server.Options.UrlPrefixes.Add(address);
responseTask = SendRequestAsync(address); responseTask = SendRequestAsync(address);
@ -283,7 +283,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
using (var server = Utilities.CreateHttpServer(out address)) using (var server = Utilities.CreateHttpServer(out address))
{ {
address += "pathbase/"; address += "pathbase/";
server.Settings.UrlPrefixes.Add(address); server.Options.UrlPrefixes.Add(address);
var responseTask = SendRequestAsync(address); var responseTask = SendRequestAsync(address);
var context = await server.AcceptAsync(Utilities.DefaultTimeout); var context = await server.AcceptAsync(Utilities.DefaultTimeout);
@ -294,7 +294,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
var response = await responseTask; var response = await responseTask;
Assert.Equal(string.Empty, response); Assert.Equal(string.Empty, response);
Assert.True(server.Settings.UrlPrefixes.Remove(address)); Assert.True(server.Options.UrlPrefixes.Remove(address));
responseTask = SendRequestAsync(address); responseTask = SendRequestAsync(address);

View File

@ -5,14 +5,14 @@ using System;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.Internal; using Microsoft.Extensions.Internal;
using Microsoft.Extensions.Logging;
namespace Microsoft.AspNetCore.Server.HttpSys.Listener namespace Microsoft.AspNetCore.Server.HttpSys.Listener
{ {
internal static class Utilities internal static class Utilities
{ {
// When tests projects are run in parallel, overlapping port ranges can cause a race condition when looking for free // When tests projects are run in parallel, overlapping port ranges can cause a race condition when looking for free
// ports during dynamic port allocation. To avoid this, make sure the port range here is different from the range in // ports during dynamic port allocation.
// Microsoft.AspNetCore.Server.WebListener.
private const int BasePort = 8001; private const int BasePort = 8001;
private const int MaxPort = 11000; private const int MaxPort = 11000;
private static int NextPort = BasePort; private static int NextPort = BasePort;
@ -33,27 +33,27 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
#endif #endif
} }
internal static WebListener CreateHttpAuthServer(AuthenticationSchemes authScheme, bool allowAnonymos, out string baseAddress) internal static HttpSysListener CreateHttpAuthServer(AuthenticationSchemes authScheme, bool allowAnonymos, out string baseAddress)
{ {
var listener = CreateHttpServer(out baseAddress); var listener = CreateHttpServer(out baseAddress);
listener.Settings.Authentication.Schemes = authScheme; listener.Options.Authentication.Schemes = authScheme;
listener.Settings.Authentication.AllowAnonymous = allowAnonymos; listener.Options.Authentication.AllowAnonymous = allowAnonymos;
return listener; return listener;
} }
internal static WebListener CreateHttpServer(out string baseAddress) internal static HttpSysListener CreateHttpServer(out string baseAddress)
{ {
string root; string root;
return CreateDynamicHttpServer(string.Empty, out root, out baseAddress); return CreateDynamicHttpServer(string.Empty, out root, out baseAddress);
} }
internal static WebListener CreateHttpServerReturnRoot(string path, out string root) internal static HttpSysListener CreateHttpServerReturnRoot(string path, out string root)
{ {
string baseAddress; string baseAddress;
return CreateDynamicHttpServer(path, out root, out baseAddress); return CreateDynamicHttpServer(path, out root, out baseAddress);
} }
internal static WebListener CreateDynamicHttpServer(string basePath, out string root, out string baseAddress) internal static HttpSysListener CreateDynamicHttpServer(string basePath, out string root, out string baseAddress)
{ {
lock (PortLock) lock (PortLock)
{ {
@ -63,14 +63,14 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
var prefix = UrlPrefix.Create("http", "localhost", port, basePath); var prefix = UrlPrefix.Create("http", "localhost", port, basePath);
root = prefix.Scheme + "://" + prefix.Host + ":" + prefix.Port; root = prefix.Scheme + "://" + prefix.Host + ":" + prefix.Port;
baseAddress = prefix.ToString(); baseAddress = prefix.ToString();
var listener = new WebListener(); var listener = new HttpSysListener(new HttpSysOptions(), new LoggerFactory());
listener.Settings.UrlPrefixes.Add(prefix); listener.Options.UrlPrefixes.Add(prefix);
try try
{ {
listener.Start(); listener.Start();
return listener; return listener;
} }
catch (WebListenerException) catch (HttpSysException)
{ {
listener.Dispose(); listener.Dispose();
} }
@ -80,15 +80,15 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
throw new Exception("Failed to locate a free port."); throw new Exception("Failed to locate a free port.");
} }
internal static WebListener CreateHttpsServer() internal static HttpSysListener CreateHttpsServer()
{ {
return CreateServer("https", "localhost", 9090, string.Empty); return CreateServer("https", "localhost", 9090, string.Empty);
} }
internal static WebListener CreateServer(string scheme, string host, int port, string path) internal static HttpSysListener CreateServer(string scheme, string host, int port, string path)
{ {
WebListener listener = new WebListener(); var listener = new HttpSysListener(new HttpSysOptions(), new LoggerFactory());
listener.Settings.UrlPrefixes.Add(UrlPrefix.Create(scheme, host, port, path)); listener.Options.UrlPrefixes.Add(UrlPrefix.Create(scheme, host, port, path));
listener.Start(); listener.Start();
return listener; return listener;
} }
@ -97,7 +97,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys.Listener
/// AcceptAsync extension with timeout. This extension should be used in all tests to prevent /// AcceptAsync extension with timeout. This extension should be used in all tests to prevent
/// unexpected hangs when a request does not arrive. /// unexpected hangs when a request does not arrive.
/// </summary> /// </summary>
internal static async Task<RequestContext> AcceptAsync(this WebListener server, TimeSpan timeout) internal static async Task<RequestContext> AcceptAsync(this HttpSysListener server, TimeSpan timeout)
{ {
var acceptTask = server.AcceptAsync(); var acceptTask = server.AcceptAsync();
var completedTask = await Task.WhenAny(acceptTask, Task.Delay(timeout)); var completedTask = await Task.WhenAny(acceptTask, Task.Delay(timeout));

View File

@ -305,11 +305,11 @@ namespace Microsoft.AspNetCore.Server.HttpSys
var dynamicServer = Utilities.CreateHttpServerReturnRoot("/", out root, app); var dynamicServer = Utilities.CreateHttpServerReturnRoot("/", out root, app);
dynamicServer.Dispose(); dynamicServer.Dispose();
var rootUri = new Uri(root); var rootUri = new Uri(root);
var server = new MessagePump(Options.Create(new WebListenerOptions()), new LoggerFactory()); var server = new MessagePump(Options.Create(new HttpSysOptions()), new LoggerFactory());
foreach (string path in new[] { "/", "/11", "/2/3", "/2", "/11/2" }) foreach (string path in new[] { "/", "/11", "/2/3", "/2", "/11/2" })
{ {
server.Listener.Settings.UrlPrefixes.Add(UrlPrefix.Create(rootUri.Scheme, rootUri.Host, rootUri.Port, path)); server.Listener.Options.UrlPrefixes.Add(UrlPrefix.Create(rootUri.Scheme, rootUri.Host, rootUri.Port, path));
} }
server.Start(new DummyApplication(app)); server.Start(new DummyApplication(app));

View File

@ -241,9 +241,9 @@ namespace Microsoft.AspNetCore.Server.HttpSys
string address; string address;
using (Utilities.CreateHttpServer(out address, httpContext => Task.FromResult(0))) { } using (Utilities.CreateHttpServer(out address, httpContext => Task.FromResult(0))) { }
var server = new MessagePump(Options.Create(new WebListenerOptions()), new LoggerFactory()); var server = new MessagePump(Options.Create(new HttpSysOptions()), new LoggerFactory());
server.Listener.Settings.UrlPrefixes.Add(UrlPrefix.Create(address)); server.Listener.Options.UrlPrefixes.Add(UrlPrefix.Create(address));
server.Listener.Settings.RequestQueueLimit = 1001; server.Listener.Options.RequestQueueLimit = 1001;
using (server) using (server)
{ {

View File

@ -13,8 +13,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
internal static class Utilities internal static class Utilities
{ {
// When tests projects are run in parallel, overlapping port ranges can cause a race condition when looking for free // When tests projects are run in parallel, overlapping port ranges can cause a race condition when looking for free
// ports during dynamic port allocation. To avoid this, make sure the port range here is different from the range in // ports during dynamic port allocation.
// Microsoft.Net.Http.Server.
private const int BasePort = 5001; private const int BasePort = 5001;
private const int MaxPort = 8000; private const int MaxPort = 8000;
private static int NextPort = BasePort; private static int NextPort = BasePort;
@ -50,16 +49,16 @@ namespace Microsoft.AspNetCore.Server.HttpSys
root = prefix.Scheme + "://" + prefix.Host + ":" + prefix.Port; root = prefix.Scheme + "://" + prefix.Host + ":" + prefix.Port;
baseAddress = prefix.ToString(); baseAddress = prefix.ToString();
var server = new MessagePump(Options.Create(new WebListenerOptions()), new LoggerFactory()); var server = new MessagePump(Options.Create(new HttpSysOptions()), new LoggerFactory());
server.Features.Get<IServerAddressesFeature>().Addresses.Add(baseAddress); server.Features.Get<IServerAddressesFeature>().Addresses.Add(baseAddress);
server.Listener.Settings.Authentication.Schemes = authType; server.Listener.Options.Authentication.Schemes = authType;
server.Listener.Settings.Authentication.AllowAnonymous = allowAnonymous; server.Listener.Options.Authentication.AllowAnonymous = allowAnonymous;
try try
{ {
server.Start(new DummyApplication(app)); server.Start(new DummyApplication(app));
return server; return server;
} }
catch (WebListenerException) catch (HttpSysException)
{ {
} }
} }
@ -75,7 +74,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
internal static IServer CreateServer(string scheme, string host, int port, string path, RequestDelegate app) internal static IServer CreateServer(string scheme, string host, int port, string path, RequestDelegate app)
{ {
var server = new MessagePump(Options.Create(new WebListenerOptions()), new LoggerFactory()); var server = new MessagePump(Options.Create(new HttpSysOptions()), new LoggerFactory());
server.Features.Get<IServerAddressesFeature>().Addresses.Add(UrlPrefix.Create(scheme, host, port, path).ToString()); server.Features.Get<IServerAddressesFeature>().Addresses.Add(UrlPrefix.Create(scheme, host, port, path).ToString());
server.Start(new DummyApplication(app)); server.Start(new DummyApplication(app));
return server; return server;

View File

@ -43,7 +43,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
[InlineData("http://www.example.com:NOTAPORT")] [InlineData("http://www.example.com:NOTAPORT")]
[InlineData("https://www.example.com:NOTAPORT")] [InlineData("https://www.example.com:NOTAPORT")]
[InlineData("http://www.example.com:NOTAPORT/")] [InlineData("http://www.example.com:NOTAPORT/")]
[InlineData("http://foo:/tmp/weblistener-test.sock:5000/doesn't/matter")] [InlineData("http://foo:/tmp/httpsys-test.sock:5000/doesn't/matter")]
public void CreateThrowsForUrlsWithInvalidPorts(string url) public void CreateThrowsForUrlsWithInvalidPorts(string url)
{ {
Assert.Throws<FormatException>(() => UrlPrefix.Create(url)); Assert.Throws<FormatException>(() => UrlPrefix.Create(url));