* SoapClientFormatterSink.cs, SoapClientFormatterSinkProvider.cs SoapServerFormatterSink.cs, SoapServerFormatterSinkProvider.cs, SoapMessageFormatter.cs: Support for the soap serialization added to the remoting infrastructure
svn path=/trunk/mcs/; revision=16062
+2003-07-09: Jean-Marc André <jean-marc.andre@polymtl.ca>
+
+ * SoapClientFormatterSink.cs, SoapClientFormatterSinkProvider.cs,
+ SoapServerFormatterSink.cs, SoapServerFormatterSinkProvider.cs,
+ SoapMessageFormatter.cs: Support for the soap serialization added to
+ the remoting infrastructure.
-//
-// System.Runtime.Remoting.Channels.SoapClientFormatterSink.cs
-//
-// Author: Rodrigo Moya (rodrigo@ximian.com)
-//
-// 2002 (C) Copyright, Ximian, Inc.
-//
-
-using System.Collections;
-using System.IO;
-using System.Runtime.Remoting.Messaging;
-
-namespace System.Runtime.Remoting.Channels
-{
- public class SoapClientFormatterSink : IClientFormatterSink,
- IMessageSink, IClientChannelSink, IChannelSinkBase
- {
- private IClientChannelSink nextClientSink;
-
- public SoapClientFormatterSink (IClientChannelSink sink)
- {
- nextClientSink = sink;
- }
-
- public IClientChannelSink NextChannelSink
- {
- get {
- return nextClientSink;
- }
- }
-
- public IMessageSink NextSink
- {
- [MonoTODO]
- get {
- throw new NotImplementedException ();
- }
- }
-
- public IDictionary Properties
- {
- [MonoTODO]
- get {
- throw new NotImplementedException ();
- }
- }
-
- [MonoTODO]
- public IMessageCtrl AsyncProcessMessage (IMessage msg,
- IMessageSink replySink)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- public void AsyncProcessRequest (IClientChannelSinkStack sinkStack,
- IMessage msg,
- ITransportHeaders headers,
- Stream stream)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- public void AsyncProcessResponse (IClientResponseChannelSinkStack sinkStack,
- object state,
- ITransportHeaders headers,
- Stream stream)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- public Stream GetRequestStream (IMessage msg,
- ITransportHeaders headers)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- public void ProcessMessage (IMessage msg,
- ITransportHeaders requestHeaders,
- Stream requestStream,
- out ITransportHeaders responseHeaders,
- out Stream responseStream)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- public IMessage SyncProcessMessage (IMessage msg)
- {
- throw new NotImplementedException ();
- }
- }
-}
+//\r
+// System.Runtime.Remoting.Channels.SoapClientFormatterSink.cs\r
+//\r
+// Authors: Rodrigo Moya (rodrigo@ximian.com)\r
+// Jean-Marc André (jean-marc.andre@polymtl.ca)\r
+//\r
+// 2002 (C) Copyright, Ximian, Inc.\r
+//\r
+\r
+using System.Collections;\r
+using System.IO;\r
+using System.Reflection;\r
+using System.Runtime.Remoting.Messaging;\r
+using System.Runtime.Serialization;\r
+using System.Runtime.Serialization.Formatters;\r
+using System.Runtime.Serialization.Formatters.Soap;\r
+\r
+namespace System.Runtime.Remoting.Channels\r
+{\r
+ public class SoapClientFormatterSink : IClientFormatterSink,\r
+ IMessageSink, IClientChannelSink, IChannelSinkBase\r
+ {\r
+ private IClientChannelSink _nextChannelSink;\r
+ private SoapFormatter _serializationFormatter;\r
+ private SoapFormatter _deserializationFormatter;\r
+ \r
+ public SoapClientFormatterSink (IClientChannelSink sink)\r
+ {\r
+ _nextChannelSink = sink;\r
+ RemotingSurrogateSelector surrogateSelector = new RemotingSurrogateSelector();\r
+ StreamingContext context = new StreamingContext(StreamingContextStates.Remoting);\r
+ _serializationFormatter = new SoapFormatter(surrogateSelector, context);\r
+ _deserializationFormatter = new SoapFormatter(null, context);\r
+ }\r
+ \r
+ // IClientChannelSink\r
+ public IClientChannelSink NextChannelSink\r
+ {\r
+ get {\r
+ return _nextChannelSink;\r
+ }\r
+ }\r
+ \r
+ // IMessageSink\r
+ public IMessageSink NextSink\r
+ {\r
+ get {\r
+ return null ;\r
+ }\r
+ }\r
+ \r
+ // IChannelSinkBase\r
+ public IDictionary Properties\r
+ {\r
+ get {\r
+ return null;\r
+ }\r
+ }\r
+\r
+ public IMessageCtrl AsyncProcessMessage (IMessage msg,\r
+ IMessageSink replySink)\r
+ {\r
+ Stream requestStream;\r
+ ITransportHeaders requestHeaders;\r
+ SoapMessageFormatter soapMsgFormatter;\r
+ \r
+ SerializeMessage(msg, out requestStream, out requestHeaders, out soapMsgFormatter);\r
+\r
+ ClientChannelSinkStack stack = new ClientChannelSinkStack(replySink);\r
+ stack.Push(this, soapMsgFormatter);\r
+\r
+ _nextChannelSink.AsyncProcessRequest(stack, msg, requestHeaders, requestStream);\r
+\r
+ return null;\r
+ }\r
+\r
+ public void AsyncProcessRequest (IClientChannelSinkStack sinkStack,\r
+ IMessage msg,\r
+ ITransportHeaders headers,\r
+ Stream stream)\r
+ {\r
+ // this method should never be called\r
+ throw new NotSupportedException ();\r
+ }\r
+\r
+ public void AsyncProcessResponse (IClientResponseChannelSinkStack sinkStack,\r
+ object state,\r
+ ITransportHeaders headers,\r
+ Stream stream)\r
+ {\r
+ SoapMessageFormatter soapMsgFormatter = (SoapMessageFormatter)state;\r
+\r
+ IMessage replyMessage = (IMessage) DeserializeMessage(stream, headers, (IMethodCallMessage)state, soapMsgFormatter);\r
+\r
+ sinkStack.DispatchReplyMessage(replyMessage);\r
+ \r
+ }\r
+\r
+ public Stream GetRequestStream (IMessage msg,\r
+ ITransportHeaders headers)\r
+ {\r
+ // First sink in the chain so this method should never\r
+ // be called\r
+ throw new NotSupportedException ();\r
+ }\r
+\r
+ public void ProcessMessage (IMessage msg,\r
+ ITransportHeaders requestHeaders,\r
+ Stream requestStream,\r
+ out ITransportHeaders responseHeaders,\r
+ out Stream responseStream)\r
+ {\r
+ // First sink in the chain so this method should never\r
+ // be called\r
+ throw new NotSupportedException ();\r
+ \r
+ }\r
+\r
+// ////[MonoTODO]\r
+ public IMessage SyncProcessMessage (IMessage msg)\r
+ {\r
+ Stream requestStream, responseStream;\r
+ ITransportHeaders requestHeaders, responseHeaders;\r
+ SoapMessageFormatter soapMsgFormatter;\r
+ \r
+ SerializeMessage(msg, out requestStream, out requestHeaders, out soapMsgFormatter);\r
+ _nextChannelSink.ProcessMessage(msg, requestHeaders, requestStream, out responseHeaders, out responseStream);\r
+ \r
+ return DeserializeMessage(responseStream, responseHeaders, (IMethodCallMessage)msg, soapMsgFormatter);\r
+ }\r
+ \r
+ \r
+ private void SerializeMessage(IMessage msg, out Stream requestStream, out ITransportHeaders requestHeaders, out SoapMessageFormatter soapMsgFormatter) {\r
+ SoapMessage soapMsg;\r
+ soapMsgFormatter = new SoapMessageFormatter();\r
+ soapMsg = soapMsgFormatter.BuildSoapMessageFromMethodCall((IMethodCallMessage) msg, out requestHeaders);\r
+ \r
+ // Get the stream where the message will be serialized\r
+ requestStream = _nextChannelSink.GetRequestStream(msg, requestHeaders);\r
+ \r
+ if(requestStream == null) requestStream = new MemoryStream();\r
+ \r
+ // Serialize the message into the stream\r
+ _serializationFormatter.Serialize(requestStream, soapMsg, null);\r
+ \r
+ if(requestStream is MemoryStream){\r
+ requestStream.Position = 0;\r
+ }\r
+\r
+ \r
+ }\r
+ \r
+ \r
+ private IMessage DeserializeMessage(Stream responseStream, ITransportHeaders responseHeaders,IMethodCallMessage mcm, SoapMessageFormatter soapMsgFormatter) {\r
+ SoapMessage rtnMessage = new SoapMessage();\r
+ _deserializationFormatter.TopObject = rtnMessage;\r
+ object objReturn = _deserializationFormatter.Deserialize(responseStream);\r
+ \r
+ return soapMsgFormatter.FormatResponse((ISoapMessage) objReturn, mcm);\r
+ \r
+ \r
+ }\r
+ }\r
+}\r
--- /dev/null
+// created on 20/05/2003 at 12:33\r
+using System.Collections;\r
+using System.Runtime.Remoting.Messaging;\r
+\r
+\r
+namespace System.Runtime.Remoting.Channels {\r
+ public class SoapClientFormatterSinkProvider: IClientFormatterSinkProvider, \r
+ IClientChannelSinkProvider \r
+ {\r
+ private IClientChannelSinkProvider _nextClientChannelSinkProvider;\r
+ private IDictionary _properties;\r
+ private ICollection _providerData;\r
+ \r
+ public SoapClientFormatterSinkProvider() {\r
+ \r
+ }\r
+ \r
+ public SoapClientFormatterSinkProvider(IDictionary properties,\r
+ ICollection providerData)\r
+ {\r
+ _properties = properties;\r
+ _providerData = providerData;\r
+ }\r
+ \r
+ public virtual IClientChannelSinkProvider Next {\r
+ get { return _nextClientChannelSinkProvider;}\r
+ set { _nextClientChannelSinkProvider = value;}\r
+ }\r
+ \r
+ public virtual IClientChannelSink CreateSink( IChannelSender channel, \r
+ string url, \r
+ object remoteChannelData)\r
+ {\r
+ IClientChannelSink _nextSink = _nextClientChannelSinkProvider.CreateSink(channel, url, remoteChannelData);\r
+ \r
+ IClientChannelSink scfs = new SoapClientFormatterSink(_nextSink); \r
+ return scfs;\r
+ \r
+ }\r
+ }\r
+}\r
--- /dev/null
+// created on 03/04/2003 at 14:09\r
+// \r
+// System.Runtime.Remoting.Channels.SoapMessageFormatter\r
+//\r
+// Author: Jean-Marc Andre (jean-marc.andre@polymtl.ca)\r
+//\r
+//\r
+\r
+using System;\r
+using System.Collections;\r
+using System.Reflection;\r
+using System.Runtime.Remoting.Messaging;\r
+using System.Runtime.Serialization;\r
+using System.Runtime.Serialization.Formatters;\r
+\r
+\r
+\r
+namespace System.Runtime.Remoting.Channels {\r
+ enum RemMessageType {\r
+ MethodCall, MethodResponse, ServerFault, NotRecognize\r
+ }\r
+ \r
+ internal class SoapMessageFormatter {\r
+ private static FieldInfo _serverFaultExceptionField;\r
+ private Type _serverType;\r
+ private MethodInfo _methodCallInfo;\r
+ private ParameterInfo[] _methodCallParameters;\r
+ private string _xmlNamespace;\r
+ \r
+ static SoapMessageFormatter() {\r
+ // Get the ServerFault exception field FieldInfo that\r
+ // will be used later if an exception occurs on the server\r
+ MemberInfo[] mi = FormatterServices.GetSerializableMembers(typeof(ServerFault), new StreamingContext(StreamingContextStates.All));\r
+ FieldInfo fi;\r
+ for(int i = 0; i < mi.Length; i++){\r
+ fi = mi[i] as FieldInfo;\r
+ if(fi != null && fi.FieldType == typeof(Exception)){\r
+ _serverFaultExceptionField = fi; \r
+ }\r
+ }\r
+ \r
+ }\r
+ \r
+ internal SoapMessageFormatter() {\r
+ \r
+ }\r
+ \r
+ // used by the client\r
+ internal IMessage FormatResponse(ISoapMessage soapMsg, \r
+ IMethodCallMessage mcm) \r
+ {\r
+ IMessage rtnMsg;\r
+ \r
+ if(soapMsg.MethodName == "Fault") {\r
+ // an exception was thrown by the server\r
+ Exception e = new SerializationException();\r
+ int i = Array.IndexOf(soapMsg.ParamNames, "detail");\r
+ if(_serverFaultExceptionField != null)\r
+ // todo: revue this 'cause it's not safe\r
+ e = (Exception) _serverFaultExceptionField.GetValue(\r
+ soapMsg.ParamValues[i]);\r
+ \r
+ rtnMsg = new ReturnMessage((System.Exception)e, mcm);\r
+ }\r
+ else {\r
+ object rtnObject = null;\r
+ ArrayList outParams = new ArrayList();\r
+ int nbOutParams = 0;\r
+ RemMessageType messageType;\r
+ \r
+ // Get the output of the function if it is not *void*\r
+ if(_methodCallInfo.ReturnType != typeof(void)){\r
+ int index = Array.IndexOf(soapMsg.ParamNames, "return");\r
+ rtnObject = soapMsg.ParamValues[index];\r
+ if(rtnObject is IConvertible) \r
+ rtnObject = Convert.ChangeType(\r
+ rtnObject, \r
+ _methodCallInfo.ReturnType);\r
+ }\r
+ // check if there are *out* parameters\r
+ foreach(ParameterInfo paramInfo in _methodCallParameters) {\r
+ \r
+ if(paramInfo.IsOut) {\r
+ int index = Array.IndexOf(soapMsg.ParamNames, paramInfo.Name);\r
+ nbOutParams++;\r
+ object outParam = soapMsg.ParamValues[index];\r
+ if(outParam is IConvertible)\r
+ outParam = Convert.ChangeType(\r
+ outParam, \r
+ paramInfo.ParameterType);\r
+ outParams.Add(outParam); \r
+ }\r
+// else outParams.Insert(paramInfo.Position - 1, null);\r
+ }\r
+ \r
+ rtnMsg = new ReturnMessage(\r
+ rtnObject, \r
+ (object[]) outParams.ToArray(typeof(object)), \r
+ nbOutParams, \r
+ mcm.LogicalCallContext, \r
+ mcm);\r
+ }\r
+ return rtnMsg;\r
+ }\r
+ \r
+ // used by the client\r
+ internal SoapMessage BuildSoapMessageFromMethodCall(\r
+ IMethodCallMessage mcm,\r
+ out ITransportHeaders requestHeaders)\r
+ {\r
+ \r
+ requestHeaders = new TransportHeaders();\r
+ SoapMessage soapMsg = new SoapMessage();\r
+ string uri = mcm.Uri;\r
+\r
+ GetInfoFromMethodCallMessage(mcm);\r
+\r
+ // Format the SoapMessage that will be used to create the RPC\r
+ soapMsg.MethodName = mcm.MethodName;\r
+ int count = mcm.ArgCount;\r
+ ArrayList paramNames = new ArrayList(_methodCallParameters.Length);\r
+ ArrayList paramTypes = new ArrayList(_methodCallParameters.Length);\r
+ ArrayList paramValues = new ArrayList(_methodCallParameters.Length);\r
+ \r
+ // Add the function parameters to the SoapMessage class\r
+ foreach(ParameterInfo paramInfo in _methodCallParameters) {\r
+ if(!paramInfo.IsOut) {\r
+ paramNames.Add(paramInfo.Name);\r
+ paramTypes.Add(paramInfo.ParameterType);\r
+ paramValues.Add(mcm.Args[paramInfo.Position - 1]);\r
+ }\r
+ } \r
+ soapMsg.ParamNames = (string[]) paramNames.ToArray(typeof(string));\r
+ soapMsg.ParamTypes = (Type[]) paramTypes.ToArray(typeof(Type));\r
+ soapMsg.ParamValues = (object[]) paramValues.ToArray(typeof(object));\r
+ soapMsg.XmlNameSpace = SoapServices.GetXmlNamespaceForMethodCall(_methodCallInfo); \r
+ \r
+ // Format the transport headers\r
+ requestHeaders["Content-Type"] = "text/xml; charset=\"utf-8\"";\r
+ requestHeaders["SOAPAction"] = "\""+\r
+ SoapServices.GetSoapActionFromMethodBase(_methodCallInfo)+"\""; \r
+ requestHeaders[CommonTransportKeys.RequestUri] = mcm.Uri;\r
+ \r
+ return soapMsg;\r
+ \r
+ }\r
+ \r
+ // used by the server\r
+ internal IMessage BuildMethodCallFromSoapMessage(SoapMessage soapMessage, string uri) {\r
+ ArrayList headersList = new ArrayList();\r
+ ArrayList argsList = new ArrayList();\r
+ \r
+ headersList.Add(new Header("__Uri", uri));\r
+ headersList.Add(new Header("__MethodName", soapMessage.MethodName));\r
+ string typeNamespace, assemblyName;\r
+ bool b = SoapServices.DecodeXmlNamespaceForClrTypeNamespace(soapMessage.XmlNameSpace, out typeNamespace, out assemblyName);\r
+ _serverType = RemotingServices.GetServerTypeForUri(uri);\r
+ headersList.Add(new Header("__TypeName", _serverType.FullName, false));\r
+ _xmlNamespace = soapMessage.XmlNameSpace;\r
+ \r
+ RemMessageType messageType;\r
+ _methodCallInfo = _serverType.GetMethod(soapMessage.MethodName); \r
+ \r
+ // the *out* parameters aren't serialized\r
+ // have to add them here\r
+ _methodCallParameters = _methodCallInfo.GetParameters();\r
+ foreach(ParameterInfo paramInfo in _methodCallParameters) {\r
+ if(paramInfo.IsOut) {\r
+ argsList.Insert(paramInfo.Position - 1, null);\r
+ }\r
+ else{\r
+ int index = Array.IndexOf(soapMessage.ParamNames, paramInfo.Name);\r
+ if(soapMessage.ParamValues[index] is IConvertible) \r
+ soapMessage.ParamValues[index] = Convert.ChangeType(\r
+ soapMessage.ParamValues[index],\r
+ paramInfo.ParameterType);\r
+ argsList.Insert(paramInfo.Position - 1, soapMessage.ParamValues[index]);\r
+ }\r
+ }\r
+ \r
+ Object[] args = (Object[])argsList.ToArray(typeof(object));\r
+ headersList.Add(new Header("__Args", args, false));\r
+ Header[] headers = (Header[])headersList.ToArray(typeof(Header));\r
+ \r
+ // build the MethodCall from the headers\r
+ MethodCall mthCall = new MethodCall(headers);\r
+ return (IMessage)mthCall;\r
+ }\r
+ \r
+ // used by the server\r
+ internal object BuildSoapMessageFromMethodResponse(IMethodReturnMessage mrm, out ITransportHeaders responseHeaders)\r
+ {\r
+ responseHeaders = new TransportHeaders();\r
+\r
+ if(mrm.Exception == null) {\r
+ // *normal* function return\r
+ \r
+ SoapMessage soapMessage = new SoapMessage();\r
+ \r
+ // fill the transport headers\r
+ responseHeaders["Content-Type"] = "text/xml; charset=\"utf-8\"";\r
+\r
+ // build the SoapMessage\r
+ ArrayList paramNames = new ArrayList();\r
+ ArrayList paramValues = new ArrayList();\r
+ ArrayList paramTypes = new ArrayList();\r
+ soapMessage.MethodName = mrm.MethodName+"Response";\r
+ if(mrm.ReturnValue != null && mrm.ReturnValue.GetType() != typeof(void)) {\r
+ paramNames.Add("return");\r
+ paramValues.Add(mrm.ReturnValue);\r
+ paramTypes.Add(mrm.ReturnValue.GetType());\r
+ }\r
+ \r
+ for(int i = 0; i < mrm.OutArgCount; i++){\r
+ paramNames.Add(mrm.GetOutArgName(i));\r
+ paramValues.Add(mrm.GetOutArg(i));\r
+ if(mrm.GetOutArg(i) != null) paramTypes.Add(mrm.GetOutArg(i).GetType());\r
+ }\r
+ soapMessage.ParamNames = (string[]) paramNames.ToArray(typeof(string));\r
+ soapMessage.ParamValues = (object[]) paramValues.ToArray(typeof(object));\r
+ soapMessage.ParamTypes = (Type[]) paramTypes.ToArray(typeof(Type));\r
+ soapMessage.XmlNameSpace = _xmlNamespace;\r
+ return soapMessage;\r
+ }\r
+ else {\r
+ // an Exception was thrown while executing the function\r
+ responseHeaders["__HttpStatusCode"] = "500";\r
+ responseHeaders["__HttpReasonPhrase"] = "Internal Server Error";\r
+ // fill the transport headers\r
+ responseHeaders["Content-Type"] = "text/xml; charset=\"utf-8\"";\r
+ ServerFault serverFault = CreateServerFault(mrm.Exception);\r
+ return new SoapFault("Server", String.Format(" **** {0} - {1}", mrm.Exception.GetType().ToString(), mrm.Exception.Message), null, serverFault);\r
+ }\r
+ }\r
+ \r
+ // used by the server when an exception is thrown\r
+ // by the called function\r
+ internal ServerFault CreateServerFault(Exception e) {\r
+ // it's really strange here\r
+ // a ServerFault object has a private System.Exception member called *exception*\r
+ // (have a look at a MS Soap message when an exception occurs on the server)\r
+ // but there is not public .ctor with an Exception as parameter...????....\r
+ // (maybe an internal one). So I searched another way...\r
+ ServerFault sf = (ServerFault) FormatterServices.GetUninitializedObject(typeof(ServerFault));\r
+ MemberInfo[] mi = FormatterServices.GetSerializableMembers(typeof(ServerFault), new StreamingContext(StreamingContextStates.All));\r
+ \r
+ FieldInfo fi;\r
+ object[] mv = new object[mi.Length];\r
+ for(int i = 0; i < mi.Length; i++) {\r
+ fi = mi[i] as FieldInfo;\r
+ if(fi != null && fi.FieldType == typeof(Exception)) mv[i] = e;\r
+ }\r
+ sf = (ServerFault) FormatterServices.PopulateObjectMembers(sf, mi, mv);\r
+ \r
+ return sf;\r
+ }\r
+\r
+ internal void GetInfoFromMethodCallMessage(IMethodCallMessage mcm) {\r
+ _serverType = Type.GetType(mcm.TypeName, true);\r
+ \r
+ _methodCallInfo = _serverType.GetMethod(mcm.MethodName);\r
+ _methodCallParameters = _methodCallInfo.GetParameters();\r
+ } \r
+ \r
+ \r
+ }\r
+}\r
-//
-// System.Runtime.Remoting.Channels.SoapServerFormatterSink.cs
-//
-// Author: Duncan Mak (duncan@ximian.com)
-//
-// 2002 (C) Copyright, Ximian, Inc.
-//
-
-using System.Collections;
-using System.IO;
-using System.Runtime.Remoting.Messaging;
-
-namespace System.Runtime.Remoting.Channels {
-
- public class SoapServerFormatterSink : IServerChannelSink, IChannelSinkBase
- {
- IServerChannelSink next_sink;
-
- [MonoTODO]
- public SoapServerFormatterSink (SoapServerFormatterSink.Protocol protocol,
- IServerChannelSink nextSink,
- IChannelReceiver receiver)
- {
- this.next_sink = nextSink;
- }
-
- public IServerChannelSink NextChannelSink {
- get {
- return next_sink;
- }
- }
-
- [MonoTODO]
- public IDictionary Properties {
- get {
- throw new NotImplementedException ();
- }
- }
-
- [MonoTODO]
- public void AsyncProcessResponse (IServerResponseChannelSinkStack sinkStack, object state,
- IMessage msg, ITransportHeaders headers, Stream stream)
-
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- public Stream GetResponseStream (IServerResponseChannelSinkStack sinkStack, object state,
- IMessage msg, ITransportHeaders headers)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- public ServerProcessing ProcessMessage (IServerChannelSinkStack sinkStack,
- IMessage requestMsg, ITransportHeaders requestHeaders, Stream requestStream,
- out IMessage responseMsg, out ITransportHeaders responseHeaders, out Stream responseStream)
- {
- throw new NotImplementedException ();
- }
-
- [Serializable]
- public enum Protocol
- {
- Http = 0,
- Other = 1,
- }
- }
-}
+//\r
+// System.Runtime.Remoting.Channels.SoapServerFormatterSink.cs\r
+//\r
+// Authors: Duncan Mak (duncan@ximian.com)\r
+// Jean-Marc Andre (jean-marc.andre@polymtl.ca)\r
+//\r
+// 2002 (C) Copyright, Ximian, Inc.\r
+//\r
+\r
+using System.Collections;\r
+using System.IO;\r
+using System.Reflection;\r
+using System.Runtime.Remoting.Messaging;\r
+using System.Runtime.Serialization;\r
+using System.Runtime.Serialization.Formatters;\r
+using System.Runtime.Serialization.Formatters.Soap;\r
+\r
+\r
+namespace System.Runtime.Remoting.Channels {\r
+\r
+ /// <summary>\r
+ // The formatter sink that uses SoapFormatter\r
+ /// </summary>\r
+ // <remarks>\r
+ // The formatter sink deserializes the message from the channel sink\r
+ // and passes the result to the remoting infrastructure\r
+ // </remark>\r
+ // \r
+ public class SoapServerFormatterSink : IServerChannelSink, IChannelSinkBase\r
+ {\r
+ IServerChannelSink next_sink;\r
+ IChannelReceiver _receiver;\r
+ private SoapFormatter _serializationFormatter;\r
+ private SoapFormatter _deserializationFormatter;\r
+ \r
+ public SoapServerFormatterSink (SoapServerFormatterSink.Protocol protocol,\r
+ IServerChannelSink nextSink,\r
+ IChannelReceiver receiver)\r
+ {\r
+ this.next_sink = nextSink;\r
+ _receiver = receiver;\r
+ RemotingSurrogateSelector surrogateSelector = new RemotingSurrogateSelector();\r
+ StreamingContext context = new StreamingContext(StreamingContextStates.Other);\r
+ _serializationFormatter = new SoapFormatter(surrogateSelector, context);\r
+ _deserializationFormatter = new SoapFormatter(null, context);\r
+ }\r
+\r
+ /// <summary>\r
+ // Gets the next channel sink in the channel sink chain\r
+ // </summary>\r
+ /// <value>\r
+ // The next channel sink in the sink chain\r
+ // </value>\r
+ public IServerChannelSink NextChannelSink {\r
+ get {\r
+ return next_sink;\r
+ }\r
+ }\r
+\r
+ public IDictionary Properties {\r
+ get {\r
+ return null;\r
+ }\r
+ }\r
+\r
+ public void AsyncProcessResponse (IServerResponseChannelSinkStack sinkStack, object state,\r
+ IMessage msg, ITransportHeaders headers, Stream stream)\r
+ \r
+ {\r
+ ITransportHeaders responseHeaders = new TransportHeaders();\r
+\r
+ if(sinkStack != null) stream = sinkStack.GetResponseStream(msg, responseHeaders);\r
+ if(stream == null) stream = new MemoryStream();\r
+\r
+ SoapMessageFormatter soapMsgFormatter = (SoapMessageFormatter)state;\r
+\r
+ SoapMessage soapMessage = (SoapMessage) soapMsgFormatter.BuildSoapMessageFromMethodResponse((IMethodReturnMessage)msg, out responseHeaders);\r
+\r
+ _serializationFormatter.Serialize(stream, soapMessage, null);\r
+\r
+ if(stream is MemoryStream) stream.Position = 0;\r
+ }\r
+\r
+ public Stream GetResponseStream (IServerResponseChannelSinkStack sinkStack, object state,\r
+ IMessage msg, ITransportHeaders headers)\r
+ {\r
+ // this method shouldn't be called\r
+ throw new NotSupportedException ();\r
+ }\r
+ \r
+ public ServerProcessing ProcessMessage (IServerChannelSinkStack sinkStack,\r
+ IMessage requestMsg, ITransportHeaders requestHeaders, Stream requestStream,\r
+ out IMessage responseMsg, out ITransportHeaders responseHeaders, out Stream responseStream)\r
+ {\r
+ responseMsg = null;\r
+ responseHeaders = null;\r
+ responseStream = null;\r
+ \r
+ string url = (string)requestHeaders[CommonTransportKeys.RequestUri];\r
+ string uri;\r
+ _receiver.Parse(url, out uri);\r
+ if(uri == null) uri = url;\r
+ Type serverType = RemotingServices.GetServerTypeForUri(uri);\r
+ \r
+ SoapMessage soapMessage = new SoapMessage();\r
+ _deserializationFormatter.TopObject = soapMessage;\r
+ ServerProcessing sp;\r
+ object rtnMessageObject;\r
+ SoapMessageFormatter soapMsgFormatter = new SoapMessageFormatter();\r
+ requestStream.Position = 0;\r
+ _deserializationFormatter.Deserialize(requestStream);\r
+ requestMsg = soapMsgFormatter.BuildMethodCallFromSoapMessage(soapMessage, uri);\r
+ \r
+ sinkStack.Push(this, soapMsgFormatter);\r
+\r
+ try{\r
+ sp = next_sink.ProcessMessage(sinkStack, requestMsg, requestHeaders, null, out responseMsg, out responseHeaders, out responseStream);\r
+ \r
+ }\r
+ catch(Exception e) {\r
+ responseMsg = (IMethodReturnMessage)new ReturnMessage(e, (IMethodCallMessage)requestMsg);\r
+ sp = ServerProcessing.Complete;\r
+ }\r
+ \r
+ if(sp == ServerProcessing.Complete) {\r
+ if(responseMsg != null && responseStream == null) {\r
+ \r
+ rtnMessageObject = soapMsgFormatter.BuildSoapMessageFromMethodResponse((IMethodReturnMessage) responseMsg, out responseHeaders);\r
+ \r
+ responseStream = new MemoryStream();\r
+ \r
+ _serializationFormatter.Serialize(responseStream, rtnMessageObject);\r
+ }\r
+\r
+ sinkStack.Pop(this);\r
+ }\r
+ \r
+ return sp;\r
+ \r
+ }\r
+\r
+ private object HH(Header[] headers) {\r
+ foreach(Header h in headers) {\r
+ Console.WriteLine("Name: {0} Value:{0}", h.Name, h.Value);\r
+ }\r
+ return null;\r
+ }\r
+ \r
+ [Serializable]\r
+ public enum Protocol\r
+ {\r
+ Http = 0,\r
+ Other = 1,\r
+ }\r
+ }\r
+\r
+}\r
-//
-// System.Runtime.Remoting.Channels.SoapServerFormatterSinkProvider.cs
-//
-// Author: Rodrigo Moya (rodrigo@ximian.com)
-//
-// 2002 (C) Copyright, Ximian, Inc.
-//
-
-using System.Collections;
-
-namespace System.Runtime.Remoting.Channels
-{
- public class SoapServerFormatterSinkProvider :
- IServerFormatterSinkProvider, IServerChannelSinkProvider
- {
- [MonoTODO]
- public SoapServerFormatterSinkProvider ()
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- public SoapServerFormatterSinkProvider (IDictionary properties,
- ICollection providerData)
- {
- throw new NotImplementedException ();
- }
-
- public IServerChannelSinkProvider Next
- {
- [MonoTODO]
- get {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- set {
- throw new NotImplementedException ();
- }
- }
-
- [MonoTODO]
- public IServerChannelSink CreateSink (IChannelReceiver channel)
- {
- throw new NotImplementedException ();
- }
-
- [MonoTODO]
- public void GetChannelData (IChannelDataStore channelData)
- {
- throw new NotImplementedException ();
- }
- }
-}
+//\r
+// System.Runtime.Remoting.Channels.SoapServerFormatterSinkProvider.cs\r
+//\r
+// Author: Rodrigo Moya (rodrigo@ximian.com)\r
+//\r
+// 2002 (C) Copyright, Ximian, Inc.\r
+//\r
+\r
+using System.Collections;\r
+\r
+namespace System.Runtime.Remoting.Channels\r
+{\r
+ public class SoapServerFormatterSinkProvider :\r
+ IServerFormatterSinkProvider, IServerChannelSinkProvider\r
+ {\r
+ private IServerChannelSinkProvider _next;\r
+// ////[MonoTODO]\r
+ public SoapServerFormatterSinkProvider ()\r
+ {\r
+// throw new NotImplementedException ();\r
+ }\r
+\r
+// ////[MonoTODO]\r
+ public SoapServerFormatterSinkProvider (IDictionary properties,\r
+ ICollection providerData)\r
+ {\r
+// throw new NotImplementedException ();\r
+ }\r
+\r
+ public IServerChannelSinkProvider Next\r
+ {\r
+// ////[MonoTODO]\r
+ get {\r
+ return _next;\r
+ }\r
+\r
+// ////[MonoTODO]\r
+ set {\r
+ _next = value;\r
+ }\r
+ }\r
+\r
+// ////[MonoTODO]\r
+ public IServerChannelSink CreateSink (IChannelReceiver channel)\r
+ {\r
+ IServerChannelSink chain = _next.CreateSink(channel);\r
+ IServerChannelSink sinkFormatter = new SoapServerFormatterSink(SoapServerFormatterSink.Protocol.Http, chain, channel);\r
+ \r
+ return sinkFormatter;\r
+ }\r
+\r
+// ////[MonoTODO]\r
+ public void GetChannelData (IChannelDataStore channelData)\r
+ {\r
+ if(_next != null)\r
+ _next.GetChannelData(channelData);\r
+ }\r
+ }\r
+}\r