2 // System.Runtime.Remoting.Channels.SoapServerFormatterSink.cs
4 // Authors: Duncan Mak (duncan@ximian.com)
5 // Jean-Marc Andre (jean-marc.andre@polymtl.ca)
7 // 2002 (C) Copyright, Ximian, Inc.
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 using System
.Collections
;
33 using System
.Reflection
;
34 using System
.Runtime
.Remoting
.Messaging
;
35 using System
.Runtime
.Serialization
;
36 using System
.Runtime
.Serialization
.Formatters
;
37 using System
.Runtime
.Serialization
.Formatters
.Soap
;
38 using System
.Runtime
.InteropServices
;
41 namespace System
.Runtime
.Remoting
.Channels
{
44 // The formatter sink that uses SoapFormatter
47 // The formatter sink deserializes the message from the channel sink
48 // and passes the result to the remoting infrastructure
51 public class SoapServerFormatterSink
: IServerChannelSink
, IChannelSinkBase
53 IServerChannelSink next_sink
;
54 IChannelReceiver _receiver
;
55 private SoapCore _soapCore
= SoapCore
.DefaultInstance
;
57 public SoapServerFormatterSink (SoapServerFormatterSink
.Protocol protocol
,
58 IServerChannelSink nextSink
,
59 IChannelReceiver receiver
)
61 this.next_sink
= nextSink
;
65 internal SoapCore SoapCore
67 get { return _soapCore; }
68 set { _soapCore = value; }
72 // Gets the next channel sink in the channel sink chain
75 // The next channel sink in the sink chain
77 public IServerChannelSink NextChannelSink
{
83 public IDictionary Properties
{
91 public TypeFilterLevel TypeFilterLevel
93 get { return _soapCore.TypeFilterLevel; }
96 IDictionary props
= (IDictionary
) ((ICloneable
)_soapCore
.Properties
).Clone ();
97 props
["typeFilterLevel"] = value;
98 _soapCore
= new SoapCore (this, props
, SoapServerFormatterSinkProvider
.AllowedProperties
);
103 public void AsyncProcessResponse (IServerResponseChannelSinkStack sinkStack
, object state
,
104 IMessage msg
, ITransportHeaders headers
, Stream stream
)
107 ITransportHeaders responseHeaders
= new TransportHeaders();
109 if(sinkStack
!= null) stream
= sinkStack
.GetResponseStream(msg
, responseHeaders
);
110 if(stream
== null) stream
= new MemoryStream();
112 SoapMessageFormatter soapMsgFormatter
= (SoapMessageFormatter
)state
;
114 SoapMessage soapMessage
= (SoapMessage
) soapMsgFormatter
.BuildSoapMessageFromMethodResponse((IMethodReturnMessage
)msg
, out responseHeaders
);
116 _soapCore
.Serializer
.Serialize(stream
, soapMessage
, null);
118 if(stream
is MemoryStream
) stream
.Position
= 0;
119 sinkStack
.AsyncProcessResponse (msg
, responseHeaders
, stream
);
122 public Stream
GetResponseStream (IServerResponseChannelSinkStack sinkStack
, object state
,
123 IMessage msg
, ITransportHeaders headers
)
125 // this method shouldn't be called
126 throw new NotSupportedException ();
129 public ServerProcessing
ProcessMessage (IServerChannelSinkStack sinkStack
,
130 IMessage requestMsg
, ITransportHeaders requestHeaders
, Stream requestStream
,
131 out IMessage responseMsg
, out ITransportHeaders responseHeaders
, out Stream responseStream
)
134 responseHeaders
= null;
135 responseStream
= null;
139 SoapMessageFormatter soapMsgFormatter
= new SoapMessageFormatter();
140 sinkStack
.Push(this, soapMsgFormatter
);
143 string url
= (string)requestHeaders
[CommonTransportKeys
.RequestUri
];
145 _receiver
.Parse(url
, out uri
);
146 if(uri
== null) uri
= url
;
147 Type serverType
= RemotingServices
.GetServerTypeForUri(uri
);
148 if (serverType
== null) throw new RemotingException ("No receiver for uri " + uri
);
150 SoapFormatter fm
= _soapCore
.GetSafeDeserializer ();
151 SoapMessage soapMessage
= soapMsgFormatter
.CreateSoapMessage (true);
152 fm
.TopObject
= soapMessage
;
153 requestStream
.Position
= 0;
154 fm
.Deserialize(requestStream
);
156 requestMsg
= soapMsgFormatter
.BuildMethodCallFromSoapMessage(soapMessage
, uri
);
158 sp
= next_sink
.ProcessMessage(sinkStack
, requestMsg
, requestHeaders
, null, out responseMsg
, out responseHeaders
, out responseStream
);
160 if(sp
== ServerProcessing
.Complete
) {
161 if(responseMsg
!= null && responseStream
== null) {
163 object rtnMessageObject
= soapMsgFormatter
.BuildSoapMessageFromMethodResponse((IMethodReturnMessage
) responseMsg
, out responseHeaders
);
164 responseStream
= new MemoryStream();
165 _soapCore
.Serializer
.Serialize(responseStream
, rtnMessageObject
);
171 responseMsg
= (IMethodReturnMessage
)new ReturnMessage(e
, (IMethodCallMessage
)requestMsg
);
172 object rtnMessageObject
= soapMsgFormatter
.BuildSoapMessageFromMethodResponse((IMethodReturnMessage
) responseMsg
, out responseHeaders
);
173 responseStream
= new MemoryStream();
174 _soapCore
.Serializer
.Serialize(responseStream
, rtnMessageObject
);
175 sp
= ServerProcessing
.Complete
;
178 if (sp
== ServerProcessing
.Complete
)