Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Channels / TransportChannelListener.cs / 1 / TransportChannelListener.cs
//------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------- namespace System.ServiceModel.Channels { using System.Collections.Generic; using System.Collections.ObjectModel; using System.ServiceModel; using System.ServiceModel.Activation; using System.Diagnostics; using System.IO; using System.Runtime.Serialization; using System.ServiceModel.Diagnostics; using System.ServiceModel.Description; using System.Text; using System.Threading; using System.Xml; using System.Net; abstract class TransportChannelListener : ChannelListenerBase, ITransportFactorySettings { static string exactGeneratedAddressPrefix; static string strongWildcardGeneratedAddressPrefix; static string weakWildcardGeneratedAddressPrefix; static object staticLock = new object(); Uri baseUri; BufferManager bufferManager; HostNameComparisonMode hostNameComparisonMode; bool inheritBaseAddressSettings; bool manualAddressing; long maxBufferPoolSize; long maxReceivedMessageSize; MessageEncoderFactory messageEncoderFactory; MessageVersion messageVersion; Uri uri; string hostedVirtualPath; MessageReceivedCallback messageReceivedCallback; ServiceSecurityAuditBehavior auditBehavior; ServiceModelActivity activity = null; TransportManagerContainer transportManagerContainer; protected TransportChannelListener(TransportBindingElement bindingElement, BindingContext context) : this(bindingElement, context, TransportDefaults.GetDefaultMessageEncoderFactory()) { } protected TransportChannelListener(TransportBindingElement bindingElement, BindingContext context, MessageEncoderFactory defaultMessageEncoderFactory) : this(bindingElement, context, defaultMessageEncoderFactory, TransportDefaults.HostNameComparisonMode) { } protected TransportChannelListener(TransportBindingElement bindingElement, BindingContext context, HostNameComparisonMode hostNameComparisonMode) : this(bindingElement, context, TransportDefaults.GetDefaultMessageEncoderFactory(), hostNameComparisonMode) { } protected TransportChannelListener(TransportBindingElement bindingElement, BindingContext context, MessageEncoderFactory defaultMessageEncoderFactory, HostNameComparisonMode hostNameComparisonMode) : base(context.Binding) { HostNameComparisonModeHelper.Validate(hostNameComparisonMode); this.hostNameComparisonMode = hostNameComparisonMode; this.manualAddressing = bindingElement.ManualAddressing; this.maxBufferPoolSize = bindingElement.MaxBufferPoolSize; this.maxReceivedMessageSize = bindingElement.MaxReceivedMessageSize; CollectionmessageEncoderBindingElements = context.BindingParameters.FindAll (); if (messageEncoderBindingElements.Count > 1) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.MultipleMebesInParameters))); } else if (messageEncoderBindingElements.Count == 1) { this.messageEncoderFactory = messageEncoderBindingElements[0].CreateMessageEncoderFactory(); context.BindingParameters.Remove (); } else { this.messageEncoderFactory = defaultMessageEncoderFactory; } if (null != this.messageEncoderFactory) this.messageVersion = this.messageEncoderFactory.MessageVersion; else this.messageVersion = MessageVersion.None; ServiceSecurityAuditBehavior auditBehavior = context.BindingParameters.Find (); if (auditBehavior != null) { this.auditBehavior = auditBehavior.Clone(); } else { this.auditBehavior = new ServiceSecurityAuditBehavior(); } if ((context.ListenUriMode == ListenUriMode.Unique) && (context.ListenUriBaseAddress == null)) { UriBuilder uriBuilder = new UriBuilder(this.Scheme, DnsCache.MachineName); uriBuilder.Path = this.GeneratedAddressPrefix; context.ListenUriBaseAddress = uriBuilder.Uri; } UriSchemeKeyedCollection.ValidateBaseAddress(context.ListenUriBaseAddress, "baseAddress"); if (context.ListenUriBaseAddress.Scheme != this.Scheme) { // URI schemes are case-insensitive, so try a case insensitive compare now if (string.Compare(context.ListenUriBaseAddress.Scheme, this.Scheme, StringComparison.OrdinalIgnoreCase) != 0) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument( "context.ListenUriBaseAddress", SR.GetString(SR.InvalidUriScheme, context.ListenUriBaseAddress.Scheme, this.Scheme)); } } DiagnosticUtility.DebugAssert(context.ListenUriRelativeAddress != null, ""); // validated by BindingContext if (context.ListenUriMode == ListenUriMode.Explicit) { this.SetUri(context.ListenUriBaseAddress, context.ListenUriRelativeAddress); } else // ListenUriMode.Unique: { string relativeAddress = context.ListenUriRelativeAddress; if (relativeAddress.Length > 0 && !relativeAddress.EndsWith("/", StringComparison.Ordinal)) { relativeAddress += "/"; } this.SetUri(context.ListenUriBaseAddress, relativeAddress + Guid.NewGuid().ToString()); } this.transportManagerContainer = new TransportManagerContainer(this); } internal ServiceModelActivity Activity { get { return this.activity; } set { this.activity = value; } } internal Uri BaseUri { get { return this.baseUri; } } string GeneratedAddressPrefix { get { // We use different address prefixes based on hostname comparison mode in order to avoid creating // starved reservations. For example, if we register http://+:80/TLA/G1 and http://*:80/TLA/G1, the // latter will never receive any traffic. We handle this case by instead using http://+:80/TLA/G1 // and http://*:80/TLA/G2. switch (this.hostNameComparisonMode) { case HostNameComparisonMode.Exact: return GetGeneratedAddressPrefix(ref exactGeneratedAddressPrefix); case HostNameComparisonMode.StrongWildcard: return GetGeneratedAddressPrefix(ref strongWildcardGeneratedAddressPrefix); case HostNameComparisonMode.WeakWildcard: return GetGeneratedAddressPrefix(ref weakWildcardGeneratedAddressPrefix); default: DiagnosticUtility.DebugAssert("invalid HostnameComparisonMode value"); return null; } } } internal string HostedVirtualPath { get { return this.hostedVirtualPath; } } internal bool InheritBaseAddressSettings { get { return this.inheritBaseAddressSettings; } set { this.inheritBaseAddressSettings = value; } } internal ServiceSecurityAuditBehavior AuditBehavior { get { return this.auditBehavior; } } public BufferManager BufferManager { get { return this.bufferManager; } } internal HostNameComparisonMode HostNameComparisonModeInternal { get { return this.hostNameComparisonMode; } } public bool ManualAddressing { get { return this.manualAddressing; } } public long MaxBufferPoolSize { get { return this.maxBufferPoolSize; } } public virtual long MaxReceivedMessageSize { get { return maxReceivedMessageSize; } } public MessageEncoderFactory MessageEncoderFactory { get { return this.messageEncoderFactory; } } public MessageVersion MessageVersion { get { return this.messageVersion; } } internal abstract UriPrefixTable TransportManagerTable { get; } public abstract string Scheme { get; } public override Uri Uri { get { return uri; } } public override T GetProperty () { if (typeof(T) == typeof(MessageVersion)) { return (T)(object)this.MessageVersion; } if (typeof(T) == typeof(FaultConverter)) { if (null == this.MessageEncoderFactory) return null; else return this.MessageEncoderFactory.Encoder.GetProperty (); } return base.GetProperty (); } internal bool IsScopeIdCompatible(HostNameComparisonMode hostNameComparisonMode, Uri uri) { if (this.hostNameComparisonMode != hostNameComparisonMode) { return false; } if (hostNameComparisonMode == HostNameComparisonMode.Exact && uri.HostNameType == UriHostNameType.IPv6) { // the hostname type of the channel listener MUST be IPv6 if we got here. // as this should have been enforced by UriPrefixTable. if (this.Uri.HostNameType != UriHostNameType.IPv6) { return false; } IPAddress channelListenerIP = IPAddress.Parse(this.Uri.DnsSafeHost); IPAddress otherIP = IPAddress.Parse(uri.DnsSafeHost); if (channelListenerIP.ScopeId != otherIP.ScopeId) { return false; } } return true; } internal virtual void ApplyHostedContext(VirtualPathExtension virtualPathExtension, bool isMetadataListener) { // Save the original hosted virtual path. this.hostedVirtualPath = virtualPathExtension.VirtualPath; } static Uri AddSegment(Uri baseUri, Uri fullUri) { Uri result = null; if (baseUri.AbsolutePath.Length < fullUri.AbsolutePath.Length) { UriBuilder builder = new UriBuilder(baseUri); TcpChannelListener.FixIpv6Hostname(builder, baseUri); if (!builder.Path.EndsWith("/", StringComparison.Ordinal)) { builder.Path = builder.Path + "/"; baseUri = builder.Uri; } Uri relativeUri = baseUri.MakeRelativeUri(fullUri); string relativePath = relativeUri.OriginalString; int slashIndex = relativePath.IndexOf('/'); string segment = (slashIndex == -1) ? relativePath : relativePath.Substring(0, slashIndex); builder.Path = builder.Path + segment; result = builder.Uri; } return result; } internal virtual ITransportManagerRegistration CreateTransportManagerRegistration() { return this.CreateTransportManagerRegistration(this.BaseUri); } internal abstract ITransportManagerRegistration CreateTransportManagerRegistration(Uri listenUri); static string GetGeneratedAddressPrefix(ref string generatedAddressPrefix) { if (generatedAddressPrefix == null) { lock (staticLock) { if (generatedAddressPrefix == null) { // we use the ephemeral namespace prefix plus a GUID for our App-Domain (which is the // extent to which we can share a TransportManager prefix) generatedAddressPrefix = "Temporary_Listen_Addresses/" + Guid.NewGuid().ToString(); } } } return generatedAddressPrefix; } internal virtual int GetMaxBufferSize() { if (MaxReceivedMessageSize > int.MaxValue) return int.MaxValue; else return (int)MaxReceivedMessageSize; } protected override void OnOpening() { base.OnOpening(); // Copy the HostNameComparisonMode. if (HostedVirtualPath != null) { HostedTransportConfigurationBase hostedConfiguration = HostedTransportConfigurationManager.GetConfiguration(this.Scheme) as HostedTransportConfigurationBase; if (hostedConfiguration != null) { BaseUriWithWildcard baseAddress = hostedConfiguration.FindBaseAddress(this.Uri); if (baseAddress != null) { this.hostNameComparisonMode = baseAddress.HostNameComparisonMode; } else { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.Hosting_TransportBindingNotFound, this.Uri.ToString()))); } } } this.bufferManager = BufferManager.CreateBufferManager(MaxBufferPoolSize, GetMaxBufferSize()); } protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state) { return this.transportManagerContainer.BeginOpen( new SelectTransportManagersCallback(this.SelectTransportManagers), callback, state); } protected override void OnEndOpen(IAsyncResult result) { this.transportManagerContainer.EndOpen(result); } protected override void OnOpen(TimeSpan timeout) { this.transportManagerContainer.Open(new SelectTransportManagersCallback(this.SelectTransportManagers)); } protected override void OnOpened() { if (DiagnosticUtility.ShouldTraceVerbose) { TraceUtility.TraceEvent(TraceEventType.Verbose, TraceCode.OpenedListener, new UriTraceRecord(this.Uri), this, null); } base.OnOpened(); } internal TransportManagerContainer GetTransportManagers() { return TransportManagerContainer.TransferTransportManagers(this.transportManagerContainer); } protected override void OnAbort() { this.transportManagerContainer.Close(); } protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state) { return this.transportManagerContainer.BeginClose(timeout, callback, state); } protected override void OnEndClose(IAsyncResult result) { this.transportManagerContainer.EndClose(result); } protected override void OnClose(TimeSpan timeout) { this.transportManagerContainer.Close(); } protected override void OnClosed() { base.OnClosed(); if (this.bufferManager != null) { this.bufferManager.Clear(); } } bool TryGetTransportManagerRegistration(out ITransportManagerRegistration registration) { if (!InheritBaseAddressSettings) { return TryGetTransportManagerRegistration(this.hostNameComparisonMode, out registration); } if (TryGetTransportManagerRegistration(HostNameComparisonMode.StrongWildcard, out registration)) { return true; } if (TryGetTransportManagerRegistration(HostNameComparisonMode.Exact, out registration)) { return true; } if (TryGetTransportManagerRegistration(HostNameComparisonMode.WeakWildcard, out registration)) { return true; } registration = null; return false; } protected virtual bool TryGetTransportManagerRegistration(HostNameComparisonMode hostNameComparisonMode, out ITransportManagerRegistration registration) { return this.TransportManagerTable.TryLookupUri(this.Uri, hostNameComparisonMode, out registration); } // This is virtual so that PeerChannelListener and MsmqChannelListener can override it. // Will be called under "lock (this.TransportManagerTable)" from TransportManagerContainer.Open internal virtual IList SelectTransportManagers() { IList foundTransportManagers = null; // Look up an existing transport manager registration. ITransportManagerRegistration registration; if (!TryGetTransportManagerRegistration(out registration)) { if (DiagnosticUtility.ShouldTraceVerbose) { TraceUtility.TraceEvent(TraceEventType.Verbose, TraceCode.NoExistingTransportManager, new UriTraceRecord(this.Uri), this, null); } // Don't create TransportManagerRegistration in hosted case. if (this.HostedVirtualPath == null) { // Create a new registration at the default point in the URI hierarchy. registration = this.CreateTransportManagerRegistration(); this.TransportManagerTable.RegisterUri(registration.ListenUri, this.hostNameComparisonMode, registration); } } // Use the registration to select/create a set of compatible transport managers. if (registration != null) { foundTransportManagers = registration.Select(this); if (foundTransportManagers == null) { if (DiagnosticUtility.ShouldTraceInformation) { TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.IncompatibleExistingTransportManager, new UriTraceRecord(this.Uri), this, null); } // Don't create TransportManagerRegistration in hosted case. if (this.HostedVirtualPath == null) { // Create a new registration one segment down from the existing incompatible registration. Uri nextUri = AddSegment(registration.ListenUri, this.Uri); if (nextUri != null) { registration = this.CreateTransportManagerRegistration(nextUri); this.TransportManagerTable.RegisterUri(nextUri, this.hostNameComparisonMode, registration); foundTransportManagers = registration.Select(this); } } } } if (foundTransportManagers == null) { ThrowTransportManagersNotFound(); } return foundTransportManagers; } void ThrowTransportManagersNotFound() { if (this.HostedVirtualPath != null) { if ((String.Compare(this.Uri.Scheme, Uri.UriSchemeHttp, StringComparison.OrdinalIgnoreCase) == 0) || (String.Compare(this.Uri.Scheme, Uri.UriSchemeHttps, StringComparison.OrdinalIgnoreCase) == 0) ) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new InvalidOperationException( SR.GetString(SR.Hosting_NoHttpTransportManagerForUri, this.Uri))); } else if ((String.Compare(this.Uri.Scheme, Uri.UriSchemeNetTcp, StringComparison.OrdinalIgnoreCase) == 0) || (String.Compare(this.Uri.Scheme, Uri.UriSchemeNetPipe, StringComparison.OrdinalIgnoreCase) == 0) ) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new InvalidOperationException(SR.GetString( SR.Hosting_NoTcpPipeTransportManagerForUri, this.Uri))); } } throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString( SR.NoCompatibleTransportManagerForUri, this.Uri))); } protected void SetUri(Uri baseAddress, string relativeAddress) { Uri fullUri = baseAddress; // Ensure that baseAddress Path does end with a slash if we have a relative address if (relativeAddress != string.Empty) { if (!baseAddress.AbsolutePath.EndsWith("/", StringComparison.Ordinal)) { UriBuilder uriBuilder = new UriBuilder(baseAddress); TcpChannelListener.FixIpv6Hostname(uriBuilder, baseAddress); uriBuilder.Path = uriBuilder.Path + "/"; baseAddress = uriBuilder.Uri; } fullUri = new Uri(baseAddress, relativeAddress); // now see if we need to update our base address (for cases like relative path = "/foo") if (!baseAddress.IsBaseOf(fullUri)) { baseAddress = fullUri; } } this.baseUri = baseAddress; ValidateUri(fullUri); this.uri = fullUri; } protected virtual void ValidateUri(Uri uri) { } long ITransportFactorySettings.MaxReceivedMessageSize { get { return MaxReceivedMessageSize; } } BufferManager ITransportFactorySettings.BufferManager { get { return BufferManager; } } bool ITransportFactorySettings.ManualAddressing { get { return ManualAddressing; } } MessageEncoderFactory ITransportFactorySettings.MessageEncoderFactory { get { return this.MessageEncoderFactory; } } internal void SetMessageReceivedCallback(MessageReceivedCallback messageReceivedCallback) { this.messageReceivedCallback = messageReceivedCallback; } internal void RaiseMessageReceived() { if (messageReceivedCallback != null) { messageReceivedCallback(); } } } interface ITransportManagerRegistration { HostNameComparisonMode HostNameComparisonMode { get; } Uri ListenUri { get; } IList Select(TransportChannelListener factory); } abstract class TransportManagerRegistration : ITransportManagerRegistration { HostNameComparisonMode hostNameComparisonMode; Uri listenUri; protected TransportManagerRegistration(Uri listenUri, HostNameComparisonMode hostNameComparisonMode) { this.listenUri = listenUri; this.hostNameComparisonMode = hostNameComparisonMode; } public HostNameComparisonMode HostNameComparisonMode { get { return this.hostNameComparisonMode; } } public Uri ListenUri { get { return this.listenUri; } } public abstract IList Select(TransportChannelListener factory); } class UriTraceRecord : TraceRecord { Uri uri; public UriTraceRecord(Uri uri) { DiagnosticUtility.DebugAssert(uri != null, "UriTraceRecord: Uri is null"); this.uri = uri; } internal override void WriteTo(XmlWriter xml) { xml.WriteElementString("Uri", this.uri.AbsoluteUri); } } } // 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
- ColumnCollection.cs
- SafeNativeMethodsMilCoreApi.cs
- ContentHostHelper.cs
- QuaternionAnimation.cs
- Token.cs
- Executor.cs
- DataGridTextBoxColumn.cs
- Rotation3DAnimation.cs
- Single.cs
- DbMetaDataCollectionNames.cs
- Attributes.cs
- GridViewRowCollection.cs
- indexingfiltermarshaler.cs
- CommandPlan.cs
- HtmlSelectionListAdapter.cs
- FramingFormat.cs
- WebPartMenuStyle.cs
- WorkflowInstanceContextProvider.cs
- Misc.cs
- FormatterConverter.cs
- HtmlShimManager.cs
- DocumentOrderQuery.cs
- TextBox.cs
- SmtpDigestAuthenticationModule.cs
- TableLayoutRowStyleCollection.cs
- HttpVersion.cs
- VerbConverter.cs
- Interlocked.cs
- WindowsAuthenticationEventArgs.cs
- Base64Encoder.cs
- XhtmlBasicLiteralTextAdapter.cs
- GridViewEditEventArgs.cs
- Validator.cs
- InvalidProgramException.cs
- PlatformCulture.cs
- ComplexLine.cs
- NodeCounter.cs
- EntityUtil.cs
- Compilation.cs
- FixedTextPointer.cs
- DocumentPaginator.cs
- ToolStripManager.cs
- SplitterPanel.cs
- SchemaMapping.cs
- ModuleConfigurationInfo.cs
- TaskForm.cs
- CfgParser.cs
- ApplicationFileCodeDomTreeGenerator.cs
- UpdateCommand.cs
- DmlSqlGenerator.cs
- EntityContainerEntitySet.cs
- CommandBinding.cs
- EmptyReadOnlyDictionaryInternal.cs
- KoreanLunisolarCalendar.cs
- FontSourceCollection.cs
- AsyncStreamReader.cs
- MediaPlayerState.cs
- CodeTypeConstructor.cs
- TreeWalkHelper.cs
- MatrixValueSerializer.cs
- RelationshipEndMember.cs
- SettingsBindableAttribute.cs
- SizeF.cs
- ContextStaticAttribute.cs
- EnlistmentState.cs
- SQLSingle.cs
- SeverityFilter.cs
- PersonalizationProvider.cs
- TransformDescriptor.cs
- validation.cs
- OptimizerPatterns.cs
- OletxVolatileEnlistment.cs
- KeyTimeConverter.cs
- VirtualPathUtility.cs
- AnimationException.cs
- ListDictionaryInternal.cs
- DataServiceRequestException.cs
- NamedPipeAppDomainProtocolHandler.cs
- Transform3DGroup.cs
- WindowsFormsHostAutomationPeer.cs
- TransformValueSerializer.cs
- BaseTemplateBuildProvider.cs
- BStrWrapper.cs
- FilteredDataSetHelper.cs
- Claim.cs
- AsyncResult.cs
- StructuralType.cs
- DiscoveryReference.cs
- RegexCompilationInfo.cs
- DbConnectionStringCommon.cs
- ProcessHostFactoryHelper.cs
- OutArgument.cs
- ComponentEditorForm.cs
- OdbcReferenceCollection.cs
- ProviderIncompatibleException.cs
- ClientScriptManagerWrapper.cs
- ProgressBarHighlightConverter.cs
- GridViewRowEventArgs.cs
- PathFigureCollectionConverter.cs
- CorePropertiesFilter.cs