From ce06872b84e73eabae3f97cb0847a367b03eec68 Mon Sep 17 00:00:00 2001 From: Chris R Date: Fri, 11 Sep 2015 14:00:58 -0700 Subject: [PATCH] Hosting#331 Add IServerAddressesFeature. --- samples/HotAddSample/Startup.cs | 11 +++---- .../ServerAddressesFeature.cs | 27 +++++++++++++++++ .../ServerFactory.cs | 30 +++++++++++++++---- src/Microsoft.Net.Http.Server/UrlPrefix.cs | 6 ++++ .../Utilities.cs | 3 +- 5 files changed, 65 insertions(+), 12 deletions(-) create mode 100644 src/Microsoft.AspNet.Server.WebListener/ServerAddressesFeature.cs diff --git a/samples/HotAddSample/Startup.cs b/samples/HotAddSample/Startup.cs index 9064491c5b..e5026e9db9 100644 --- a/samples/HotAddSample/Startup.cs +++ b/samples/HotAddSample/Startup.cs @@ -2,6 +2,7 @@ using Microsoft.AspNet.Builder; using Microsoft.AspNet.Http; using Microsoft.AspNet.Http.Features; +using Microsoft.AspNet.Server.Features; using Microsoft.Framework.Logging; namespace HotAddSample @@ -15,8 +16,8 @@ namespace HotAddSample { loggerfactory.AddConsole(LogLevel.Information); - var listener = app.ServerFeatures.Get(); - listener.UrlPrefixes.Add("http://localhost:12346/pathBase/"); + var addresses = app.ServerFeatures.Get().Addresses; + addresses.Add("http://localhost:12346/pathBase/"); app.Use(async (context, next) => { @@ -28,7 +29,7 @@ namespace HotAddSample await context.Response.WriteAsync(""); try { - listener.UrlPrefixes.Add(toAdd); + addresses.Add(toAdd); await context.Response.WriteAsync("Added: " + toAdd); } catch (Exception ex) @@ -52,7 +53,7 @@ namespace HotAddSample { context.Response.ContentType = "text/html"; await context.Response.WriteAsync(""); - if (listener.UrlPrefixes.Remove(toRemove)) + if (addresses.Remove(toRemove)) { await context.Response.WriteAsync("Removed: " + toRemove); } @@ -72,7 +73,7 @@ namespace HotAddSample context.Response.ContentType = "text/html"; await context.Response.WriteAsync(""); await context.Response.WriteAsync("Listening on these prefixes:
"); - foreach (var prefix in listener.UrlPrefixes) + foreach (var prefix in addresses) { await context.Response.WriteAsync("" + prefix + " (remove)
"); } diff --git a/src/Microsoft.AspNet.Server.WebListener/ServerAddressesFeature.cs b/src/Microsoft.AspNet.Server.WebListener/ServerAddressesFeature.cs new file mode 100644 index 0000000000..d617baa7ea --- /dev/null +++ b/src/Microsoft.AspNet.Server.WebListener/ServerAddressesFeature.cs @@ -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 Addresses { get; } = new List(); + } +} diff --git a/src/Microsoft.AspNet.Server.WebListener/ServerFactory.cs b/src/Microsoft.AspNet.Server.WebListener/ServerFactory.cs index accaf6372c..238c268df7 100644 --- a/src/Microsoft.AspNet.Server.WebListener/ServerFactory.cs +++ b/src/Microsoft.AspNet.Server.WebListener/ServerFactory.cs @@ -35,10 +35,12 @@ // limitations under the License. using System; +using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Threading.Tasks; using Microsoft.AspNet.Hosting.Server; using Microsoft.AspNet.Http.Features; +using Microsoft.AspNet.Server.Features; using Microsoft.Framework.Configuration; using Microsoft.Framework.Logging; using Microsoft.Net.Http.Server; @@ -67,10 +69,10 @@ namespace Microsoft.AspNet.Server.WebListener public IFeatureCollection Initialize(IConfiguration configuration) { Microsoft.Net.Http.Server.WebListener listener = new Microsoft.Net.Http.Server.WebListener(_loggerFactory); - ParseAddresses(configuration, listener); var serverFeatures = new FeatureCollection(); serverFeatures.Set(listener); serverFeatures.Set(new MessagePump(listener, _loggerFactory)); + serverFeatures.Set(SplitAddresses(configuration)); return serverFeatures; } @@ -96,22 +98,38 @@ namespace Microsoft.AspNet.Server.WebListener throw new InvalidOperationException("messagePump"); } + var addressesFeature = serverFeatures.Get(); + if (addressesFeature == null) + { + throw new InvalidOperationException("IServerAddressesFeature"); + } + + ParseAddresses(addressesFeature.Addresses, messagePump.Listener); + messagePump.Start(app); 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"])) { 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 addresses, Microsoft.Net.Http.Server.WebListener listener) + { + foreach (var value in addresses) + { + listener.UrlPrefixes.Add(UrlPrefix.Create(value)); + } } } } diff --git a/src/Microsoft.Net.Http.Server/UrlPrefix.cs b/src/Microsoft.Net.Http.Server/UrlPrefix.cs index 0c53cc67c9..34689b9eac 100644 --- a/src/Microsoft.Net.Http.Server/UrlPrefix.cs +++ b/src/Microsoft.Net.Http.Server/UrlPrefix.cs @@ -122,6 +122,12 @@ namespace Microsoft.Net.Http.Server int delimiterStart1 = whole.IndexOf("://", StringComparison.Ordinal); 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); } int delimiterEnd1 = delimiterStart1 + "://".Length; diff --git a/test/Microsoft.AspNet.Server.WebListener.FunctionalTests/Utilities.cs b/test/Microsoft.AspNet.Server.WebListener.FunctionalTests/Utilities.cs index e838ced3fb..899c18beea 100644 --- a/test/Microsoft.AspNet.Server.WebListener.FunctionalTests/Utilities.cs +++ b/test/Microsoft.AspNet.Server.WebListener.FunctionalTests/Utilities.cs @@ -18,6 +18,7 @@ using System; using System.Threading.Tasks; using Microsoft.AspNet.Http.Features; +using Microsoft.AspNet.Server.Features; using Microsoft.Net.Http.Server; namespace Microsoft.AspNet.Server.WebListener @@ -88,7 +89,7 @@ namespace Microsoft.AspNet.Server.WebListener { var factory = new ServerFactory(loggerFactory: null); var serverFeatures = factory.Initialize(configuration: null); - serverFeatures.Get().UrlPrefixes.Add(UrlPrefix.Create(scheme, host, port, path)); + serverFeatures.Get().Addresses.Add(UrlPrefix.Create(scheme, host, port, path).ToString()); return factory.Start(serverFeatures, app); } }