Merge branch 'feature/owin' into 1.x

This commit is contained in:
Zoltán Lehóczky
2015-01-06 22:18:08 +01:00
21 changed files with 3950 additions and 60 deletions

View File

@@ -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>

View File

@@ -25,6 +25,7 @@
<appSettings>
<add key="webpages:Enabled" value="false" />
<add key="owin:AutomaticAppStartup" value="false" />
</appSettings>

View File

@@ -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();

View File

@@ -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 {

View File

@@ -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",

View File

@@ -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>

View File

@@ -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"/>

View File

@@ -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()) {

View File

@@ -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);
}
}

View File

@@ -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
};

View File

@@ -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);
}
}
}

View File

@@ -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" />

View File

@@ -0,0 +1,7 @@
using System.Collections.Generic;
namespace Orchard.Owin {
public interface IOwinMiddlewareProvider : IDependency {
IEnumerable<OwinMiddleware> GetOwinMiddlewares();
}
}

View 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;
}
}
}

View 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; }
}
}

View 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();
});
}
}
}