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, IDictionaryimplementedContracts, 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
- GlobalItem.cs
- NativeMethods.cs
- unsafenativemethodsother.cs
- PenThread.cs
- WeakReference.cs
- SqlGenericUtil.cs
- GenericWebPart.cs
- WorkflowMarkupSerializationException.cs
- SHA1CryptoServiceProvider.cs
- ExpressionBuilderCollection.cs
- Helper.cs
- FontStretch.cs
- Expr.cs
- FilterException.cs
- CacheForPrimitiveTypes.cs
- TemplatedMailWebEventProvider.cs
- SelectionPatternIdentifiers.cs
- SerializerWriterEventHandlers.cs
- TrustSection.cs
- SmiEventSink_Default.cs
- BamlVersionHeader.cs
- XmlDocumentFragment.cs
- RichTextBoxConstants.cs
- TcpServerChannel.cs
- AuthenticateEventArgs.cs
- ReflectionServiceProvider.cs
- ContentFilePart.cs
- TextTreeRootTextBlock.cs
- Vars.cs
- DataServiceQuery.cs
- SoapSchemaExporter.cs
- IndicShape.cs
- BitmapImage.cs
- FormatConvertedBitmap.cs
- OracleConnectionString.cs
- PagedDataSource.cs
- SimpleMailWebEventProvider.cs
- ProtocolsConfigurationHandler.cs
- ButtonStandardAdapter.cs
- XmlAnyElementAttributes.cs
- xml.cs
- SqlDataReaderSmi.cs
- UrlPropertyAttribute.cs
- Container.cs
- XmlElementAttributes.cs
- CompilerScopeManager.cs
- ValidationService.cs
- SqlDataSourceCache.cs
- relpropertyhelper.cs
- CompilerGlobalScopeAttribute.cs
- InstanceKeyCompleteException.cs
- ViewCellSlot.cs
- Vector3DAnimationBase.cs
- TextEditorCopyPaste.cs
- FieldNameLookup.cs
- SystemTcpStatistics.cs
- SqlNotificationEventArgs.cs
- XmlSchemaType.cs
- XmlSubtreeReader.cs
- Rect3DValueSerializer.cs
- StatusCommandUI.cs
- Profiler.cs
- AccessDataSourceWizardForm.cs
- FieldAccessException.cs
- DataGridViewAdvancedBorderStyle.cs
- ClassHandlersStore.cs
- PageAsyncTask.cs
- ContextMenuStrip.cs
- GridItemCollection.cs
- Vector3DAnimationUsingKeyFrames.cs
- PanelContainerDesigner.cs
- DiscoveryClientDocuments.cs
- CodeDOMProvider.cs
- HwndHost.cs
- OleDbPermission.cs
- FastEncoder.cs
- BindingMemberInfo.cs
- HttpProxyCredentialType.cs
- _NestedMultipleAsyncResult.cs
- SchemaDeclBase.cs
- MediaEntryAttribute.cs
- XmlNamespaceMappingCollection.cs
- OrderedDictionary.cs
- ToolStripContainerDesigner.cs
- ToolboxItemSnapLineBehavior.cs
- SubqueryTrackingVisitor.cs
- SocketInformation.cs
- NullExtension.cs
- DigitalSignature.cs
- TableStyle.cs
- WorkflowControlClient.cs
- XmlSchemaComplexContentExtension.cs
- ContractValidationHelper.cs
- EventListener.cs
- OraclePermission.cs
- TextFindEngine.cs
- StylusPointPropertyId.cs
- WarningException.cs
- SafeCertificateStore.cs
- ConfigXmlComment.cs