| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 |
- //
- // System.Runtime.Remoting.Channels.SoapServerFormatterSink.cs
- //
- // Authors: Duncan Mak ([email protected])
- // Jean-Marc Andre ([email protected])
- //
- // 2002 (C) Copyright, Ximian, Inc.
- //
- //
- // Permission is hereby granted, free of charge, to any person obtaining
- // a copy of this software and associated documentation files (the
- // "Software"), to deal in the Software without restriction, including
- // without limitation the rights to use, copy, modify, merge, publish,
- // distribute, sublicense, and/or sell copies of the Software, and to
- // permit persons to whom the Software is furnished to do so, subject to
- // the following conditions:
- //
- // The above copyright notice and this permission notice shall be
- // included in all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- //
- using System.Collections;
- using System.IO;
- using System.Reflection;
- using System.Runtime.Remoting.Messaging;
- using System.Runtime.Serialization;
- using System.Runtime.Serialization.Formatters;
- using System.Runtime.Serialization.Formatters.Soap;
- using System.Runtime.InteropServices;
- namespace System.Runtime.Remoting.Channels {
- /// <summary>
- // The formatter sink that uses SoapFormatter
- /// </summary>
- // <remarks>
- // The formatter sink deserializes the message from the channel sink
- // and passes the result to the remoting infrastructure
- // </remark>
- //
- public class SoapServerFormatterSink : IServerChannelSink, IChannelSinkBase
- {
- IServerChannelSink next_sink;
- IChannelReceiver _receiver;
- private SoapCore _soapCore = SoapCore.DefaultInstance;
-
- public SoapServerFormatterSink (SoapServerFormatterSink.Protocol protocol,
- IServerChannelSink nextSink,
- IChannelReceiver receiver)
- {
- this.next_sink = nextSink;
- _receiver = receiver;
- }
- internal SoapCore SoapCore
- {
- get { return _soapCore; }
- set { _soapCore = value; }
- }
-
- /// <summary>
- // Gets the next channel sink in the channel sink chain
- // </summary>
- /// <value>
- // The next channel sink in the sink chain
- // </value>
- public IServerChannelSink NextChannelSink {
- get {
- return next_sink;
- }
- }
- public IDictionary Properties {
- get {
- return null;
- }
- }
- #if NET_1_1
- [ComVisible(false)]
- public TypeFilterLevel TypeFilterLevel
- {
- get { return _soapCore.TypeFilterLevel; }
- set
- {
- IDictionary props = (IDictionary) ((ICloneable)_soapCore.Properties).Clone ();
- props ["typeFilterLevel"] = value;
- _soapCore = new SoapCore (this, props, SoapServerFormatterSinkProvider.AllowedProperties);
- }
- }
- #endif
- public void AsyncProcessResponse (IServerResponseChannelSinkStack sinkStack, object state,
- IMessage msg, ITransportHeaders headers, Stream stream)
-
- {
- ITransportHeaders responseHeaders = new TransportHeaders();
- if(sinkStack != null) stream = sinkStack.GetResponseStream(msg, responseHeaders);
- if(stream == null) stream = new MemoryStream();
- SoapMessageFormatter soapMsgFormatter = (SoapMessageFormatter)state;
- SoapMessage soapMessage = (SoapMessage) soapMsgFormatter.BuildSoapMessageFromMethodResponse((IMethodReturnMessage)msg, out responseHeaders);
- _soapCore.Serializer.Serialize(stream, soapMessage, null);
- if(stream is MemoryStream) stream.Position = 0;
- sinkStack.AsyncProcessResponse (msg, responseHeaders, stream);
- }
- public Stream GetResponseStream (IServerResponseChannelSinkStack sinkStack, object state,
- IMessage msg, ITransportHeaders headers)
- {
- // this method shouldn't be called
- throw new NotSupportedException ();
- }
-
- public ServerProcessing ProcessMessage (IServerChannelSinkStack sinkStack,
- IMessage requestMsg, ITransportHeaders requestHeaders, Stream requestStream,
- out IMessage responseMsg, out ITransportHeaders responseHeaders, out Stream responseStream)
- {
- responseMsg = null;
- responseHeaders = null;
- responseStream = null;
- ServerProcessing sp;
- SoapMessageFormatter soapMsgFormatter = new SoapMessageFormatter();
- sinkStack.Push(this, soapMsgFormatter);
- try {
- string url = (string)requestHeaders[CommonTransportKeys.RequestUri];
- string uri;
- _receiver.Parse(url, out uri);
- if(uri == null) uri = url;
- Type serverType = RemotingServices.GetServerTypeForUri(uri);
- if (serverType == null) throw new RemotingException ("No receiver for uri " + uri);
-
- SoapFormatter fm = _soapCore.GetSafeDeserializer ();
- SoapMessage soapMessage = soapMsgFormatter.CreateSoapMessage (true);
- fm.TopObject = soapMessage;
- requestStream.Position = 0;
- fm.Deserialize(requestStream);
- requestMsg = soapMsgFormatter.BuildMethodCallFromSoapMessage(soapMessage, uri);
-
- sp = next_sink.ProcessMessage(sinkStack, requestMsg, requestHeaders, null, out responseMsg, out responseHeaders, out responseStream);
-
- if(sp == ServerProcessing.Complete) {
- if(responseMsg != null && responseStream == null) {
- object rtnMessageObject = soapMsgFormatter.BuildSoapMessageFromMethodResponse((IMethodReturnMessage) responseMsg, out responseHeaders);
- responseStream = new MemoryStream();
- _soapCore.Serializer.Serialize(responseStream, rtnMessageObject);
- }
- }
- }
- catch(Exception e)
- {
- responseMsg = (IMethodReturnMessage)new ReturnMessage(e, (IMethodCallMessage)requestMsg);
- object rtnMessageObject = soapMsgFormatter.BuildSoapMessageFromMethodResponse((IMethodReturnMessage) responseMsg, out responseHeaders);
- responseStream = new MemoryStream();
- _soapCore.Serializer.Serialize(responseStream, rtnMessageObject);
- sp = ServerProcessing.Complete;
- }
- if (sp == ServerProcessing.Complete)
- sinkStack.Pop(this);
- return sp;
-
- }
- [Serializable]
- public enum Protocol
- {
- Http = 0,
- Other = 1,
- }
- }
- }
|