Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / NetFx35 / System.ServiceModel.Web / System / ServiceModel / Web / WebServiceHost.cs / 3 / WebServiceHost.cs
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------
namespace System.ServiceModel.Web
{
using System.IO;
using System.Collections.Generic;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.Diagnostics.CodeAnalysis;
using System.Configuration;
using System.Net;
using System.Web.Hosting;
using System.Web;
using System.Globalization;
using System.ServiceModel.Dispatcher;
using System.Web.Configuration;
using System.Runtime.CompilerServices;
public class WebServiceHost : ServiceHost
{
static bool isAspNetAuthenticationModeDetermined;
static bool isWindowsAuthentication;
public WebServiceHost()
: base()
{
}
public WebServiceHost(object singletonInstance, params Uri[] baseAddresses)
: base(singletonInstance, baseAddresses)
{
}
public WebServiceHost(Type serviceType, params Uri[] baseAddresses) :
base(serviceType, baseAddresses)
{
}
// This method adds automatic endpoints at the base addresses, 1 per site binding (http or https). It only configures
// the security on the binding. It does not add any behaviors.
// If there are no base addresses or endpoints have been configured explicitly at the base address it does not add any
// automatic endpoints.
// If it adds automatic endpoints, it validates that the service implements a single contract
internal static void AddAutomaticWebHttpBindingEndpoints(ServiceHost host, IDictionary implementedContracts, string multipleContractsErrorMessage)
{
AuthenticationSchemes supportedSchemes;
if (ServiceHostingEnvironment.IsHosted)
{
supportedSchemes = GetAuthenticationSchemes(host.BaseAddresses[0]);
}
else
{
supportedSchemes = AuthenticationSchemes.None;
}
Type contractType = null;
// add an endpoint with the contract at each base address
foreach (Uri baseAddress in host.BaseAddresses)
{
string uriScheme = baseAddress.Scheme;
// HTTP and HTTPs are only supported schemes
if (Object.ReferenceEquals(uriScheme, Uri.UriSchemeHttp) || Object.ReferenceEquals(uriScheme, Uri.UriSchemeHttps))
{
// bypass adding the automatic endpoint if there's already one at the base address
bool isExplicitEndpointConfigured = false;
foreach (ServiceEndpoint endpoint in host.Description.Endpoints)
{
if (endpoint.Address != null && EndpointAddress.UriEquals(endpoint.Address.Uri, baseAddress, true, false))
{
isExplicitEndpointConfigured = true;
break;
}
}
if (isExplicitEndpointConfigured)
{
continue;
}
if (contractType == null)
{
if (implementedContracts.Count != 1)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(multipleContractsErrorMessage));
}
foreach (ContractDescription contract in implementedContracts.Values)
{
contractType = contract.ContractType;
break;
}
}
WebHttpBinding binding = new WebHttpBinding();
if (Object.ReferenceEquals(uriScheme, Uri.UriSchemeHttps))
{
binding.Security.Mode = WebHttpSecurityMode.Transport;
}
else if (supportedSchemes != AuthenticationSchemes.None && supportedSchemes != AuthenticationSchemes.Anonymous)
{
binding.Security.Mode = WebHttpSecurityMode.TransportCredentialOnly;
}
else
{
binding.Security.Mode = WebHttpSecurityMode.None;
}
ServiceEndpoint automaticEndpoint = host.AddServiceEndpoint(contractType, binding, baseAddress);
if (ServiceHostingEnvironment.IsHosted)
{
SetBindingCredentialBasedOnHostedEnvironment(automaticEndpoint, supportedSchemes);
}
}
}
}
internal static AuthenticationSchemes GetAuthenticationSchemes(Uri baseAddress)
{
string fileName = VirtualPathUtility.GetFileName(baseAddress.AbsolutePath);
string virtualPath = ServiceHostingEnvironment.CurrentVirtualPath;
string completePath;
if (virtualPath != null && virtualPath.EndsWith("/", StringComparison.Ordinal))
{
completePath = virtualPath + fileName;
}
else
{
completePath = String.Format(CultureInfo.InvariantCulture, "{0}/{1}", virtualPath, fileName);
}
return HostedTransportConfigurationManager.MetabaseSettings.GetAuthenticationSchemes(completePath);
}
internal static void SetRawContentTypeMapperIfNecessary(ServiceEndpoint endpoint, bool isDispatch)
{
Binding binding = endpoint.Binding;
ContractDescription contract = endpoint.Contract;
if (binding == null)
{
return;
}
CustomBinding customBinding = new CustomBinding(binding);
BindingElementCollection bec = customBinding.Elements;
WebMessageEncodingBindingElement encodingElement = bec.Find();
if (encodingElement == null || encodingElement.ContentTypeMapper != null)
{
return;
}
bool areAllOperationsRawMapperCompatible = true;
int numStreamOperations = 0;
foreach (OperationDescription operation in contract.Operations)
{
bool isCompatible = (isDispatch) ? IsRawContentMapperCompatibleDispatchOperation(operation, ref numStreamOperations) : IsRawContentMapperCompatibleClientOperation(operation, ref numStreamOperations);
if (!isCompatible)
{
areAllOperationsRawMapperCompatible = false;
break;
}
}
if (areAllOperationsRawMapperCompatible && numStreamOperations > 0)
{
encodingElement.ContentTypeMapper = RawContentTypeMapper.Instance;
endpoint.Binding = customBinding;
}
}
protected override void OnOpening()
{
base.OnOpening();
if (this.Description == null)
{
return;
}
// disable other things that listen for GET at base address and may conflict with auto-endpoints
ServiceDebugBehavior sdb = this.Description.Behaviors.Find();
if (sdb != null)
{
sdb.HttpHelpPageEnabled = false;
sdb.HttpsHelpPageEnabled = false;
}
ServiceMetadataBehavior smb = this.Description.Behaviors.Find();
if (smb != null)
{
smb.HttpGetEnabled = false;
smb.HttpsGetEnabled = false;
}
AddAutomaticWebHttpBindingEndpoints(this, this.ImplementedContracts, SR2.GetString(SR2.HttpTransferServiceHostMultipleContracts, this.Description.Name));
// for both user-defined and automatic endpoints, ensure they have the right behavior and content type mapper added
foreach (ServiceEndpoint serviceEndpoint in this.Description.Endpoints)
{
if (serviceEndpoint.Binding != null && serviceEndpoint.Binding.CreateBindingElements().Find() != null)
{
SetRawContentTypeMapperIfNecessary(serviceEndpoint, true);
if (serviceEndpoint.Behaviors.Find() == null)
{
serviceEndpoint.Behaviors.Add(new WebHttpBehavior());
}
}
}
}
static bool IsRawContentMapperCompatibleClientOperation(OperationDescription operation, ref int numStreamOperations)
{
// An operation is raw encoder compatible on the client side iff the response is a Stream or void
// The request is driven by the format property on the message and not by the content type
if (operation.Messages.Count > 1 & !IsResponseStreamOrVoid(operation, ref numStreamOperations))
{
return false;
}
return true;
}
static bool IsRawContentMapperCompatibleDispatchOperation(OperationDescription operation, ref int numStreamOperations)
{
// An operation is raw encoder compatible on the dispatch side iff the request body is a Stream or void
// The response is driven by the format property on the message and not by the content type
UriTemplateDispatchFormatter throwAway = new UriTemplateDispatchFormatter(operation, null, new QueryStringConverter(), operation.DeclaringContract.Name, new Uri("http://localhost"));
int numUriVariables = throwAway.pathMapping.Count + throwAway.queryMapping.Count;
bool isRequestCompatible = false;
if (numUriVariables > 0)
{
// we need the local variable tmp because ref parameters are not allowed to be passed into
// anonymous methods by the compiler.
int tmp = 0;
WebHttpBehavior.HideRequestUriTemplateParameters(operation, throwAway, delegate()
{
isRequestCompatible = IsRequestStreamOrVoid(operation, ref tmp);
});
numStreamOperations += tmp;
}
else
{
isRequestCompatible = IsRequestStreamOrVoid(operation, ref numStreamOperations);
}
return isRequestCompatible;
}
static bool IsRequestStreamOrVoid(OperationDescription operation, ref int numStreamOperations)
{
MessageDescription message = operation.Messages[0];
if (WebHttpBehavior.IsTypedMessage(message) || WebHttpBehavior.IsUntypedMessage(message))
{
return false;
}
if (message.Body.Parts.Count == 0)
{
return true;
}
else if (message.Body.Parts.Count == 1)
{
if (IsStreamPart(message.Body.Parts[0].Type))
{
++numStreamOperations;
return true;
}
else if (IsVoidPart(message.Body.Parts[0].Type))
{
return true;
}
}
return false;
}
static bool IsResponseStreamOrVoid(OperationDescription operation, ref int numStreamOperations)
{
if (operation.Messages.Count < 1)
{
return true;
}
MessageDescription message = operation.Messages[1];
if (WebHttpBehavior.IsTypedMessage(message) || WebHttpBehavior.IsUntypedMessage(message))
{
return false;
}
if (message.Body.Parts.Count == 0)
{
if (message.Body.ReturnValue == null || IsVoidPart(message.Body.ReturnValue.Type))
{
return true;
}
else if (IsStreamPart(message.Body.ReturnValue.Type))
{
++numStreamOperations;
return true;
}
}
return false;
}
static bool IsStreamPart(Type type)
{
return (type == typeof(Stream));
}
static bool IsVoidPart(Type type)
{
return (type == null || type == typeof(void));
}
[MethodImpl(MethodImplOptions.NoInlining)]
static bool IsWindowsAuthenticationConfigured()
{
if (!isAspNetAuthenticationModeDetermined)
{
AuthenticationSection authSection = (AuthenticationSection) WebConfigurationManager.GetSection("system.web/authentication");
if (authSection != null)
{
isWindowsAuthentication = (authSection.Mode == AuthenticationMode.Windows);
}
isAspNetAuthenticationModeDetermined = true;
}
return isWindowsAuthentication;
}
// For automatic endpoints, in the hosted case we configure a credential type based on the vdir settings.
// For IIS, in IntegratedWindowsAuth mode we pick Negotiate.
// For Cassini, we alway pick Ntlm (Cassini always returns the supported schemes as Ntlm | Anonymous and the
// user cannot configure this.
static void SetBindingCredentialBasedOnHostedEnvironment(ServiceEndpoint serviceEndpoint, AuthenticationSchemes supportedSchemes)
{
if (ServiceHostingEnvironment.IsSimpleApplicationHost)
{
// Cassini always reports the auth scheme as anonymous or Ntlm. Map this to Ntlm, except when forms auth
// is requested
if (supportedSchemes == (AuthenticationSchemes.Anonymous | AuthenticationSchemes.Ntlm))
{
if (IsWindowsAuthenticationConfigured())
{
supportedSchemes = AuthenticationSchemes.Ntlm;
}
else
{
supportedSchemes = AuthenticationSchemes.Anonymous;
}
}
}
WebHttpBinding whb = serviceEndpoint.Binding as WebHttpBinding;
Fx.Assert(whb != null, "Automatic endpoint must be WebHttpBinding");
switch (supportedSchemes)
{
case AuthenticationSchemes.Digest:
whb.Security.Transport.ClientCredentialType = HttpClientCredentialType.Digest;
break;
case AuthenticationSchemes.IntegratedWindowsAuthentication:
// fall through to Negotiate
case AuthenticationSchemes.Negotiate:
whb.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
break;
case AuthenticationSchemes.Ntlm:
whb.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm;
break;
case AuthenticationSchemes.Basic:
whb.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
break;
case AuthenticationSchemes.Anonymous:
whb.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
break;
default:
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR2.GetString(
SR2.HttpTransferServiceHostBadAuthSchemes, supportedSchemes)));
}
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ClassHandlersStore.cs
- elementinformation.cs
- hresults.cs
- TimersDescriptionAttribute.cs
- Setter.cs
- Message.cs
- SdlChannelSink.cs
- WindowsSlider.cs
- ImageCodecInfoPrivate.cs
- TextPenaltyModule.cs
- CompositeTypefaceMetrics.cs
- AxisAngleRotation3D.cs
- XNodeValidator.cs
- AssertUtility.cs
- TraceShell.cs
- XPathAncestorQuery.cs
- GlyphCache.cs
- Stylesheet.cs
- VisualBasicValue.cs
- DownloadProgressEventArgs.cs
- Serializer.cs
- ADMembershipUser.cs
- AssemblyBuilderData.cs
- EntitySqlQueryState.cs
- HttpRuntimeSection.cs
- DuplicateWaitObjectException.cs
- errorpatternmatcher.cs
- Merger.cs
- AttributeEmitter.cs
- QilXmlReader.cs
- TextBoxDesigner.cs
- MemoryFailPoint.cs
- Stylus.cs
- BaseTemplateCodeDomTreeGenerator.cs
- GCHandleCookieTable.cs
- HtmlHistory.cs
- RuntimeConfig.cs
- CompilationUtil.cs
- NumericExpr.cs
- DataObjectPastingEventArgs.cs
- GridSplitterAutomationPeer.cs
- ResourceManager.cs
- Adorner.cs
- ImageListStreamer.cs
- SelectionProviderWrapper.cs
- HtmlElementEventArgs.cs
- EventListener.cs
- OdbcEnvironmentHandle.cs
- DetailsViewPageEventArgs.cs
- Thumb.cs
- SmiRecordBuffer.cs
- Font.cs
- ListViewSelectEventArgs.cs
- ProcessManager.cs
- VBIdentifierName.cs
- _ListenerResponseStream.cs
- ImageListUtils.cs
- DynamicILGenerator.cs
- HttpRawResponse.cs
- HideDisabledControlAdapter.cs
- EntityConnectionStringBuilderItem.cs
- ElementsClipboardData.cs
- EDesignUtil.cs
- RequestCacheEntry.cs
- RenderData.cs
- SoapReflectionImporter.cs
- GroupBoxAutomationPeer.cs
- Int16.cs
- ToolStripDropDownItem.cs
- RemotingSurrogateSelector.cs
- ProtectedProviderSettings.cs
- FormsAuthenticationModule.cs
- ListItemConverter.cs
- BufferedOutputStream.cs
- SessionStateItemCollection.cs
- DefaultParameterValueAttribute.cs
- LinqDataSource.cs
- OdbcStatementHandle.cs
- ClassicBorderDecorator.cs
- DescendentsWalkerBase.cs
- TemplateKeyConverter.cs
- SerializerWriterEventHandlers.cs
- RequestQueue.cs
- BaseUriHelper.cs
- UrlPropertyAttribute.cs
- RegexNode.cs
- AdjustableArrowCap.cs
- DesignerSerializationOptionsAttribute.cs
- GenericParameterDataContract.cs
- EventlogProvider.cs
- RootCodeDomSerializer.cs
- MimeXmlImporter.cs
- KeyConstraint.cs
- ClientScriptManager.cs
- JoinSymbol.cs
- ChangesetResponse.cs
- LinkedResource.cs
- RecognitionResult.cs
- _NtlmClient.cs
- TripleDESCryptoServiceProvider.cs