// 2002 (C) Copyright, Ximian, Inc.\r
//\r
\r
+//\r
+// Permission is hereby granted, free of charge, to any person obtaining\r
+// a copy of this software and associated documentation files (the\r
+// "Software"), to deal in the Software without restriction, including\r
+// without limitation the rights to use, copy, modify, merge, publish,\r
+// distribute, sublicense, and/or sell copies of the Software, and to\r
+// permit persons to whom the Software is furnished to do so, subject to\r
+// the following conditions:\r
+// \r
+// The above copyright notice and this permission notice shall be\r
+// included in all copies or substantial portions of the Software.\r
+// \r
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\r
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\r
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+//\r
+\r
using System.Collections;\r
using System.IO;\r
using System.Reflection;\r
using System.Runtime.Serialization;\r
using System.Runtime.Serialization.Formatters;\r
using System.Runtime.Serialization.Formatters.Soap;\r
+using System.Runtime.InteropServices;\r
\r
\r
namespace System.Runtime.Remoting.Channels {\r
{\r
IServerChannelSink next_sink;\r
IChannelReceiver _receiver;\r
- private SoapFormatter _serializationFormatter;\r
- private SoapFormatter _deserializationFormatter;\r
+ private SoapCore _soapCore = SoapCore.DefaultInstance;\r
\r
public SoapServerFormatterSink (SoapServerFormatterSink.Protocol protocol,\r
IServerChannelSink nextSink,\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
+ internal SoapCore SoapCore\r
+ {\r
+ get { return _soapCore; }\r
+ set { _soapCore = value; }\r
+ }\r
+ \r
/// <summary>\r
// Gets the next channel sink in the channel sink chain\r
// </summary>\r
}\r
}\r
\r
+ [ComVisible(false)]\r
+ public TypeFilterLevel TypeFilterLevel\r
+ {\r
+ get { return _soapCore.TypeFilterLevel; }\r
+ set \r
+ {\r
+ IDictionary props = (IDictionary) ((ICloneable)_soapCore.Properties).Clone ();\r
+ props ["typeFilterLevel"] = value;\r
+ _soapCore = new SoapCore (this, props, SoapServerFormatterSinkProvider.AllowedProperties);\r
+ }\r
+ }\r
+\r
public void AsyncProcessResponse (IServerResponseChannelSinkStack sinkStack, object state,\r
IMessage msg, ITransportHeaders headers, Stream stream)\r
\r
\r
SoapMessage soapMessage = (SoapMessage) soapMsgFormatter.BuildSoapMessageFromMethodResponse((IMethodReturnMessage)msg, out responseHeaders);\r
\r
- _serializationFormatter.Serialize(stream, soapMessage, null);\r
+ _soapCore.Serializer.Serialize(stream, soapMessage, null);\r
\r
if(stream is MemoryStream) stream.Position = 0;\r
+ sinkStack.AsyncProcessResponse (msg, responseHeaders, stream);\r
}\r
\r
public Stream GetResponseStream (IServerResponseChannelSinkStack sinkStack, object state,\r
IMessage requestMsg, ITransportHeaders requestHeaders, Stream requestStream,\r
out IMessage responseMsg, out ITransportHeaders responseHeaders, out Stream responseStream)\r
{\r
+ // Check whether the request was already processed by another\r
+ // formatter sink and pass the request to the next sink if so.\r
+ if (requestMsg != null)\r
+ return next_sink.ProcessMessage (sinkStack,\r
+ requestMsg,\r
+ requestHeaders,\r
+ requestStream,\r
+ out responseMsg,\r
+ out responseHeaders,\r
+ out responseStream);\r
+\r
+ // Check whether the request is suitable for this formatter\r
+ // and pass the request to the next sink if not.\r
+ // Note that a null content-type is handled as suitable,\r
+ // otherwise no other sink will be able to handle the request.\r
+ string contentType = requestHeaders["Content-Type"] as string;\r
+ if (contentType == null || !contentType.StartsWith ("text/xml") || requestHeaders["SOAPAction"] == null) {\r
+ return next_sink.ProcessMessage (sinkStack,\r
+ requestMsg,\r
+ requestHeaders,\r
+ requestStream,\r
+ out responseMsg,\r
+ out responseHeaders,\r
+ out responseStream);\r
+ }\r
+\r
responseMsg = null;\r
responseHeaders = null;\r
responseStream = null;\r
\r
- Exception exception;\r
ServerProcessing sp;\r
SoapMessageFormatter soapMsgFormatter = new SoapMessageFormatter();\r
sinkStack.Push(this, soapMsgFormatter);\r
Type serverType = RemotingServices.GetServerTypeForUri(uri);\r
if (serverType == null) throw new RemotingException ("No receiver for uri " + uri);\r
\r
- SoapMessage soapMessage = new SoapMessage();\r
- _deserializationFormatter.TopObject = soapMessage;\r
- requestStream.Position = 0;\r
- _deserializationFormatter.Deserialize(requestStream);\r
+ SoapFormatter fm = _soapCore.GetSafeDeserializer ();\r
+ SoapMessage soapMessage = soapMsgFormatter.CreateSoapMessage (true);\r
+ fm.TopObject = soapMessage;\r
+ fm.Deserialize(requestStream);\r
\r
requestMsg = soapMsgFormatter.BuildMethodCallFromSoapMessage(soapMessage, uri);\r
\r
\r
object rtnMessageObject = soapMsgFormatter.BuildSoapMessageFromMethodResponse((IMethodReturnMessage) responseMsg, out responseHeaders);\r
responseStream = new MemoryStream();\r
- _serializationFormatter.Serialize(responseStream, rtnMessageObject);\r
+ _soapCore.Serializer.Serialize(responseStream, rtnMessageObject);\r
+ responseStream.Position = 0;\r
}\r
}\r
}\r
responseMsg = (IMethodReturnMessage)new ReturnMessage(e, (IMethodCallMessage)requestMsg);\r
object rtnMessageObject = soapMsgFormatter.BuildSoapMessageFromMethodResponse((IMethodReturnMessage) responseMsg, out responseHeaders);\r
responseStream = new MemoryStream();\r
- _serializationFormatter.Serialize(responseStream, rtnMessageObject);\r
+ _soapCore.Serializer.Serialize(responseStream, rtnMessageObject);\r
+ responseStream.Position = 0;\r
sp = ServerProcessing.Complete;\r
}\r
\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