// 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.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Web.Cors;
using System.Web.Http.Cors;
using System.Web.Http.Cors.Tracing;
using System.Web.Http.Tracing;
namespace System.Web.Http
{
///
/// CORS-related extension methods for .
///
[EditorBrowsable(EditorBrowsableState.Never)]
public static class CorsHttpConfigurationExtensions
{
private const string CorsEngineKey = "MS_CorsEngineKey";
private const string CorsPolicyProviderFactoryKey = "MS_CorsPolicyProviderFactoryKey";
private const string CorsEnabledKey = "MS_CorsEnabledKey";
///
/// Enables the support for CORS.
///
/// The .
public static void EnableCors(this HttpConfiguration httpConfiguration)
{
EnableCors(httpConfiguration, null, false);
}
///
/// Enables the support for CORS.
///
/// The .
/// Indicates whether upstream exceptions should be rethrown
public static void EnableCors(this HttpConfiguration httpConfiguration, bool rethrowExceptions)
{
EnableCors(httpConfiguration, null, rethrowExceptions);
}
///
/// Enables the support for CORS.
///
/// The .
/// The default .
public static void EnableCors(this HttpConfiguration httpConfiguration, ICorsPolicyProvider defaultPolicyProvider)
{
EnableCors(httpConfiguration, defaultPolicyProvider, false);
}
///
/// Enables the support for CORS.
///
/// The .
/// The default .
/// Indicates whether upstream exceptions should be rethrown
/// httpConfiguration
public static void EnableCors(this HttpConfiguration httpConfiguration, ICorsPolicyProvider defaultPolicyProvider,
bool rethrowExceptions)
{
if (httpConfiguration == null)
{
throw new ArgumentNullException("httpConfiguration");
}
if (defaultPolicyProvider != null)
{
AttributeBasedPolicyProviderFactory policyProviderFactory = new AttributeBasedPolicyProviderFactory();
policyProviderFactory.DefaultPolicyProvider = defaultPolicyProvider;
httpConfiguration.SetCorsPolicyProviderFactory(policyProviderFactory);
}
AddCorsMessageHandler(httpConfiguration, rethrowExceptions);
}
[SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "Caller owns the disposable object")]
private static void AddCorsMessageHandler(this HttpConfiguration httpConfiguration, bool rethrowExceptions)
{
object corsEnabled;
if (!httpConfiguration.Properties.TryGetValue(CorsEnabledKey, out corsEnabled))
{
Action defaultInitializer = httpConfiguration.Initializer;
httpConfiguration.Initializer = config =>
{
if (!config.Properties.TryGetValue(CorsEnabledKey, out corsEnabled))
{
// Execute this in the Initializer to ensure that the CorsMessageHandler is added last.
config.MessageHandlers.Add(new CorsMessageHandler(config, rethrowExceptions));
ITraceWriter traceWriter = config.Services.GetTraceWriter();
if (traceWriter != null)
{
ICorsPolicyProviderFactory factory = config.GetCorsPolicyProviderFactory();
config.SetCorsPolicyProviderFactory(new CorsPolicyProviderFactoryTracer(factory, traceWriter));
ICorsEngine corsEngine = config.GetCorsEngine();
config.SetCorsEngine(new CorsEngineTracer(corsEngine, traceWriter));
}
config.Properties[CorsEnabledKey] = true;
}
defaultInitializer(config);
};
}
}
///
/// Sets the on the .
///
/// The .
/// The .
///
/// httpConfiguration
/// or
/// corsEngine
///
public static void SetCorsEngine(this HttpConfiguration httpConfiguration, ICorsEngine corsEngine)
{
if (httpConfiguration == null)
{
throw new ArgumentNullException("httpConfiguration");
}
if (corsEngine == null)
{
throw new ArgumentNullException("corsEngine");
}
httpConfiguration.Properties[CorsEngineKey] = corsEngine;
}
///
/// Gets the from the .
///
/// The .
/// The .
/// httpConfiguration
public static ICorsEngine GetCorsEngine(this HttpConfiguration httpConfiguration)
{
if (httpConfiguration == null)
{
throw new ArgumentNullException("httpConfiguration");
}
return (ICorsEngine)httpConfiguration.Properties.GetOrAdd(CorsEngineKey, k => new CorsEngine());
}
///
/// Sets the on the .
///
/// The .
/// The .
///
/// httpConfiguration
/// or
/// corsPolicyProviderFactory
///
public static void SetCorsPolicyProviderFactory(this HttpConfiguration httpConfiguration, ICorsPolicyProviderFactory corsPolicyProviderFactory)
{
if (httpConfiguration == null)
{
throw new ArgumentNullException("httpConfiguration");
}
if (corsPolicyProviderFactory == null)
{
throw new ArgumentNullException("corsPolicyProviderFactory");
}
httpConfiguration.Properties[CorsPolicyProviderFactoryKey] = corsPolicyProviderFactory;
}
///
/// Gets the from the .
///
/// The .
/// The .
/// httpConfiguration
public static ICorsPolicyProviderFactory GetCorsPolicyProviderFactory(this HttpConfiguration httpConfiguration)
{
if (httpConfiguration == null)
{
throw new ArgumentNullException("httpConfiguration");
}
return (ICorsPolicyProviderFactory)httpConfiguration.Properties.GetOrAdd(CorsPolicyProviderFactoryKey, k => new AttributeBasedPolicyProviderFactory());
}
}
}