Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Channels / SharedHttpTransportManager.cs / 1 / SharedHttpTransportManager.cs
//---------------------------------------------------------------------------- // Copyright (c) Microsoft Corporation. All rights reserved. //--------------------------------------------------------------------------- namespace System.ServiceModel.Channels { using System.Diagnostics; using System.ServiceModel; using System.Net; using System.ServiceModel.Diagnostics; using System.ServiceModel.Dispatcher; using System.Threading; using System.Security.Principal; class SharedHttpTransportManager : HttpTransportManager { const int maxPendingGetContexts = 10; #if DEBUG // add performance counter instead in v.Next - see MessageBus bug #54117 int currentPendingGetContexts; #endif HttpListener listener; ManualResetEvent listenStartedEvent; Exception listenStartedException; AsyncCallback onGetContext; ItemDequeuedCallback onMessageDequeued; WaitCallback onCompleteGetContextLater; bool unsafeConnectionNtlmAuthentication; internal SharedHttpTransportManager(Uri listenUri, HttpChannelListener channelListener) : base(listenUri, channelListener.HostNameComparisonMode, channelListener.Realm) { this.onGetContext = DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(OnGetContext)); this.onMessageDequeued = new ItemDequeuedCallback(OnMessageDequeued); this.unsafeConnectionNtlmAuthentication = channelListener.UnsafeConnectionNtlmAuthentication; } internal override bool IsCompatible(HttpChannelListener channelListener) { if (channelListener.InheritBaseAddressSettings) return true; if (!channelListener.IsScopeIdCompatible(HostNameComparisonMode, this.ListenUri)) { return false; } return channelListener.UnsafeConnectionNtlmAuthentication == this.unsafeConnectionNtlmAuthentication && base.IsCompatible(channelListener); } internal override void OnClose() { try { listener.Stop(); } finally { try { listener.Close(); } finally { base.OnClose(); } } listener = null; } IAsyncResult BeginGetContext(AsyncCallback callback, object state, bool startListening) { while (true) { Exception unexpectedException = null; try { try { if (ExecutionContext.IsFlowSuppressed()) { return listener.BeginGetContext(callback, state); } else { using (ExecutionContext.SuppressFlow()) { return listener.BeginGetContext(callback, state); } } } catch (HttpListenerException e) { switch (e.ErrorCode) { case UnsafeNativeMethods.ERROR_NOT_ENOUGH_MEMORY: case UnsafeNativeMethods.ERROR_OUTOFMEMORY: case UnsafeNativeMethods.ERROR_NO_SYSTEM_RESOURCES: throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InsufficientMemoryException(SR.GetString(SR.InsufficentMemory), e)); default: if (!ExceptionHandler.HandleTransportExceptionHelper(e)) throw; break; } } } catch (Exception e) { if (DiagnosticUtility.IsFatal(e)) { throw; } if (startListening) { // Since we're under a call to StartListening(), just throw the exception up the stack. throw; } unexpectedException = e; } if (unexpectedException != null) { this.Fault(unexpectedException); return null; } } } void OnGetContext(IAsyncResult result) { if (result.CompletedSynchronously) { return; } OnGetContextCore(result); } void OnGetContextCore(IAsyncResult result) { bool enqueued = false; while (!enqueued) { Exception unexpectedException = null; try { try { HttpListenerContext listenerContext = null; lock (base.ThisLock) { if (listener == null) // we've been closed return; listenerContext = listener.EndGetContext(result); DiagnosticUtility.DebugAssert(listenerContext != null && listenerContext.Request != null, ""); } HttpChannelListener channelListener = null; // Grab the activity from the context and set that as the surrounding activity. // If a message appears, we will transfer to the message's activity next using (DiagnosticUtility.ShouldUseActivity ? ServiceModelActivity.BoundOperation(this.Activity) : null) { using (ServiceModelActivity activity = DiagnosticUtility.ShouldUseActivity ? ServiceModelActivity.CreateBoundedActivityWithTransferInOnly(listenerContext.Request.RequestTraceIdentifier) : null) { if (activity != null && DiagnosticUtility.ShouldUseActivity) { ServiceModelActivity.Start(activity, SR.GetString(SR.ActivityReceiveBytes, listenerContext.Request.Url.ToString()), ActivityType.ReceiveBytes); } if (DiagnosticUtility.ShouldTraceInformation) { TraceUtility.TraceHttpConnectionInformation(listenerContext.Request.LocalEndPoint.ToString(), listenerContext.Request.RemoteEndPoint.ToString(), this); } if (base.TryLookupUri(listenerContext.Request.Url, listenerContext.Request.HttpMethod, this.HostNameComparisonMode, out channelListener)) { enqueued = channelListener.HttpContextReceived( HttpRequestContext.CreateContext(channelListener, listenerContext), onMessageDequeued); #if DEBUG // add performance counter instead in v.Next - see MessageBus bug #54117 if (enqueued) { bool traceLimit = false; lock (ThisLock) { currentPendingGetContexts++; if (currentPendingGetContexts >= maxPendingGetContexts) { traceLimit = true; } } if (traceLimit) { if (DiagnosticUtility.ShouldTraceWarning) { DiagnosticUtility.DiagnosticTrace.TraceEvent(TraceEventType.Warning, TraceCode.HttpChannelConcurrentReceiveQuotaReached, SR.GetString(SR.HttpConcurrentReceiveQuotaReached, maxPendingGetContexts)); } } } #endif } else { if (DiagnosticUtility.ShouldTraceWarning) { TraceUtility.TraceEvent(TraceEventType.Warning, TraceCode.HttpChannelMessageReceiveFailed, null); } // no match -- 405 or 404 if (string.Compare(listenerContext.Request.HttpMethod, "POST", StringComparison.OrdinalIgnoreCase) != 0) { listenerContext.Response.StatusCode = (int)HttpStatusCode.MethodNotAllowed; listenerContext.Response.Headers.Add(HttpResponseHeader.Allow, "POST"); } else { listenerContext.Response.StatusCode = (int)HttpStatusCode.NotFound; } listenerContext.Response.ContentLength64 = 0; listenerContext.Response.Close(); } } } } catch (HttpListenerException e) { switch (e.ErrorCode) { case UnsafeNativeMethods.ERROR_NOT_ENOUGH_MEMORY: case UnsafeNativeMethods.ERROR_OUTOFMEMORY: case UnsafeNativeMethods.ERROR_NO_SYSTEM_RESOURCES: throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InsufficientMemoryException(SR.GetString(SR.InsufficentMemory), e)); default: if (!ExceptionHandler.HandleTransportExceptionHelper(e)) throw; break; } } } catch (Exception exception) { if (DiagnosticUtility.IsFatal(exception)) { throw; } unexpectedException = exception; } if (unexpectedException != null) { this.Fault(unexpectedException); } if (!enqueued) // onMessageDequeued will handle this in the enqueued case { lock (base.ThisLock) { if (listener != null) { result = BeginGetContext(onGetContext, null, false); if ((result == null) || !result.CompletedSynchronously) { return; } } } } } } void OnCompleteGetContextLater(object state) { OnGetContextCore((IAsyncResult)state); } void StartListening() { for (int i = 0; i < maxPendingGetContexts; i++) { IAsyncResult result = BeginGetContext(onGetContext, null, true); if (result.CompletedSynchronously) { if (onCompleteGetContextLater == null) { onCompleteGetContextLater = new WaitCallback(OnCompleteGetContextLater); } IOThreadScheduler.ScheduleCallback(onCompleteGetContextLater, result); } } } void OnListening(object state) { try { StartListening(); } catch (Exception e) { if (DiagnosticUtility.IsFatal(e)) { throw; } listenStartedException = e; } finally { listenStartedEvent.Set(); } } void OnMessageDequeued() { ThreadTrace.Trace("message dequeued"); IAsyncResult result = null; lock (base.ThisLock) { if (listener != null) { #if DEBUG // add performance counter instead in v.Next - see MessageBus bug #54117 currentPendingGetContexts--; #endif result = BeginGetContext(onGetContext, null, false); } } if (result != null && result.CompletedSynchronously) { if (onCompleteGetContextLater == null) { onCompleteGetContextLater = new WaitCallback(OnCompleteGetContextLater); } IOThreadScheduler.ScheduleCallback(onCompleteGetContextLater, result); } } internal override void OnOpen() { listener = new HttpListener(); string host; switch (HostNameComparisonMode) { case HostNameComparisonMode.Exact: // Uri.DnsSafeHost strips the [], but preserves the scopeid for IPV6 addresses. if (ListenUri.HostNameType == UriHostNameType.IPv6) { host = string.Concat("[", ListenUri.DnsSafeHost, "]"); } else { host = ListenUri.DnsSafeHost; } break; case HostNameComparisonMode.StrongWildcard: host = "+"; break; case HostNameComparisonMode.WeakWildcard: host = "*"; break; default: throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.UnrecognizedHostNameComparisonMode, HostNameComparisonMode.ToString()))); } string path = ListenUri.GetComponents(UriComponents.Path, UriFormat.Unescaped); if (!path.StartsWith("/", StringComparison.Ordinal)) path = "/" + path; if (!path.EndsWith("/", StringComparison.Ordinal)) path = path + "/"; string httpListenUrl = string.Concat(Scheme, "://", host, ":", ListenUri.Port, path); listener.UnsafeConnectionNtlmAuthentication = this.unsafeConnectionNtlmAuthentication; listener.AuthenticationSchemeSelectorDelegate = new AuthenticationSchemeSelector(SelectAuthenticationScheme); if (this.Realm != null) { listener.Realm = this.Realm; } bool success = false; try { listener.Prefixes.Add(httpListenUrl); listener.Start(); bool startedListening = false; try { if (Thread.CurrentThread.IsThreadPoolThread) { StartListening(); } else { // If we're not on a threadpool thread, then we need to post a callback to start our accepting loop // Otherwise if the calling thread aborts then the async I/O will get inadvertantly cancelled listenStartedEvent = new ManualResetEvent(false); IOThreadScheduler.ScheduleCallback(OnListening, null); listenStartedEvent.WaitOne(); listenStartedEvent.Close(); listenStartedEvent = null; if (listenStartedException != null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(listenStartedException); } } startedListening = true; } finally { if (!startedListening) { listener.Stop(); } } success = true; } catch (HttpListenerException listenerException) { switch (listenerException.NativeErrorCode) { case UnsafeNativeMethods.ERROR_ALREADY_EXISTS: throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new AddressAlreadyInUseException(SR.GetString(SR.HttpRegistrationAlreadyExists, httpListenUrl), listenerException)); case UnsafeNativeMethods.ERROR_SHARING_VIOLATION: throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new AddressAlreadyInUseException(SR.GetString(SR.HttpRegistrationPortInUse, httpListenUrl, ListenUri.Port), listenerException)); case UnsafeNativeMethods.ERROR_ACCESS_DENIED: throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new AddressAccessDeniedException(SR.GetString(SR.HttpRegistrationAccessDenied, httpListenUrl), listenerException)); case UnsafeNativeMethods.ERROR_ALLOTTED_SPACE_EXCEEDED: throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new CommunicationException(SR.GetString(SR.HttpRegistrationLimitExceeded, httpListenUrl), listenerException)); case UnsafeNativeMethods.ERROR_INVALID_PARAMETER: throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.HttpInvalidListenURI, ListenUri.OriginalString), listenerException)); default: throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( HttpChannelUtilities.CreateCommunicationException(listenerException)); } } finally { if (!success) { listener.Abort(); } } } AuthenticationSchemes SelectAuthenticationScheme(HttpListenerRequest request) { try { AuthenticationSchemes result; HttpChannelListener channelListener; if (base.TryLookupUri(request.Url, request.HttpMethod, this.HostNameComparisonMode, out channelListener)) { result = channelListener.AuthenticationScheme; } else { // if we don't match a listener factory, we want to "fall through" the // auth delegate code and run through our normal OnGetContext codepath. // System.Net treats "None" as Access Denied, which is not our intent here. // In most cases this will just fall through to the code that returns a "404 Not Found" result = AuthenticationSchemes.Anonymous; } return result; } catch (Exception e) { DiagnosticUtility.ExceptionUtility.TraceHandledException(e, TraceEventType.Error); throw; } } } } // 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
- _ConnectionGroup.cs
- HijriCalendar.cs
- Environment.cs
- ObjectHelper.cs
- LinqExpressionNormalizer.cs
- EntityDataSource.cs
- SelectorItemAutomationPeer.cs
- ToolStripMenuItem.cs
- SQLBinary.cs
- ButtonColumn.cs
- QuotedPrintableStream.cs
- GregorianCalendar.cs
- TypeToArgumentTypeConverter.cs
- RemotingConfiguration.cs
- HtmlMeta.cs
- ParentUndoUnit.cs
- ProfileService.cs
- _SslState.cs
- ProviderConnectionPointCollection.cs
- SinglePageViewer.cs
- FilteredAttributeCollection.cs
- UIElement3D.cs
- TiffBitmapDecoder.cs
- ProcessHostMapPath.cs
- WebSysDisplayNameAttribute.cs
- SerializableAttribute.cs
- SkewTransform.cs
- TypeBuilderInstantiation.cs
- DataServiceQuery.cs
- InputChannel.cs
- NonBatchDirectoryCompiler.cs
- Stylesheet.cs
- DrawingCollection.cs
- ImageField.cs
- SecurityResources.cs
- Base64Encoder.cs
- AssemblyInfo.cs
- Int16AnimationBase.cs
- RecordBuilder.cs
- HostedAspNetEnvironment.cs
- SiteMapHierarchicalDataSourceView.cs
- SafeRightsManagementEnvironmentHandle.cs
- DtrList.cs
- StrongNameIdentityPermission.cs
- AttachInfo.cs
- ConstraintManager.cs
- Point.cs
- MulticastOption.cs
- CodeIdentifiers.cs
- SplitterEvent.cs
- MarkupCompilePass2.cs
- SecurityContextSecurityTokenResolver.cs
- SecureUICommand.cs
- Atom10FormatterFactory.cs
- HttpProcessUtility.cs
- WorkflowMarkupSerializer.cs
- PaginationProgressEventArgs.cs
- HttpRequestBase.cs
- XmlArrayAttribute.cs
- AsymmetricSignatureFormatter.cs
- BitSet.cs
- TypeExtensionConverter.cs
- ApplicationSecurityInfo.cs
- ConfigDefinitionUpdates.cs
- SequenceQuery.cs
- ScrollChrome.cs
- IisTraceWebEventProvider.cs
- InfoCardTraceRecord.cs
- SimpleLine.cs
- NamespaceInfo.cs
- SuppressIldasmAttribute.cs
- ControlCommandSet.cs
- SqlMethodCallConverter.cs
- _LazyAsyncResult.cs
- StrongNameUtility.cs
- DrawingImage.cs
- COM2PropertyPageUITypeConverter.cs
- DataService.cs
- MinimizableAttributeTypeConverter.cs
- Selector.cs
- KeyboardInputProviderAcquireFocusEventArgs.cs
- BatchWriter.cs
- MetadataCache.cs
- EntityDataSourceUtil.cs
- WrapPanel.cs
- DataViewListener.cs
- SafeCryptoHandles.cs
- ToolStripItemRenderEventArgs.cs
- ZipIOLocalFileHeader.cs
- VersionedStream.cs
- Pen.cs
- TextServicesProperty.cs
- FunctionParameter.cs
- CachingHintValidation.cs
- DesignBinding.cs
- SystemBrushes.cs
- ExpressionTextBox.xaml.cs
- DataObjectCopyingEventArgs.cs
- Ref.cs
- Timeline.cs