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
- EditCommandColumn.cs
- AuthStoreRoleProvider.cs
- CacheAxisQuery.cs
- ObjectStateEntryDbDataRecord.cs
- XmlHierarchicalEnumerable.cs
- GridLengthConverter.cs
- DaylightTime.cs
- FederatedMessageSecurityOverHttp.cs
- PictureBox.cs
- WebFormsRootDesigner.cs
- XmlBoundElement.cs
- WebPartTracker.cs
- Bits.cs
- BamlReader.cs
- NodeFunctions.cs
- ObjectStateEntryDbUpdatableDataRecord.cs
- ListControlConvertEventArgs.cs
- ComIntegrationManifestGenerator.cs
- PolyBezierSegment.cs
- WindowsSolidBrush.cs
- safemediahandle.cs
- NameSpaceExtractor.cs
- GenericEnumConverter.cs
- SystemException.cs
- Crypto.cs
- ContextProperty.cs
- SecurityChannel.cs
- CssTextWriter.cs
- Expander.cs
- RegexParser.cs
- InputEventArgs.cs
- WebAdminConfigurationHelper.cs
- DPAPIProtectedConfigurationProvider.cs
- PagerSettings.cs
- TypeGeneratedEventArgs.cs
- UTF8Encoding.cs
- TimeSpanStorage.cs
- UIElementParaClient.cs
- ClientFormsAuthenticationCredentials.cs
- Action.cs
- Stack.cs
- SqlFactory.cs
- FontDialog.cs
- TextEditorCharacters.cs
- MenuBase.cs
- DataSetViewSchema.cs
- ProcessModelInfo.cs
- MetroSerializationManager.cs
- ObjectComplexPropertyMapping.cs
- LinqDataSourceInsertEventArgs.cs
- MethodBuilder.cs
- PointIndependentAnimationStorage.cs
- Pointer.cs
- PropertyGroupDescription.cs
- Unit.cs
- DBNull.cs
- TextEndOfSegment.cs
- FormViewDeleteEventArgs.cs
- DataServiceHost.cs
- HttpCookie.cs
- Classification.cs
- RadioButton.cs
- TextRunCache.cs
- TokenFactoryBase.cs
- dataprotectionpermissionattribute.cs
- ObjectParameter.cs
- XmlNamespaceMappingCollection.cs
- CreateUserErrorEventArgs.cs
- AsymmetricKeyExchangeDeformatter.cs
- RegionIterator.cs
- DeclarativeCatalogPart.cs
- MethodBuilder.cs
- EntityCommand.cs
- SoapIncludeAttribute.cs
- GridViewAutomationPeer.cs
- MailAddressCollection.cs
- IndexExpression.cs
- AttributeProviderAttribute.cs
- IISUnsafeMethods.cs
- milexports.cs
- Empty.cs
- LocalizabilityAttribute.cs
- DelayedRegex.cs
- DataServiceBehavior.cs
- CodeTypeOfExpression.cs
- TemplateField.cs
- _AuthenticationState.cs
- SendingRequestEventArgs.cs
- WebPartTracker.cs
- PointLightBase.cs
- PathSegment.cs
- EditorPartDesigner.cs
- MethodCallTranslator.cs
- RSAPKCS1SignatureDeformatter.cs
- ControlOperationBehavior.cs
- CustomError.cs
- SchemaNamespaceManager.cs
- NegotiateStream.cs
- Activity.cs
- SqlException.cs