Hosting#331 Add IServerAddressesFeature.

This commit is contained in:
Chris R 2015-09-11 14:00:58 -07:00
parent 3a0182688a
commit ce06872b84
5 changed files with 65 additions and 12 deletions

View File

@ -2,6 +2,7 @@
using Microsoft.AspNet.Builder; using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Http; using Microsoft.AspNet.Http;
using Microsoft.AspNet.Http.Features; using Microsoft.AspNet.Http.Features;
using Microsoft.AspNet.Server.Features;
using Microsoft.Framework.Logging; using Microsoft.Framework.Logging;
namespace HotAddSample namespace HotAddSample
@ -15,8 +16,8 @@ namespace HotAddSample
{ {
loggerfactory.AddConsole(LogLevel.Information); loggerfactory.AddConsole(LogLevel.Information);
var listener = app.ServerFeatures.Get<Microsoft.Net.Http.Server.WebListener>(); var addresses = app.ServerFeatures.Get<IServerAddressesFeature>().Addresses;
listener.UrlPrefixes.Add("http://localhost:12346/pathBase/"); addresses.Add("http://localhost:12346/pathBase/");
app.Use(async (context, next) => app.Use(async (context, next) =>
{ {
@ -28,7 +29,7 @@ namespace HotAddSample
await context.Response.WriteAsync("<html><body>"); await context.Response.WriteAsync("<html><body>");
try try
{ {
listener.UrlPrefixes.Add(toAdd); addresses.Add(toAdd);
await context.Response.WriteAsync("Added: " + toAdd); await context.Response.WriteAsync("Added: " + toAdd);
} }
catch (Exception ex) catch (Exception ex)
@ -52,7 +53,7 @@ namespace HotAddSample
{ {
context.Response.ContentType = "text/html"; context.Response.ContentType = "text/html";
await context.Response.WriteAsync("<html><body>"); await context.Response.WriteAsync("<html><body>");
if (listener.UrlPrefixes.Remove(toRemove)) if (addresses.Remove(toRemove))
{ {
await context.Response.WriteAsync("Removed: " + toRemove); await context.Response.WriteAsync("Removed: " + toRemove);
} }
@ -72,7 +73,7 @@ namespace HotAddSample
context.Response.ContentType = "text/html"; context.Response.ContentType = "text/html";
await context.Response.WriteAsync("<html><body>"); await context.Response.WriteAsync("<html><body>");
await context.Response.WriteAsync("Listening on these prefixes: <br>"); await context.Response.WriteAsync("Listening on these prefixes: <br>");
foreach (var prefix in listener.UrlPrefixes) foreach (var prefix in addresses)
{ {
await context.Response.WriteAsync("<a href=\"" + prefix + "\">" + prefix + "</a> <a href=\"?remove=" + prefix + "\">(remove)</a><br>"); await context.Response.WriteAsync("<a href=\"" + prefix + "\">" + prefix + "</a> <a href=\"?remove=" + prefix + "\">(remove)</a><br>");
} }

View File

@ -0,0 +1,27 @@
// Copyright (c) Microsoft Open Technologies, Inc.
// All Rights Reserved
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING
// WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
// TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR
// NON-INFRINGEMENT.
// See the Apache 2 License for the specific language governing
// permissions and limitations under the License.
using System.Collections.Generic;
using Microsoft.AspNet.Server.Features;
namespace Microsoft.AspNet.Server.WebListener
{
internal class ServerAddressesFeature : IServerAddressesFeature
{
public ICollection<string> Addresses { get; } = new List<string>();
}
}

View File

@ -35,10 +35,12 @@
// limitations under the License. // limitations under the License.
using System; using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
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.Framework.Configuration; using Microsoft.Framework.Configuration;
using Microsoft.Framework.Logging; using Microsoft.Framework.Logging;
using Microsoft.Net.Http.Server; using Microsoft.Net.Http.Server;
@ -67,10 +69,10 @@ namespace Microsoft.AspNet.Server.WebListener
public IFeatureCollection Initialize(IConfiguration configuration) public IFeatureCollection Initialize(IConfiguration configuration)
{ {
Microsoft.Net.Http.Server.WebListener listener = new Microsoft.Net.Http.Server.WebListener(_loggerFactory); Microsoft.Net.Http.Server.WebListener listener = new Microsoft.Net.Http.Server.WebListener(_loggerFactory);
ParseAddresses(configuration, listener);
var serverFeatures = new FeatureCollection(); var serverFeatures = new FeatureCollection();
serverFeatures.Set(listener); serverFeatures.Set(listener);
serverFeatures.Set(new MessagePump(listener, _loggerFactory)); serverFeatures.Set(new MessagePump(listener, _loggerFactory));
serverFeatures.Set(SplitAddresses(configuration));
return serverFeatures; return serverFeatures;
} }
@ -96,22 +98,38 @@ namespace Microsoft.AspNet.Server.WebListener
throw new InvalidOperationException("messagePump"); throw new InvalidOperationException("messagePump");
} }
var addressesFeature = serverFeatures.Get<IServerAddressesFeature>();
if (addressesFeature == null)
{
throw new InvalidOperationException("IServerAddressesFeature");
}
ParseAddresses(addressesFeature.Addresses, messagePump.Listener);
messagePump.Start(app); messagePump.Start(app);
return messagePump; return messagePump;
} }
private void ParseAddresses(IConfiguration config, Microsoft.Net.Http.Server.WebListener listener) private IServerAddressesFeature SplitAddresses(IConfiguration config)
{ {
// TODO: Key format? var addressesFeature = new ServerAddressesFeature();
if (config != null && !string.IsNullOrEmpty(config["server.urls"])) if (config != null && !string.IsNullOrEmpty(config["server.urls"]))
{ {
var urls = config["server.urls"]; var urls = config["server.urls"];
foreach (var value in urls.Split(';')) foreach (var value in urls.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries))
{ {
listener.UrlPrefixes.Add(UrlPrefix.Create(value)); addressesFeature.Addresses.Add(value);
} }
} }
// TODO: look for just a port option? return addressesFeature;
}
private void ParseAddresses(ICollection<string> addresses, Microsoft.Net.Http.Server.WebListener listener)
{
foreach (var value in addresses)
{
listener.UrlPrefixes.Add(UrlPrefix.Create(value));
}
} }
} }
} }

