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
- XmlILAnnotation.cs
- HtmlContainerControl.cs
- HtmlInputSubmit.cs
- DialogWindow.cs
- EventProviderTraceListener.cs
- ConfigurationSectionGroupCollection.cs
- BaseCAMarshaler.cs
- Part.cs
- PlainXmlWriter.cs
- ResourceSet.cs
- CompiledRegexRunnerFactory.cs
- SecurityDescriptor.cs
- SqlRowUpdatingEvent.cs
- ParserOptions.cs
- DBBindings.cs
- ZoneMembershipCondition.cs
- SqlConnectionManager.cs
- LocalFileSettingsProvider.cs
- EnumValidator.cs
- QilVisitor.cs
- DelimitedListTraceListener.cs
- SchemaImporter.cs
- DataGridCheckBoxColumn.cs
- PhysicalOps.cs
- PartialCachingAttribute.cs
- AsymmetricKeyExchangeFormatter.cs
- BrushMappingModeValidation.cs
- ThicknessKeyFrameCollection.cs
- ChildrenQuery.cs
- ColorContext.cs
- TextProviderWrapper.cs
- Compiler.cs
- TextWriter.cs
- BitmapEffectGroup.cs
- XmlDsigSep2000.cs
- Calendar.cs
- StringOutput.cs
- EntityDataSourceWrapperPropertyDescriptor.cs
- HScrollProperties.cs
- MachineKeySection.cs
- HttpConfigurationSystem.cs
- PageAsyncTask.cs
- dataobject.cs
- PersistenceParticipant.cs
- tabpagecollectioneditor.cs
- UshortList2.cs
- PagerSettings.cs
- HttpDictionary.cs
- NotifyIcon.cs
- StreamGeometry.cs
- ComponentResourceManager.cs
- KeyFrames.cs
- SynchronizedDispatch.cs
- NameValueSectionHandler.cs
- WasHttpHandlersInstallComponent.cs
- TabPage.cs
- _NegoStream.cs
- Reference.cs
- ListViewInsertionMark.cs
- SymmetricAlgorithm.cs
- RequestTimeoutManager.cs
- PermissionAttributes.cs
- AutoResizedEvent.cs
- ToolStripOverflowButton.cs
- DefaultAsyncDataDispatcher.cs
- WebContext.cs
- PropertyPath.cs
- TriggerBase.cs
- FormatterConverter.cs
- EnumerableValidator.cs
- EdmPropertyAttribute.cs
- WebGetAttribute.cs
- BindingManagerDataErrorEventArgs.cs
- SamlAuthenticationStatement.cs
- MenuEventArgs.cs
- ApplicationServiceManager.cs
- ObjectDataSourceChooseMethodsPanel.cs
- PointValueSerializer.cs
- FlowchartDesignerCommands.cs
- ControlBuilder.cs
- RadialGradientBrush.cs
- ListView.cs
- IdentitySection.cs
- DummyDataSource.cs
- DoWorkEventArgs.cs
- MessageQueuePermissionEntryCollection.cs
- DataGridViewColumnDesigner.cs
- ImageCodecInfo.cs
- ISSmlParser.cs
- ColorDialog.cs
- Vector3DAnimationUsingKeyFrames.cs
- FixedPageProcessor.cs
- XhtmlBasicTextViewAdapter.cs
- RangeValuePattern.cs
- TextTrailingWordEllipsis.cs
- ToolbarAUtomationPeer.cs
- XNodeSchemaApplier.cs
- PartialTrustHelpers.cs
- HttpListenerPrefixCollection.cs
- validationstate.cs