Direct address configuration #297

This commit is contained in:
John Luo 2017-02-27 19:40:38 -08:00 committed by =
parent 71c1f371f8
commit aac4eebd79
9 changed files with 133 additions and 31 deletions

View File

@ -3,9 +3,8 @@
"SelfHostServer": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "http://localhost:8080/",
"launchUrl": "http://localhost:5000/",
"environmentVariables": {
"ASPNETCORE_URLS": "http://localhost:8080/",
"ASPNETCORE_ENVIRONMENT": "Development"
}
}

View File

@ -37,6 +37,7 @@ namespace SelfHostServer
.UseStartup<Startup>()
.UseHttpSys(options =>
{
options.UrlPrefixes.Add("http://localhost:5000");
options.Authentication.Schemes = AuthenticationSchemes.None;
options.Authentication.AllowAnonymous = true;
})

View File

@ -13,6 +13,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
internal const string Close = "close";
internal const string Zero = "0";
internal const string SchemeDelimiter = "://";
internal const string DefaultServerAddress = "http://localhost:5000";
internal static Version V1_0 = new Version(1, 0);
internal static Version V1_1 = new Version(1, 1);

View File

@ -2,8 +2,6 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
namespace Microsoft.AspNetCore.Server.HttpSys
{

View File

@ -31,6 +31,30 @@ namespace Microsoft.AspNetCore.Server.HttpSys
}
}
internal static void LogWarning(ILogger logger, string data)
{
if (logger == null)
{
Debug.WriteLine(data);
}
else
{
logger.LogWarning(data);
}
}
internal static void LogDebug(ILogger logger, string data)
{
if (logger == null)
{
Debug.WriteLine(data);
}
else
{
logger.LogDebug(data);
}
}
internal static void LogDebug(ILogger logger, string location, string data)
{
if (logger == null)

View File

@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.AspNetCore.Hosting.Server.Features;
using Microsoft.AspNetCore.Http.Features;
@ -16,8 +17,8 @@ namespace Microsoft.AspNetCore.Server.HttpSys
{
internal class MessagePump : IServer
{
private readonly HttpSysListener _listener;
private readonly ILogger _logger;
private readonly HttpSysOptions _options;
private IHttpApplication<object> _application;
@ -42,23 +43,20 @@ namespace Microsoft.AspNetCore.Server.HttpSys
throw new ArgumentNullException(nameof(loggerFactory));
}
var optionsInstance = options.Value;
_listener = new HttpSysListener(optionsInstance, loggerFactory);
_options = options.Value;
Listener = new HttpSysListener(_options, loggerFactory);
_logger = LogHelper.CreateLogger(loggerFactory, typeof(MessagePump));
Features = new FeatureCollection();
_serverAddresses = new ServerAddressesFeature();
Features.Set<IServerAddressesFeature>(_serverAddresses);
_processRequest = new Action<object>(ProcessRequestAsync);
_maxAccepts = optionsInstance.MaxAccepts;
EnableResponseCaching = optionsInstance.EnableResponseCaching;
_maxAccepts = _options.MaxAccepts;
EnableResponseCaching = _options.EnableResponseCaching;
_shutdownSignal = new ManualResetEvent(false);
}
internal HttpSysListener Listener
{
get { return _listener; }
}
internal HttpSysListener Listener { get; }
internal bool EnableResponseCaching { get; set; }
@ -71,7 +69,37 @@ namespace Microsoft.AspNetCore.Server.HttpSys
throw new ArgumentNullException(nameof(application));
}
ParseAddresses(_serverAddresses.Addresses, Listener);
var serverAdressesPresent = _serverAddresses.Addresses.Count > 0;
if (_options.UrlPrefixes.Count > 0)
{
if (serverAdressesPresent)
{
LogHelper.LogWarning(_logger, $"Overriding address(es) '{string.Join(", ", _serverAddresses.Addresses)}'. " +
$"Binding to endpoints added to {nameof(HttpSysOptions.UrlPrefixes)} instead.");
_serverAddresses.Addresses.Clear();
foreach (var prefix in _options.UrlPrefixes)
{
_serverAddresses.Addresses.Add(prefix.FullPrefix);
}
}
}
else if (serverAdressesPresent)
{
foreach (var value in _serverAddresses.Addresses)
{
Listener.Options.UrlPrefixes.Add(value);
}
}
else
{
LogHelper.LogDebug(_logger, $"No listening endpoints were configured. Binding to {Constants.DefaultServerAddress} by default.");
_serverAddresses.Addresses.Add(Constants.DefaultServerAddress);
Listener.Options.UrlPrefixes.Add(Constants.DefaultServerAddress);
}
// Can't call Start twice
Contract.Assert(_application == null);
@ -80,12 +108,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
_application = new ApplicationWrapper<TContext>(application);
if (_listener.Options.UrlPrefixes.Count == 0)
{
throw new InvalidOperationException("No address prefixes were defined.");
}
_listener.Start();
Listener.Start();
ActivateRequestProcessingLimits();
}
@ -111,7 +134,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
RequestContext requestContext;
try
{
requestContext = await _listener.AcceptAsync().SupressContext();
requestContext = await Listener.AcceptAsync().SupressContext();
}
catch (Exception exception)
{
@ -206,14 +229,6 @@ namespace Microsoft.AspNetCore.Server.HttpSys
context.Dispose();
}
private void ParseAddresses(ICollection<string> addresses, HttpSysListener listener)
{
foreach (var value in addresses)
{
listener.Options.UrlPrefixes.Add(UrlPrefix.Create(value));
}
}
public void Dispose()
{
_stopping = true;
@ -232,7 +247,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
}
}
// All requests are finished
_listener.Dispose();
Listener.Dispose();
}
private class ApplicationWrapper<TContext> : IHttpApplication<object>

