Hosting#331 Add IServerAddressesFeature.

This commit is contained in:
Chris R 2015-09-11 14:07:18 -07:00
parent 78de14d248
commit 2e225b0db6
5 changed files with 70 additions and 31 deletions

View File

@ -1,3 +0,0 @@

Server = Microsoft.AspNet.Server.Kestrel
Server.Urls = http://localhost:5000/

View File

@ -15,7 +15,6 @@
"commands": { "commands": {
"run": "Microsoft.AspNet.Server.Kestrel", "run": "Microsoft.AspNet.Server.Kestrel",
"run-socket": "Microsoft.AspNet.Server.Kestrel --server.urls http://unix:/tmp/kestrel-test.sock", "run-socket": "Microsoft.AspNet.Server.Kestrel --server.urls http://unix:/tmp/kestrel-test.sock",
"kestrel": "Microsoft.AspNet.Server.Kestrel", "kestrel": "Microsoft.AspNet.Server.Kestrel"
"web": "Microsoft.AspNet.Hosting"
} }
} }

View File

@ -3,35 +3,27 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Microsoft.AspNet.Server.Features;
using Microsoft.Framework.Configuration; using Microsoft.Framework.Configuration;
namespace Microsoft.AspNet.Server.Kestrel namespace Microsoft.AspNet.Server.Kestrel
{ {
public class KestrelServerInformation : IKestrelServerInformation public class KestrelServerInformation : IKestrelServerInformation, IServerAddressesFeature
{ {
public KestrelServerInformation() public ICollection<string> Addresses { get; } = new List<string>();
{
Addresses = new List<ServerAddress>();
}
public IList<ServerAddress> Addresses { get; private set; }
public int ThreadCount { get; set; } public int ThreadCount { get; set; }
public void Initialize(IConfiguration configuration) public void Initialize(IConfiguration configuration)
{ {
var urls = configuration["server.urls"]; var urls = configuration["server.urls"] ?? string.Empty;
if (string.IsNullOrEmpty(urls))
{
urls = "http://+:5000/";
}
foreach (var url in urls.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)) foreach (var url in urls.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries))
{ {
var address = ServerAddress.FromUrl(url); Addresses.Add(url);
if (address != null) }
{ if (Addresses.Count == 0)
Addresses.Add(address); {
} Addresses.Add("http://+:5000/");
} }
} }
} }

View File

@ -14,6 +14,29 @@ namespace Microsoft.AspNet.Server.Kestrel
public int Port { get; private set; } public int Port { get; private set; }
public string Scheme { get; private set; } public string Scheme { get; private set; }
public override string ToString()
{
return Scheme.ToLowerInvariant() + "://" + Host.ToLowerInvariant() + ":" + Port.ToString(CultureInfo.InvariantCulture) + Path.ToLowerInvariant();
}
public override int GetHashCode()
{
return ToString().GetHashCode();
}
public override bool Equals(object obj)
{
var other = obj as ServerAddress;
if (other == null)
{
return false;
}
return string.Equals(Scheme, other.Scheme, StringComparison.OrdinalIgnoreCase)
&& string.Equals(Host, other.Host, StringComparison.OrdinalIgnoreCase)
&& Port == other.Port
&& string.Equals(Path, other.Path, StringComparison.OrdinalIgnoreCase);
}
public static ServerAddress FromUrl(string url) public static ServerAddress FromUrl(string url)
{ {
url = url ?? string.Empty; url = url ?? string.Empty;
@ -21,6 +44,17 @@ namespace Microsoft.AspNet.Server.Kestrel
int schemeDelimiterStart = url.IndexOf("://", StringComparison.Ordinal); int schemeDelimiterStart = url.IndexOf("://", StringComparison.Ordinal);
if (schemeDelimiterStart < 0) if (schemeDelimiterStart < 0)
{ {
int port;
if (int.TryParse(url, NumberStyles.None, CultureInfo.InvariantCulture, out port))
{
return new ServerAddress()
{
Scheme = "http",
Host = "+",
Port = port,
Path = "/"
};
}
return null; return null;
} }
int schemeDelimiterEnd = schemeDelimiterStart + "://".Length; int schemeDelimiterEnd = schemeDelimiterStart + "://".Length;

View File

@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNet.Hosting.Server; using Microsoft.AspNet.Hosting.Server;
using Microsoft.AspNet.Http.Features; using Microsoft.AspNet.Http.Features;
using Microsoft.AspNet.Server.Features;
using Microsoft.Dnx.Runtime; using Microsoft.Dnx.Runtime;
using Microsoft.Framework.Configuration; using Microsoft.Framework.Configuration;
using Microsoft.Framework.Logging; using Microsoft.Framework.Logging;
@ -34,6 +35,7 @@ namespace Microsoft.AspNet.Server.Kestrel
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);
return serverFeatures; return serverFeatures;
} }
@ -63,18 +65,33 @@ namespace Microsoft.AspNet.Server.Kestrel
} }
engine.Start(information.ThreadCount == 0 ? 1 : information.ThreadCount); engine.Start(information.ThreadCount == 0 ? 1 : information.ThreadCount);
bool atLeastOneListener = false;
foreach (var address in information.Addresses) foreach (var address in information.Addresses)
{ {
disposables.Push(engine.CreateServer( var parsedAddress = ServerAddress.FromUrl(address);
address.Scheme, if (parsedAddress == null)
address.Host, {
address.Port, throw new FormatException("Unrecognized listening address: " + address);
async frame => }
{ else
var request = new ServerRequest(frame); {
await application.Invoke(request.Features).ConfigureAwait(false); atLeastOneListener = true;
})); disposables.Push(engine.CreateServer(
parsedAddress.Scheme,
parsedAddress.Host,
parsedAddress.Port,
async frame =>
{
var request = new ServerRequest(frame);
await application.Invoke(request.Features).ConfigureAwait(false);
}));
}
}
if (!atLeastOneListener)
{
throw new InvalidOperationException("No recognized listening addresses were configured.");
} }
return disposer; return disposer;