Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / clr / src / ManagedLibraries / Remoting / Channels / Sinks / SoapFormatterSinks.cs / 1305376 / SoapFormatterSinks.cs
// ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== //========================================================================== // File: SoapFormatterSinks.cs // // Summary: Soap formatter client and server sinks. // //========================================================================= using System; using System.Collections; using System.IO; using System.Reflection; using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Http; using System.Runtime.Remoting.Messaging; using System.Runtime.Remoting.Metadata; using System.Runtime.Serialization; using System.Security; using System.Security.Permissions; using System.Runtime.Serialization.Formatters; using System.Runtime.Serialization.Formatters.Soap; using System.Text; using System.Globalization; namespace System.Runtime.Remoting.Channels { // // CLIENT-SIDE SOAP FORMATTER SINKS // public class SoapClientFormatterSinkProvider : IClientFormatterSinkProvider { private IClientChannelSinkProvider _next = null; // settings from config private bool _includeVersioning = true; private bool _strictBinding = false; public SoapClientFormatterSinkProvider() { } public SoapClientFormatterSinkProvider(IDictionary properties, ICollection providerData) { // look at properties if (properties != null) { foreach (DictionaryEntry entry in properties) { String keyStr = entry.Key.ToString(); switch (keyStr) { case "includeVersions": _includeVersioning = Convert.ToBoolean(entry.Value, CultureInfo.InvariantCulture); break; case "strictBinding": _strictBinding = Convert.ToBoolean(entry.Value, CultureInfo.InvariantCulture); break; default: break; } } } // not expecting any provider data CoreChannel.VerifyNoProviderData(this.GetType().Name, providerData); } [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] public IClientChannelSink CreateSink(IChannelSender channel, String url, Object remoteChannelData) { IClientChannelSink nextSink = null; if (_next != null) { nextSink = _next.CreateSink(channel, url, remoteChannelData); if (nextSink == null) return null; } SinkChannelProtocol protocol = CoreChannel.DetermineChannelProtocol(channel); SoapClientFormatterSink sink = new SoapClientFormatterSink(nextSink); sink.IncludeVersioning = _includeVersioning; sink.StrictBinding = _strictBinding; sink.ChannelProtocol = protocol; return sink; } public IClientChannelSinkProvider Next { [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] get { return _next; } [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] set { _next = value; } } } // class SoapClientFormatterSinkProvider public class SoapClientFormatterSink : IClientFormatterSink { private IClientChannelSink _nextSink = null; private bool _includeVersioning = true; // should versioning be used private bool _strictBinding = false; // strict binding should be used private SinkChannelProtocol _channelProtocol = SinkChannelProtocol.Other; public SoapClientFormatterSink(IClientChannelSink nextSink) { _nextSink = nextSink; } // SoapClientFormatterSink internal bool IncludeVersioning { set { _includeVersioning = value; } } // IncludeVersioning internal bool StrictBinding { set { _strictBinding = value; } } // StrictBinding internal SinkChannelProtocol ChannelProtocol { set { _channelProtocol = value; } } // ChannelProtocol // // IMessageSink implementation // // formatter sender sink is always last "IMessageSink" public IMessageSink NextSink { [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] get { throw new NotSupportedException(); } } [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] public IMessage SyncProcessMessage(IMessage msg) { IMethodCallMessage mcm = (IMethodCallMessage)msg; IMessage retMsg; try { // serialize message ITransportHeaders headers; Stream requestStream; SerializeMessage(mcm, out headers, out requestStream); // process message Stream returnStream; ITransportHeaders returnHeaders; _nextSink.ProcessMessage(msg, headers, requestStream, out returnHeaders, out returnStream); if (returnHeaders == null) throw new ArgumentNullException("returnHeaders"); // deserialize stream retMsg = DeserializeMessage(mcm, returnHeaders, returnStream); } catch (Exception e) { retMsg = new ReturnMessage(e, mcm); } return retMsg; } // SyncProcessMessage [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] public IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink) { IMethodCallMessage mcm = (IMethodCallMessage)msg; IMessage retMsg; try { // serialize message ITransportHeaders headers; Stream requestStream; SerializeMessage(mcm, out headers, out requestStream); // process message ClientChannelSinkStack sinkStack = new ClientChannelSinkStack(replySink); sinkStack.Push(this, mcm); _nextSink.AsyncProcessRequest(sinkStack, msg, headers, requestStream); } catch (Exception e) { retMsg = new ReturnMessage(e, mcm); if (replySink != null) replySink.SyncProcessMessage(retMsg); } return null; } // AsyncProcessMessage // // end of IMessageSink implementation // // helper function to serialize the message private void SerializeMessage(IMethodCallMessage mcm, out ITransportHeaders headers, out Stream stream) { BaseTransportHeaders requestHeaders = new BaseTransportHeaders(); headers = requestHeaders; // add SOAPAction header MethodBase mb = mcm.MethodBase; headers["SOAPAction"] = '"' + HttpEncodingHelper.EncodeUriAsXLinkHref( SoapServices.GetSoapActionFromMethodBase(mb)) + '"'; // add other http soap headers requestHeaders.ContentType = CoreChannel.SOAPContentType; if (_channelProtocol == SinkChannelProtocol.Http) headers["__RequestVerb"] = "POST"; bool bMemStream = false; stream = _nextSink.GetRequestStream(mcm, headers); if (stream == null) { stream = new ChunkedMemoryStream(CoreChannel.BufferPool); bMemStream = true; } CoreChannel.SerializeSoapMessage(mcm, stream, _includeVersioning); if (bMemStream) stream.Position = 0; } // SerializeMessage // helper function to deserialize the message private IMessage DeserializeMessage(IMethodCallMessage mcm, ITransportHeaders headers, Stream stream) { IMessage retMsg; Header[] h = new Header[3]; h[0] = new Header("__TypeName", mcm.TypeName); h[1] = new Header("__MethodName", mcm.MethodName); h[2] = new Header("__MethodSignature", mcm.MethodSignature); String contentTypeHeader = headers["Content-Type"] as String; String contentTypeValue, charsetValue; HttpChannelHelper.ParseContentType(contentTypeHeader, out contentTypeValue, out charsetValue); if (String.Compare(contentTypeValue, CoreChannel.SOAPMimeType, StringComparison.Ordinal) == 0) { // deserialize the message retMsg = CoreChannel.DeserializeSoapResponseMessage(stream, mcm, h, _strictBinding); } else { // an error has occurred int bufferSize = 1024; byte[] buffer = new byte[bufferSize]; StringBuilder sb = new StringBuilder(); int readCount = stream.Read(buffer, 0, bufferSize); while (readCount > 0) { sb.Append(Encoding.ASCII.GetString(buffer, 0, readCount)); readCount = stream.Read(buffer, 0, bufferSize); } retMsg = new ReturnMessage(new RemotingException(sb.ToString()), mcm); } // Close the stream since we're done with it (especially important if this // happened to be a network stream) stream.Close(); return retMsg; } // DeserializeMessage // // IClientChannelSink implementation // [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] public void ProcessMessage(IMessage msg, ITransportHeaders requestHeaders, Stream requestStream, out ITransportHeaders responseHeaders, out Stream responseStream) { // never gets called, this sink is always first throw new NotSupportedException(); } // ProcessMessage [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] public void AsyncProcessRequest(IClientChannelSinkStack sinkStack, IMessage msg, ITransportHeaders headers, Stream stream) { // never gets called, this sink is always first throw new NotSupportedException(); } // AsyncProcessRequest [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] public void AsyncProcessResponse(IClientResponseChannelSinkStack sinkStack, Object state, ITransportHeaders headers, Stream stream) { // previously we stored the outgoing message in state IMethodCallMessage mcm = (IMethodCallMessage)state; IMessage retMsg = DeserializeMessage(mcm, headers, stream); sinkStack.DispatchReplyMessage(retMsg); } // AsyncProcessRequest [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] public Stream GetRequestStream(IMessage msg, ITransportHeaders headers) { // should never be called on formatter sender sink throw new NotSupportedException(); } // GetRequestStream public IClientChannelSink NextChannelSink { [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] get { return _nextSink; } } // Next public IDictionary Properties { [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] get { return null; } } // Properties // // end of IClientChannelSink implementation // } // class SoapClientFormatterSink // // SERVER-SIDE SOAP FORMATTER SINKS // public class SoapServerFormatterSinkProvider : IServerFormatterSinkProvider { private IServerChannelSinkProvider _next = null; // settings from config private bool _includeVersioning = true; private bool _strictBinding = false; private TypeFilterLevel _formatterSecurityLevel = TypeFilterLevel.Low; public SoapServerFormatterSinkProvider() { } // SoapServerFormatterSinkProvider public SoapServerFormatterSinkProvider(IDictionary properties, ICollection providerData) { // look at properties if (properties != null) { foreach (DictionaryEntry entry in properties) { String keyStr = entry.Key.ToString(); switch (keyStr) { case "includeVersions": _includeVersioning = Convert.ToBoolean(entry.Value, CultureInfo.InvariantCulture); break; case "strictBinding": _strictBinding = Convert.ToBoolean(entry.Value, CultureInfo.InvariantCulture); break; case "typeFilterLevel": _formatterSecurityLevel = (TypeFilterLevel) Enum.Parse(typeof(TypeFilterLevel), (string)entry.Value); break; default: break; } } } // not expecting any provider data CoreChannel.VerifyNoProviderData(this.GetType().Name, providerData); } // SoapServerFormatterSinkProvider [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] public void GetChannelData(IChannelDataStore channelData) { } // GetChannelData [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] public IServerChannelSink CreateSink(IChannelReceiver channel) { if(null == channel) { throw new ArgumentNullException("channel"); } IServerChannelSink nextSink = null; if (_next != null) nextSink = _next.CreateSink(channel); SoapServerFormatterSink.Protocol protocol = SoapServerFormatterSink.Protocol.Other; // see if this is an http channel String uri = channel.GetUrlsForUri("")[0]; if (String.Compare("http", 0, uri, 0, 4, StringComparison.OrdinalIgnoreCase) == 0) protocol = SoapServerFormatterSink.Protocol.Http; SoapServerFormatterSink sink = new SoapServerFormatterSink(protocol, nextSink, channel); sink.IncludeVersioning = _includeVersioning; sink.StrictBinding = _strictBinding; sink.TypeFilterLevel = _formatterSecurityLevel; return sink; } public IServerChannelSinkProvider Next { [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] get { return _next; } [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] set { _next = value; } } [System.Runtime.InteropServices.ComVisible(false)] public TypeFilterLevel TypeFilterLevel { get { return _formatterSecurityLevel; } set { _formatterSecurityLevel = value; } } } // class SoapServerFormatterSinkProvider public class SoapServerFormatterSink : IServerChannelSink { [Serializable] public enum Protocol { Http, // special processing needed for http Other } private IServerChannelSink _nextSink; // If this sink doesn't recognize, the incoming // format then he should call the next // sink if there is one. private Protocol _protocol; // transport protocol being used private IChannelReceiver _receiver; // transport sink used to parse url private bool _includeVersioning = true; // should versioning be used private bool _strictBinding = false; // should strict binding be used private TypeFilterLevel _formatterSecurityLevel = TypeFilterLevel.Full; public SoapServerFormatterSink(Protocol protocol, IServerChannelSink nextSink, IChannelReceiver receiver) { if (receiver == null) throw new ArgumentNullException("receiver"); _nextSink = nextSink; _protocol = protocol; _receiver = receiver; } // SoapServerFormatterSinkProvider internal bool IncludeVersioning { set { _includeVersioning = value; } } // IncludeVersioning internal bool StrictBinding { set { _strictBinding = value; } } // StrictBinding [System.Runtime.InteropServices.ComVisible(false)] public TypeFilterLevel TypeFilterLevel { get { return _formatterSecurityLevel; } set { _formatterSecurityLevel = value; } } [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] public ServerProcessing ProcessMessage(IServerChannelSinkStack sinkStack, IMessage requestMsg, ITransportHeaders requestHeaders, Stream requestStream, out IMessage responseMsg, out ITransportHeaders responseHeaders, out Stream responseStream) { if (requestMsg != null) { // The message has already been deserialized so delegate to the next sink. return _nextSink.ProcessMessage( sinkStack, requestMsg, requestHeaders, requestStream, out responseMsg, out responseHeaders, out responseStream); } if (requestHeaders == null) throw new ArgumentNullException("requestHeaders"); BaseTransportHeaders wkRequestHeaders = requestHeaders as BaseTransportHeaders; ServerProcessing processing; responseHeaders = null; responseStream = null; String verb = null; String contentType = null; bool bCanServiceRequest = true; // determine the content type String contentTypeHeader = null; if (wkRequestHeaders != null) contentTypeHeader = wkRequestHeaders.ContentType; else contentTypeHeader = requestHeaders["Content-Type"] as String; if (contentTypeHeader != null) { String charsetValue; HttpChannelHelper.ParseContentType(contentTypeHeader, out contentType, out charsetValue); } // check to see if Content-Type matches if ((contentType != null) && (String.Compare(contentType, CoreChannel.SOAPMimeType, StringComparison.Ordinal) != 0)) { bCanServiceRequest = false; } // check for http specific verbs if (_protocol == Protocol.Http) { verb = (String)requestHeaders["__RequestVerb"]; if (!verb.Equals("POST") && !verb.Equals("M-POST")) bCanServiceRequest = false; } // either delegate or return an error message if we can't service the request if (!bCanServiceRequest) { // delegate to next sink if available if (_nextSink != null) { return _nextSink.ProcessMessage(sinkStack, null, requestHeaders, requestStream, out responseMsg, out responseHeaders, out responseStream); } else { // send back an error message if (_protocol == Protocol.Http) { // return a client bad request error responseHeaders = new TransportHeaders(); responseHeaders["__HttpStatusCode"] = "400"; responseHeaders["__HttpReasonPhrase"] = "Bad Request"; responseStream = null; responseMsg = null; return ServerProcessing.Complete; } else { // The transport sink will catch this and do something here. throw new RemotingException( CoreChannel.GetResourceString("Remoting_Channels_InvalidRequestFormat")); } } } bool bClientIsClr = true; try { String objectUri = null; if (wkRequestHeaders != null) objectUri = wkRequestHeaders.RequestUri; else objectUri = (String)requestHeaders[CommonTransportKeys.RequestUri]; if (RemotingServices.GetServerTypeForUri(objectUri) == null) throw new RemotingException( CoreChannel.GetResourceString("Remoting_ChnlSink_UriNotPublished")); if (_protocol == Protocol.Http) { String userAgent = (String)requestHeaders["User-Agent"]; if (userAgent != null) { if (userAgent.IndexOf("MS .NET Remoting") == -1) { // user agent string did not contain ".NET Remoting", so it is someone else bClientIsClr = false; } } else { bClientIsClr = false; } } bool bIsCustomErrorEnabled = true; object oIsCustomErrorEnabled = requestHeaders["__CustomErrorsEnabled"]; if (oIsCustomErrorEnabled != null && oIsCustomErrorEnabled is bool){ bIsCustomErrorEnabled = (bool)oIsCustomErrorEnabled; } CallContext.SetData("__CustomErrorsEnabled", bIsCustomErrorEnabled); String soapActionToVerify; Header[] h = GetChannelHeaders(requestHeaders, out soapActionToVerify); PermissionSet currentPermissionSet = null; if (this.TypeFilterLevel != TypeFilterLevel.Full) { currentPermissionSet = new PermissionSet(PermissionState.None); currentPermissionSet.SetPermission(new SecurityPermission(SecurityPermissionFlag.SerializationFormatter)); } try { if (currentPermissionSet != null) currentPermissionSet.PermitOnly(); // Deserialize Request - Stream to IMessage requestMsg = CoreChannel.DeserializeSoapRequestMessage(requestStream, h, _strictBinding, this.TypeFilterLevel); } finally { if (currentPermissionSet != null) CodeAccessPermission.RevertPermitOnly(); } requestStream.Close(); if(requestMsg == null) { throw new RemotingException(CoreChannel.GetResourceString("Remoting_DeserializeMessage")); } // verify soap action if necessary if ((soapActionToVerify != null) && (!SoapServices.IsSoapActionValidForMethodBase( soapActionToVerify, ((IMethodMessage)requestMsg).MethodBase))) { throw new RemotingException( String.Format( CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Soap_InvalidSoapAction"), soapActionToVerify) ); } // Dispatch Call sinkStack.Push(this, null); processing = _nextSink.ProcessMessage(sinkStack, requestMsg, requestHeaders, null, out responseMsg, out responseHeaders, out responseStream); // make sure that responseStream is null if (responseStream != null) { throw new RemotingException( CoreChannel.GetResourceString("Remoting_ChnlSink_WantNullResponseStream")); } switch (processing) { case ServerProcessing.Complete: { if (responseMsg == null) throw new RemotingException(CoreChannel.GetResourceString("Remoting_DispatchMessage")); sinkStack.Pop(this); SerializeResponse(sinkStack, responseMsg, bClientIsClr, ref responseHeaders, out responseStream); break; } // case ServerProcessing.Complete case ServerProcessing.OneWay: { sinkStack.Pop(this); break; } // case ServerProcessing.OneWay: case ServerProcessing.Async: { sinkStack.Store(this, null); break; } // case ServerProcessing.Async } // switch (processing) } catch(Exception e) { processing = ServerProcessing.Complete; responseMsg = new ReturnMessage(e, (IMethodCallMessage)(requestMsg==null?new ErrorMessage():requestMsg)); // CallContext.SetData("__ClientIsClr", bClientIsClr); responseStream = (MemoryStream)CoreChannel.SerializeSoapMessage(responseMsg, _includeVersioning); CallContext.FreeNamedDataSlot("__ClientIsClr"); responseStream.Position = 0; responseHeaders = new TransportHeaders(); if (_protocol == Protocol.Http) { responseHeaders["__HttpStatusCode"] = "500"; responseHeaders["__HttpReasonPhrase"] = "Internal Server Error"; responseHeaders["Content-Type"] = CoreChannel.SOAPContentType; } } finally{ CallContext.FreeNamedDataSlot("__CustomErrorsEnabled"); } return processing; } // ProcessMessage [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] public void AsyncProcessResponse(IServerResponseChannelSinkStack sinkStack, Object state, IMessage msg, ITransportHeaders headers, Stream stream) { // < SerializeResponse(sinkStack, msg, true, ref headers, out stream); sinkStack.AsyncProcessResponse(msg, headers, stream); } // AsyncProcessResponse [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] private void SerializeResponse(IServerResponseChannelSinkStack sinkStack, IMessage msg, bool bClientIsClr, ref ITransportHeaders headers, out Stream stream) { BaseTransportHeaders responseHeaders = new BaseTransportHeaders(); if (headers != null) { // copy old headers into new headers foreach (DictionaryEntry entry in headers) { responseHeaders[entry.Key] = entry.Value; } } headers = responseHeaders; responseHeaders.ContentType = CoreChannel.SOAPContentType; if (_protocol == Protocol.Http) { // check to see if an exception occurred (requires special status code for HTTP) IMethodReturnMessage mrm = msg as IMethodReturnMessage; if ((mrm != null) && (mrm.Exception != null)) { headers["__HttpStatusCode"] = "500"; headers["__HttpReasonPhrase"] = "Internal Server Error"; } } bool bMemStream = false; stream = sinkStack.GetResponseStream(msg, headers); if (stream == null) { stream = new ChunkedMemoryStream(CoreChannel.BufferPool); bMemStream = true; } bool bBashUrl = CoreChannel.SetupUrlBashingForIisSslIfNecessary(); CallContext.SetData("__ClientIsClr", bClientIsClr); try { CoreChannel.SerializeSoapMessage(msg, stream, _includeVersioning); } finally { CallContext.FreeNamedDataSlot("__ClientIsClr"); CoreChannel.CleanupUrlBashingForIisSslIfNecessary(bBashUrl); } if (bMemStream) stream.Position = 0; } // SerializeResponse [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] public Stream GetResponseStream(IServerResponseChannelSinkStack sinkStack, Object state, IMessage msg, ITransportHeaders headers) { // We don't need to implement this because it will never be called. throw new NotSupportedException(); } // GetResponseStream public IServerChannelSink NextChannelSink { [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] get { return _nextSink; } } public IDictionary Properties { [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] get { return null; } } // Properties // Helper method for analyzing headers private Header[] GetChannelHeaders(ITransportHeaders requestHeaders, out String soapActionToVerify) { soapActionToVerify = null; // transport sink removes any channel specific information String objectURI = (String)requestHeaders[CommonTransportKeys.RequestUri]; // see if a unique SOAPAction is present (if more than one SOAPAction is present some // scenarios won't work, but one-many soap action to method base relationships are // for interop scenarios only) String soapAction = (String) requestHeaders["SOAPAction"]; if (soapAction == null) throw new RemotingException(CoreChannel.GetResourceString("Remoting_SoapActionMissing")); soapAction = HttpEncodingHelper.DecodeUri(soapAction); soapActionToVerify = soapAction; String typeName, methodName; if (!SoapServices.GetTypeAndMethodNameFromSoapAction(soapAction, out typeName, out methodName)) { // This means there are multiple methods for this soap action, so we will have to // settle for the type based off of the uri. Type type = RemotingServices.GetServerTypeForUri(objectURI); if (type == null) { throw new RemotingException( String.Format( CultureInfo.CurrentCulture, CoreChannel.GetResourceString( "Remoting_TypeNotFoundFromUri"), objectURI)); } // @todo: This throws away the version, culture and public key token typeName = "clr:" + type.FullName + ", " + type.Assembly.GetName().Name; } else { typeName = "clr:" + typeName; } // Create a new header array and pass it back. int headerLen = 2; Header[] h = new Header[headerLen]; h[0] = new Header("__Uri", objectURI); h[1] = new Header("__TypeName", typeName); return h; } // GetChannelHeaders } // class SoapServerFormatterSink } // namespace System.Runtime.Remoting.Channnels // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // ==++== // // Copyright (c) Microsoft Corporation. All rights reserved. // // ==--== //========================================================================== // File: SoapFormatterSinks.cs // // Summary: Soap formatter client and server sinks. // //========================================================================= using System; using System.Collections; using System.IO; using System.Reflection; using System.Runtime.Remoting; using System.Runtime.Remoting.Channels; using System.Runtime.Remoting.Channels.Http; using System.Runtime.Remoting.Messaging; using System.Runtime.Remoting.Metadata; using System.Runtime.Serialization; using System.Security; using System.Security.Permissions; using System.Runtime.Serialization.Formatters; using System.Runtime.Serialization.Formatters.Soap; using System.Text; using System.Globalization; namespace System.Runtime.Remoting.Channels { // // CLIENT-SIDE SOAP FORMATTER SINKS // public class SoapClientFormatterSinkProvider : IClientFormatterSinkProvider { private IClientChannelSinkProvider _next = null; // settings from config private bool _includeVersioning = true; private bool _strictBinding = false; public SoapClientFormatterSinkProvider() { } public SoapClientFormatterSinkProvider(IDictionary properties, ICollection providerData) { // look at properties if (properties != null) { foreach (DictionaryEntry entry in properties) { String keyStr = entry.Key.ToString(); switch (keyStr) { case "includeVersions": _includeVersioning = Convert.ToBoolean(entry.Value, CultureInfo.InvariantCulture); break; case "strictBinding": _strictBinding = Convert.ToBoolean(entry.Value, CultureInfo.InvariantCulture); break; default: break; } } } // not expecting any provider data CoreChannel.VerifyNoProviderData(this.GetType().Name, providerData); } [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] public IClientChannelSink CreateSink(IChannelSender channel, String url, Object remoteChannelData) { IClientChannelSink nextSink = null; if (_next != null) { nextSink = _next.CreateSink(channel, url, remoteChannelData); if (nextSink == null) return null; } SinkChannelProtocol protocol = CoreChannel.DetermineChannelProtocol(channel); SoapClientFormatterSink sink = new SoapClientFormatterSink(nextSink); sink.IncludeVersioning = _includeVersioning; sink.StrictBinding = _strictBinding; sink.ChannelProtocol = protocol; return sink; } public IClientChannelSinkProvider Next { [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] get { return _next; } [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] set { _next = value; } } } // class SoapClientFormatterSinkProvider public class SoapClientFormatterSink : IClientFormatterSink { private IClientChannelSink _nextSink = null; private bool _includeVersioning = true; // should versioning be used private bool _strictBinding = false; // strict binding should be used private SinkChannelProtocol _channelProtocol = SinkChannelProtocol.Other; public SoapClientFormatterSink(IClientChannelSink nextSink) { _nextSink = nextSink; } // SoapClientFormatterSink internal bool IncludeVersioning { set { _includeVersioning = value; } } // IncludeVersioning internal bool StrictBinding { set { _strictBinding = value; } } // StrictBinding internal SinkChannelProtocol ChannelProtocol { set { _channelProtocol = value; } } // ChannelProtocol // // IMessageSink implementation // // formatter sender sink is always last "IMessageSink" public IMessageSink NextSink { [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] get { throw new NotSupportedException(); } } [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] public IMessage SyncProcessMessage(IMessage msg) { IMethodCallMessage mcm = (IMethodCallMessage)msg; IMessage retMsg; try { // serialize message ITransportHeaders headers; Stream requestStream; SerializeMessage(mcm, out headers, out requestStream); // process message Stream returnStream; ITransportHeaders returnHeaders; _nextSink.ProcessMessage(msg, headers, requestStream, out returnHeaders, out returnStream); if (returnHeaders == null) throw new ArgumentNullException("returnHeaders"); // deserialize stream retMsg = DeserializeMessage(mcm, returnHeaders, returnStream); } catch (Exception e) { retMsg = new ReturnMessage(e, mcm); } return retMsg; } // SyncProcessMessage [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] public IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink) { IMethodCallMessage mcm = (IMethodCallMessage)msg; IMessage retMsg; try { // serialize message ITransportHeaders headers; Stream requestStream; SerializeMessage(mcm, out headers, out requestStream); // process message ClientChannelSinkStack sinkStack = new ClientChannelSinkStack(replySink); sinkStack.Push(this, mcm); _nextSink.AsyncProcessRequest(sinkStack, msg, headers, requestStream); } catch (Exception e) { retMsg = new ReturnMessage(e, mcm); if (replySink != null) replySink.SyncProcessMessage(retMsg); } return null; } // AsyncProcessMessage // // end of IMessageSink implementation // // helper function to serialize the message private void SerializeMessage(IMethodCallMessage mcm, out ITransportHeaders headers, out Stream stream) { BaseTransportHeaders requestHeaders = new BaseTransportHeaders(); headers = requestHeaders; // add SOAPAction header MethodBase mb = mcm.MethodBase; headers["SOAPAction"] = '"' + HttpEncodingHelper.EncodeUriAsXLinkHref( SoapServices.GetSoapActionFromMethodBase(mb)) + '"'; // add other http soap headers requestHeaders.ContentType = CoreChannel.SOAPContentType; if (_channelProtocol == SinkChannelProtocol.Http) headers["__RequestVerb"] = "POST"; bool bMemStream = false; stream = _nextSink.GetRequestStream(mcm, headers); if (stream == null) { stream = new ChunkedMemoryStream(CoreChannel.BufferPool); bMemStream = true; } CoreChannel.SerializeSoapMessage(mcm, stream, _includeVersioning); if (bMemStream) stream.Position = 0; } // SerializeMessage // helper function to deserialize the message private IMessage DeserializeMessage(IMethodCallMessage mcm, ITransportHeaders headers, Stream stream) { IMessage retMsg; Header[] h = new Header[3]; h[0] = new Header("__TypeName", mcm.TypeName); h[1] = new Header("__MethodName", mcm.MethodName); h[2] = new Header("__MethodSignature", mcm.MethodSignature); String contentTypeHeader = headers["Content-Type"] as String; String contentTypeValue, charsetValue; HttpChannelHelper.ParseContentType(contentTypeHeader, out contentTypeValue, out charsetValue); if (String.Compare(contentTypeValue, CoreChannel.SOAPMimeType, StringComparison.Ordinal) == 0) { // deserialize the message retMsg = CoreChannel.DeserializeSoapResponseMessage(stream, mcm, h, _strictBinding); } else { // an error has occurred int bufferSize = 1024; byte[] buffer = new byte[bufferSize]; StringBuilder sb = new StringBuilder(); int readCount = stream.Read(buffer, 0, bufferSize); while (readCount > 0) { sb.Append(Encoding.ASCII.GetString(buffer, 0, readCount)); readCount = stream.Read(buffer, 0, bufferSize); } retMsg = new ReturnMessage(new RemotingException(sb.ToString()), mcm); } // Close the stream since we're done with it (especially important if this // happened to be a network stream) stream.Close(); return retMsg; } // DeserializeMessage // // IClientChannelSink implementation // [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] public void ProcessMessage(IMessage msg, ITransportHeaders requestHeaders, Stream requestStream, out ITransportHeaders responseHeaders, out Stream responseStream) { // never gets called, this sink is always first throw new NotSupportedException(); } // ProcessMessage [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] public void AsyncProcessRequest(IClientChannelSinkStack sinkStack, IMessage msg, ITransportHeaders headers, Stream stream) { // never gets called, this sink is always first throw new NotSupportedException(); } // AsyncProcessRequest [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] public void AsyncProcessResponse(IClientResponseChannelSinkStack sinkStack, Object state, ITransportHeaders headers, Stream stream) { // previously we stored the outgoing message in state IMethodCallMessage mcm = (IMethodCallMessage)state; IMessage retMsg = DeserializeMessage(mcm, headers, stream); sinkStack.DispatchReplyMessage(retMsg); } // AsyncProcessRequest [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] public Stream GetRequestStream(IMessage msg, ITransportHeaders headers) { // should never be called on formatter sender sink throw new NotSupportedException(); } // GetRequestStream public IClientChannelSink NextChannelSink { [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] get { return _nextSink; } } // Next public IDictionary Properties { [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] get { return null; } } // Properties // // end of IClientChannelSink implementation // } // class SoapClientFormatterSink // // SERVER-SIDE SOAP FORMATTER SINKS // public class SoapServerFormatterSinkProvider : IServerFormatterSinkProvider { private IServerChannelSinkProvider _next = null; // settings from config private bool _includeVersioning = true; private bool _strictBinding = false; private TypeFilterLevel _formatterSecurityLevel = TypeFilterLevel.Low; public SoapServerFormatterSinkProvider() { } // SoapServerFormatterSinkProvider public SoapServerFormatterSinkProvider(IDictionary properties, ICollection providerData) { // look at properties if (properties != null) { foreach (DictionaryEntry entry in properties) { String keyStr = entry.Key.ToString(); switch (keyStr) { case "includeVersions": _includeVersioning = Convert.ToBoolean(entry.Value, CultureInfo.InvariantCulture); break; case "strictBinding": _strictBinding = Convert.ToBoolean(entry.Value, CultureInfo.InvariantCulture); break; case "typeFilterLevel": _formatterSecurityLevel = (TypeFilterLevel) Enum.Parse(typeof(TypeFilterLevel), (string)entry.Value); break; default: break; } } } // not expecting any provider data CoreChannel.VerifyNoProviderData(this.GetType().Name, providerData); } // SoapServerFormatterSinkProvider [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] public void GetChannelData(IChannelDataStore channelData) { } // GetChannelData [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] public IServerChannelSink CreateSink(IChannelReceiver channel) { if(null == channel) { throw new ArgumentNullException("channel"); } IServerChannelSink nextSink = null; if (_next != null) nextSink = _next.CreateSink(channel); SoapServerFormatterSink.Protocol protocol = SoapServerFormatterSink.Protocol.Other; // see if this is an http channel String uri = channel.GetUrlsForUri("")[0]; if (String.Compare("http", 0, uri, 0, 4, StringComparison.OrdinalIgnoreCase) == 0) protocol = SoapServerFormatterSink.Protocol.Http; SoapServerFormatterSink sink = new SoapServerFormatterSink(protocol, nextSink, channel); sink.IncludeVersioning = _includeVersioning; sink.StrictBinding = _strictBinding; sink.TypeFilterLevel = _formatterSecurityLevel; return sink; } public IServerChannelSinkProvider Next { [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] get { return _next; } [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] set { _next = value; } } [System.Runtime.InteropServices.ComVisible(false)] public TypeFilterLevel TypeFilterLevel { get { return _formatterSecurityLevel; } set { _formatterSecurityLevel = value; } } } // class SoapServerFormatterSinkProvider public class SoapServerFormatterSink : IServerChannelSink { [Serializable] public enum Protocol { Http, // special processing needed for http Other } private IServerChannelSink _nextSink; // If this sink doesn't recognize, the incoming // format then he should call the next // sink if there is one. private Protocol _protocol; // transport protocol being used private IChannelReceiver _receiver; // transport sink used to parse url private bool _includeVersioning = true; // should versioning be used private bool _strictBinding = false; // should strict binding be used private TypeFilterLevel _formatterSecurityLevel = TypeFilterLevel.Full; public SoapServerFormatterSink(Protocol protocol, IServerChannelSink nextSink, IChannelReceiver receiver) { if (receiver == null) throw new ArgumentNullException("receiver"); _nextSink = nextSink; _protocol = protocol; _receiver = receiver; } // SoapServerFormatterSinkProvider internal bool IncludeVersioning { set { _includeVersioning = value; } } // IncludeVersioning internal bool StrictBinding { set { _strictBinding = value; } } // StrictBinding [System.Runtime.InteropServices.ComVisible(false)] public TypeFilterLevel TypeFilterLevel { get { return _formatterSecurityLevel; } set { _formatterSecurityLevel = value; } } [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] public ServerProcessing ProcessMessage(IServerChannelSinkStack sinkStack, IMessage requestMsg, ITransportHeaders requestHeaders, Stream requestStream, out IMessage responseMsg, out ITransportHeaders responseHeaders, out Stream responseStream) { if (requestMsg != null) { // The message has already been deserialized so delegate to the next sink. return _nextSink.ProcessMessage( sinkStack, requestMsg, requestHeaders, requestStream, out responseMsg, out responseHeaders, out responseStream); } if (requestHeaders == null) throw new ArgumentNullException("requestHeaders"); BaseTransportHeaders wkRequestHeaders = requestHeaders as BaseTransportHeaders; ServerProcessing processing; responseHeaders = null; responseStream = null; String verb = null; String contentType = null; bool bCanServiceRequest = true; // determine the content type String contentTypeHeader = null; if (wkRequestHeaders != null) contentTypeHeader = wkRequestHeaders.ContentType; else contentTypeHeader = requestHeaders["Content-Type"] as String; if (contentTypeHeader != null) { String charsetValue; HttpChannelHelper.ParseContentType(contentTypeHeader, out contentType, out charsetValue); } // check to see if Content-Type matches if ((contentType != null) && (String.Compare(contentType, CoreChannel.SOAPMimeType, StringComparison.Ordinal) != 0)) { bCanServiceRequest = false; } // check for http specific verbs if (_protocol == Protocol.Http) { verb = (String)requestHeaders["__RequestVerb"]; if (!verb.Equals("POST") && !verb.Equals("M-POST")) bCanServiceRequest = false; } // either delegate or return an error message if we can't service the request if (!bCanServiceRequest) { // delegate to next sink if available if (_nextSink != null) { return _nextSink.ProcessMessage(sinkStack, null, requestHeaders, requestStream, out responseMsg, out responseHeaders, out responseStream); } else { // send back an error message if (_protocol == Protocol.Http) { // return a client bad request error responseHeaders = new TransportHeaders(); responseHeaders["__HttpStatusCode"] = "400"; responseHeaders["__HttpReasonPhrase"] = "Bad Request"; responseStream = null; responseMsg = null; return ServerProcessing.Complete; } else { // The transport sink will catch this and do something here. throw new RemotingException( CoreChannel.GetResourceString("Remoting_Channels_InvalidRequestFormat")); } } } bool bClientIsClr = true; try { String objectUri = null; if (wkRequestHeaders != null) objectUri = wkRequestHeaders.RequestUri; else objectUri = (String)requestHeaders[CommonTransportKeys.RequestUri]; if (RemotingServices.GetServerTypeForUri(objectUri) == null) throw new RemotingException( CoreChannel.GetResourceString("Remoting_ChnlSink_UriNotPublished")); if (_protocol == Protocol.Http) { String userAgent = (String)requestHeaders["User-Agent"]; if (userAgent != null) { if (userAgent.IndexOf("MS .NET Remoting") == -1) { // user agent string did not contain ".NET Remoting", so it is someone else bClientIsClr = false; } } else { bClientIsClr = false; } } bool bIsCustomErrorEnabled = true; object oIsCustomErrorEnabled = requestHeaders["__CustomErrorsEnabled"]; if (oIsCustomErrorEnabled != null && oIsCustomErrorEnabled is bool){ bIsCustomErrorEnabled = (bool)oIsCustomErrorEnabled; } CallContext.SetData("__CustomErrorsEnabled", bIsCustomErrorEnabled); String soapActionToVerify; Header[] h = GetChannelHeaders(requestHeaders, out soapActionToVerify); PermissionSet currentPermissionSet = null; if (this.TypeFilterLevel != TypeFilterLevel.Full) { currentPermissionSet = new PermissionSet(PermissionState.None); currentPermissionSet.SetPermission(new SecurityPermission(SecurityPermissionFlag.SerializationFormatter)); } try { if (currentPermissionSet != null) currentPermissionSet.PermitOnly(); // Deserialize Request - Stream to IMessage requestMsg = CoreChannel.DeserializeSoapRequestMessage(requestStream, h, _strictBinding, this.TypeFilterLevel); } finally { if (currentPermissionSet != null) CodeAccessPermission.RevertPermitOnly(); } requestStream.Close(); if(requestMsg == null) { throw new RemotingException(CoreChannel.GetResourceString("Remoting_DeserializeMessage")); } // verify soap action if necessary if ((soapActionToVerify != null) && (!SoapServices.IsSoapActionValidForMethodBase( soapActionToVerify, ((IMethodMessage)requestMsg).MethodBase))) { throw new RemotingException( String.Format( CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Soap_InvalidSoapAction"), soapActionToVerify) ); } // Dispatch Call sinkStack.Push(this, null); processing = _nextSink.ProcessMessage(sinkStack, requestMsg, requestHeaders, null, out responseMsg, out responseHeaders, out responseStream); // make sure that responseStream is null if (responseStream != null) { throw new RemotingException( CoreChannel.GetResourceString("Remoting_ChnlSink_WantNullResponseStream")); } switch (processing) { case ServerProcessing.Complete: { if (responseMsg == null) throw new RemotingException(CoreChannel.GetResourceString("Remoting_DispatchMessage")); sinkStack.Pop(this); SerializeResponse(sinkStack, responseMsg, bClientIsClr, ref responseHeaders, out responseStream); break; } // case ServerProcessing.Complete case ServerProcessing.OneWay: { sinkStack.Pop(this); break; } // case ServerProcessing.OneWay: case ServerProcessing.Async: { sinkStack.Store(this, null); break; } // case ServerProcessing.Async } // switch (processing) } catch(Exception e) { processing = ServerProcessing.Complete; responseMsg = new ReturnMessage(e, (IMethodCallMessage)(requestMsg==null?new ErrorMessage():requestMsg)); // CallContext.SetData("__ClientIsClr", bClientIsClr); responseStream = (MemoryStream)CoreChannel.SerializeSoapMessage(responseMsg, _includeVersioning); CallContext.FreeNamedDataSlot("__ClientIsClr"); responseStream.Position = 0; responseHeaders = new TransportHeaders(); if (_protocol == Protocol.Http) { responseHeaders["__HttpStatusCode"] = "500"; responseHeaders["__HttpReasonPhrase"] = "Internal Server Error"; responseHeaders["Content-Type"] = CoreChannel.SOAPContentType; } } finally{ CallContext.FreeNamedDataSlot("__CustomErrorsEnabled"); } return processing; } // ProcessMessage [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] public void AsyncProcessResponse(IServerResponseChannelSinkStack sinkStack, Object state, IMessage msg, ITransportHeaders headers, Stream stream) { // < SerializeResponse(sinkStack, msg, true, ref headers, out stream); sinkStack.AsyncProcessResponse(msg, headers, stream); } // AsyncProcessResponse [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] private void SerializeResponse(IServerResponseChannelSinkStack sinkStack, IMessage msg, bool bClientIsClr, ref ITransportHeaders headers, out Stream stream) { BaseTransportHeaders responseHeaders = new BaseTransportHeaders(); if (headers != null) { // copy old headers into new headers foreach (DictionaryEntry entry in headers) { responseHeaders[entry.Key] = entry.Value; } } headers = responseHeaders; responseHeaders.ContentType = CoreChannel.SOAPContentType; if (_protocol == Protocol.Http) { // check to see if an exception occurred (requires special status code for HTTP) IMethodReturnMessage mrm = msg as IMethodReturnMessage; if ((mrm != null) && (mrm.Exception != null)) { headers["__HttpStatusCode"] = "500"; headers["__HttpReasonPhrase"] = "Internal Server Error"; } } bool bMemStream = false; stream = sinkStack.GetResponseStream(msg, headers); if (stream == null) { stream = new ChunkedMemoryStream(CoreChannel.BufferPool); bMemStream = true; } bool bBashUrl = CoreChannel.SetupUrlBashingForIisSslIfNecessary(); CallContext.SetData("__ClientIsClr", bClientIsClr); try { CoreChannel.SerializeSoapMessage(msg, stream, _includeVersioning); } finally { CallContext.FreeNamedDataSlot("__ClientIsClr"); CoreChannel.CleanupUrlBashingForIisSslIfNecessary(bBashUrl); } if (bMemStream) stream.Position = 0; } // SerializeResponse [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] public Stream GetResponseStream(IServerResponseChannelSinkStack sinkStack, Object state, IMessage msg, ITransportHeaders headers) { // We don't need to implement this because it will never be called. throw new NotSupportedException(); } // GetResponseStream public IServerChannelSink NextChannelSink { [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] get { return _nextSink; } } public IDictionary Properties { [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.Infrastructure, Infrastructure=true)] get { return null; } } // Properties // Helper method for analyzing headers private Header[] GetChannelHeaders(ITransportHeaders requestHeaders, out String soapActionToVerify) { soapActionToVerify = null; // transport sink removes any channel specific information String objectURI = (String)requestHeaders[CommonTransportKeys.RequestUri]; // see if a unique SOAPAction is present (if more than one SOAPAction is present some // scenarios won't work, but one-many soap action to method base relationships are // for interop scenarios only) String soapAction = (String) requestHeaders["SOAPAction"]; if (soapAction == null) throw new RemotingException(CoreChannel.GetResourceString("Remoting_SoapActionMissing")); soapAction = HttpEncodingHelper.DecodeUri(soapAction); soapActionToVerify = soapAction; String typeName, methodName; if (!SoapServices.GetTypeAndMethodNameFromSoapAction(soapAction, out typeName, out methodName)) { // This means there are multiple methods for this soap action, so we will have to // settle for the type based off of the uri. Type type = RemotingServices.GetServerTypeForUri(objectURI); if (type == null) { throw new RemotingException( String.Format( CultureInfo.CurrentCulture, CoreChannel.GetResourceString( "Remoting_TypeNotFoundFromUri"), objectURI)); } // @todo: This throws away the version, culture and public key token typeName = "clr:" + type.FullName + ", " + type.Assembly.GetName().Name; } else { typeName = "clr:" + typeName; } // Create a new header array and pass it back. int headerLen = 2; Header[] h = new Header[headerLen]; h[0] = new Header("__Uri", objectURI); h[1] = new Header("__TypeName", typeName); return h; } // GetChannelHeaders } // class SoapServerFormatterSink } // namespace System.Runtime.Remoting.Channnels // File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- SecureStringHasher.cs
- CompiledXpathExpr.cs
- MouseActionValueSerializer.cs
- VisualBrush.cs
- DescendantOverDescendantQuery.cs
- ApplicationFileParser.cs
- DataFormats.cs
- CopyNodeSetAction.cs
- XmlSerializerFactory.cs
- SiteMapNode.cs
- TakeQueryOptionExpression.cs
- IdentifierElement.cs
- UrlRoutingHandler.cs
- AnonymousIdentificationSection.cs
- BasicExpressionVisitor.cs
- MouseBinding.cs
- SafeNativeMemoryHandle.cs
- LayoutTableCell.cs
- TaskDesigner.cs
- Int64AnimationUsingKeyFrames.cs
- WinInetCache.cs
- RepeaterDesigner.cs
- UpDownEvent.cs
- FontNamesConverter.cs
- CodeDomSerializer.cs
- TableCellCollection.cs
- UnSafeCharBuffer.cs
- TransformCollection.cs
- ConfigXmlSignificantWhitespace.cs
- InheritanceContextChangedEventManager.cs
- DataColumn.cs
- Typeface.cs
- ThicknessAnimation.cs
- CfgSemanticTag.cs
- GridViewColumnHeaderAutomationPeer.cs
- WebPartDisplayModeEventArgs.cs
- peernodeimplementation.cs
- FrameSecurityDescriptor.cs
- BroadcastEventHelper.cs
- AnonymousIdentificationSection.cs
- Int32Converter.cs
- MimeTypeMapper.cs
- FixedStringLookup.cs
- RuleInfoComparer.cs
- TypeContext.cs
- ForeignKeyFactory.cs
- xdrvalidator.cs
- MatrixTransform.cs
- SemaphoreSecurity.cs
- AssemblyHash.cs
- ScriptingAuthenticationServiceSection.cs
- XXXInfos.cs
- XmlDataCollection.cs
- PersistChildrenAttribute.cs
- DependencyPropertyAttribute.cs
- UnitySerializationHolder.cs
- ConnectionManagementElementCollection.cs
- MemoryMappedViewAccessor.cs
- CodeIterationStatement.cs
- DataGridBoolColumn.cs
- DirectionalLight.cs
- MemberHolder.cs
- StatusStrip.cs
- CngKeyCreationParameters.cs
- EntityCommandExecutionException.cs
- LiteralControl.cs
- Transform3DCollection.cs
- EUCJPEncoding.cs
- GrammarBuilderDictation.cs
- InputLanguageManager.cs
- DictionaryContent.cs
- ProfileModule.cs
- CredentialCache.cs
- PenContext.cs
- GroupDescription.cs
- TraceHandler.cs
- WindowsUpDown.cs
- SizeConverter.cs
- ResourceDefaultValueAttribute.cs
- SerializationSectionGroup.cs
- SqlDataSourceSelectingEventArgs.cs
- BeginStoryboard.cs
- CacheSection.cs
- DesignerRegion.cs
- WsdlImporterElement.cs
- XamlGridLengthSerializer.cs
- UserThread.cs
- XPathParser.cs
- HttpCapabilitiesEvaluator.cs
- BamlResourceContent.cs
- __Filters.cs
- AgileSafeNativeMemoryHandle.cs
- HtmlTableRow.cs
- HttpWebResponse.cs
- AdornerPresentationContext.cs
- ExternalFile.cs
- SingleStorage.cs
- Compiler.cs
- DataKeyCollection.cs
- NativeObjectSecurity.cs