Reacting to new IServer IHttpApplication design
This commit is contained in:
parent
82c855d172
commit
8712ba4855
|
|
@ -21,7 +21,6 @@ using System.Diagnostics.Contracts;
|
|||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Hosting.Server;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.Http.Features;
|
||||
using Microsoft.AspNet.Server.Features;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
|
@ -35,9 +34,8 @@ namespace Microsoft.AspNet.Server.WebListener
|
|||
|
||||
private readonly Microsoft.Net.Http.Server.WebListener _listener;
|
||||
private readonly ILogger _logger;
|
||||
private readonly IHttpContextFactory _httpContextFactory;
|
||||
|
||||
private RequestDelegate _appFunc;
|
||||
private IHttpApplication<object> _application;
|
||||
|
||||
private int _maxAccepts;
|
||||
private int _acceptorCounts;
|
||||
|
|
@ -47,17 +45,16 @@ namespace Microsoft.AspNet.Server.WebListener
|
|||
private int _outstandingRequests;
|
||||
private ManualResetEvent _shutdownSignal;
|
||||
|
||||
internal MessagePump(Microsoft.Net.Http.Server.WebListener listener, ILoggerFactory loggerFactory, IFeatureCollection features, IHttpContextFactory httpContextFactory)
|
||||
internal MessagePump(Microsoft.Net.Http.Server.WebListener listener, ILoggerFactory loggerFactory, IFeatureCollection features)
|
||||
{
|
||||
if (features == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(Features));
|
||||
throw new ArgumentNullException(nameof(features));
|
||||
}
|
||||
|
||||
Contract.Assert(listener != null);
|
||||
_listener = listener;
|
||||
_logger = LogHelper.CreateLogger(loggerFactory, typeof(MessagePump));
|
||||
_httpContextFactory = httpContextFactory;
|
||||
Features = features;
|
||||
|
||||
_processRequest = new Action<object>(ProcessRequestAsync);
|
||||
|
|
@ -90,11 +87,11 @@ namespace Microsoft.AspNet.Server.WebListener
|
|||
|
||||
public IFeatureCollection Features { get; }
|
||||
|
||||
public void Start(RequestDelegate app)
|
||||
public void Start<TContext>(IHttpApplication<TContext> application)
|
||||
{
|
||||
if (app == null)
|
||||
if (application == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(app));
|
||||
throw new ArgumentNullException(nameof(application));
|
||||
}
|
||||
|
||||
var addressesFeature = Features.Get<IServerAddressesFeature>();
|
||||
|
|
@ -106,11 +103,11 @@ namespace Microsoft.AspNet.Server.WebListener
|
|||
ParseAddresses(addressesFeature.Addresses, Listener);
|
||||
|
||||
// Can't call Start twice
|
||||
Contract.Assert(_appFunc == null);
|
||||
Contract.Assert(_application == null);
|
||||
|
||||
Contract.Assert(app != null);
|
||||
Contract.Assert(application != null);
|
||||
|
||||
_appFunc = app;
|
||||
_application = new ApplicationWrapper<TContext>(application);
|
||||
|
||||
if (_listener.UrlPrefixes.Count == 0)
|
||||
{
|
||||
|
|
@ -183,14 +180,15 @@ namespace Microsoft.AspNet.Server.WebListener
|
|||
return;
|
||||
}
|
||||
|
||||
HttpContext httpContext = null;
|
||||
object context = null;
|
||||
try
|
||||
{
|
||||
Interlocked.Increment(ref _outstandingRequests);
|
||||
FeatureContext featureContext = new FeatureContext(requestContext, EnableResponseCaching);
|
||||
httpContext = _httpContextFactory.Create(featureContext.Features);
|
||||
await _appFunc(httpContext).SupressContext();
|
||||
context = _application.CreateContext(featureContext.Features);
|
||||
await _application.ProcessRequestAsync(context).SupressContext();
|
||||
requestContext.Dispose();
|
||||
_application.DisposeContext(context, null);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
@ -205,13 +203,10 @@ namespace Microsoft.AspNet.Server.WebListener
|
|||
requestContext.Response.Reset();
|
||||
SetFatalResponse(requestContext, 500);
|
||||
}
|
||||
_application.DisposeContext(context, ex);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (httpContext != null)
|
||||
{
|
||||
_httpContextFactory.Dispose(httpContext);
|
||||
}
|
||||
if (Interlocked.Decrement(ref _outstandingRequests) == 0 && _stopping)
|
||||
{
|
||||
_shutdownSignal.Set();
|
||||
|
|
@ -253,5 +248,30 @@ namespace Microsoft.AspNet.Server.WebListener
|
|||
// All requests are finished
|
||||
_listener.Dispose();
|
||||
}
|
||||
|
||||
private class ApplicationWrapper<TContext> : IHttpApplication<object>
|
||||
{
|
||||
private readonly IHttpApplication<TContext> _application;
|
||||
|
||||
public ApplicationWrapper(IHttpApplication<TContext> application)
|
||||
{
|
||||
_application = application;
|
||||
}
|
||||
|
||||
public object CreateContext(IFeatureCollection contextFeatures)
|
||||
{
|
||||
return _application.CreateContext(contextFeatures);
|
||||
}
|
||||
|
||||
public void DisposeContext(object context, Exception exception)
|
||||
{
|
||||
_application.DisposeContext((TContext)context, exception);
|
||||
}
|
||||
|
||||
public Task ProcessRequestAsync(object context)
|
||||
{
|
||||
return _application.ProcessRequestAsync((TContext)context);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,6 @@
|
|||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Microsoft.AspNet.Hosting.Server;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.Http.Features;
|
||||
using Microsoft.AspNet.Server.Features;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
|
@ -51,12 +50,10 @@ namespace Microsoft.AspNet.Server.WebListener
|
|||
public class ServerFactory : IServerFactory
|
||||
{
|
||||
private ILoggerFactory _loggerFactory;
|
||||
private IHttpContextFactory _httpContextFactory;
|
||||
|
||||
public ServerFactory(ILoggerFactory loggerFactory, IHttpContextFactory httpContextFactory)
|
||||
public ServerFactory(ILoggerFactory loggerFactory)
|
||||
{
|
||||
_loggerFactory = loggerFactory;
|
||||
_httpContextFactory = httpContextFactory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -72,7 +69,7 @@ namespace Microsoft.AspNet.Server.WebListener
|
|||
serverFeatures.Set(listener);
|
||||
serverFeatures.Set(SplitAddresses(configuration));
|
||||
|
||||
return new MessagePump(listener, _loggerFactory, serverFeatures, _httpContextFactory);
|
||||
return new MessagePump(listener, _loggerFactory, serverFeatures);
|
||||
}
|
||||
|
||||
private IServerAddressesFeature SplitAddresses(IConfiguration config)
|
||||
|
|
|
|||
|
|
@ -20,9 +20,7 @@ using System.Linq;
|
|||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Http.Features;
|
||||
using Microsoft.AspNet.Http.Features.Authentication;
|
||||
using Microsoft.AspNet.Http.Internal;
|
||||
using Xunit;
|
||||
using AuthenticationSchemes = Microsoft.Net.Http.Server.AuthenticationSchemes;
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,51 @@
|
|||
// 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.Threading.Tasks;
|
||||
using Microsoft.AspNet.Hosting.Server;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.Http.Features;
|
||||
using Microsoft.AspNet.Http.Internal;
|
||||
|
||||
namespace Microsoft.AspNet.Server.WebListener
|
||||
{
|
||||
internal class DummyApplication : IHttpApplication<HttpContext>
|
||||
{
|
||||
private readonly RequestDelegate _requestDelegate;
|
||||
|
||||
public DummyApplication(RequestDelegate requestDelegate)
|
||||
{
|
||||
_requestDelegate = requestDelegate;
|
||||
}
|
||||
|
||||
public HttpContext CreateContext(IFeatureCollection contextFeatures)
|
||||
{
|
||||
return new DefaultHttpContext(contextFeatures);
|
||||
}
|
||||
|
||||
public void DisposeContext(HttpContext httpContext, Exception exception)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public async Task ProcessRequestAsync(HttpContext httpContext)
|
||||
{
|
||||
await _requestDelegate(httpContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -22,7 +22,6 @@ using System.Text;
|
|||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Http.Features;
|
||||
using Microsoft.AspNet.Http.Internal;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNet.Server.WebListener
|
||||
|
|
|
|||
|
|
@ -20,11 +20,9 @@ using System.IO;
|
|||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Hosting.Builder;
|
||||
using Microsoft.AspNet.Hosting.Server;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.Http.Features;
|
||||
using Microsoft.AspNet.Http.Internal;
|
||||
using Microsoft.Net.Http.Server;
|
||||
using Xunit;
|
||||
|
||||
|
|
@ -171,7 +169,7 @@ namespace Microsoft.AspNet.Server.WebListener
|
|||
var dynamicServer = Utilities.CreateHttpServerReturnRoot("/", out root, app);
|
||||
dynamicServer.Dispose();
|
||||
var rootUri = new Uri(root);
|
||||
var factory = new ServerFactory(loggerFactory: null, httpContextFactory: new HttpContextFactory(new HttpContextAccessor()));
|
||||
var factory = new ServerFactory(loggerFactory: null);
|
||||
var server = factory.CreateServer(configuration: null);
|
||||
var listener = server.Features.Get<Microsoft.Net.Http.Server.WebListener>();
|
||||
|
||||
|
|
@ -180,7 +178,7 @@ namespace Microsoft.AspNet.Server.WebListener
|
|||
listener.UrlPrefixes.Add(UrlPrefix.Create(rootUri.Scheme, rootUri.Host, rootUri.Port, path));
|
||||
}
|
||||
|
||||
server.Start(app);
|
||||
server.Start(new DummyApplication(app));
|
||||
return server;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,10 +24,8 @@ using System.Net.Sockets;
|
|||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Hosting.Builder;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.Http.Features;
|
||||
using Microsoft.AspNet.Http.Internal;
|
||||
using Microsoft.Net.Http.Server;
|
||||
using Xunit;
|
||||
|
||||
|
|
@ -253,7 +251,7 @@ namespace Microsoft.AspNet.Server.WebListener
|
|||
string address;
|
||||
using (Utilities.CreateHttpServer(out address, httpContext => Task.FromResult(0))) { }
|
||||
|
||||
var factory = new ServerFactory(loggerFactory: null, httpContextFactory: new HttpContextFactory(new HttpContextAccessor()));
|
||||
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));
|
||||
|
|
@ -261,7 +259,7 @@ namespace Microsoft.AspNet.Server.WebListener
|
|||
|
||||
using (server)
|
||||
{
|
||||
server.Start(httpContext => Task.FromResult(0));
|
||||
server.Start(new DummyApplication(httpContext => Task.FromResult(0)));
|
||||
string response = await SendRequestAsync(address);
|
||||
Assert.Equal(string.Empty, response);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ namespace Microsoft.AspNet.Server.WebListener
|
|||
|
||||
internal static IServer CreateDynamicHttpServer(string basePath, AuthenticationSchemes authType, out string root, out string baseAddress, RequestDelegate app)
|
||||
{
|
||||
var factory = new ServerFactory(loggerFactory: null, httpContextFactory: Factory);
|
||||
var factory = new ServerFactory(loggerFactory: null);
|
||||
lock (PortLock)
|
||||
{
|
||||
while (NextPort < MaxPort)
|
||||
|
|
@ -73,7 +73,7 @@ namespace Microsoft.AspNet.Server.WebListener
|
|||
listener.AuthenticationManager.AuthenticationSchemes = authType;
|
||||
try
|
||||
{
|
||||
server.Start(app);
|
||||
server.Start(new DummyApplication(app));
|
||||
return server;
|
||||
}
|
||||
catch (WebListenerException)
|
||||
|
|
@ -92,10 +92,10 @@ namespace Microsoft.AspNet.Server.WebListener
|
|||
|
||||
internal static IServer CreateServer(string scheme, string host, int port, string path, RequestDelegate app)
|
||||
{
|
||||
var factory = new ServerFactory(loggerFactory: null, httpContextFactory: Factory);
|
||||
var factory = new ServerFactory(loggerFactory: null);
|
||||
var server = factory.CreateServer(configuration: null);
|
||||
server.Features.Get<IServerAddressesFeature>().Addresses.Add(UrlPrefix.Create(scheme, host, port, path).ToString());
|
||||
server.Start(app);
|
||||
server.Start(new DummyApplication(app));
|
||||
return server;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue