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
- SecurityTokenInclusionMode.cs
- GridViewSortEventArgs.cs
- SrgsText.cs
- SqlReferenceCollection.cs
- VariableAction.cs
- DeviceSpecificDialogCachedState.cs
- Vector3DConverter.cs
- ButtonField.cs
- PeerApplicationLaunchInfo.cs
- ScalarType.cs
- TypeDescriptionProviderAttribute.cs
- EngineSite.cs
- DBSchemaRow.cs
- NodeInfo.cs
- ToolStripLabel.cs
- MonthCalendar.cs
- ResXResourceReader.cs
- ReplacementText.cs
- TemplateContent.cs
- AnimationLayer.cs
- DataBindingCollection.cs
- InkPresenter.cs
- UnknownBitmapEncoder.cs
- XPathExpr.cs
- WindowsSpinner.cs
- SimpleBitVector32.cs
- XmlSchemaSimpleTypeRestriction.cs
- WriteLineDesigner.xaml.cs
- MethodExpr.cs
- InfocardExtendedInformationCollection.cs
- ActivitiesCollection.cs
- ColorContextHelper.cs
- InvokeAction.cs
- PolicyManager.cs
- ADMembershipProvider.cs
- SrgsGrammar.cs
- StringWriter.cs
- CodeCompiler.cs
- SystemKeyConverter.cs
- CustomActivityDesigner.cs
- SrgsElement.cs
- DoubleLink.cs
- Listen.cs
- ErrorBehavior.cs
- TimelineGroup.cs
- DbProviderFactories.cs
- RequestCacheEntry.cs
- WorkflowApplicationEventArgs.cs
- ReaderOutput.cs
- TextCharacters.cs
- BooleanToSelectiveScrollingOrientationConverter.cs
- EventManager.cs
- SingleSelectRootGridEntry.cs
- Perspective.cs
- DataObjectMethodAttribute.cs
- PersonalizationProvider.cs
- BamlLocalizer.cs
- EncryptedPackage.cs
- Cursors.cs
- RowToFieldTransformer.cs
- TreeViewCancelEvent.cs
- EmptyControlCollection.cs
- DataGridViewColumnCollection.cs
- OpCopier.cs
- SchemaHelper.cs
- DesignerCatalogPartChrome.cs
- DocumentPageViewAutomationPeer.cs
- LinqDataSourceContextData.cs
- ImageDesigner.cs
- ImmutableCollection.cs
- ToolStripItemDesigner.cs
- CapabilitiesUse.cs
- CodeSnippetTypeMember.cs
- ISAPIApplicationHost.cs
- _AutoWebProxyScriptWrapper.cs
- HtmlTableCell.cs
- ServiceReference.cs
- CachedRequestParams.cs
- DesignerVerbCollection.cs
- EntityDataSourceView.cs
- CapabilitiesSection.cs
- CodeFieldReferenceExpression.cs
- WorkflowPrinting.cs
- Scene3D.cs
- EntityTypeEmitter.cs
- MimeXmlReflector.cs
- ClientEventManager.cs
- CodeExpressionStatement.cs
- RegexCharClass.cs
- CookielessHelper.cs
- EventDescriptor.cs
- SafeTokenHandle.cs
- WebBrowser.cs
- EntityDataSourceWrapperPropertyDescriptor.cs
- ScrollViewer.cs
- DataGridViewElement.cs
- EntityDataSourceContextCreatedEventArgs.cs
- DesignerDataTableBase.cs
- XmlAttributes.cs
- SpecialNameAttribute.cs