Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Channels / HttpRequestContext.cs / 2 / HttpRequestContext.cs
//---------------------------------------------------------------------------- // Copyright (c) Microsoft Corporation. All rights reserved. //--------------------------------------------------------------------------- namespace System.ServiceModel.Channels { using System; using System.ServiceModel; using System.ServiceModel.Activation; using System.IO; using System.Net; using System.IdentityModel.Claims; using System.IdentityModel.Policy; using System.ServiceModel.Security; using System.Text; using System.Threading; using System.Web; using System.Xml; using System.ServiceModel.Diagnostics; abstract class HttpRequestContext : RequestContextBase { HttpOutput httpOutput; HttpInput httpInput; HttpChannelListener listener; SecurityMessageProperty securityProperty; protected HttpRequestContext(HttpChannelListener listener, Message requestMessage) : base(requestMessage, listener.InternalCloseTimeout, listener.InternalSendTimeout) { this.listener = listener; } public bool KeepAliveEnabled { get { return listener.KeepAliveEnabled; } } protected HttpChannelListener Listener { get { return this.listener; } } internal static HttpRequestContext CreateContext(HttpChannelListener listener, HttpListenerContext listenerContext) { return new ListenerHttpContext(listener, listenerContext); } internal static HttpRequestContext CreateContext(HttpChannelListener listener, HostedHttpRequestAsyncResult result) { return new HostedHttpContext(listener, result); } protected HttpInput HttpInput { get { if (httpInput == null) { httpInput = GetHttpInput(); } return httpInput; } } public abstract string HttpMethod { get; } protected abstract SecurityMessageProperty OnProcessAuthentication(); protected abstract HttpOutput GetHttpOutput(Message message); protected abstract HttpInput GetHttpInput(); protected override void OnAbort() { if (this.httpOutput != null) { this.httpOutput.Abort(HttpAbortReason.Aborted); } } protected override void OnClose(TimeSpan timeout) { if (this.httpOutput != null) { this.httpOutput.Close(); } } void SetRequestMessage(Message message, Exception requestException) { if (requestException != null) { base.SetRequestMessage(requestException); message.Close(); } else { message.Properties.Security = (this.securityProperty != null) ? (SecurityMessageProperty)this.securityProperty.CreateCopy() : null; base.SetRequestMessage(message); } } public void CreateMessage() { HttpInput httpInput = this.HttpInput; Message message; Exception requestException; message = httpInput.ParseIncomingMessage(out requestException); if ((message == null) && (requestException == null)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new ProtocolException(SR.GetString(SR.MessageXmlProtocolError), new XmlException(SR.GetString(SR.MessageIsEmpty)))); } this.SetRequestMessage(message, requestException); } protected abstract HttpStatusCode ValidateAuthentication(); bool PrepareReply(ref Message message) { // null means we're done if (message == null) { message = CreateAckMessage(HttpStatusCode.Accepted, string.Empty); } if (!listener.ManualAddressing) { if (message.Version.Addressing == AddressingVersion.WSAddressingAugust2004) { message.Headers.To = message.Version.Addressing.AnonymousUri; } else if (message.Version.Addressing == AddressingVersion.WSAddressing10 || message.Version.Addressing == AddressingVersion.None) { message.Headers.To = null; } else { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new ProtocolException(SR.GetString(SR.AddressingVersionNotSupported, message.Version.Addressing))); } } message.Properties.AllowOutputBatching = false; this.httpOutput = GetHttpOutput(message); // now see if the output should be closed after we reply HttpDelayedAcceptStream requestStream = HttpInput.InputStream as HttpDelayedAcceptStream; if (requestStream != null && TransferModeHelper.IsRequestStreamed(listener.TransferMode) && requestStream.EnableDelayedAccept(this.httpOutput)) { return false; } return true; } protected override void OnReply(Message message, TimeSpan timeout) { TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); bool closeOutputAfterReply = PrepareReply(ref message); ThreadTrace.Trace("Begin sending http reply"); httpOutput.Send(timeoutHelper.RemainingTime()); ThreadTrace.Trace("End sending http reply"); if (closeOutputAfterReply) { httpOutput.Close(); } } protected override IAsyncResult OnBeginReply( Message message, TimeSpan timeout, AsyncCallback callback, object state) { return new ReplyAsyncResult(this, message, timeout, callback, state); } protected override void OnEndReply(IAsyncResult result) { ReplyAsyncResult.End(result); } class ReplyAsyncResult : AsyncResult { static AsyncCallback onSend; HttpRequestContext context; bool closeOutputAfterReply; public ReplyAsyncResult(HttpRequestContext context, Message message, TimeSpan timeout, AsyncCallback callback, object state) : base(callback, state) { this.context = context; this.closeOutputAfterReply = context.PrepareReply(ref message); ThreadTrace.Trace("Begin sending http reply"); if (onSend == null) { onSend = DiagnosticUtility.ThunkAsyncCallback(new AsyncCallback(OnSend)); } IAsyncResult result = context.httpOutput.BeginSend(timeout, onSend, this); if (!result.CompletedSynchronously) { return; } HandleEndSend(result); base.Complete(true); } public static void End(IAsyncResult result) { AsyncResult.End(result); } void HandleEndSend(IAsyncResult result) { context.httpOutput.EndSend(result); ThreadTrace.Trace("End sending http reply"); if (this.closeOutputAfterReply) { context.httpOutput.Close(); } } static void OnSend(IAsyncResult result) { if (result.CompletedSynchronously) { return; } ReplyAsyncResult thisPtr = (ReplyAsyncResult)result.AsyncState; Exception completionException = null; try { thisPtr.HandleEndSend(result); } #pragma warning suppress 56500 // covered by FxCOP catch (Exception e) { if (DiagnosticUtility.IsFatal(e)) { throw; } completionException = e; } thisPtr.Complete(false, completionException); } } public bool ProcessAuthentication() { HttpStatusCode statusCode = ValidateAuthentication(); if (statusCode == HttpStatusCode.OK) { bool authenticationSucceeded = false; try { this.securityProperty = OnProcessAuthentication(); authenticationSucceeded = true; return true; } finally { if (!authenticationSucceeded) { SendResponseAndClose(HttpStatusCode.Forbidden); } } } else { SendResponseAndClose(statusCode); return false; } } internal void SendResponseAndClose(HttpStatusCode statusCode) { SendResponseAndClose(statusCode, string.Empty); } internal void SendResponseAndClose(HttpStatusCode statusCode, string statusDescription) { if (ReplyInitiated) { this.Close(); return; } using (Message ackMessage = CreateAckMessage(statusCode, statusDescription)) { this.Reply(ackMessage); } this.Close(); } Message CreateAckMessage(HttpStatusCode statusCode, string statusDescription) { Message ackMessage = new NullMessage(); HttpResponseMessageProperty httpResponseProperty = new HttpResponseMessageProperty(); httpResponseProperty.StatusCode = statusCode; httpResponseProperty.SuppressEntityBody = true; if (statusDescription.Length > 0) { httpResponseProperty.StatusDescription = statusDescription; } ackMessage.Properties.Add(HttpResponseMessageProperty.Name, httpResponseProperty); return ackMessage; } class ListenerHttpContext : HttpRequestContext { HttpListenerContext listenerContext; public ListenerHttpContext(HttpChannelListener listener, HttpListenerContext listenerContext) : base(listener, null) { this.listenerContext = listenerContext; } public override string HttpMethod { get { return listenerContext.Request.HttpMethod; } } protected override HttpInput GetHttpInput() { return new ListenerContextHttpInput(this); } protected override HttpOutput GetHttpOutput(Message message) { // work around http.sys keep alive bug with chunked requests, see MB 49676, this is fixed in Vista if (listenerContext.Request.ContentLength64 == -1 && !OSEnvironmentHelper.IsVistaOrGreater) { listenerContext.Response.KeepAlive = false; } else { listenerContext.Response.KeepAlive = listener.KeepAliveEnabled; } return HttpOutput.CreateHttpOutput(listenerContext.Response, Listener, message); } protected override SecurityMessageProperty OnProcessAuthentication() { return Listener.ProcessAuthentication(listenerContext); } protected override HttpStatusCode ValidateAuthentication() { return Listener.ValidateAuthentication(listenerContext); } protected override void OnAbort() { listenerContext.Response.Abort(); } protected override void OnClose(TimeSpan timeout) { TimeoutHelper timeoutHelper = new TimeoutHelper(timeout); base.OnClose(timeoutHelper.RemainingTime()); try { listenerContext.Response.Close(); } catch (HttpListenerException listenerException) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( HttpChannelUtilities.CreateCommunicationException(listenerException)); } } class ListenerContextHttpInput : HttpInput { ListenerHttpContext listenerHttpContext; string cachedContentType; // accessing the header in System.Net involves a native transition byte[] preReadBuffer; public ListenerContextHttpInput(ListenerHttpContext listenerHttpContext) : base(listenerHttpContext.Listener, true) { this.listenerHttpContext = listenerHttpContext; if (this.listenerHttpContext.listenerContext.Request.ContentLength64 == -1) { this.preReadBuffer = new byte[1]; if (this.listenerHttpContext.listenerContext.Request.InputStream.Read(preReadBuffer, 0, 1) == 0) { this.preReadBuffer = null; } } } public override long ContentLength { get { return this.listenerHttpContext.listenerContext.Request.ContentLength64; } } protected override string ContentType { get { if (this.cachedContentType == null) { this.cachedContentType = this.listenerHttpContext.listenerContext.Request.ContentType; } return this.cachedContentType; } } protected override bool HasContent { get { return (this.preReadBuffer != null || this.ContentLength > 0); } } protected override string SoapActionHeader { get { return this.listenerHttpContext.listenerContext.Request.Headers["SOAPAction"]; } } protected override void AddProperties(Message message) { HttpRequestMessageProperty requestProperty = new HttpRequestMessageProperty(this.listenerHttpContext.listenerContext.Request); requestProperty.Method = this.listenerHttpContext.listenerContext.Request.HttpMethod; // Uri.Query always includes the '?' if (this.listenerHttpContext.listenerContext.Request.Url.Query.Length > 1) { requestProperty.QueryString = this.listenerHttpContext.listenerContext.Request.Url.Query.Substring(1); } message.Properties.Add(HttpRequestMessageProperty.Name, requestProperty); message.Properties.Via = this.listenerHttpContext.listenerContext.Request.Url; RemoteEndpointMessageProperty remoteEndpointProperty = new RemoteEndpointMessageProperty(this.listenerHttpContext.listenerContext.Request.RemoteEndPoint); message.Properties.Add(RemoteEndpointMessageProperty.Name, remoteEndpointProperty); } protected override Stream GetInputStream() { if (this.preReadBuffer != null) { return new ListenerContextInputStream(listenerHttpContext, preReadBuffer); } else { return new ListenerContextInputStream(listenerHttpContext); } } class ListenerContextInputStream : HttpDelayedAcceptStream { public ListenerContextInputStream(ListenerHttpContext listenerHttpContext) : base(listenerHttpContext.listenerContext.Request.InputStream) { } public ListenerContextInputStream(ListenerHttpContext listenerHttpContext, byte[] preReadBuffer) : base(new PreReadStream(listenerHttpContext.listenerContext.Request.InputStream, preReadBuffer)) { } public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state) { try { return base.BeginRead(buffer, offset, count, callback, state); } catch (HttpListenerException listenerException) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( HttpChannelUtilities.CreateCommunicationException(listenerException)); } } public override int EndRead(IAsyncResult result) { try { return base.EndRead(result); } catch (HttpListenerException listenerException) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( HttpChannelUtilities.CreateCommunicationException(listenerException)); } } public override int Read(byte[] buffer, int offset, int count) { try { return base.Read(buffer, offset, count); } catch (HttpListenerException listenerException) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( HttpChannelUtilities.CreateCommunicationException(listenerException)); } } public override int ReadByte() { try { return base.ReadByte(); } catch (HttpListenerException listenerException) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( HttpChannelUtilities.CreateCommunicationException(listenerException)); } } } } } } } // 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
- TransformerTypeCollection.cs
- BasePattern.cs
- CodeTypeDeclarationCollection.cs
- DataGridViewLinkColumn.cs
- WebPartTracker.cs
- ToolboxBitmapAttribute.cs
- ObjectConverter.cs
- SecurityAccessDeniedException.cs
- MediaSystem.cs
- FamilyMapCollection.cs
- ObjectDataSourceMethodEventArgs.cs
- OleDbCommand.cs
- SrgsToken.cs
- StringValidatorAttribute.cs
- ResourcePermissionBaseEntry.cs
- AnnotationDocumentPaginator.cs
- SpecialNameAttribute.cs
- MetafileHeader.cs
- DataGridViewComboBoxEditingControl.cs
- Int64Animation.cs
- CodeAccessPermission.cs
- DataAdapter.cs
- KeyEventArgs.cs
- IdentityModelStringsVersion1.cs
- SplashScreen.cs
- TreeNode.cs
- TileModeValidation.cs
- WebBrowserNavigatingEventHandler.cs
- ExtensibleClassFactory.cs
- _ContextAwareResult.cs
- ParameterToken.cs
- EncodingStreamWrapper.cs
- SimpleFileLog.cs
- HtmlLink.cs
- WebPartsPersonalization.cs
- TreeBuilder.cs
- MessageQueuePermissionEntryCollection.cs
- Int32Converter.cs
- NaturalLanguageHyphenator.cs
- ResXResourceReader.cs
- HttpFileCollectionWrapper.cs
- DataListItemEventArgs.cs
- XmlSerializerNamespaces.cs
- RuleSettingsCollection.cs
- WebPartZone.cs
- GroupPartitionExpr.cs
- PrintController.cs
- ProtectedConfiguration.cs
- RequiredAttributeAttribute.cs
- AppliedDeviceFiltersDialog.cs
- CompareInfo.cs
- InheritanceUI.cs
- X509CertificateStore.cs
- Error.cs
- ReverseQueryOperator.cs
- MimeTextImporter.cs
- ComponentResourceKeyConverter.cs
- ToolStripDropDownItem.cs
- DesignerTransactionCloseEvent.cs
- UmAlQuraCalendar.cs
- RegexWriter.cs
- Classification.cs
- SortDescription.cs
- ContextMenuAutomationPeer.cs
- NetworkAddressChange.cs
- CodeSubDirectory.cs
- PrintEvent.cs
- GestureRecognitionResult.cs
- cookie.cs
- UInt64Storage.cs
- Style.cs
- PageContentCollection.cs
- ConfigsHelper.cs
- QuinticEase.cs
- RuntimeCompatibilityAttribute.cs
- GridEntry.cs
- RSAOAEPKeyExchangeFormatter.cs
- DefaultAsyncDataDispatcher.cs
- Aes.cs
- DocComment.cs
- UnmanagedHandle.cs
- DataServiceBehavior.cs
- DesignerActionPanel.cs
- SimpleRecyclingCache.cs
- Missing.cs
- ExpressionNode.cs
- DataGridViewDataErrorEventArgs.cs
- ApplicationInterop.cs
- CodeBinaryOperatorExpression.cs
- DiagnosticStrings.cs
- RectangleHotSpot.cs
- HijriCalendar.cs
- DataContractJsonSerializerOperationBehavior.cs
- EllipseGeometry.cs
- DelegateHelpers.cs
- XmlSchemaFacet.cs
- WebPartTransformer.cs
- ChangeBlockUndoRecord.cs
- PrintPreviewGraphics.cs
- SmtpDigestAuthenticationModule.cs