View File

@ -122,6 +122,12 @@ namespace Microsoft.Net.Http.Server
int delimiterStart1 = whole.IndexOf("://", StringComparison.Ordinal); int delimiterStart1 = whole.IndexOf("://", StringComparison.Ordinal);
if (delimiterStart1 < 0) if (delimiterStart1 < 0)
{ {
int aPort;
if (int.TryParse(whole, NumberStyles.None, CultureInfo.InvariantCulture, out aPort))
{
return UrlPrefix.Create("http", "localhost", aPort, "/");
}
throw new FormatException("Invalid prefix, missing scheme separator: " + prefix); throw new FormatException("Invalid prefix, missing scheme separator: " + prefix);
} }
int delimiterEnd1 = delimiterStart1 + "://".Length; int delimiterEnd1 = delimiterStart1 + "://".Length;

View File

@ -18,6 +18,7 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNet.Http.Features; using Microsoft.AspNet.Http.Features;
using Microsoft.AspNet.Server.Features;
using Microsoft.Net.Http.Server; using Microsoft.Net.Http.Server;
namespace Microsoft.AspNet.Server.WebListener namespace Microsoft.AspNet.Server.WebListener
@ -88,7 +89,7 @@ namespace Microsoft.AspNet.Server.WebListener
{ {
var factory = new ServerFactory(loggerFactory: null); var factory = new ServerFactory(loggerFactory: null);
var serverFeatures = factory.Initialize(configuration: null); var serverFeatures = factory.Initialize(configuration: null);
serverFeatures.Get<Microsoft.Net.Http.Server.WebListener>().UrlPrefixes.Add(UrlPrefix.Create(scheme, host, port, path)); serverFeatures.Get<IServerAddressesFeature>().Addresses.Add(UrlPrefix.Create(scheme, host, port, path).ToString());
return factory.Start(serverFeatures, app); return factory.Start(serverFeatures, app);
} }
} }