Merge branch 'release' into dev
This commit is contained in:
commit
9cb3345511
|
|
@ -3,7 +3,7 @@ using Microsoft.AspNetCore.Builder;
|
|||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.AspNetCore.Server.Features;
|
||||
using Microsoft.AspNetCore.Hosting.Server.Features;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Net.Http.Server;
|
||||
|
||||
|
|
@ -94,7 +94,7 @@ namespace HotAddSample
|
|||
var host = new WebHostBuilder()
|
||||
.UseDefaultHostingConfiguration(args)
|
||||
.UseStartup<Startup>()
|
||||
.UseServer("Microsoft.AspNetCore.Server.WebListener")
|
||||
.UseWebListener()
|
||||
.Build();
|
||||
|
||||
host.Run();
|
||||
|
|
|
|||
|
|
@ -15,9 +15,6 @@ namespace SelfHostServer
|
|||
{
|
||||
public void Configure(IApplicationBuilder app, ILoggerFactory loggerfactory)
|
||||
{
|
||||
var listener = app.ServerFeatures.Get<WebListener>();
|
||||
listener.AuthenticationManager.AuthenticationSchemes = AuthenticationSchemes.AllowAnonymous;
|
||||
|
||||
loggerfactory.AddConsole(LogLevel.Debug);
|
||||
|
||||
app.Run(async context =>
|
||||
|
|
@ -43,7 +40,10 @@ namespace SelfHostServer
|
|||
var host = new WebHostBuilder()
|
||||
.UseDefaultHostingConfiguration(args)
|
||||
.UseStartup<Startup>()
|
||||
.UseServer("Microsoft.AspNetCore.Server.WebListener")
|
||||
.UseWebListener(options =>
|
||||
{
|
||||
options.Listener.AuthenticationManager.AuthenticationSchemes = AuthenticationSchemes.AllowAnonymous;
|
||||
})
|
||||
.Build();
|
||||
|
||||
host.Run();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
// 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;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.WebListener.Internal
|
||||
{
|
||||
public class WebListenerOptionsSetup : IConfigureOptions<WebListenerOptions>
|
||||
{
|
||||
private ILoggerFactory _loggerFactory;
|
||||
|
||||
public WebListenerOptionsSetup(ILoggerFactory loggerFactory)
|
||||
{
|
||||
_loggerFactory = loggerFactory;
|
||||
}
|
||||
|
||||
public void Configure(WebListenerOptions options)
|
||||
{
|
||||
options.Listener = new Microsoft.Net.Http.Server.WebListener(_loggerFactory);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -21,14 +21,15 @@ using System.Diagnostics.Contracts;
|
|||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Hosting.Server;
|
||||
using Microsoft.AspNetCore.Hosting.Server.Features;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.AspNetCore.Server.Features;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Microsoft.Net.Http.Server;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.WebListener
|
||||
{
|
||||
internal class MessagePump : IServer
|
||||
public class MessagePump : IServer
|
||||
{
|
||||
private static readonly int DefaultMaxAccepts = 5 * Environment.ProcessorCount;
|
||||
|
||||
|
|
@ -44,25 +45,32 @@ namespace Microsoft.AspNetCore.Server.WebListener
|
|||
private bool _stopping;
|
||||
private int _outstandingRequests;
|
||||
private ManualResetEvent _shutdownSignal;
|
||||
|
||||
internal MessagePump(Microsoft.Net.Http.Server.WebListener listener, ILoggerFactory loggerFactory, IFeatureCollection features)
|
||||
|
||||
private readonly ServerAddressesFeature _serverAddresses;
|
||||
|
||||
public MessagePump(IOptions<WebListenerOptions> options, ILoggerFactory loggerFactory)
|
||||
{
|
||||
if (features == null)
|
||||
if (options == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(features));
|
||||
throw new ArgumentNullException(nameof(options));
|
||||
}
|
||||
if (loggerFactory == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(loggerFactory));
|
||||
}
|
||||
|
||||
Contract.Assert(listener != null);
|
||||
_listener = listener;
|
||||
_listener = options.Value?.Listener ?? new Microsoft.Net.Http.Server.WebListener(loggerFactory);
|
||||
_logger = LogHelper.CreateLogger(loggerFactory, typeof(MessagePump));
|
||||
Features = features;
|
||||
Features = new FeatureCollection();
|
||||
_serverAddresses = new ServerAddressesFeature();
|
||||
Features.Set<IServerAddressesFeature>(_serverAddresses);
|
||||
|
||||
_processRequest = new Action<object>(ProcessRequestAsync);
|
||||
_maxAccepts = DefaultMaxAccepts;
|
||||
_shutdownSignal = new ManualResetEvent(false);
|
||||
}
|
||||
|
||||
internal Microsoft.Net.Http.Server.WebListener Listener
|
||||
public Microsoft.Net.Http.Server.WebListener Listener
|
||||
{
|
||||
get { return _listener; }
|
||||
}
|
||||
|
|
@ -94,13 +102,7 @@ namespace Microsoft.AspNetCore.Server.WebListener
|
|||
throw new ArgumentNullException(nameof(application));
|
||||
}
|
||||
|
||||
var addressesFeature = Features.Get<IServerAddressesFeature>();
|
||||
if (addressesFeature == null)
|
||||
{
|
||||
throw new InvalidOperationException($"{nameof(IServerAddressesFeature)} is missing.");
|
||||
}
|
||||
|
||||
ParseAddresses(addressesFeature.Addresses, Listener);
|
||||
ParseAddresses(_serverAddresses.Addresses, Listener);
|
||||
|
||||
// Can't call Start twice
|
||||
Contract.Assert(_application == null);
|
||||
|
|
|
|||
|
|
@ -1,89 +0,0 @@
|
|||
// 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.
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// <copyright file="ServerFactory.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
// Copyright 2011-2012 Katana contributors
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Microsoft.AspNetCore.Hosting.Server;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.AspNetCore.Server.Features;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.WebListener
|
||||
{
|
||||
/// <summary>
|
||||
/// Implements the setup process for this server.
|
||||
/// </summary>
|
||||
public class ServerFactory : IServerFactory
|
||||
{
|
||||
private ILoggerFactory _loggerFactory;
|
||||
|
||||
public ServerFactory(ILoggerFactory loggerFactory)
|
||||
{
|
||||
_loggerFactory = loggerFactory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a configurable instance of the server.
|
||||
/// </summary>
|
||||
/// <param name="configuration"></param>
|
||||
/// <returns>The server. Invoke Dispose to shut down.</returns>
|
||||
[SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "Disposed by caller")]
|
||||
public IServer CreateServer(IConfiguration configuration)
|
||||
{
|
||||
Microsoft.Net.Http.Server.WebListener listener = new Microsoft.Net.Http.Server.WebListener(_loggerFactory);
|
||||
var serverFeatures = new FeatureCollection();
|
||||
serverFeatures.Set(listener);
|
||||
serverFeatures.Set(SplitAddresses(configuration));
|
||||
|
||||
return new MessagePump(listener, _loggerFactory, serverFeatures);
|
||||
}
|
||||
|
||||
private IServerAddressesFeature SplitAddresses(IConfiguration config)
|
||||
{
|
||||
var addressesFeature = new ServerAddressesFeature();
|
||||
if (config != null && !string.IsNullOrEmpty(config["server.urls"]))
|
||||
{
|
||||
var urls = config["server.urls"];
|
||||
foreach (var value in urls.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries))
|
||||
{
|
||||
addressesFeature.Addresses.Add(value);
|
||||
}
|
||||
}
|
||||
return addressesFeature;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
// 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;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Hosting.Server;
|
||||
using Microsoft.AspNetCore.Server.WebListener;
|
||||
using Microsoft.AspNetCore.Server.WebListener.Internal;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Microsoft.AspNetCore.Hosting
|
||||
{
|
||||
public static class WebHostBuilderWebListenerExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Specify WebListener as the server to be used by the web host.
|
||||
/// </summary>
|
||||
/// <param name="hostBuilder">
|
||||
/// The Microsoft.AspNetCore.Hosting.IWebHostBuilder to configure.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The Microsoft.AspNetCore.Hosting.IWebHostBuilder.
|
||||
/// </returns>
|
||||
public static IWebHostBuilder UseWebListener(this IWebHostBuilder hostBuilder)
|
||||
{
|
||||
return hostBuilder.ConfigureServices(services => services.AddSingleton<IServer, MessagePump>());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specify WebListener as the server to be used by the web host.
|
||||
/// </summary>
|
||||
/// <param name="hostBuilder">
|
||||
/// The Microsoft.AspNetCore.Hosting.IWebHostBuilder to configure.
|
||||
/// </param>
|
||||
/// <param name="options">
|
||||
/// A callback to configure WebListener options.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The Microsoft.AspNetCore.Hosting.IWebHostBuilder.
|
||||
/// </returns>
|
||||
public static IWebHostBuilder UseWebListener(this IWebHostBuilder hostBuilder, Action<WebListenerOptions> options)
|
||||
{
|
||||
hostBuilder.ConfigureServices(services =>
|
||||
{
|
||||
services.AddTransient<IConfigureOptions<WebListenerOptions>, WebListenerOptionsSetup>();
|
||||
services.Configure(options);
|
||||
});
|
||||
|
||||
return hostBuilder.UseWebListener();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// Copyright (c) Microsoft Open Technologies, Inc.
|
||||
// All Rights Reserved
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
|
|
@ -15,13 +15,15 @@
|
|||
// See the Apache 2 License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Server.Features;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.WebListener
|
||||
{
|
||||
internal class ServerAddressesFeature : IServerAddressesFeature
|
||||
public class WebListenerOptions
|
||||
{
|
||||
public ICollection<string> Addresses { get; } = new List<string>();
|
||||
public Microsoft.Net.Http.Server.WebListener Listener { get; set; } = new Microsoft.Net.Http.Server.WebListener();
|
||||
}
|
||||
}
|
||||
|
|
@ -24,6 +24,8 @@ using System.Threading.Tasks;
|
|||
using Microsoft.AspNetCore.Hosting.Server;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Microsoft.Net.Http.Server;
|
||||
using Xunit;
|
||||
|
||||
|
|
@ -187,13 +189,11 @@ namespace Microsoft.AspNetCore.Server.WebListener
|
|||
var dynamicServer = Utilities.CreateHttpServerReturnRoot("/", out root, app);
|
||||
dynamicServer.Dispose();
|
||||
var rootUri = new Uri(root);
|
||||
var factory = new ServerFactory(loggerFactory: null);
|
||||
var server = factory.CreateServer(configuration: null);
|
||||
var listener = server.Features.Get<Microsoft.Net.Http.Server.WebListener>();
|
||||
var server = new MessagePump(Options.Create(new WebListenerOptions()), new LoggerFactory());
|
||||
|
||||
foreach (string path in new[] { "/", "/11", "/2/3", "/2", "/11/2" })
|
||||
{
|
||||
listener.UrlPrefixes.Add(UrlPrefix.Create(rootUri.Scheme, rootUri.Host, rootUri.Port, path));
|
||||
server.Listener.UrlPrefixes.Add(UrlPrefix.Create(rootUri.Scheme, rootUri.Host, rootUri.Port, path));
|
||||
}
|
||||
|
||||
server.Start(new DummyApplication(app));
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@ using System.Threading;
|
|||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Microsoft.Net.Http.Server;
|
||||
using Xunit;
|
||||
|
||||
|
|
@ -253,11 +255,9 @@ namespace Microsoft.AspNetCore.Server.WebListener
|
|||
string address;
|
||||
using (Utilities.CreateHttpServer(out address, httpContext => Task.FromResult(0))) { }
|
||||
|
||||
var factory = new ServerFactory(loggerFactory: null);
|
||||
var server = factory.CreateServer(configuration: null);
|
||||
var listener = server.Features.Get<Microsoft.Net.Http.Server.WebListener>();
|
||||
listener.UrlPrefixes.Add(UrlPrefix.Create(address));
|
||||
listener.SetRequestQueueLimit(1001);
|
||||
var server = new MessagePump(Options.Create(new WebListenerOptions()), new LoggerFactory());
|
||||
server.Listener.UrlPrefixes.Add(UrlPrefix.Create(address));
|
||||
server.Listener.SetRequestQueueLimit(1001);
|
||||
|
||||
using (server)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -17,8 +17,10 @@
|
|||
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Hosting.Server;
|
||||
using Microsoft.AspNetCore.Hosting.Server.Features;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Server.Features;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Microsoft.Net.Http.Server;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.WebListener
|
||||
|
|
@ -53,7 +55,6 @@ namespace Microsoft.AspNetCore.Server.WebListener
|
|||
|
||||
internal static IServer CreateDynamicHttpServer(string basePath, AuthenticationSchemes authType, out string root, out string baseAddress, RequestDelegate app)
|
||||
{
|
||||
var factory = new ServerFactory(loggerFactory: null);
|
||||
lock (PortLock)
|
||||
{
|
||||
while (NextPort < MaxPort)
|
||||
|
|
@ -64,10 +65,9 @@ namespace Microsoft.AspNetCore.Server.WebListener
|
|||
root = prefix.Scheme + "://" + prefix.Host + ":" + prefix.Port;
|
||||
baseAddress = prefix.ToString();
|
||||
|
||||
var server = factory.CreateServer(configuration: null);
|
||||
var listener = server.Features.Get<Microsoft.Net.Http.Server.WebListener>();
|
||||
listener.UrlPrefixes.Add(prefix);
|
||||
listener.AuthenticationManager.AuthenticationSchemes = authType;
|
||||
var server = new MessagePump(Options.Create(new WebListenerOptions()), new LoggerFactory());
|
||||
server.Features.Get<IServerAddressesFeature>().Addresses.Add(baseAddress);
|
||||
server.Listener.AuthenticationManager.AuthenticationSchemes = authType;
|
||||
try
|
||||
{
|
||||
server.Start(new DummyApplication(app));
|
||||
|
|
@ -89,8 +89,7 @@ namespace Microsoft.AspNetCore.Server.WebListener
|
|||
|
||||
internal static IServer CreateServer(string scheme, string host, int port, string path, RequestDelegate app)
|
||||
{
|
||||
var factory = new ServerFactory(loggerFactory: null);
|
||||
var server = factory.CreateServer(configuration: null);
|
||||
var server = new MessagePump(Options.Create(new WebListenerOptions()), new LoggerFactory());
|
||||
server.Features.Get<IServerAddressesFeature>().Addresses.Add(UrlPrefix.Create(scheme, host, port, path).ToString());
|
||||
server.Start(new DummyApplication(app));
|
||||
return server;
|
||||
|
|
|
|||
Loading…
Reference in New Issue