// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Contracts;
using System.Threading;
using System.Web.Http;
using System.Web.Http.Controllers;
using System.Web.Http.ExceptionHandling;
using System.Web.Http.Hosting;
using System.Web.Http.Owin;
namespace Owin
{
///
/// Provides extension methods for the class.
///
[EditorBrowsable(EditorBrowsableState.Never)]
public static class WebApiAppBuilderExtensions
{
private static readonly IHostBufferPolicySelector _defaultBufferPolicySelector =
new OwinBufferPolicySelector();
/// Adds a component to the OWIN pipeline for running a Web API endpoint.
/// The application builder.
/// The used to configure the endpoint.
/// The application builder.
[SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope",
Justification = "In the success path, HttpMessageHandlerAdapter owns the message handler.")]
public static IAppBuilder UseWebApi(this IAppBuilder builder, HttpConfiguration configuration)
{
if (builder == null)
{
throw new ArgumentNullException("builder");
}
if (configuration == null)
{
throw new ArgumentNullException("configuration");
}
HttpServer server = new HttpServer(configuration);
try
{
HttpMessageHandlerOptions options = CreateOptions(builder, server, configuration);
return UseMessageHandler(builder, options);
}
catch
{
server.Dispose();
throw;
}
}
/// Adds a component to the OWIN pipeline for running a Web API endpoint.
/// The application builder.
/// The http server.
/// The application builder.
public static IAppBuilder UseWebApi(this IAppBuilder builder, HttpServer httpServer)
{
if (builder == null)
{
throw new ArgumentNullException("builder");
}
if (httpServer == null)
{
throw new ArgumentNullException("httpServer");
}
HttpConfiguration configuration = httpServer.Configuration;
Contract.Assert(configuration != null);
HttpMessageHandlerOptions options = CreateOptions(builder, httpServer, configuration);
return UseMessageHandler(builder, options);
}
private static IAppBuilder UseMessageHandler(this IAppBuilder builder, HttpMessageHandlerOptions options)
{
Contract.Assert(builder != null);
Contract.Assert(options != null);
return builder.Use(typeof(HttpMessageHandlerAdapter), options);
}
private static HttpMessageHandlerOptions CreateOptions(IAppBuilder builder, HttpServer server,
HttpConfiguration configuration)
{
Contract.Assert(builder != null);
Contract.Assert(server != null);
Contract.Assert(configuration != null);
ServicesContainer services = configuration.Services;
Contract.Assert(services != null);
IHostBufferPolicySelector bufferPolicySelector = services.GetHostBufferPolicySelector()
?? _defaultBufferPolicySelector;
IExceptionLogger exceptionLogger = ExceptionServices.GetLogger(services);
IExceptionHandler exceptionHandler = ExceptionServices.GetHandler(services);
return new HttpMessageHandlerOptions
{
MessageHandler = server,
BufferPolicySelector = bufferPolicySelector,
ExceptionLogger = exceptionLogger,
ExceptionHandler = exceptionHandler,
AppDisposing = builder.GetOnAppDisposingProperty()
};
}
internal static CancellationToken GetOnAppDisposingProperty(this IAppBuilder builder)
{
Contract.Assert(builder != null);
IDictionary properties = builder.Properties;
if (properties == null)
{
return CancellationToken.None;
}
object value;
if (!properties.TryGetValue("host.OnAppDisposing", out value))
{
return CancellationToken.None;
}
CancellationToken? token = value as CancellationToken?;
if (!token.HasValue)
{
return CancellationToken.None;
}
return token.Value;
}
}
}