The Labs \ Source Viewer \ SSCLI \ System.Runtime.Remoting.Channels \ BinaryServerFormatterSink

  1. // ==++==
  2. //
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. //
  14. // ==--==
  15. //==========================================================================
  16. // File: BinaryFormatterSinks.cs
  17. //
  18. // Summary: Binary formatter client and server sinks.
  19. //
  20. //==========================================================================
  21. using System;
  22. using System.Collections;
  23. using System.IO;
  24. using System.Reflection;
  25. using System.Runtime.Serialization.Formatters;
  26. using System.Runtime.Remoting;
  27. using System.Runtime.Remoting.Channels;
  28. using System.Runtime.Remoting.Channels.Http;
  29. using System.Runtime.Remoting.Messaging;
  30. using System.Runtime.Remoting.Metadata;
  31. using System.Security;
  32. using System.Security.Permissions;
  33. using System.Globalization;
  34. namespace System.Runtime.Remoting.Channels
  35. {
  36.    
  37.     //
  38.     // CLIENT-SIDE BINARY FORMATTER SINKS
  39.     //
  40.    
  41.     public class BinaryClientFormatterSinkProvider : IClientFormatterSinkProvider
  42.     {
  43.         private IClientChannelSinkProvider _next;
  44.        
  45.         // settings from config
  46.         private bool _includeVersioning = true;
  47.         private bool _strictBinding = false;
  48.        
  49.        
  50.         public BinaryClientFormatterSinkProvider()
  51.         {
  52.         }
  53.         // BinaryClientFormatterSinkProvider
  54.        
  55.         public BinaryClientFormatterSinkProvider(IDictionary properties, ICollection providerData)
  56.         {
  57.             // look at properties
  58.             if (properties != null) {
  59.                 foreach (DictionaryEntry entry in properties) {
  60.                     string keyStr = entry.Key.ToString();
  61.                     switch (keyStr) {
  62.                         case "includeVersions":
  63.                             _includeVersioning = Convert.ToBoolean(entry.Value, CultureInfo.InvariantCulture);
  64.                             break;
  65.                         case "strictBinding":
  66.                             _strictBinding = Convert.ToBoolean(entry.Value, CultureInfo.InvariantCulture);
  67.                             break;
  68.                         default:
  69.                            
  70.                             break;
  71.                     }
  72.                 }
  73.             }
  74.            
  75.             // not expecting any provider data
  76.             CoreChannel.VerifyNoProviderData(this.GetType().Name, providerData);
  77.         }
  78.         // BinaryClientFormatterSinkProvider
  79.        
  80.         [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure, Infrastructure = true)]
  81.         public IClientChannelSink CreateSink(IChannelSender channel, string url, object remoteChannelData)
  82.         {
  83.             IClientChannelSink nextSink = null;
  84.             if (_next != null) {
  85.                 nextSink = _next.CreateSink(channel, url, remoteChannelData);
  86.                 if (nextSink == null)
  87.                     return null;
  88.             }
  89.            
  90.             SinkChannelProtocol protocol = CoreChannel.DetermineChannelProtocol(channel);
  91.            
  92.             BinaryClientFormatterSink sink = new BinaryClientFormatterSink(nextSink);
  93.             sink.IncludeVersioning = _includeVersioning;
  94.             sink.StrictBinding = _strictBinding;
  95.             sink.ChannelProtocol = protocol;
  96.             return sink;
  97.         }
  98.         // CreateSink
  99.         public IClientChannelSinkProvider Next {
  100.             [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure, Infrastructure = true)]
  101.             get { return _next; }
  102.             [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure, Infrastructure = true)]
  103.             set { _next = value; }
  104.         }
  105.     }
  106.     // class BinaryClientFormatterSinkProvider
  107.    
  108.     public class BinaryClientFormatterSink : IClientFormatterSink
  109.     {
  110.         private IClientChannelSink _nextSink = null;
  111.        
  112.         private bool _includeVersioning = true;
  113.         // should versioning be used
  114.         private bool _strictBinding = false;
  115.         // strict binding should be used
  116.         private SinkChannelProtocol _channelProtocol = SinkChannelProtocol.Other;
  117.        
  118.        
  119.         public BinaryClientFormatterSink(IClientChannelSink nextSink)
  120.         {
  121.             _nextSink = nextSink;
  122.         }
  123.         // BinaryClientFormatterSink
  124.         internal bool IncludeVersioning {
  125.             set { _includeVersioning = value; }
  126.         }
  127.         // IncludeVersioning
  128.         internal bool StrictBinding {
  129.             set { _strictBinding = value; }
  130.         }
  131.         // StrictBinding
  132.         internal SinkChannelProtocol ChannelProtocol {
  133.             set { _channelProtocol = value; }
  134.         }
  135.         // ChannelProtocol
  136.        
  137.        
  138.         public IMessageSink NextSink {
  139.             [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure, Infrastructure = true)]
  140.             get {
  141.                 throw new NotSupportedException();
  142.             }
  143.         }
  144.        
  145.         [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure, Infrastructure = true)]
  146.         public IMessage SyncProcessMessage(IMessage msg)
  147.         {
  148.             IMethodCallMessage mcm = msg as IMethodCallMessage;
  149.             IMessage retMsg;
  150.            
  151.             try {
  152.                 // serialize message
  153.                 ITransportHeaders headers;
  154.                 Stream requestStream;
  155.                 SerializeMessage(msg, out headers, out requestStream);
  156.                
  157.                 // process message
  158.                 Stream returnStream;
  159.                 ITransportHeaders returnHeaders;
  160.                 _nextSink.ProcessMessage(msg, headers, requestStream, out returnHeaders, out returnStream);
  161.                 if (returnHeaders == null)
  162.                     throw new ArgumentNullException("returnHeaders");
  163.                
  164.                 // deserialize stream
  165.                 retMsg = DeserializeMessage(mcm, returnHeaders, returnStream);
  166.             }
  167.             catch (Exception e) {
  168.                 retMsg = new ReturnMessage(e, mcm);
  169.             }
  170.             catch {
  171.                 retMsg = new ReturnMessage(new Exception(CoreChannel.GetResourceString("Remoting_nonClsCompliantException")), mcm);
  172.             }
  173.            
  174.             return retMsg;
  175.         }
  176.         // SyncProcessMessage
  177.        
  178.         [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure, Infrastructure = true)]
  179.         public IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink)
  180.         {
  181.             IMethodCallMessage mcm = (IMethodCallMessage)msg;
  182.             IMessage retMsg;
  183.            
  184.             try {
  185.                 // serialize message
  186.                 ITransportHeaders headers;
  187.                 Stream requestStream;
  188.                 SerializeMessage(msg, out headers, out requestStream);
  189.                
  190.                 // process message
  191.                 ClientChannelSinkStack sinkStack = new ClientChannelSinkStack(replySink);
  192.                 sinkStack.Push(this, msg);
  193.                 _nextSink.AsyncProcessRequest(sinkStack, msg, headers, requestStream);
  194.             }
  195.             catch (Exception e) {
  196.                 retMsg = new ReturnMessage(e, mcm);
  197.                 if (replySink != null)
  198.                     replySink.SyncProcessMessage(retMsg);
  199.             }
  200.             catch {
  201.                 retMsg = new ReturnMessage(new Exception(CoreChannel.GetResourceString("Remoting_nonClsCompliantException")), mcm);
  202.                 if (replySink != null)
  203.                     replySink.SyncProcessMessage(retMsg);
  204.             }
  205.            
  206.             return null;
  207.         }
  208.         // AsyncProcessMessage
  209.        
  210.         // helper function to serialize the message
  211.         private void SerializeMessage(IMessage msg, out ITransportHeaders headers, out Stream stream)
  212.         {
  213.             BaseTransportHeaders requestHeaders = new BaseTransportHeaders();
  214.             headers = requestHeaders;
  215.            
  216.             // add other http soap headers
  217.             requestHeaders.ContentType = CoreChannel.BinaryMimeType;
  218.             if (_channelProtocol == SinkChannelProtocol.Http)
  219.                 headers["__RequestVerb"] = "POST";
  220.            
  221.             bool bMemStream = false;
  222.             stream = _nextSink.GetRequestStream(msg, headers);
  223.             if (stream == null) {
  224.                 stream = new ChunkedMemoryStream(CoreChannel.BufferPool);
  225.                 bMemStream = true;
  226.             }
  227.             CoreChannel.SerializeBinaryMessage(msg, stream, _includeVersioning);
  228.             if (bMemStream)
  229.                 stream.Position = 0;
  230.         }
  231.         // SerializeMessage
  232.        
  233.         // helper function to deserialize the message
  234.         private IMessage DeserializeMessage(IMethodCallMessage mcm, ITransportHeaders headers, Stream stream)
  235.         {
  236.             // deserialize the message
  237.             IMessage retMsg = CoreChannel.DeserializeBinaryResponseMessage(stream, mcm, _strictBinding);
  238.            
  239.             stream.Close();
  240.             return retMsg;
  241.         }
  242.         // DeserializeMessage
  243.        
  244.         //
  245.         // IClientChannelSink implementation
  246.         //
  247.        
  248.         [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure, Infrastructure = true)]
  249.         public void ProcessMessage(IMessage msg, ITransportHeaders requestHeaders, Stream requestStream, out ITransportHeaders responseHeaders, out Stream responseStream)
  250.         {
  251.             // should never gets called, since this sink is always first
  252.             throw new NotSupportedException();
  253.         }
  254.         // ProcessMessage
  255.        
  256.         [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure, Infrastructure = true)]
  257.         public void AsyncProcessRequest(IClientChannelSinkStack sinkStack, IMessage msg, ITransportHeaders headers, Stream stream)
  258.         {
  259.             // should never be called, this sink is always first
  260.             throw new NotSupportedException();
  261.         }
  262.         // AsyncProcessRequest
  263.        
  264.         [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure, Infrastructure = true)]
  265.         public void AsyncProcessResponse(IClientResponseChannelSinkStack sinkStack, object state, ITransportHeaders headers, Stream stream)
  266.         {
  267.             // previously we stored the outgoing message in state
  268.             IMethodCallMessage mcm = (IMethodCallMessage)state;
  269.             IMessage retMsg = DeserializeMessage(mcm, headers, stream);
  270.             sinkStack.DispatchReplyMessage(retMsg);
  271.         }
  272.         // AsyncProcessRequest
  273.        
  274.         [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure, Infrastructure = true)]
  275.         public Stream GetRequestStream(IMessage msg, ITransportHeaders headers)
  276.         {
  277.             // never called on formatter sender sink
  278.             throw new NotSupportedException();
  279.         }
  280.        
  281.        
  282.         public IClientChannelSink NextChannelSink {
  283.             [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure, Infrastructure = true)]
  284.             get { return _nextSink; }
  285.         }
  286.        
  287.        
  288.         public IDictionary Properties {
  289.             [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure, Infrastructure = true)]
  290.             get { return null; }
  291.         }
  292.         // Properties
  293.         //
  294.         // end of IClientChannelSink implementation
  295.         //
  296.        
  297.     }
  298.     // class BinaryClientFormatterSink
  299.    
  300.    
  301.     //
  302.     // SERVER-SIDE SOAP FORMATTER SINKS
  303.     //
  304.    
  305.     public class BinaryServerFormatterSinkProvider : IServerFormatterSinkProvider
  306.     {
  307.         private IServerChannelSinkProvider _next = null;
  308.        
  309.         // settings from config
  310.         private bool _includeVersioning = true;
  311.         private bool _strictBinding = false;
  312.         private TypeFilterLevel _formatterSecurityLevel = TypeFilterLevel.Low;
  313.        
  314.         public BinaryServerFormatterSinkProvider()
  315.         {
  316.         }
  317.         // BinaryServerFormatterSinkProvider
  318.        
  319.         public BinaryServerFormatterSinkProvider(IDictionary properties, ICollection providerData)
  320.         {
  321.             // look at properties
  322.             if (properties != null) {
  323.                 foreach (DictionaryEntry entry in properties) {
  324.                     string keyStr = entry.Key.ToString();
  325.                     switch (keyStr) {
  326.                         case "includeVersions":
  327.                             _includeVersioning = Convert.ToBoolean(entry.Value, CultureInfo.InvariantCulture);
  328.                             break;
  329.                         case "strictBinding":
  330.                             _strictBinding = Convert.ToBoolean(entry.Value, CultureInfo.InvariantCulture);
  331.                             break;
  332.                         case "typeFilterLevel":
  333.                             _formatterSecurityLevel = (TypeFilterLevel)Enum.Parse(typeof(TypeFilterLevel), (string)entry.Value);
  334.                             break;
  335.                         default:
  336.                            
  337.                             break;
  338.                     }
  339.                 }
  340.             }
  341.            
  342.             // not expecting any provider data
  343.             CoreChannel.VerifyNoProviderData(this.GetType().Name, providerData);
  344.         }
  345.         // BinaryServerFormatterSinkProvider
  346.        
  347.         [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure, Infrastructure = true)]
  348.         public void GetChannelData(IChannelDataStore channelData)
  349.         {
  350.         }
  351.         // GetChannelData
  352.         [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure, Infrastructure = true)]
  353.         public IServerChannelSink CreateSink(IChannelReceiver channel)
  354.         {
  355.             if (null == channel) {
  356.                 throw new ArgumentNullException("channel");
  357.             }
  358.            
  359.             IServerChannelSink nextSink = null;
  360.             if (_next != null)
  361.                 nextSink = _next.CreateSink(channel);
  362.            
  363.             BinaryServerFormatterSink.Protocol protocol = BinaryServerFormatterSink.Protocol.Other;
  364.            
  365.             // see if this is an http channel
  366.             string uri = channel.GetUrlsForUri("")[0];
  367.             if (String.Compare("http", 0, uri, 0, 4, StringComparison.OrdinalIgnoreCase) == 0)
  368.                 protocol = BinaryServerFormatterSink.Protocol.Http;
  369.            
  370.             BinaryServerFormatterSink sink = new BinaryServerFormatterSink(protocol, nextSink, channel);
  371.             sink.TypeFilterLevel = _formatterSecurityLevel;
  372.             sink.IncludeVersioning = _includeVersioning;
  373.             sink.StrictBinding = _strictBinding;
  374.             return sink;
  375.         }
  376.         // CreateSink
  377.         public IServerChannelSinkProvider Next {
  378.             [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure, Infrastructure = true)]
  379.             get { return _next; }
  380.             [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure, Infrastructure = true)]
  381.             set { _next = value; }
  382.         }
  383.         // Next
  384.         [System.Runtime.InteropServices.ComVisible(false)]
  385.         public TypeFilterLevel TypeFilterLevel {
  386.             get { return _formatterSecurityLevel; }
  387.            
  388.             set { _formatterSecurityLevel = value; }
  389.         }
  390.     }
  391.     // class BinaryServerFormatterSinkProvider
  392.    
  393.     public class BinaryServerFormatterSink : IServerChannelSink
  394.     {
  395.         [Serializable()]
  396.         public enum Protocol
  397.         {
  398.             Http,
  399.             // special processing needed for http
  400.             Other
  401.         }
  402.        
  403.         private IServerChannelSink _nextSink;
  404.         // If this sink doesn't recognize, the incoming
  405.         // format then it should call the next
  406.         // sink if there is one.
  407.         private Protocol _protocol;
  408.         // remembers which protocol is being used
  409.         private IChannelReceiver _receiver;
  410.         // transport sink used to parse url
  411.         private bool _includeVersioning = true;
  412.         // should versioning be used
  413.         private bool _strictBinding = false;
  414.         // strict binding should be used
  415.         private TypeFilterLevel _formatterSecurityLevel = TypeFilterLevel.Full;
  416.         private string lastUri = null;
  417.        
  418.         public BinaryServerFormatterSink(Protocol protocol, IServerChannelSink nextSink, IChannelReceiver receiver)
  419.         {
  420.             if (receiver == null)
  421.                 throw new ArgumentNullException("receiver");
  422.            
  423.             _nextSink = nextSink;
  424.             _protocol = protocol;
  425.             _receiver = receiver;
  426.         }
  427.         // BinaryServerFormatterSinkProvider
  428.        
  429.         internal bool IncludeVersioning {
  430.             set { _includeVersioning = value; }
  431.         }
  432.         // IncludeVersioning
  433.         internal bool StrictBinding {
  434.             set { _strictBinding = value; }
  435.         }
  436.         // StrictBinding
  437.         [System.Runtime.InteropServices.ComVisible(false)]
  438.         public TypeFilterLevel TypeFilterLevel {
  439.             get { return _formatterSecurityLevel; }
  440.            
  441.             set { _formatterSecurityLevel = value; }
  442.         }
  443.        
  444.         [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure, Infrastructure = true)]
  445.         public ServerProcessing ProcessMessage(IServerChannelSinkStack sinkStack, IMessage requestMsg, ITransportHeaders requestHeaders, Stream requestStream, out IMessage responseMsg, out ITransportHeaders responseHeaders, out Stream responseStream)
  446.         {
  447.             if (requestMsg != null) {
  448.                 // The message has already been deserialized so delegate to the next sink.
  449.                 return _nextSink.ProcessMessage(sinkStack, requestMsg, requestHeaders, requestStream, out responseMsg, out responseHeaders, out responseStream);
  450.             }
  451.            
  452.             if (requestHeaders == null)
  453.                 throw new ArgumentNullException("requestHeaders");
  454.            
  455.             BaseTransportHeaders wkRequestHeaders = requestHeaders as BaseTransportHeaders;
  456.            
  457.             ServerProcessing processing;
  458.            
  459.             responseHeaders = null;
  460.             responseStream = null;
  461.            
  462.             string verb = null;
  463.             string contentType = null;
  464.            
  465.             bool bCanServiceRequest = true;
  466.            
  467.             // determine the content type
  468.             string contentTypeHeader = null;
  469.             if (wkRequestHeaders != null)
  470.                 contentTypeHeader = wkRequestHeaders.ContentType;
  471.             else
  472.                 contentTypeHeader = requestHeaders["Content-Type"] as string;
  473.             if (contentTypeHeader != null) {
  474.                 string charsetValue;
  475.                 HttpChannelHelper.ParseContentType(contentTypeHeader, out contentType, out charsetValue);
  476.             }
  477.            
  478.             // check to see if Content-Type matches
  479.             if ((contentType != null) && (String.CompareOrdinal(contentType, CoreChannel.BinaryMimeType) != 0)) {
  480.                 bCanServiceRequest = false;
  481.             }
  482.            
  483.             // check for http specific verbs
  484.             if (_protocol == Protocol.Http) {
  485.                 verb = (string)requestHeaders["__RequestVerb"];
  486.                 if (!verb.Equals("POST") && !verb.Equals("M-POST"))
  487.                     bCanServiceRequest = false;
  488.             }
  489.            
  490.             // either delegate or return an error message if we can't service the request
  491.             if (!bCanServiceRequest) {
  492.                 // delegate to next sink if available
  493.                 if (_nextSink != null) {
  494.                     return _nextSink.ProcessMessage(sinkStack, null, requestHeaders, requestStream, out responseMsg, out responseHeaders, out responseStream);
  495.                 }
  496.                 else {
  497.                     // send back an error message
  498.                     if (_protocol == Protocol.Http) {
  499.                         // return a client bad request error
  500.                         responseHeaders = new TransportHeaders();
  501.                         responseHeaders["__HttpStatusCode"] = "400";
  502.                         responseHeaders["__HttpReasonPhrase"] = "Bad Request";
  503.                         responseStream = null;
  504.                         responseMsg = null;
  505.                         return ServerProcessing.Complete;
  506.                     }
  507.                     else {
  508.                         // The transport sink will catch this and do something here.
  509.                         throw new RemotingException(CoreChannel.GetResourceString("Remoting_Channels_InvalidRequestFormat"));
  510.                     }
  511.                 }
  512.             }
  513.            
  514.            
  515.             try {
  516.                 string objectUri = null;
  517.                
  518.                 bool bIsCustomErrorEnabled = true;
  519.                 object oIsCustomErrorEnabled = requestHeaders["__CustomErrorsEnabled"];
  520.                 if (oIsCustomErrorEnabled != null && oIsCustomErrorEnabled is bool) {
  521.                     bIsCustomErrorEnabled = (bool)oIsCustomErrorEnabled;
  522.                 }
  523.                 CallContext.SetData("__CustomErrorsEnabled", bIsCustomErrorEnabled);
  524.                
  525.                 if (wkRequestHeaders != null)
  526.                     objectUri = wkRequestHeaders.RequestUri;
  527.                 else
  528.                     objectUri = (string)requestHeaders[CommonTransportKeys.RequestUri];
  529.                
  530.                 if (objectUri != lastUri && RemotingServices.GetServerTypeForUri(objectUri) == null)
  531.                     throw new RemotingException(CoreChannel.GetResourceString("Remoting_ChnlSink_UriNotPublished"));
  532.                 else
  533.                     lastUri = objectUri;
  534.                
  535.                 PermissionSet currentPermissionSet = null;
  536.                 if (this.TypeFilterLevel != TypeFilterLevel.Full) {
  537.                     currentPermissionSet = new PermissionSet(PermissionState.None);
  538.                     currentPermissionSet.SetPermission(new SecurityPermission(SecurityPermissionFlag.SerializationFormatter));
  539.                 }
  540.                
  541.                 try {
  542.                     if (currentPermissionSet != null)
  543.                         currentPermissionSet.PermitOnly();
  544.                    
  545.                     // Deserialize Request - Stream to IMessage
  546.                     requestMsg = CoreChannel.DeserializeBinaryRequestMessage(objectUri, requestStream, _strictBinding, this.TypeFilterLevel);
  547.                 }
  548.                 finally {
  549.                     if (currentPermissionSet != null)
  550.                         CodeAccessPermission.RevertPermitOnly();
  551.                 }
  552.                 requestStream.Close();
  553.                
  554.                 if (requestMsg == null) {
  555.                     throw new RemotingException(CoreChannel.GetResourceString("Remoting_DeserializeMessage"));
  556.                 }
  557.                
  558.                
  559.                 // Dispatch Call
  560.                 sinkStack.Push(this, null);
  561.                 processing = _nextSink.ProcessMessage(sinkStack, requestMsg, requestHeaders, null, out responseMsg, out responseHeaders, out responseStream);
  562.                 // make sure that responseStream is null
  563.                 if (responseStream != null) {
  564.                     throw new RemotingException(CoreChannel.GetResourceString("Remoting_ChnlSink_WantNullResponseStream"));
  565.                 }
  566.                
  567.                 switch (processing) {
  568.                     case ServerProcessing.Complete:
  569.                        
  570.                        
  571.                         {
  572.                             if (responseMsg == null)
  573.                                 throw new RemotingException(CoreChannel.GetResourceString("Remoting_DispatchMessage"));
  574.                            
  575.                             sinkStack.Pop(this);
  576.                            
  577.                             SerializeResponse(sinkStack, responseMsg, ref responseHeaders, out responseStream);
  578.                             break;
  579.                         }
  580.                         break;
  581.                     case ServerProcessing.OneWay:
  582.                         // case ServerProcessing.Complete
  583.                        
  584.                         {
  585.                             sinkStack.Pop(this);
  586.                             break;
  587.                         }
  588.                         break;
  589.                     case ServerProcessing.Async:
  590.                         // case ServerProcessing.OneWay:
  591.                        
  592.                         {
  593.                             sinkStack.Store(this, null);
  594.                             break;
  595.                         }
  596.                         break;
  597.                     // case ServerProcessing.Async
  598.                 }
  599.                 // switch (processing)
  600.             }
  601.             catch (Exception e) {
  602.                 processing = ServerProcessing.Complete;
  603.                 responseMsg = new ReturnMessage(e, (IMethodCallMessage)(requestMsg == null ? new ErrorMessage() : requestMsg));
  604.                 //TODO, sowmys: See if we could call SerializeResponse here
  605.                 //We always set __ClientIsClr here since interop is not an issue
  606.                 CallContext.SetData("__ClientIsClr", true);
  607.                 responseStream = (MemoryStream)CoreChannel.SerializeBinaryMessage(responseMsg, _includeVersioning);
  608.                 CallContext.FreeNamedDataSlot("__ClientIsClr");
  609.                 responseStream.Position = 0;
  610.                 responseHeaders = new TransportHeaders();
  611.                
  612.                 if (_protocol == Protocol.Http) {
  613.                     responseHeaders["Content-Type"] = CoreChannel.BinaryMimeType;
  614.                 }
  615.             }
  616.             catch {
  617.                 processing = ServerProcessing.Complete;
  618.                 responseMsg = new ReturnMessage(new Exception(CoreChannel.GetResourceString("Remoting_nonClsCompliantException")), (IMethodCallMessage)(requestMsg == null ? new ErrorMessage() : requestMsg));
  619.                 //TODO, sowmys: See if we could call SerializeResponse here
  620.                 //We always set __ClientIsClr here since interop is not an issue
  621.                 CallContext.SetData("__ClientIsClr", true);
  622.                 responseStream = (MemoryStream)CoreChannel.SerializeBinaryMessage(responseMsg, _includeVersioning);
  623.                 CallContext.FreeNamedDataSlot("__ClientIsClr");
  624.                 responseStream.Position = 0;
  625.                 responseHeaders = new TransportHeaders();
  626.                
  627.                 if (_protocol == Protocol.Http) {
  628.                     responseHeaders["Content-Type"] = CoreChannel.BinaryMimeType;
  629.                 }
  630.             }
  631.             finally {
  632.                 CallContext.FreeNamedDataSlot("__CustomErrorsEnabled");
  633.             }
  634.            
  635.             return processing;
  636.         }
  637.         // ProcessMessage
  638.        
  639.         [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure, Infrastructure = true)]
  640.         public void AsyncProcessResponse(IServerResponseChannelSinkStack sinkStack, object state, IMessage msg, ITransportHeaders headers, Stream stream)
  641.         {
  642.             SerializeResponse(sinkStack, msg, ref headers, out stream);
  643.             sinkStack.AsyncProcessResponse(msg, headers, stream);
  644.         }
  645.         // AsyncProcessResponse
  646.        
  647.         [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure, Infrastructure = true)]
  648.         private void SerializeResponse(IServerResponseChannelSinkStack sinkStack, IMessage msg, ref ITransportHeaders headers, out Stream stream)
  649.         {
  650.             BaseTransportHeaders responseHeaders = new BaseTransportHeaders();
  651.             if (headers != null) {
  652.                 // copy old headers into new headers
  653.                 foreach (DictionaryEntry entry in headers) {
  654.                     responseHeaders[entry.Key] = entry.Value;
  655.                 }
  656.             }
  657.             headers = responseHeaders;
  658.            
  659.             if (_protocol == Protocol.Http) {
  660.                 responseHeaders.ContentType = CoreChannel.BinaryMimeType;
  661.             }
  662.            
  663.             bool bMemStream = false;
  664.             stream = sinkStack.GetResponseStream(msg, headers);
  665.             if (stream == null) {
  666.                 stream = new ChunkedMemoryStream(CoreChannel.BufferPool);
  667.                 bMemStream = true;
  668.             }
  669.            
  670.             bool bBashUrl = CoreChannel.SetupUrlBashingForIisSslIfNecessary();
  671.             try {
  672.                 CallContext.SetData("__ClientIsClr", true);
  673.                 CoreChannel.SerializeBinaryMessage(msg, stream, _includeVersioning);
  674.             }
  675.             finally {
  676.                 CallContext.FreeNamedDataSlot("__ClientIsClr");
  677.                 CoreChannel.CleanupUrlBashingForIisSslIfNecessary(bBashUrl);
  678.             }
  679.            
  680.             if (bMemStream)
  681.                 stream.Position = 0;
  682.         }
  683.         // SerializeResponse
  684.        
  685.         [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure, Infrastructure = true)]
  686.         public Stream GetResponseStream(IServerResponseChannelSinkStack sinkStack, object state, IMessage msg, ITransportHeaders headers)
  687.         {
  688.             // This should never get called since we're the last in the chain, and never
  689.             // push ourselves to the sink stack.
  690.             throw new NotSupportedException();
  691.         }
  692.         // GetResponseStream
  693.        
  694.         public IServerChannelSink NextChannelSink {
  695.             [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure, Infrastructure = true)]
  696.             get { return _nextSink; }
  697.         }
  698.        
  699.        
  700.         public IDictionary Properties {
  701.             [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.Infrastructure, Infrastructure = true)]
  702.             get { return null; }
  703.         }
  704.         // Properties
  705.        
  706.     }
  707.     // class BinaryServerFormatterSink
  708.    
  709.    
  710. }
  711. // namespace System.Runtime.Remoting.Channnels

Developer Fusion