| File: OwinExtensions.cs | Web Access |
| Project: src\aspnetcore\src\Http\Owin\src\Microsoft.AspNetCore.Owin.csproj (Microsoft.AspNetCore.Owin) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Features; using Microsoft.AspNetCore.Owin; namespace Microsoft.AspNetCore.Builder; using AddMiddleware = Action<Func< Func<IDictionary<string, object>, Task>, Func<IDictionary<string, object>, Task> >>; using AppFunc = Func<IDictionary<string, object>, Task>; using CreateMiddleware = Func< Func<IDictionary<string, object>, Task>, Func<IDictionary<string, object>, Task> >; /// <summary> /// Extension methods to add OWIN to an HTTP application pipeline. /// </summary> public static class OwinExtensions { /// <summary> /// Adds an OWIN pipeline to the specified <see cref="IApplicationBuilder"/>. /// </summary> /// <param name="builder">The <see cref="IApplicationBuilder"/> to add the pipeline to.</param> /// <returns>An action used to create the OWIN pipeline.</returns> public static AddMiddleware UseOwin(this IApplicationBuilder builder) { ArgumentNullException.ThrowIfNull(builder); AddMiddleware add = middleware => { Func<RequestDelegate, RequestDelegate> middleware1 = next1 => { AppFunc exitMiddleware = env => { return next1((HttpContext)env[typeof(HttpContext).FullName]); }; var app = middleware(exitMiddleware); return httpContext => { // Use the existing OWIN env if there is one. IDictionary<string, object> env; var owinEnvFeature = httpContext.Features.Get<IOwinEnvironmentFeature>(); if (owinEnvFeature != null) { env = owinEnvFeature.Environment; env[typeof(HttpContext).FullName] = httpContext; } else { env = new OwinEnvironment(httpContext); } return app.Invoke(env); }; }; builder.Use(middleware1); }; // Adapt WebSockets by default. add(WebSocketAcceptAdapter.AdaptWebSockets); return add; } /// <summary> /// Adds OWIN middleware pipeline to the specified <see cref="IApplicationBuilder"/>. /// </summary> /// <param name="builder">The <see cref="IApplicationBuilder"/> to add the middleware to.</param> /// <param name="pipeline">A delegate which can specify the OWIN pipeline.</param> /// <returns>The original <see cref="IApplicationBuilder"/>.</returns> public static IApplicationBuilder UseOwin(this IApplicationBuilder builder, Action<AddMiddleware> pipeline) { ArgumentNullException.ThrowIfNull(builder); ArgumentNullException.ThrowIfNull(pipeline); pipeline(builder.UseOwin()); return builder; } /// <summary> /// Creates an <see cref="IApplicationBuilder"/> for an OWIN pipeline. /// </summary> /// <param name="app">The OWIN pipeline.</param> /// <returns>An <see cref="IApplicationBuilder"/></returns> public static IApplicationBuilder UseBuilder(this AddMiddleware app) { return app.UseBuilder(serviceProvider: null); } /// <summary> /// Creates an <see cref="IApplicationBuilder"/> for an OWIN pipeline. /// </summary> /// <param name="app">The OWIN pipeline.</param> /// <param name="serviceProvider">A service provider for <see cref="IApplicationBuilder.ApplicationServices"/>.</param> /// <returns>An <see cref="IApplicationBuilder"/>.</returns> public static IApplicationBuilder UseBuilder(this AddMiddleware app, IServiceProvider serviceProvider) { ArgumentNullException.ThrowIfNull(app); // Do not set ApplicationBuilder.ApplicationServices to null. May fail later due to missing services but // at least that results in a more useful Exception than a NRE. if (serviceProvider == null) { serviceProvider = new EmptyProvider(); } // Adapt WebSockets by default. app(OwinWebSocketAcceptAdapter.AdaptWebSockets); var builder = new ApplicationBuilder(serviceProvider: serviceProvider); var middleware = CreateMiddlewareFactory(exit => { builder.Use(ignored => exit); return builder.Build(); }, builder.ApplicationServices); app(middleware); return builder; } private static CreateMiddleware CreateMiddlewareFactory(Func<RequestDelegate, RequestDelegate> middleware, IServiceProvider services) { return next => { var app = middleware(httpContext => { return next(httpContext.Features.Get<IOwinEnvironmentFeature>().Environment); }); return env => { // Use the existing HttpContext if there is one. HttpContext context; object obj; if (env.TryGetValue(typeof(HttpContext).FullName, out obj)) { context = (HttpContext)obj; context.Features.Set<IOwinEnvironmentFeature>(new OwinEnvironmentFeature() { Environment = env }); } else { context = new DefaultHttpContext( new FeatureCollection( new OwinFeatureCollection(env))); context.RequestServices = services; } return app.Invoke(context); }; }; } /// <summary> /// Creates an <see cref="IApplicationBuilder"/> for an OWIN pipeline. /// </summary> /// <param name="app">The OWIN pipeline.</param> /// <param name="pipeline">A delegate used to configure a middleware pipeline.</param> /// <returns>An <see cref="IApplicationBuilder"/>.</returns> public static AddMiddleware UseBuilder(this AddMiddleware app, Action<IApplicationBuilder> pipeline) { return app.UseBuilder(pipeline, serviceProvider: null); } /// <summary> /// Creates an <see cref="IApplicationBuilder"/> for an OWIN pipeline. /// </summary> /// <param name="app">The OWIN pipeline.</param> /// <param name="pipeline">A delegate used to configure a middleware pipeline.</param> /// <param name="serviceProvider">A service provider for <see cref="IApplicationBuilder.ApplicationServices"/>.</param> /// <returns>An <see cref="IApplicationBuilder"/>.</returns> public static AddMiddleware UseBuilder(this AddMiddleware app, Action<IApplicationBuilder> pipeline, IServiceProvider serviceProvider) { ArgumentNullException.ThrowIfNull(app); ArgumentNullException.ThrowIfNull(pipeline); var builder = app.UseBuilder(serviceProvider); pipeline(builder); return app; } private sealed class EmptyProvider : IServiceProvider { public object GetService(Type serviceType) { return null; } } }