/mcs/class/referencesource/System.ServiceModel.Activation/System/ServiceModel/Activation/HostedTransportConfigurationManager.cs
C# | 275 lines | 236 code | 31 blank | 8 comment | 27 complexity | aac3cdfd91fee9eb9ae8b812fa843d28 MD5 | raw file
Possible License(s): LGPL-2.0, MPL-2.0-no-copyleft-exception, CC-BY-SA-3.0, GPL-2.0
- //----------------------------------------------------------------------------
- // Copyright (c) Microsoft Corporation. All rights reserved.
- //----------------------------------------------------------------------------
- namespace System.ServiceModel.Activation
- {
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Reflection;
- using System.Runtime;
- using System.Runtime.Diagnostics;
- using System.Security;
- using System.Security.Permissions;
- using System.ServiceModel;
- using System.ServiceModel.Configuration;
- using System.ServiceModel.Activation.Diagnostics;
- using System.ServiceModel.Diagnostics.Application;
- using System.Diagnostics.CodeAnalysis;
- class HostedTransportConfigurationManager
- {
- IDictionary<string, HostedTransportConfiguration> configurations = new Dictionary<string, HostedTransportConfiguration>(StringComparer.Ordinal);
- // Double-checked locking pattern requires volatile for read/write synchronization
- volatile bool initialized = false;
- MetabaseSettings metabaseSettings;
- // Double-checked locking pattern requires volatile for read/write synchronization
- static volatile HostedTransportConfigurationManager singleton;
- static object syncRoot = new object();
- #pragma warning disable 436
- const string WasHostingAssemblyName = "System.ServiceModel.WasHosting, Version=" + ThisAssembly.Version + ", Culture=neutral, PublicKeyToken=" + AssemblyRef.EcmaPublicKey;
- const string MetabaseSettingsIis7FactoryTypeName = "System.ServiceModel.WasHosting.MetabaseSettingsIis7Factory, " + WasHostingAssemblyName;
- #pragma warning restore 436
- const string CreateMetabaseSettingsIis7MethodName = "CreateMetabaseSettings";
- HostedTransportConfigurationManager()
- {
- if (!Iis7Helper.IsIis7)
- {
- metabaseSettings = new MetabaseSettingsIis6();
- }
- else
- {
- metabaseSettings = CreateWasHostingMetabaseSettings();
- }
- }
- HostedTransportConfigurationManager(MetabaseSettings metabaseSettings)
- {
- this.metabaseSettings = metabaseSettings;
- }
- [Fx.Tag.SecurityNote(Critical = "Calls Critical methods CreateMetabaseSettings.",
- Safe = "Ensures that only the correct, well-known method is called to construct the metabase settings. No other " +
- "details are leaked, and no control flow or data is allowed in.")]
- [SecuritySafeCritical]
- static MetabaseSettingsIis CreateWasHostingMetabaseSettings()
- {
- Type type = Type.GetType(MetabaseSettingsIis7FactoryTypeName, false);
- if (type == null)
- {
- throw FxTrace.Exception.AsError(new InvalidOperationException(SR.Hosting_MetabaseSettingsIis7TypeNotFound(MetabaseSettingsIis7FactoryTypeName, WasHostingAssemblyName)));
- }
- return CreateMetabaseSettings(type);
- }
- [SuppressMessage(FxCop.Category.Security, FxCop.Rule.SecureAsserts, Justification = "This is a private SecurityCritical method and its only caller passes in non-user data. Users cannot pass arbitrary data to this code.")]
- [Fx.Tag.SecurityNote(Critical = "Asserts full trust in order to call a well-known internal static in WasHosting.dll." +
- "Caller must ensure that 'type' argument refers to the trusted, well-known Type.")]
- [SecurityCritical]
- static MetabaseSettingsIis CreateMetabaseSettings(Type type)
- {
- object instance = null;
- MethodInfo method = type.GetMethod(CreateMetabaseSettingsIis7MethodName, BindingFlags.NonPublic | BindingFlags.Static);
- try
- {
- new PermissionSet(PermissionState.Unrestricted).Assert();
- instance = method.Invoke(null, null);
- }
- finally
- {
- PermissionSet.RevertAssert();
- }
- if (!(instance is MetabaseSettingsIis))
- {
- throw FxTrace.Exception.AsError(new InvalidOperationException(SR.Hosting_BadMetabaseSettingsIis7Type(type.AssemblyQualifiedName)));
- }
- return (MetabaseSettingsIis)instance;
- }
- internal static void EnsureInitializedForSimpleApplicationHost(HostedHttpRequestAsyncResult result)
- {
- if (singleton != null)
- {
- return;
- }
- lock (syncRoot)
- {
- if (singleton != null)
- return;
- singleton = new HostedTransportConfigurationManager(new MetabaseSettingsCassini(result));
- }
- }
- internal static MetabaseSettings MetabaseSettings
- {
- get
- {
- return HostedTransportConfigurationManager.Value.metabaseSettings;
- }
- }
- object ThisLock
- {
- get
- {
- return this;
- }
- }
- static HostedTransportConfigurationManager Value
- {
- get
- {
- if (singleton == null)
- {
- lock (syncRoot)
- {
- if (singleton == null)
- {
- //Ensure ETW tracing is initialized
- System.ServiceModel.Diagnostics.TraceUtility.SetEtwProviderId();
- if (TD.HostedTransportConfigurationManagerConfigInitStartIsEnabled())
- {
- TD.HostedTransportConfigurationManagerConfigInitStart();
- }
- ServiceHostingEnvironment.EnsureInitialized();
- singleton = new HostedTransportConfigurationManager();
- if (TD.HostedTransportConfigurationManagerConfigInitStopIsEnabled())
- {
- TD.HostedTransportConfigurationManagerConfigInitStop();
- }
- }
- }
- }
- return singleton;
- }
- }
- void EnsureInitialized()
- {
- if (!initialized)
- {
- lock (ThisLock)
- {
- if (!initialized)
- {
- // Register protocols.
- foreach (string protocol in metabaseSettings.GetProtocols())
- {
- // special case HTTP, it's a legacy protocol
- if (string.CompareOrdinal(protocol, Uri.UriSchemeHttp) == 0 ||
- string.CompareOrdinal(protocol, Uri.UriSchemeHttps) == 0)
- {
- HttpHostedTransportConfiguration httpConfiguration = null;
- if (string.CompareOrdinal(protocol, Uri.UriSchemeHttp) == 0)
- {
- httpConfiguration = new HttpHostedTransportConfiguration();
- }
- else
- {
- httpConfiguration = new HttpsHostedTransportConfiguration();
- }
- configurations.Add(protocol, httpConfiguration);
- }
- else
- {
- if (!Iis7Helper.IsIis7)
- {
- throw Fx.AssertAndThrowFatal("HostedTransportConfigurationManager.EnsureInitialized() protocols other than http and https can only be configured in IIS7");
- }
- if (AspNetPartialTrustHelpers.NeedPartialTrustInvoke)
- {
- throw FxTrace.Exception.AsError(new InvalidOperationException(SR.PartialTrustNonHttpActivation(protocol, HostingEnvironmentWrapper.ApplicationVirtualPath)));
- }
- AddHostedTransportConfigurationIis7(protocol);
- }
- }
- initialized = true;
- }
- }
- }
- }
- void AddHostedTransportConfigurationIis7(string protocol)
- {
- HostedTransportConfiguration configuration = null;
- try
- {
- ServiceHostingEnvironmentSection section = ServiceHostingEnvironmentSection.GetSection();
- if (section.TransportConfigurationTypes.ContainsKey(protocol))
- {
- TransportConfigurationTypeElement element = section.TransportConfigurationTypes[protocol];
- Debug.Print("HostedTransportConfigurationManager.AddHostedTransportConfigurationIis7() found TransportConfigurationTypes for protocol: " + protocol + " name: " + element.TransportConfigurationType);
- Type type = Type.GetType(element.TransportConfigurationType);
- configuration = Activator.CreateInstance(type) as HostedTransportConfiguration;
- configurations.Add(protocol, configuration);
- }
- else
- {
- throw FxTrace.Exception.AsError(new InvalidOperationException(SR.Hosting_ProtocolNoConfiguration(protocol)));
- }
- }
- catch (Exception exception)
- {
- if (!Fx.IsFatal(exception))
- {
- Debug.Print("HostedTransportConfigurationManager.AddHostedTransportConfigurationIis7() caught exception: " + exception);
- if (DiagnosticUtility.ShouldTraceError)
- {
- TraceUtility.TraceEvent(TraceEventType.Error, TraceCode.WebHostProtocolMisconfigured, SR.TraceCodeWebHostProtocolMisconfigured,
- new StringTraceRecord("Protocol", protocol),
- this, exception);
- }
- }
- throw;
- }
- }
- internal static Uri[] GetBaseAddresses(string virtualPath)
- {
- return HostedTransportConfigurationManager.Value.InternalGetBaseAddresses(virtualPath);
- }
- internal static HostedTransportConfiguration GetConfiguration(string scheme)
- {
- return HostedTransportConfigurationManager.Value.InternalGetConfiguration(scheme);
- }
- Uri[] InternalGetBaseAddresses(string virtualPath)
- {
- EnsureInitialized();
- List<Uri> baseAddresses = new List<Uri>();
- foreach (HostedTransportConfiguration configuration in configurations.Values)
- {
- baseAddresses.AddRange(configuration.GetBaseAddresses(virtualPath));
- }
- return baseAddresses.ToArray();
- }
- HostedTransportConfiguration InternalGetConfiguration(string scheme)
- {
- EnsureInitialized();
- if (!configurations.ContainsKey(scheme))
- {
- throw FxTrace.Exception.AsError(new InvalidOperationException(SR.Hosting_NotSupportedProtocol(scheme)));
- }
- return configurations[scheme];
- }
- }
- }