source: xmlrpcnet/trunk/fuentes/src/XmlRpcClientFormatterSink.cs @ 379

Last change on this file since 379 was 379, checked in by hectorgh, 5 years ago

adding project files

File size: 5.7 KB
Line 
1/*
2XML-RPC.NET library
3Copyright (c) 2001-2006, Charles Cook <charlescook@cookcomputing.com>
4
5Permission is hereby granted, free of charge, to any person
6obtaining a copy of this software and associated documentation
7files (the "Software"), to deal in the Software without restriction,
8including without limitation the rights to use, copy, modify, merge,
9publish, distribute, sublicense, and/or sell copies of the Software,
10and to permit persons to whom the Software is furnished to do so,
11subject to the following conditions:
12
13The above copyright notice and this permission notice shall be
14included in all copies or substantial portions of the Software.
15
16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23DEALINGS IN THE SOFTWARE.
24*/
25
26using System;
27using System.Collections;
28using System.IO;
29using System.Reflection;
30using System.Runtime.Remoting.Channels;
31using System.Runtime.Remoting.Messaging;
32
33using CookComputing.XmlRpc;
34
35namespace CookComputing.XmlRpc
36{
37  public class XmlRpcClientFormatterSink : IClientChannelSink, IMessageSink
38  {
39    // constructors
40    //
41    public XmlRpcClientFormatterSink(
42      IClientChannelSink NextSink)
43    {
44      m_next = NextSink;
45    }
46
47    // properties
48    //
49    public IClientChannelSink NextChannelSink
50    {
51      get { return m_next; }
52    }
53
54    public IMessageSink NextSink
55    {
56      get {  throw new NotSupportedException(); }
57    }
58 
59    public IDictionary Properties
60    {
61      get {  return null; }
62    }
63
64    //  public methods
65    //
66    public IMessageCtrl AsyncProcessMessage(
67      IMessage msg,
68      IMessageSink replySink)
69    {
70      throw new NotSupportedException();
71    }
72
73    public void AsyncProcessRequest(
74      IClientChannelSinkStack sinkStack,
75      IMessage msg,
76      ITransportHeaders headers,
77      Stream stream)
78    {
79      throw new Exception("not implemented");
80    }
81
82    public void AsyncProcessResponse(
83      IClientResponseChannelSinkStack sinkStack,
84      object state,
85      ITransportHeaders headers,
86      Stream stream)
87    {
88      throw new Exception("not implemented");
89    }
90 
91    public Stream GetRequestStream(
92      IMessage msg,
93      ITransportHeaders headers)
94    {
95      return null; // TODO: ???
96    }
97 
98    public void ProcessMessage(
99      IMessage msg,
100      ITransportHeaders requestHeaders,
101      Stream requestStream,
102      out ITransportHeaders responseHeaders,
103      out Stream responseStream)
104    {
105      responseHeaders = null;
106      responseStream = null;
107    }
108 
109    public IMessage SyncProcessMessage(
110      IMessage msg
111      )
112    {
113      IMethodCallMessage mcm = msg as IMethodCallMessage;
114      try
115      {
116        Stream reqStm = null;
117        ITransportHeaders reqHeaders = null;
118        SerializeMessage(mcm, ref reqHeaders, ref reqStm);
119       
120        Stream respStm = null;
121        ITransportHeaders respHeaders = null;
122        m_next.ProcessMessage(msg, reqHeaders, reqStm, 
123          out respHeaders, out respStm);
124
125        IMessage imsg = DeserializeMessage(mcm, respHeaders, respStm);
126        return imsg;
127      }
128      catch(Exception ex)
129      {
130        return new ReturnMessage(ex, mcm);
131      }
132    }
133
134    //  private methods
135    //
136    void SerializeMessage(
137      IMethodCallMessage mcm, 
138      ref ITransportHeaders headers, 
139      ref Stream stream)
140    {
141      ITransportHeaders reqHeaders = new TransportHeaders();
142      reqHeaders["__Uri"] = mcm.Uri;
143      reqHeaders["Content-Type"] = "text/xml; charset=\"utf-8\"";
144      reqHeaders["__RequestVerb"] = "POST";
145
146      MethodInfo mi = (MethodInfo) mcm.MethodBase;
147      string methodName = GetRpcMethodName(mi);
148      XmlRpcRequest xmlRpcReq = new XmlRpcRequest(methodName, mcm.InArgs);
149      // TODO: possibly call GetRequestStream from next sink in chain?
150      // TODO: SoapClientFormatter sink uses ChunkedStream - check why?
151      Stream stm = new MemoryStream();
152      XmlRpcSerializer serializer = new XmlRpcSerializer();
153      serializer.SerializeRequest(stm, xmlRpcReq);
154      stm.Position = 0;
155
156      headers = reqHeaders;
157      stream = stm;
158    }
159
160    IMessage DeserializeMessage(
161      IMethodCallMessage mcm,
162      ITransportHeaders headers,
163      Stream stream)
164    {
165      XmlRpcSerializer serializer = new XmlRpcSerializer();
166      object tp = mcm.MethodBase;           
167      System.Reflection.MethodInfo mi = (System.Reflection.MethodInfo)tp;
168      System.Type t = mi.ReturnType;
169      XmlRpcResponse xmlRpcResp = serializer.DeserializeResponse(stream, t);
170      IMessage imsg = new ReturnMessage(xmlRpcResp.retVal, null, 0, null, mcm);
171      return imsg;
172    } 
173
174    string GetRpcMethodName(MethodInfo mi)
175    {
176      Attribute attr = Attribute.GetCustomAttribute(mi, 
177        typeof(XmlRpcMethodAttribute));
178      // TODO: do methods need attribute?
179      //      if (attr == null)
180      //      {
181      //        throw new Exception("missing method attribute");
182      //      }
183      string rpcMethod = "";
184      if (attr != null)
185      {
186        XmlRpcMethodAttribute xrmAttr = attr as XmlRpcMethodAttribute;
187        rpcMethod = xrmAttr.Method;
188      }
189      if (rpcMethod == "")
190        rpcMethod = mi.Name;
191      return rpcMethod;
192    }
193
194    // data
195    //
196    IClientChannelSink m_next;
197  }
198}
Note: See TracBrowser for help on using the repository browser.