mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2026-02-09 09:16:41 +08:00
Merge branch 'feature/owin' into 1.x
This commit is contained in:
@@ -18,11 +18,12 @@
|
||||
|
||||
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" requirePermission="false" />
|
||||
</configSections>
|
||||
|
||||
|
||||
<appSettings>
|
||||
<add key="webpages:Enabled" value="false" />
|
||||
<add key="webpages:Version" value="3.0.0.0"/>
|
||||
<add key="log4net.Config" value="Config\log4net.config" />
|
||||
<add key="owin:AutomaticAppStartup" value="false" />
|
||||
</appSettings>
|
||||
|
||||
<system.web.webPages.razor>
|
||||
@@ -57,7 +58,7 @@
|
||||
during development.
|
||||
-->
|
||||
<compilation debug="false" targetFramework="4.5.1" batch="true" numRecompilesBeforeAppRestart="250" optimizeCompilations="true">
|
||||
<buildProviders>
|
||||
<buildProviders>
|
||||
<add extension=".csproj" type="Orchard.Environment.Extensions.Compilers.CSharpExtensionBuildProviderShim"/>
|
||||
</buildProviders>
|
||||
<assemblies>
|
||||
@@ -67,6 +68,7 @@
|
||||
<add assembly="System.Data.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
|
||||
<add assembly="System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<add assembly="System.Data.Entity.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<add assembly="Microsoft.Owin.Host.SystemWeb, Version=3.0.0.0" />
|
||||
<remove assembly="System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
|
||||
<remove assembly="System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
|
||||
<remove assembly="System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
|
||||
@@ -127,7 +129,7 @@
|
||||
|
||||
<modules runAllManagedModulesForAllRequests="false">
|
||||
<remove name="WarmupHttpModule" />
|
||||
<add name="WarmupHttpModule" type="Orchard.WarmupStarter.WarmupHttpModule, Orchard.WarmupStarter, Version=1.0.20, Culture=neutral"/>
|
||||
<add name="WarmupHttpModule" type="Orchard.WarmupStarter.WarmupHttpModule, Orchard.WarmupStarter, Version=1.8.1, Culture=neutral"/>
|
||||
</modules>
|
||||
<handlers accessPolicy="Script">
|
||||
<!-- clear all handlers, prevents executing code file extensions, prevents returning any file contents -->
|
||||
@@ -142,7 +144,7 @@
|
||||
<add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
|
||||
<add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
|
||||
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
|
||||
|
||||
|
||||
</handlers>
|
||||
<!-- Prevent IIS 7.0 from returning a custom 404/500 error page of its own -->
|
||||
<httpErrors existingResponse="PassThrough" />
|
||||
@@ -184,27 +186,27 @@
|
||||
<assemblyIdentity name="System.Net.Http.Formatting" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-5.1.0.0" newVersion="5.1.0.0" />
|
||||
</dependentAssembly>
|
||||
|
||||
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-5.1.0.0" newVersion="5.1.0.0" />
|
||||
</dependentAssembly>
|
||||
|
||||
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="NHibernate" publicKeyToken="aa95f207798dfdb4" culture="neutral"/>
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.0.4000" newVersion="4.0.0.4000"/>
|
||||
</dependentAssembly>
|
||||
|
||||
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Autofac" publicKeyToken="17863af14b0044da"/>
|
||||
<bindingRedirect oldVersion="0.0.0.0-3.5.0.0" newVersion="3.5.0.0"/>
|
||||
</dependentAssembly>
|
||||
|
||||
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed"/>
|
||||
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0"/>
|
||||
</dependentAssembly>
|
||||
|
||||
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
</configuration>
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
<appSettings>
|
||||
<add key="webpages:Enabled" value="false" />
|
||||
<add key="owin:AutomaticAppStartup" value="false" />
|
||||
</appSettings>
|
||||
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ using Orchard.FileSystems.AppData;
|
||||
using Orchard.FileSystems.VirtualPath;
|
||||
using Orchard.Mvc.ModelBinders;
|
||||
using Orchard.Mvc.Routes;
|
||||
using Orchard.Owin;
|
||||
using Orchard.Tests.Environment.TestDependencies;
|
||||
using Orchard.Tests.Stubs;
|
||||
using Orchard.Tests.Utility;
|
||||
@@ -62,7 +63,9 @@ namespace Orchard.Tests.Environment {
|
||||
.Ignore<IExtensionFolders>()
|
||||
.Ignore<IRouteProvider>()
|
||||
.Ignore<IHttpRouteProvider>()
|
||||
.Ignore<IModelBinderProvider>();
|
||||
.Ignore<IModelBinderProvider>()
|
||||
.Ignore<IWorkContextEvents>()
|
||||
.Ignore<IOwinMiddlewareProvider>();
|
||||
});
|
||||
_lifetime = _container.BeginLifetimeScope();
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Routing;
|
||||
using NUnit.Framework;
|
||||
@@ -65,6 +66,8 @@ namespace Orchard.Tests.Environment {
|
||||
Routes = routes;
|
||||
}
|
||||
public IEnumerable<RouteDescriptor> Routes { get; set; }
|
||||
public void Publish(IEnumerable<RouteDescriptor> routes, Func<IDictionary<string, object>, Task> pipeline) {
|
||||
}
|
||||
}
|
||||
|
||||
public class StubModelBinderProvider : IModelBinderProvider {
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.Remoting.Messaging;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Routing;
|
||||
@@ -43,6 +46,16 @@ namespace Orchard.Tests.Mvc.Routes {
|
||||
rootBuilder.RegisterType<StubAsyncTokenProvider>().As<IAsyncTokenProvider>();
|
||||
rootBuilder.RegisterType<StubParallelCacheContext>().As<IParallelCacheContext>();
|
||||
|
||||
rootBuilder.Register<Func<RouteBase, ShellRoute>>(c => {
|
||||
var context = c.Resolve<IComponentContext>();
|
||||
return new Func<RouteBase, ShellRoute>(routeBase =>
|
||||
new ShellRoute(
|
||||
routeBase,
|
||||
_settingsA,
|
||||
context.Resolve<IWorkContextAccessor>(),
|
||||
context.Resolve<IRunningShellTable>(), objects => { return null; }));
|
||||
});
|
||||
|
||||
_rootContainer = rootBuilder.Build();
|
||||
|
||||
_containerA = _rootContainer.BeginLifetimeScope(
|
||||
@@ -59,33 +72,37 @@ namespace Orchard.Tests.Mvc.Routes {
|
||||
builder.RegisterType<RoutePublisher>().As<IRoutePublisher>().InstancePerMatchingLifetimeScope("shell");
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void FactoryMethodWillCreateShellRoutes() {
|
||||
var settings = new ShellSettings { Name = "Alpha" };
|
||||
var builder = new ContainerBuilder();
|
||||
builder.RegisterType<ShellRoute>().InstancePerDependency();
|
||||
builder.RegisterAutoMocking();
|
||||
builder.Register(ctx => settings);
|
||||
|
||||
var container = builder.Build();
|
||||
var buildShellRoute = container.Resolve<Func<RouteBase, ShellRoute>>();
|
||||
var buildShellRoute = new Func<RouteBase, ShellRoute>(routeBase =>
|
||||
new ShellRoute(
|
||||
routeBase,
|
||||
_settingsA,
|
||||
container.Resolve<IWorkContextAccessor>(),
|
||||
container.Resolve<IRunningShellTable>(),
|
||||
objects => { return null; }));
|
||||
|
||||
var routeA = new Route("foo", new MvcRouteHandler());
|
||||
var route1 = buildShellRoute(routeA);
|
||||
|
||||
var routeB = new Route("bar", new MvcRouteHandler()) {
|
||||
DataTokens = new RouteValueDictionary { { "area", "Beta" } }
|
||||
DataTokens = new RouteValueDictionary { { "area", _settingsB.Name } }
|
||||
};
|
||||
var route2 = buildShellRoute(routeB);
|
||||
|
||||
Assert.That(route1, Is.Not.SameAs(route2));
|
||||
|
||||
Assert.That(route1.ShellSettingsName, Is.EqualTo("Alpha"));
|
||||
Assert.That(route1.ShellSettingsName, Is.EqualTo(_settingsA.Name));
|
||||
Assert.That(route1.Area, Is.Null);
|
||||
|
||||
Assert.That(route2.ShellSettingsName, Is.EqualTo("Alpha"));
|
||||
Assert.That(route2.Area, Is.EqualTo("Beta"));
|
||||
Assert.That(route2.ShellSettingsName, Is.EqualTo(_settingsA.Name));
|
||||
Assert.That(route2.Area, Is.EqualTo(_settingsB.Name));
|
||||
}
|
||||
|
||||
|
||||
@@ -196,7 +213,13 @@ namespace Orchard.Tests.Mvc.Routes {
|
||||
.Returns(settings);
|
||||
|
||||
|
||||
var shellRouteFactory = container.Resolve<Func<RouteBase, ShellRoute>>();
|
||||
var shellRouteFactory = new Func<RouteBase, ShellRoute>(routeBase =>
|
||||
new ShellRoute(
|
||||
routeBase,
|
||||
settings,
|
||||
container.Resolve<IWorkContextAccessor>(),
|
||||
container.Resolve<IRunningShellTable>(),
|
||||
objects => { return null; }));
|
||||
|
||||
var helloRoute = shellRouteFactory(new Route(
|
||||
"hello",
|
||||
|
||||
@@ -51,6 +51,9 @@
|
||||
<HintPath>..\..\lib\autofac\Autofac.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Owin.Host.SystemWeb">
|
||||
<HintPath>..\..\lib\owin\Microsoft.Owin.Host.SystemWeb.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Web.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\lib\aspnetmvc\Microsoft.Web.Infrastructure.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
<add key="webpages:Enabled" value="false"/>
|
||||
<add key="webpages:Version" value="3.0.0.0"/>
|
||||
<add key="log4net.Config" value="Config\log4net.config"/>
|
||||
<add key="owin:AppStartup" value="Orchard.Owin.Startup, Orchard.Framework" />
|
||||
</appSettings>
|
||||
<system.web.webPages.razor>
|
||||
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
|
||||
@@ -53,6 +54,7 @@
|
||||
<add assembly="System.Data.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
|
||||
<add assembly="System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
|
||||
<add assembly="System.Data.Entity.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
|
||||
<add assembly="Microsoft.Owin.Host.SystemWeb, Version=3.0.0.0" />
|
||||
<remove assembly="System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
|
||||
<remove assembly="System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
|
||||
<remove assembly="System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Autofac.Features.OwnedInstances;
|
||||
using Microsoft.Owin.Builder;
|
||||
using Orchard.Environment.Configuration;
|
||||
using Orchard.Logging;
|
||||
using Orchard.Mvc.ModelBinders;
|
||||
using Orchard.Mvc.Routes;
|
||||
using Orchard.Owin;
|
||||
using Orchard.Tasks;
|
||||
using Orchard.UI;
|
||||
using Orchard.WebApi.Routes;
|
||||
using Owin;
|
||||
using IModelBinderProvider = Orchard.Mvc.ModelBinders.IModelBinderProvider;
|
||||
|
||||
namespace Orchard.Environment {
|
||||
@@ -18,6 +24,8 @@ namespace Orchard.Environment {
|
||||
private readonly IEnumerable<IModelBinderProvider> _modelBinderProviders;
|
||||
private readonly IModelBinderPublisher _modelBinderPublisher;
|
||||
private readonly ISweepGenerator _sweepGenerator;
|
||||
private readonly IEnumerable<IOwinMiddlewareProvider> _owinMiddlewareProviders;
|
||||
private readonly ShellSettings _shellSettings;
|
||||
|
||||
public DefaultOrchardShell(
|
||||
Func<Owned<IOrchardShellEvents>> eventsFactory,
|
||||
@@ -26,7 +34,9 @@ namespace Orchard.Environment {
|
||||
IRoutePublisher routePublisher,
|
||||
IEnumerable<IModelBinderProvider> modelBinderProviders,
|
||||
IModelBinderPublisher modelBinderPublisher,
|
||||
ISweepGenerator sweepGenerator) {
|
||||
ISweepGenerator sweepGenerator,
|
||||
IEnumerable<IOwinMiddlewareProvider> owinMiddlewareProviders,
|
||||
ShellSettings shellSettings) {
|
||||
_eventsFactory = eventsFactory;
|
||||
_routeProviders = routeProviders;
|
||||
_httpRouteProviders = httpRouteProviders;
|
||||
@@ -34,6 +44,8 @@ namespace Orchard.Environment {
|
||||
_modelBinderProviders = modelBinderProviders;
|
||||
_modelBinderPublisher = modelBinderPublisher;
|
||||
_sweepGenerator = sweepGenerator;
|
||||
_owinMiddlewareProviders = owinMiddlewareProviders;
|
||||
_shellSettings = shellSettings;
|
||||
|
||||
Logger = NullLogger.Instance;
|
||||
}
|
||||
@@ -41,11 +53,27 @@ namespace Orchard.Environment {
|
||||
public ILogger Logger { get; set; }
|
||||
|
||||
public void Activate() {
|
||||
IAppBuilder appBuilder = new AppBuilder();
|
||||
appBuilder.Properties["host.AppName"] = _shellSettings.Name;
|
||||
|
||||
var orderedMiddlewares = _owinMiddlewareProviders
|
||||
.SelectMany(p => p.GetOwinMiddlewares())
|
||||
.OrderBy(obj => obj.Priority, new FlatPositionComparer());
|
||||
|
||||
foreach (var middleware in orderedMiddlewares) {
|
||||
middleware.Configure(appBuilder);
|
||||
}
|
||||
|
||||
// register the Orchard middleware after all others
|
||||
appBuilder.UseOrchard();
|
||||
|
||||
Func<IDictionary<string, object>, Task> pipeline = appBuilder.Build();
|
||||
|
||||
var allRoutes = new List<RouteDescriptor>();
|
||||
allRoutes.AddRange(_routeProviders.SelectMany(provider => provider.GetRoutes()));
|
||||
allRoutes.AddRange(_httpRouteProviders.SelectMany(provider => provider.GetRoutes()));
|
||||
|
||||
_routePublisher.Publish(allRoutes);
|
||||
_routePublisher.Publish(allRoutes, pipeline);
|
||||
_modelBinderPublisher.Publish(_modelBinderProviders.SelectMany(provider => provider.GetModelBinders()));
|
||||
|
||||
using (var events = _eventsFactory()) {
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Orchard.Mvc.Routes {
|
||||
public interface IRoutePublisher : IDependency {
|
||||
void Publish(IEnumerable<RouteDescriptor> routes);
|
||||
void Publish(IEnumerable<RouteDescriptor> routes, Func<IDictionary<string, object>, Task> pipeline = null);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web.Http;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Routing;
|
||||
@@ -32,7 +33,7 @@ namespace Orchard.Mvc.Routes {
|
||||
_extensionManager = extensionManager;
|
||||
}
|
||||
|
||||
public void Publish(IEnumerable<RouteDescriptor> routes) {
|
||||
public void Publish(IEnumerable<RouteDescriptor> routes, Func<IDictionary<string, object>, Task> env) {
|
||||
var routesArray = routes
|
||||
.OrderByDescending(r => r.Priority)
|
||||
.ToArray();
|
||||
@@ -52,7 +53,7 @@ namespace Orchard.Mvc.Routes {
|
||||
|
||||
preloading.Add(routeDescriptor.Name, routeDescriptor.Route);
|
||||
}
|
||||
|
||||
|
||||
|
||||
using (_routeCollection.GetWriteLock()) {
|
||||
// existing routes are removed while the collection is briefly inaccessable
|
||||
@@ -66,17 +67,17 @@ namespace Orchard.Mvc.Routes {
|
||||
var defaultSessionState = SessionStateBehavior.Default;
|
||||
|
||||
ExtensionDescriptor extensionDescriptor = null;
|
||||
if(routeDescriptor.Route is Route) {
|
||||
if (routeDescriptor.Route is Route) {
|
||||
object extensionId;
|
||||
var route = routeDescriptor.Route as Route;
|
||||
if(route.DataTokens != null && route.DataTokens.TryGetValue("area", out extensionId) ||
|
||||
if (route.DataTokens != null && route.DataTokens.TryGetValue("area", out extensionId) ||
|
||||
route.Defaults != null && route.Defaults.TryGetValue("area", out extensionId)) {
|
||||
extensionDescriptor = _extensionManager.GetExtension(extensionId.ToString());
|
||||
extensionDescriptor = _extensionManager.GetExtension(extensionId.ToString());
|
||||
}
|
||||
}
|
||||
else if(routeDescriptor.Route is IRouteWithArea) {
|
||||
else if (routeDescriptor.Route is IRouteWithArea) {
|
||||
var route = routeDescriptor.Route as IRouteWithArea;
|
||||
extensionDescriptor = _extensionManager.GetExtension(route.Area);
|
||||
extensionDescriptor = _extensionManager.GetExtension(route.Area);
|
||||
}
|
||||
|
||||
if (extensionDescriptor != null) {
|
||||
@@ -87,9 +88,9 @@ namespace Orchard.Mvc.Routes {
|
||||
}
|
||||
|
||||
// Route-level setting overrides module-level setting (from manifest).
|
||||
var sessionStateBehavior = routeDescriptor.SessionState == SessionStateBehavior.Default ? defaultSessionState : routeDescriptor.SessionState ;
|
||||
var sessionStateBehavior = routeDescriptor.SessionState == SessionStateBehavior.Default ? defaultSessionState : routeDescriptor.SessionState;
|
||||
|
||||
var shellRoute = new ShellRoute(routeDescriptor.Route, _shellSettings, _workContextAccessor, _runningShellTable) {
|
||||
var shellRoute = new ShellRoute(routeDescriptor.Route, _shellSettings, _workContextAccessor, _runningShellTable, env) {
|
||||
IsHttpRoute = routeDescriptor is HttpRouteDescriptor,
|
||||
SessionState = sessionStateBehavior
|
||||
};
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Routing;
|
||||
@@ -15,12 +16,14 @@ namespace Orchard.Mvc.Routes {
|
||||
private readonly ShellSettings _shellSettings;
|
||||
private readonly IWorkContextAccessor _workContextAccessor;
|
||||
private readonly IRunningShellTable _runningShellTable;
|
||||
private readonly Func<IDictionary<string, object>, Task> _pipeline;
|
||||
private readonly UrlPrefix _urlPrefix;
|
||||
|
||||
public ShellRoute(RouteBase route, ShellSettings shellSettings, IWorkContextAccessor workContextAccessor, IRunningShellTable runningShellTable) {
|
||||
public ShellRoute(RouteBase route, ShellSettings shellSettings, IWorkContextAccessor workContextAccessor, IRunningShellTable runningShellTable, Func<IDictionary<string, object>, Task> pipeline) {
|
||||
_route = route;
|
||||
_shellSettings = shellSettings;
|
||||
_runningShellTable = runningShellTable;
|
||||
_pipeline = pipeline;
|
||||
_workContextAccessor = workContextAccessor;
|
||||
if (!string.IsNullOrEmpty(_shellSettings.RequestUrlPrefix))
|
||||
_urlPrefix = new UrlPrefix(_shellSettings.RequestUrlPrefix);
|
||||
@@ -56,13 +59,13 @@ namespace Orchard.Mvc.Routes {
|
||||
}
|
||||
|
||||
// otherwise wrap handler and return it
|
||||
routeData.RouteHandler = new RouteHandler(_workContextAccessor, routeData.RouteHandler, SessionState);
|
||||
routeData.RouteHandler = new RouteHandler(_workContextAccessor, routeData.RouteHandler, SessionState, _pipeline);
|
||||
routeData.DataTokens["IWorkContextAccessor"] = _workContextAccessor;
|
||||
|
||||
if (IsHttpRoute) {
|
||||
routeData.Values["IWorkContextAccessor"] = _workContextAccessor; // for WebApi
|
||||
}
|
||||
|
||||
|
||||
return routeData;
|
||||
}
|
||||
|
||||
@@ -93,26 +96,30 @@ namespace Orchard.Mvc.Routes {
|
||||
private readonly IWorkContextAccessor _workContextAccessor;
|
||||
private readonly IRouteHandler _routeHandler;
|
||||
private readonly SessionStateBehavior _sessionStateBehavior;
|
||||
private readonly Func<IDictionary<string, object>, Task> _pipeline;
|
||||
|
||||
public RouteHandler(IWorkContextAccessor workContextAccessor, IRouteHandler routeHandler, SessionStateBehavior sessionStateBehavior) {
|
||||
public RouteHandler(IWorkContextAccessor workContextAccessor, IRouteHandler routeHandler, SessionStateBehavior sessionStateBehavior, Func<IDictionary<string, object>, Task> pipeline) {
|
||||
_workContextAccessor = workContextAccessor;
|
||||
_routeHandler = routeHandler;
|
||||
_sessionStateBehavior = sessionStateBehavior;
|
||||
_pipeline = pipeline;
|
||||
}
|
||||
|
||||
public IHttpHandler GetHttpHandler(RequestContext requestContext) {
|
||||
var httpHandler = _routeHandler.GetHttpHandler(requestContext);
|
||||
|
||||
requestContext.HttpContext.SetSessionStateBehavior(_sessionStateBehavior);
|
||||
|
||||
|
||||
if (httpHandler is IHttpAsyncHandler) {
|
||||
return new HttpAsyncHandler(_workContextAccessor, (IHttpAsyncHandler)httpHandler);
|
||||
return new HttpAsyncHandler(_workContextAccessor, httpHandler, _pipeline);
|
||||
}
|
||||
|
||||
return new HttpHandler(_workContextAccessor, httpHandler);
|
||||
}
|
||||
}
|
||||
|
||||
class HttpHandler : IHttpHandler, IRequiresSessionState, IHasRequestContext {
|
||||
protected readonly IWorkContextAccessor _workContextAccessor;
|
||||
private readonly IWorkContextAccessor _workContextAccessor;
|
||||
private readonly IHttpHandler _httpHandler;
|
||||
|
||||
public HttpHandler(IWorkContextAccessor workContextAccessor, IHttpHandler httpHandler) {
|
||||
@@ -138,33 +145,40 @@ namespace Orchard.Mvc.Routes {
|
||||
}
|
||||
}
|
||||
|
||||
class HttpAsyncHandler : HttpHandler, IHttpAsyncHandler {
|
||||
class HttpAsyncHandler : HttpTaskAsyncHandler, IRequiresSessionState {
|
||||
private readonly IWorkContextAccessor _workContextAccessor;
|
||||
private readonly IHttpAsyncHandler _httpAsyncHandler;
|
||||
private IDisposable _scope;
|
||||
private readonly Func<IDictionary<string, object>, Task> _pipeline;
|
||||
|
||||
public HttpAsyncHandler(IWorkContextAccessor containerProvider, IHttpAsyncHandler httpAsyncHandler)
|
||||
: base(containerProvider, httpAsyncHandler) {
|
||||
_httpAsyncHandler = httpAsyncHandler;
|
||||
public HttpAsyncHandler(IWorkContextAccessor workContextAccessor, IHttpHandler httpHandler, Func<IDictionary<string, object>, Task> env) {
|
||||
_workContextAccessor = workContextAccessor;
|
||||
_httpAsyncHandler = httpHandler as IHttpAsyncHandler;
|
||||
_pipeline = env;
|
||||
}
|
||||
|
||||
public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData) {
|
||||
_scope = _workContextAccessor.CreateWorkContextScope(new HttpContextWrapper(context));
|
||||
try {
|
||||
return _httpAsyncHandler.BeginProcessRequest(context, cb, extraData);
|
||||
}
|
||||
catch {
|
||||
_scope.Dispose();
|
||||
throw;
|
||||
}
|
||||
public override void ProcessRequest(HttpContext context) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
[DebuggerStepThrough]
|
||||
public void EndProcessRequest(IAsyncResult result) {
|
||||
try {
|
||||
_httpAsyncHandler.EndProcessRequest(result);
|
||||
}
|
||||
finally {
|
||||
_scope.Dispose();
|
||||
public override async Task ProcessRequestAsync(HttpContext context) {
|
||||
using (_workContextAccessor.CreateWorkContextScope(new HttpContextWrapper(context))) {
|
||||
|
||||
var environment = context.Items["owin.Environment"] as IDictionary<string, object>;
|
||||
|
||||
if (environment == null) {
|
||||
// It seems Owin is disabled by the owin:AutomaticAppStartup=false appSettings configuration.
|
||||
environment = new Dictionary<string, object>();
|
||||
}
|
||||
|
||||
environment["orchard.Handler"] = new Func<Task>(async () => {
|
||||
await Task.Factory.FromAsync(
|
||||
_httpAsyncHandler.BeginProcessRequest,
|
||||
_httpAsyncHandler.EndProcessRequest,
|
||||
context,
|
||||
null);
|
||||
});
|
||||
|
||||
await _pipeline.Invoke(environment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,6 +81,9 @@
|
||||
<HintPath>..\..\lib\log4net\log4net.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="Microsoft.Owin">
|
||||
<HintPath>..\..\lib\owin\Microsoft.Owin.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\lib\newtonsoft.json\Newtonsoft.Json.dll</HintPath>
|
||||
@@ -94,6 +97,9 @@
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\lib\nhibernate.linq\NHibernate.Linq.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Owin">
|
||||
<HintPath>..\..\lib\owin\Owin.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.ComponentModel.DataAnnotations">
|
||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||
@@ -312,6 +318,10 @@
|
||||
<Compile Include="Mvc\ViewEngines\Razor\IRazorCompilationEvents.cs" />
|
||||
<Compile Include="Mvc\ViewEngines\ThemeAwareness\ThemeViewLocationCache.cs" />
|
||||
<Compile Include="OrchardFatalException.cs" />
|
||||
<Compile Include="Owin\IOwinMiddlewareProvider.cs" />
|
||||
<Compile Include="Owin\OrchardMiddleware.cs" />
|
||||
<Compile Include="Owin\OwinMiddleware.cs" />
|
||||
<Compile Include="Owin\Startup.cs" />
|
||||
<Compile Include="Recipes\Events\IRecipeExecuteEventHandler.cs" />
|
||||
<Compile Include="Recipes\Events\IRecipeSchedulerEventHandler.cs" />
|
||||
<Compile Include="Recipes\Models\Recipe.cs" />
|
||||
|
||||
7
src/Orchard/Owin/IOwinMiddlewareProvider.cs
Normal file
7
src/Orchard/Owin/IOwinMiddlewareProvider.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Orchard.Owin {
|
||||
public interface IOwinMiddlewareProvider : IDependency {
|
||||
IEnumerable<OwinMiddleware> GetOwinMiddlewares();
|
||||
}
|
||||
}
|
||||
20
src/Orchard/Owin/OrchardMiddleware.cs
Normal file
20
src/Orchard/Owin/OrchardMiddleware.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Owin;
|
||||
|
||||
namespace Orchard.Owin {
|
||||
public static class OrchardMiddleware {
|
||||
public static IAppBuilder UseOrchard(this IAppBuilder app) {
|
||||
app.Use(async (context, next) => {
|
||||
var handler = context.Environment["orchard.Handler"] as Func<Task>;
|
||||
|
||||
if (handler == null) {
|
||||
throw new ArgumentException("orchard.Handler can't be null");
|
||||
}
|
||||
await handler();
|
||||
});
|
||||
|
||||
return app;
|
||||
}
|
||||
}
|
||||
}
|
||||
9
src/Orchard/Owin/OwinMiddleware.cs
Normal file
9
src/Orchard/Owin/OwinMiddleware.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
using System;
|
||||
using Owin;
|
||||
|
||||
namespace Orchard.Owin {
|
||||
public class OwinMiddleware {
|
||||
public Action<IAppBuilder> Configure { get; set; }
|
||||
public string Priority { get; set; }
|
||||
}
|
||||
}
|
||||
12
src/Orchard/Owin/Startup.cs
Normal file
12
src/Orchard/Owin/Startup.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using Owin;
|
||||
|
||||
namespace Orchard.Owin {
|
||||
public class Startup {
|
||||
public void Configuration(IAppBuilder app) {
|
||||
app.Use((context, next) => {
|
||||
context.Response.Headers.Append("X-Generator", "Orchard");
|
||||
return next();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user