diff --git a/src/Microsoft.AspNet.Server.WebListener/MessagePump.cs b/src/Microsoft.AspNet.Server.WebListener/MessagePump.cs index acc5247da6..7476929f5e 100644 --- a/src/Microsoft.AspNet.Server.WebListener/MessagePump.cs +++ b/src/Microsoft.AspNet.Server.WebListener/MessagePump.cs @@ -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 _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(ProcessRequestAsync); @@ -90,11 +87,11 @@ namespace Microsoft.AspNet.Server.WebListener public IFeatureCollection Features { get; } - public void Start(RequestDelegate app) + public void Start(IHttpApplication application) { - if (app == null) + if (application == null) { - throw new ArgumentNullException(nameof(app)); + throw new ArgumentNullException(nameof(application)); } var addressesFeature = Features.Get(); @@ -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(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 : IHttpApplication + { + private readonly IHttpApplication _application; + + public ApplicationWrapper(IHttpApplication 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); + } + } } } diff --git a/src/Microsoft.AspNet.Server.WebListener/ServerFactory.cs b/src/Microsoft.AspNet.Server.WebListener/ServerFactory.cs index 4775cad150..1e72371d8a 100644 --- a/src/Microsoft.AspNet.Server.WebListener/ServerFactory.cs +++ b/src/Microsoft.AspNet.Server.WebListener/ServerFactory.cs @@ -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; } /// @@ -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) diff --git a/test/Microsoft.AspNet.Server.WebListener.FunctionalTests/AuthenticationTests.cs b/test/Microsoft.AspNet.Server.WebListener.FunctionalTests/AuthenticationTests.cs index 89dac6caaa..d93c8b6579 100644 --- a/test/Microsoft.AspNet.Server.WebListener.FunctionalTests/AuthenticationTests.cs +++ b/test/Microsoft.AspNet.Server.WebListener.FunctionalTests/AuthenticationTests.cs @@ -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; diff --git a/test/Microsoft.AspNet.Server.WebListener.FunctionalTests/DummyApplication.cs b/test/Microsoft.AspNet.Server.WebListener.FunctionalTests/DummyApplication.cs new file mode 100644 index 0000000000..21c4aed52f --- /dev/null +++ b/test/Microsoft.AspNet.Server.WebListener.FunctionalTests/DummyApplication.cs @@ -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 + { + 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); + } + } +} diff --git a/test/Microsoft.AspNet.Server.WebListener.FunctionalTests/HttpsTests.cs b/test/Microsoft.AspNet.Server.WebListener.FunctionalTests/HttpsTests.cs index 8a4595705d..ba18f67160 100644 --- a/test/Microsoft.AspNet.Server.WebListener.FunctionalTests/HttpsTests.cs +++ b/test/Microsoft.AspNet.Server.WebListener.FunctionalTests/HttpsTests.cs @@ -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 diff --git a/test/Microsoft.AspNet.Server.WebListener.FunctionalTests/RequestTests.cs b/test/Microsoft.AspNet.Server.WebListener.FunctionalTests/RequestTests.cs index 424f536847..b31e02852a 100644 --- a/test/Microsoft.AspNet.Server.WebListener.FunctionalTests/RequestTests.cs +++ b/test/Microsoft.AspNet.Server.WebListener.FunctionalTests/RequestTests.cs @@ -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(); @@ -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; } diff --git a/test/Microsoft.AspNet.Server.WebListener.FunctionalTests/ServerTests.cs b/test/Microsoft.AspNet.Server.WebListener.FunctionalTests/ServerTests.cs index 89127762de..d06ee8841c 100644 --- a/test/Microsoft.AspNet.Server.WebListener.FunctionalTests/ServerTests.cs +++ b/test/Microsoft.AspNet.Server.WebListener.FunctionalTests/ServerTests.cs @@ -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(); 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); } diff --git a/test/Microsoft.AspNet.Server.WebListener.FunctionalTests/Utilities.cs b/test/Microsoft.AspNet.Server.WebListener.FunctionalTests/Utilities.cs index d3440800bd..597f9aaf32 100644 --- a/test/Microsoft.AspNet.Server.WebListener.FunctionalTests/Utilities.cs +++ b/test/Microsoft.AspNet.Server.WebListener.FunctionalTests/Utilities.cs @@ -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().Addresses.Add(UrlPrefix.Create(scheme, host, port, path).ToString()); - server.Start(app); + server.Start(new DummyApplication(app)); return server; } }