View File

@ -6,6 +6,7 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.Extensions.Internal;
namespace Microsoft.AspNetCore.Server.HttpSys
{
@ -13,6 +14,8 @@ namespace Microsoft.AspNetCore.Server.HttpSys
{
private readonly RequestDelegate _requestDelegate;
public DummyApplication() : this(context => TaskCache.CompletedTask) { }
public DummyApplication(RequestDelegate requestDelegate)
{
_requestDelegate = requestDelegate;

View File

@ -0,0 +1,61 @@
// 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.Linq;
using Microsoft.AspNetCore.Hosting.Server.Features;
using Microsoft.AspNetCore.Testing.xunit;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Xunit;
namespace Microsoft.AspNetCore.Server.HttpSys
{
public class MessagePumpTests
{
[ConditionalTheory]
[InlineData("http://localhost:11001/")]
[InlineData("invalid address")]
[InlineData("")]
[InlineData(null)]
public void OverridingIServerAdressesFeatureWithDirectConfiguration_WarnsOnStart(string serverAddress)
{
var overrideAddress = "http://localhost:11002/";
using (var server = new MessagePump(Options.Create(new HttpSysOptions()), new LoggerFactory()))
{
var serverAddressesFeature = server.Features.Get<IServerAddressesFeature>();
serverAddressesFeature.Addresses.Add(serverAddress);
server.Listener.Options.UrlPrefixes.Add(overrideAddress);
server.Start(new DummyApplication());
Assert.Equal(overrideAddress, serverAddressesFeature.Addresses.Single());
}
}
[ConditionalFact]
public void UseIServerAdressesFeature_WhenNoDirectConfiguration()
{
var serverAddress = "http://localhost:11001/";
using (var server = new MessagePump(Options.Create(new HttpSysOptions()), new LoggerFactory()))
{
var serverAddressesFeature = server.Features.Get<IServerAddressesFeature>();
serverAddressesFeature.Addresses.Add(serverAddress);
server.Start(new DummyApplication());
}
}
[ConditionalFact]
public void UseDefaultAddress_WhenNoServerAddressAndNoDirectConfiguration()
{
using (var server = new MessagePump(Options.Create(new HttpSysOptions()), new LoggerFactory()))
{
server.Start(new DummyApplication());
Assert.Equal(Constants.DefaultServerAddress, server.Features.Get<IServerAddressesFeature>().Addresses.Single());
}
}
}
}

View File

@ -271,7 +271,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
using (server)
{
server.Start(new DummyApplication(httpContext => Task.FromResult(0)));
server.Start(new DummyApplication());
string response = await SendRequestAsync(address);
Assert.Equal(string.Empty, response);
}