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
- DataGridTextBox.cs
- ListBoxChrome.cs
- DataGrid.cs
- TypeCodeDomSerializer.cs
- XmlBindingWorker.cs
- ImageMapEventArgs.cs
- DocumentOrderComparer.cs
- unsafeIndexingFilterStream.cs
- AndCondition.cs
- SchemaAttDef.cs
- ToolStripControlHost.cs
- PackageRelationshipCollection.cs
- SQLUtility.cs
- TimeSpan.cs
- ActiveXContainer.cs
- StringBuilder.cs
- COM2IVsPerPropertyBrowsingHandler.cs
- XMLUtil.cs
- ScaleTransform.cs
- CodeAttributeArgument.cs
- ColorIndependentAnimationStorage.cs
- StrokeNodeOperations2.cs
- DbProviderSpecificTypePropertyAttribute.cs
- GridPattern.cs
- TreeViewAutomationPeer.cs
- GridView.cs
- BookmarkOptionsHelper.cs
- GuidConverter.cs
- SQLInt32Storage.cs
- StringBlob.cs
- RepeaterItem.cs
- NotCondition.cs
- EFTableProvider.cs
- WizardSideBarListControlItemEventArgs.cs
- EditingMode.cs
- TypeDescriptor.cs
- RequestContext.cs
- BinaryConverter.cs
- PhoneCallDesigner.cs
- CachedPathData.cs
- QualificationDataItem.cs
- QilTernary.cs
- ConfigurationLockCollection.cs
- EditorZoneBase.cs
- SchemaType.cs
- XPathDescendantIterator.cs
- ProfilePropertyMetadata.cs
- StylusDownEventArgs.cs
- SafeArrayTypeMismatchException.cs
- XmlIncludeAttribute.cs
- FormViewInsertEventArgs.cs
- SplitterEvent.cs
- ManualResetEventSlim.cs
- SqlCharStream.cs
- ObjectQuery.cs
- OdbcUtils.cs
- DefaultProxySection.cs
- AnimationLayer.cs
- EventLog.cs
- GridViewSortEventArgs.cs
- AnonymousIdentificationModule.cs
- GridSplitter.cs
- WindowsGraphics2.cs
- DbDeleteCommandTree.cs
- QueryOperationResponseOfT.cs
- MouseWheelEventArgs.cs
- Misc.cs
- TextPatternIdentifiers.cs
- CopyOnWriteList.cs
- PingReply.cs
- EdmTypeAttribute.cs
- Quaternion.cs
- EmptyControlCollection.cs
- Asn1IntegerConverter.cs
- LayoutTableCell.cs
- CompositeCollection.cs
- GAC.cs
- BinaryFormatter.cs
- TdsParameterSetter.cs
- WebControlAdapter.cs
- Image.cs
- XmlName.cs
- DoubleAnimationBase.cs
- LogStore.cs
- UriWriter.cs
- ActivityBuilderXamlWriter.cs
- ValidationHelper.cs
- ElapsedEventArgs.cs
- altserialization.cs
- RadioButtonStandardAdapter.cs
- SqlProvider.cs
- StyleXamlParser.cs
- MouseGestureValueSerializer.cs
- EnumBuilder.cs
- ConnectionStringsExpressionBuilder.cs
- ContextStack.cs
- RC2.cs
- ContextDataSourceContextData.cs
- DesignerAttribute.cs
- EntityDataSourceStatementEditor.cs