Rename Prefix to UrlPrefix. Seperate IServerInformation to its own implementation.
This commit is contained in:
parent
eb27892470
commit
546af5ddee
|
|
@ -70,7 +70,7 @@ namespace Microsoft.AspNet.Server.WebListener
|
|||
|
||||
private object _internalLock;
|
||||
|
||||
private List<Prefix> _uriPrefixes = new List<Prefix>();
|
||||
private List<UrlPrefix> _urlPrefixes = new List<UrlPrefix>();
|
||||
|
||||
// The native request queue
|
||||
private long? _requestQueueLength;
|
||||
|
|
@ -105,9 +105,9 @@ namespace Microsoft.AspNet.Server.WebListener
|
|||
get { return _logger; }
|
||||
}
|
||||
|
||||
public List<Prefix> UriPrefixes
|
||||
public List<UrlPrefix> UrlPrefixes
|
||||
{
|
||||
get { return _uriPrefixes; }
|
||||
get { return _urlPrefixes; }
|
||||
}
|
||||
|
||||
internal SafeHandle RequestQueueHandle
|
||||
|
|
@ -247,12 +247,12 @@ namespace Microsoft.AspNet.Server.WebListener
|
|||
{
|
||||
CheckDisposed();
|
||||
// go through the uri list and unregister for each one of them
|
||||
if (_uriPrefixes.Count > 0)
|
||||
if (_urlPrefixes.Count > 0)
|
||||
{
|
||||
LogHelper.LogInfo(_logger, "RemoveAll");
|
||||
if (_state == State.Started)
|
||||
{
|
||||
foreach (Prefix registeredPrefix in _uriPrefixes)
|
||||
foreach (UrlPrefix registeredPrefix in _urlPrefixes)
|
||||
{
|
||||
// ignore possible failures
|
||||
InternalRemovePrefix(registeredPrefix.Whole);
|
||||
|
|
@ -261,7 +261,7 @@ namespace Microsoft.AspNet.Server.WebListener
|
|||
|
||||
if (clear)
|
||||
{
|
||||
_uriPrefixes.Clear();
|
||||
_urlPrefixes.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -605,12 +605,12 @@ namespace Microsoft.AspNet.Server.WebListener
|
|||
private void AddAllPrefixes()
|
||||
{
|
||||
// go through the uri list and register for each one of them
|
||||
if (_uriPrefixes.Count > 0)
|
||||
if (_urlPrefixes.Count > 0)
|
||||
{
|
||||
for (int i = 0; i < _uriPrefixes.Count; i++)
|
||||
for (int i = 0; i < _urlPrefixes.Count; i++)
|
||||
{
|
||||
// We'll get this index back on each request and use it to look up the prefix to calculate PathBase.
|
||||
Prefix registeredPrefix = _uriPrefixes[i];
|
||||
UrlPrefix registeredPrefix = _urlPrefixes[i];
|
||||
uint statusCode = InternalAddPrefix(registeredPrefix.Whole, i);
|
||||
if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,28 +0,0 @@
|
|||
// <copyright file="PumpLimits.cs" company="Katana contributors">
|
||||
// Copyright 2011-2012 Katana contributors
|
||||
// </copyright>
|
||||
//
|
||||
// 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.
|
||||
|
||||
namespace Microsoft.AspNet.Server.WebListener
|
||||
{
|
||||
internal struct PumpLimits
|
||||
{
|
||||
internal PumpLimits(int maxAccepts)
|
||||
{
|
||||
MaxOutstandingAccepts = maxAccepts;
|
||||
}
|
||||
|
||||
internal readonly int MaxOutstandingAccepts;
|
||||
}
|
||||
}
|
||||
|
|
@ -90,7 +90,7 @@ namespace Microsoft.AspNet.Server.WebListener
|
|||
_cookedUrlQuery = Marshal.PtrToStringUni((IntPtr)cookedUrl.pQueryString, cookedUrl.QueryStringLength / 2);
|
||||
}
|
||||
|
||||
Prefix prefix = httpContext.Server.UriPrefixes[(int)_contextId];
|
||||
UrlPrefix prefix = httpContext.Server.UrlPrefixes[(int)_contextId];
|
||||
string orriginalPath = RequestPath;
|
||||
|
||||
// These paths are both unescaped already.
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ namespace Microsoft.AspNet.Server.WebListener
|
|||
{
|
||||
OwinWebListener listener = new OwinWebListener();
|
||||
ParseAddresses(configuration, listener);
|
||||
return new WebListenerWrapper(listener, _loggerFactory);
|
||||
return new ServerInformation(new WebListenerWrapper(listener, _loggerFactory));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -70,16 +70,16 @@ namespace Microsoft.AspNet.Server.WebListener
|
|||
throw new ArgumentNullException("app");
|
||||
}
|
||||
|
||||
WebListenerWrapper wrapper = server as WebListenerWrapper;
|
||||
if (wrapper == null)
|
||||
var serverInfo = server as ServerInformation;
|
||||
if (serverInfo == null)
|
||||
{
|
||||
throw new ArgumentException("server");
|
||||
}
|
||||
|
||||
// TODO: var capabilities = new Dictionary<string, object>();
|
||||
|
||||
wrapper.Start(app);
|
||||
return wrapper;
|
||||
serverInfo.Wrapper.Start(app);
|
||||
return serverInfo.Wrapper;
|
||||
}
|
||||
|
||||
private void ParseAddresses(IConfiguration config, OwinWebListener listener)
|
||||
|
|
@ -90,7 +90,7 @@ namespace Microsoft.AspNet.Server.WebListener
|
|||
{
|
||||
foreach (var value in urls.Split(';'))
|
||||
{
|
||||
listener.UriPrefixes.Add(Prefix.Create(value));
|
||||
listener.UrlPrefixes.Add(UrlPrefix.Create(value));
|
||||
}
|
||||
}
|
||||
// TODO: look for just a port option?
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
using System.Reflection;
|
||||
using Microsoft.AspNet.Abstractions;
|
||||
|
||||
namespace Microsoft.AspNet.Server.WebListener
|
||||
{
|
||||
public class ServerInformation : IServerInformation
|
||||
{
|
||||
private WebListenerWrapper _webListenerWrapper;
|
||||
|
||||
internal ServerInformation(WebListenerWrapper webListenerWrapper)
|
||||
{
|
||||
_webListenerWrapper = webListenerWrapper;
|
||||
}
|
||||
|
||||
internal WebListenerWrapper Wrapper
|
||||
{
|
||||
get { return _webListenerWrapper; }
|
||||
}
|
||||
|
||||
// Microsoft.AspNet.Server.WebListener
|
||||
public string Name
|
||||
{
|
||||
get { return GetType().GetTypeInfo().Assembly.GetName().Name; }
|
||||
}
|
||||
|
||||
public OwinWebListener Listener
|
||||
{
|
||||
get { return _webListenerWrapper.Listener; }
|
||||
}
|
||||
|
||||
public int MaxAccepts
|
||||
{
|
||||
get { return _webListenerWrapper.MaxAccepts; }
|
||||
set { _webListenerWrapper.MaxAccepts = value; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <copyright file="HttpListener.cs" company="Microsoft">
|
||||
// <copyright file="UrlPrefix.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//------------------------------------------------------------------------------
|
||||
|
|
@ -9,9 +9,9 @@ using System.Globalization;
|
|||
|
||||
namespace Microsoft.AspNet.Server.WebListener
|
||||
{
|
||||
public class Prefix
|
||||
public class UrlPrefix
|
||||
{
|
||||
private Prefix(bool isHttps, string scheme, string host, string port, int portValue, string path)
|
||||
private UrlPrefix(bool isHttps, string scheme, string host, string port, int portValue, string path)
|
||||
{
|
||||
IsHttps = isHttps;
|
||||
Scheme = scheme;
|
||||
|
|
@ -29,7 +29,7 @@ namespace Microsoft.AspNet.Server.WebListener
|
|||
/// <param name="host">+, *, IPv4, [IPv6], or a dns name. Http.Sys does not permit punycode (xn--), use Unicode instead.</param>
|
||||
/// <param name="port">If empty, the default port for the given scheme will be used (80 or 443).</param>
|
||||
/// <param name="path">Should start and end with a '/', though a missing trailing slash will be added. This value must be un-escaped.</param>
|
||||
public static Prefix Create(string scheme, string host, string port, string path)
|
||||
public static UrlPrefix Create(string scheme, string host, string port, string path)
|
||||
{
|
||||
bool isHttps;
|
||||
if (string.Equals(Constants.HttpScheme, scheme, StringComparison.OrdinalIgnoreCase))
|
||||
|
|
@ -73,10 +73,10 @@ namespace Microsoft.AspNet.Server.WebListener
|
|||
path += "/";
|
||||
}
|
||||
|
||||
return new Prefix(isHttps, scheme, host, port, portValue, path);
|
||||
return new UrlPrefix(isHttps, scheme, host, port, portValue, path);
|
||||
}
|
||||
|
||||
public static Prefix Create(string prefix)
|
||||
public static UrlPrefix Create(string prefix)
|
||||
{
|
||||
string scheme = null;
|
||||
string host = null;
|
||||
|
|
@ -118,7 +118,7 @@ namespace Microsoft.AspNet.Server.WebListener
|
|||
}
|
||||
path = whole.Substring(delimiterStart3);
|
||||
|
||||
return Prefix.Create(scheme, host, port, path);
|
||||
return UrlPrefix.Create(scheme, host, port, path);
|
||||
}
|
||||
|
||||
public bool IsHttps { get; private set; }
|
||||
|
|
@ -1,18 +1,14 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Abstractions;
|
||||
using Microsoft.AspNet.Logging;
|
||||
|
||||
namespace Microsoft.AspNet.Server.WebListener
|
||||
{
|
||||
using AppFunc = Func<object, Task>;
|
||||
|
||||
public class WebListenerWrapper : IServerInformation, IDisposable
|
||||
internal class WebListenerWrapper : IDisposable
|
||||
{
|
||||
private static readonly int DefaultMaxAccepts = 5 * Environment.ProcessorCount;
|
||||
|
||||
|
|
@ -21,7 +17,7 @@ namespace Microsoft.AspNet.Server.WebListener
|
|||
|
||||
private AppFunc _appFunc;
|
||||
|
||||
private PumpLimits _pumpLimits;
|
||||
private int _maxAccepts;
|
||||
private int _acceptorCounts;
|
||||
private Action<object> _processRequest;
|
||||
|
||||
|
|
@ -34,18 +30,28 @@ namespace Microsoft.AspNet.Server.WebListener
|
|||
_logger = LogHelper.CreateLogger(loggerFactory, typeof(WebListenerWrapper));
|
||||
|
||||
_processRequest = new Action<object>(ProcessRequestAsync);
|
||||
_pumpLimits = new PumpLimits(DefaultMaxAccepts);
|
||||
_maxAccepts = DefaultMaxAccepts;
|
||||
}
|
||||
|
||||
public OwinWebListener Listener
|
||||
internal OwinWebListener Listener
|
||||
{
|
||||
get { return _listener; }
|
||||
}
|
||||
|
||||
// Microsoft.AspNet.Server.WebListener
|
||||
public string Name
|
||||
internal int MaxAccepts
|
||||
{
|
||||
get { return GetType().GetTypeInfo().Assembly.GetName().Name; }
|
||||
get
|
||||
{
|
||||
return _maxAccepts;
|
||||
}
|
||||
set
|
||||
{
|
||||
_maxAccepts = value;
|
||||
if (_listener.IsListening)
|
||||
{
|
||||
ActivateRequestProcessingLimits();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void Start(AppFunc app)
|
||||
|
|
@ -57,7 +63,7 @@ namespace Microsoft.AspNet.Server.WebListener
|
|||
|
||||
_appFunc = app;
|
||||
|
||||
if (_listener.UriPrefixes.Count == 0)
|
||||
if (_listener.UrlPrefixes.Count == 0)
|
||||
{
|
||||
throw new InvalidOperationException("No address prefixes were defined.");
|
||||
}
|
||||
|
|
@ -69,40 +75,14 @@ namespace Microsoft.AspNet.Server.WebListener
|
|||
ActivateRequestProcessingLimits();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// These are merged as one operation because they should be swapped out atomically.
|
||||
/// This controls how many requests the server attempts to process concurrently.
|
||||
/// </summary>
|
||||
/// <param name="maxAccepts">The maximum number of pending accepts.</param>
|
||||
public void SetRequestProcessingLimits(int maxAccepts)
|
||||
{
|
||||
_pumpLimits = new PumpLimits(maxAccepts);
|
||||
|
||||
if (_listener.IsListening)
|
||||
{
|
||||
ActivateRequestProcessingLimits();
|
||||
}
|
||||
}
|
||||
|
||||
private void ActivateRequestProcessingLimits()
|
||||
{
|
||||
for (int i = _acceptorCounts; i < _pumpLimits.MaxOutstandingAccepts; i++)
|
||||
for (int i = _acceptorCounts; i < MaxAccepts; i++)
|
||||
{
|
||||
ProcessRequestsWorker();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the request processing limits.
|
||||
/// </summary>
|
||||
/// <param name="maxAccepts">The maximum number of pending accepts.</param>
|
||||
[SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "0#", Justification = "By design")]
|
||||
public void GetRequestProcessingLimits(out int maxAccepts)
|
||||
{
|
||||
PumpLimits limits = _pumpLimits;
|
||||
maxAccepts = limits.MaxOutstandingAccepts;
|
||||
}
|
||||
|
||||
// The message pump.
|
||||
// When we start listening for the next request on one thread, we may need to be sure that the
|
||||
// completion continues on another thread as to not block the current request processing.
|
||||
|
|
@ -110,7 +90,7 @@ namespace Microsoft.AspNet.Server.WebListener
|
|||
private async void ProcessRequestsWorker()
|
||||
{
|
||||
int workerIndex = Interlocked.Increment(ref _acceptorCounts);
|
||||
while (_listener.IsListening && workerIndex <= _pumpLimits.MaxOutstandingAccepts)
|
||||
while (_listener.IsListening && workerIndex <= MaxAccepts)
|
||||
{
|
||||
// Receive a request
|
||||
RequestContext requestContext;
|
||||
|
|
|
|||
|
|
@ -150,15 +150,15 @@ namespace Microsoft.AspNet.Server.WebListener.Test
|
|||
|
||||
private IDisposable CreateServer(AppFunc app)
|
||||
{
|
||||
var factory = new ServerFactory(null);
|
||||
var wrapper = (WebListenerWrapper)factory.Initialize(null);
|
||||
var factory = new ServerFactory(loggerFactory: null);
|
||||
var serverInfo = (ServerInformation)factory.Initialize(configuration: null);
|
||||
|
||||
foreach (string path in new[] { "/", "/11", "/2/3", "/2", "/11/2" })
|
||||
{
|
||||
wrapper.Listener.UriPrefixes.Add(Prefix.Create("http", "localhost", "8080", path));
|
||||
serverInfo.Listener.UrlPrefixes.Add(UrlPrefix.Create("http", "localhost", "8080", path));
|
||||
}
|
||||
|
||||
return factory.Start(wrapper, app);
|
||||
return factory.Start(serverInfo, app);
|
||||
}
|
||||
|
||||
private async Task<string> SendRequestAsync(string uri)
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ namespace Microsoft.AspNet.Server.WebListener.Test
|
|||
requestTasks.Add(requestTask);
|
||||
}
|
||||
|
||||
bool success = Task.WaitAll(requestTasks.ToArray(), TimeSpan.FromSeconds(5));
|
||||
bool success = Task.WaitAll(requestTasks.ToArray(), TimeSpan.FromSeconds(10));
|
||||
if (!success)
|
||||
{
|
||||
Console.WriteLine();
|
||||
|
|
@ -191,13 +191,13 @@ namespace Microsoft.AspNet.Server.WebListener.Test
|
|||
[Fact]
|
||||
public async Task Server_SetQueueLimit_Success()
|
||||
{
|
||||
var factory = new ServerFactory(null);
|
||||
var wrapper = (WebListenerWrapper)factory.Initialize(null);
|
||||
wrapper.Listener.UriPrefixes.Add(Prefix.Create("http://localhost:8080"));
|
||||
var factory = new ServerFactory(loggerFactory: null);
|
||||
var serverInfo = (ServerInformation)factory.Initialize(configuration: null);
|
||||
serverInfo.Listener.UrlPrefixes.Add(UrlPrefix.Create("http://localhost:8080"));
|
||||
|
||||
wrapper.Listener.SetRequestQueueLimit(1001);
|
||||
serverInfo.Listener.SetRequestQueueLimit(1001);
|
||||
|
||||
using (factory.Start(wrapper, env => Task.FromResult(0)))
|
||||
using (factory.Start(serverInfo, env => Task.FromResult(0)))
|
||||
{
|
||||
string response = await SendRequestAsync(Address);
|
||||
Assert.Equal(string.Empty, response);
|
||||
|
|
|
|||
|
|
@ -32,12 +32,12 @@ namespace Microsoft.AspNet.Server.WebListener.Test
|
|||
|
||||
internal static IDisposable CreateServer(string scheme, string host, string port, string path, AuthenticationType authType, AppFunc app)
|
||||
{
|
||||
ServerFactory factory = new ServerFactory(null);
|
||||
WebListenerWrapper wrapper = (WebListenerWrapper)factory.Initialize(null);
|
||||
wrapper.Listener.UriPrefixes.Add(Prefix.Create(scheme, host, port, path));
|
||||
wrapper.Listener.AuthenticationManager.AuthenticationTypes = authType;
|
||||
var factory = new ServerFactory(loggerFactory: null);
|
||||
var serverInfo = (ServerInformation)factory.Initialize(configuration: null);
|
||||
serverInfo.Listener.UrlPrefixes.Add(UrlPrefix.Create(scheme, host, port, path));
|
||||
serverInfo.Listener.AuthenticationManager.AuthenticationTypes = authType;
|
||||
|
||||
return factory.Start(wrapper, app);
|
||||
return factory.Start(serverInfo, app);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue