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

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

adding project files

File size: 30.5 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.ComponentModel;
28using System.Collections;
29using System.Diagnostics;
30using System.IO;
31using System.Net;
32using System.Reflection;
33using System.Security.Cryptography.X509Certificates;
34using System.Text;
35
36namespace CookComputing.XmlRpc
37{
38  public class XmlRpcClientProtocol : Component, IXmlRpcProxy
39  {
40    #region Instance Variables
41    private bool _allowAutoRedirect = true;
42#if (!COMPACT_FRAMEWORK)
43    private string _connectionGroupName = null;
44#endif
45#if (!COMPACT_FRAMEWORK && !FX1_0)
46    private bool _expect100Continue = false;
47    private bool _enableCompression = false;
48#endif
49    private ICredentials _credentials = null;
50    private WebHeaderCollection _headers = new WebHeaderCollection();
51    private int _indentation = 2;
52    private bool _keepAlive = true;
53    private XmlRpcNonStandard _nonStandard = XmlRpcNonStandard.None;
54    private bool _preAuthenticate = false;
55    private Version _protocolVersion = HttpVersion.Version11;
56    private IWebProxy _proxy = null;
57#if (!COMPACT_FRAMEWORK)
58    private CookieCollection _responseCookies;
59    private WebHeaderCollection _responseHeaders;
60#endif
61    private int _timeout = 3600000;
62    private string _url = null;
63    private string _userAgent = "XML-RPC.NET";
64    private bool _useEmptyParamsTag = true;
65    private bool _useIndentation = true;
66    private bool _useIntTag = false;
67    private bool _useStringTag = true;
68    private Encoding _xmlEncoding = null;
69    private string _xmlRpcMethod = null;
70
71#if (!COMPACT_FRAMEWORK)
72    private X509CertificateCollection _clientCertificates
73      = new X509CertificateCollection();
74    private CookieContainer _cookies = new CookieContainer();
75#endif
76    #endregion
77    private Guid _id = Util.NewGuid();
78
79
80#if (!COMPACT_FRAMEWORK)
81    public XmlRpcClientProtocol(System.ComponentModel.IContainer container)
82    {
83      container.Add(this);
84      InitializeComponent();
85    }
86#endif
87    public XmlRpcClientProtocol()
88    {
89      InitializeComponent();
90    }
91
92    public object Invoke(
93      MethodBase mb,
94      params object[] Parameters)
95    {
96      return Invoke(this, mb as MethodInfo, Parameters);
97    }
98
99    public object Invoke(
100      MethodInfo mi,
101      params object[] Parameters)
102    {
103      return Invoke(this, mi, Parameters);
104    }
105
106    public object Invoke(
107      string MethodName,
108      params object[] Parameters)
109    {
110      return Invoke(this, MethodName, Parameters);
111    }
112
113    public object Invoke(
114      Object clientObj,
115      string methodName,
116      params object[] parameters)
117    {
118      MethodInfo mi = GetMethodInfoFromName(clientObj, methodName, parameters);
119      return Invoke(this, mi, parameters);
120    }
121
122    public object Invoke(
123      Object clientObj,
124      MethodInfo mi,
125      params object[] parameters)
126    {
127#if (!COMPACT_FRAMEWORK)
128      _responseHeaders = null;
129      _responseCookies = null;
130#endif
131      WebRequest webReq = null;
132      object reto = null;
133      try
134      {
135        string useUrl = GetEffectiveUrl(clientObj);
136        webReq = GetWebRequest(new Uri(useUrl));
137        XmlRpcRequest req = MakeXmlRpcRequest(webReq, mi, parameters,
138          clientObj, _xmlRpcMethod, _id);
139        SetProperties(webReq);
140        SetRequestHeaders(_headers, webReq);
141#if (!COMPACT_FRAMEWORK)
142        SetClientCertificates(_clientCertificates, webReq);
143#endif
144        Stream serStream = null;
145        Stream reqStream = null;
146        bool logging = (RequestEvent != null);
147        if (!logging)
148          serStream = reqStream = webReq.GetRequestStream();
149        else
150          serStream = new MemoryStream(2000);
151        try
152        {
153          XmlRpcSerializer serializer = new XmlRpcSerializer();
154          if (_xmlEncoding != null)
155            serializer.XmlEncoding = _xmlEncoding;
156          serializer.UseIndentation = _useIndentation;
157          serializer.Indentation = _indentation;
158          serializer.NonStandard = _nonStandard;
159          serializer.UseStringTag = _useStringTag;
160          serializer.UseIntTag = _useIntTag;
161          serializer.UseEmptyParamsTag = _useEmptyParamsTag;
162          serializer.SerializeRequest(serStream, req);
163          if (logging)
164          {
165            reqStream = webReq.GetRequestStream();
166            serStream.Position = 0;
167            Util.CopyStream(serStream, reqStream);
168            reqStream.Flush();
169            serStream.Position = 0;
170            OnRequest(new XmlRpcRequestEventArgs(req.proxyId, req.number,
171              serStream));
172          }
173        }
174        finally
175        {
176          if (reqStream != null)
177            reqStream.Close();
178        }
179        HttpWebResponse webResp = GetWebResponse(webReq) as HttpWebResponse;
180#if (!COMPACT_FRAMEWORK)
181        _responseCookies = webResp.Cookies;
182        _responseHeaders = webResp.Headers;
183#endif
184        Stream respStm = null;
185        Stream deserStream;
186        logging = (ResponseEvent != null);
187        try
188        {
189          respStm = webResp.GetResponseStream();
190          if (!logging)
191          {
192            deserStream = respStm;
193          }
194          else
195          {
196            deserStream = new MemoryStream(2000);
197            Util.CopyStream(respStm, deserStream);
198            deserStream.Flush();
199            deserStream.Position = 0;
200          }
201#if (!COMPACT_FRAMEWORK && !FX1_0)
202          deserStream = MaybeDecompressStream((HttpWebResponse)webResp, 
203            deserStream);         
204#endif
205          try
206          {
207            XmlRpcResponse resp = ReadResponse(req, webResp, deserStream, null);
208            reto = resp.retVal;
209          }
210          finally
211          {
212            if (logging)
213            {
214              deserStream.Position = 0;
215              OnResponse(new XmlRpcResponseEventArgs(req.proxyId, req.number,
216                deserStream));
217            }
218          }
219        }
220        finally
221        {
222          if (respStm != null)
223            respStm.Close();
224        }
225      }
226      finally
227      {
228        if (webReq != null)
229          webReq = null;
230      }
231      return reto;
232    }
233
234    #region Properties
235
236    public bool AllowAutoRedirect
237    {
238      get { return _allowAutoRedirect; }
239      set { _allowAutoRedirect = value; }
240    }
241
242#if (!COMPACT_FRAMEWORK)
243    [Browsable(false)]
244    public X509CertificateCollection ClientCertificates
245    {
246      get { return _clientCertificates; }
247    }
248#endif
249
250#if (!COMPACT_FRAMEWORK)
251    public string ConnectionGroupName
252    {
253      get { return _connectionGroupName; }
254      set { _connectionGroupName = value; }
255    }
256#endif
257
258    [Browsable(false)]
259    public ICredentials Credentials
260    {
261      get { return _credentials; }
262      set { _credentials = value; }
263    }
264
265#if (!COMPACT_FRAMEWORK && !FX1_0)
266    public bool EnableCompression
267    {
268      get { return _enableCompression; }
269      set { _enableCompression = value; }
270    }
271#endif
272
273    [Browsable(false)]
274    public WebHeaderCollection Headers
275    {
276      get { return _headers; }
277    }
278
279#if (!COMPACT_FRAMEWORK && !FX1_0)
280    public bool Expect100Continue
281    {
282      get { return _expect100Continue; }
283      set { _expect100Continue = value; }
284    }
285#endif
286
287#if (!COMPACT_FRAMEWORK)
288    public CookieContainer CookieContainer
289    {
290      get { return _cookies; }
291    }
292#endif
293
294    public Guid Id
295    {
296      get { return _id; }
297    }
298
299    public int Indentation
300    {
301      get { return _indentation; }
302      set { _indentation = value; }
303    }
304
305    public bool KeepAlive
306    {
307      get { return _keepAlive; }
308      set { _keepAlive = value; }
309    }
310
311    public XmlRpcNonStandard NonStandard
312    {
313      get { return _nonStandard; }
314      set { _nonStandard = value; }
315    }
316
317    public bool PreAuthenticate
318    {
319      get { return _preAuthenticate; }
320      set { _preAuthenticate = value; }
321    }
322
323    [Browsable(false)]
324    public System.Version ProtocolVersion
325    {
326      get { return _protocolVersion; }
327      set { _protocolVersion = value; }
328    }
329
330    [Browsable(false)]
331    public IWebProxy Proxy
332    {
333      get { return _proxy; }
334      set { _proxy = value; }
335    }
336
337#if (!COMPACT_FRAMEWORK)
338    public CookieCollection ResponseCookies
339    {
340      get { return _responseCookies; }
341    }
342#endif
343
344#if (!COMPACT_FRAMEWORK)
345    public WebHeaderCollection ResponseHeaders
346    {
347      get { return _responseHeaders; }
348    }
349#endif
350
351    public int Timeout
352    {
353      get { return _timeout; }
354      set { _timeout = value; }
355    }
356
357    public string Url
358    {
359      get { return _url; }
360      set { _url = value; }
361    }
362
363    public bool UseEmptyParamsTag
364    {
365      get { return _useEmptyParamsTag; }
366      set { _useEmptyParamsTag = value; }
367    }
368
369    public bool UseIndentation
370    {
371      get { return _useIndentation; }
372      set { _useIndentation = value; }
373    }
374
375    public bool UseIntTag
376    {
377      get { return _useIntTag; }
378      set { _useIntTag = value; }
379    }
380
381    public string UserAgent
382    {
383      get { return _userAgent; }
384      set { _userAgent = value; }
385    }
386
387    public bool UseStringTag
388    {
389      get { return _useStringTag; }
390      set { _useStringTag = value; }
391    }
392
393    [Browsable(false)]
394    public Encoding XmlEncoding
395    {
396      get { return _xmlEncoding; }
397      set { _xmlEncoding = value; }
398    }
399
400    public string XmlRpcMethod
401    {
402      get { return _xmlRpcMethod; }
403      set { _xmlRpcMethod = value; }
404    }
405
406    #endregion
407
408    public void SetProperties(WebRequest webReq)
409    {
410      if (_proxy != null)
411        webReq.Proxy = _proxy;
412      HttpWebRequest httpReq = (HttpWebRequest)webReq;
413      httpReq.UserAgent = _userAgent;
414      httpReq.ProtocolVersion = _protocolVersion;
415      httpReq.KeepAlive = _keepAlive;
416#if (!COMPACT_FRAMEWORK)
417      httpReq.CookieContainer = _cookies;
418#endif
419#if (!COMPACT_FRAMEWORK && !FX1_0)
420      httpReq.ServicePoint.Expect100Continue = _expect100Continue;
421#endif
422      httpReq.AllowAutoRedirect = _allowAutoRedirect;
423      webReq.Timeout = Timeout;
424#if (!COMPACT_FRAMEWORK)
425      webReq.ConnectionGroupName = this._connectionGroupName;
426#endif
427      webReq.Credentials = Credentials;
428      webReq.PreAuthenticate = PreAuthenticate;
429      // Compact Framework sets this to false by default
430      (webReq as HttpWebRequest).AllowWriteStreamBuffering = true;
431#if (!COMPACT_FRAMEWORK && !FX1_0)
432      if (_enableCompression)
433        webReq.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip,deflate");
434#endif
435    }
436
437    private void SetRequestHeaders(
438      WebHeaderCollection headers,
439      WebRequest webReq)
440    {
441      foreach (string key in headers)
442      {
443        webReq.Headers.Add(key, headers[key]);
444      }
445    }
446#if (!COMPACT_FRAMEWORK)
447    private void SetClientCertificates(
448      X509CertificateCollection certificates,
449      WebRequest webReq)
450    {
451      foreach (X509Certificate certificate in certificates)
452      {
453        HttpWebRequest httpReq = (HttpWebRequest)webReq;
454        httpReq.ClientCertificates.Add(certificate);
455      }
456    }
457#endif
458    XmlRpcRequest MakeXmlRpcRequest(WebRequest webReq, MethodInfo mi,
459      object[] parameters, object clientObj, string xmlRpcMethod,
460      Guid proxyId)
461    {
462      webReq.Method = "POST";
463      webReq.ContentType = "text/xml";
464      string rpcMethodName = GetRpcMethodName(clientObj, mi);
465      XmlRpcRequest req = new XmlRpcRequest(rpcMethodName, parameters, mi,
466        xmlRpcMethod, proxyId);
467      return req;
468    }
469
470    XmlRpcResponse ReadResponse(
471      XmlRpcRequest req,
472      WebResponse webResp,
473      Stream respStm,
474      Type returnType)
475    {
476      HttpWebResponse httpResp = (HttpWebResponse)webResp;
477      if (httpResp.StatusCode != HttpStatusCode.OK)
478      {
479        // status 400 is used for errors caused by the client
480        // status 500 is used for server errors (not server application
481        // errors which are returned as fault responses)
482        if (httpResp.StatusCode == HttpStatusCode.BadRequest)
483          throw new XmlRpcException(httpResp.StatusDescription);
484        else
485          throw new XmlRpcServerException(httpResp.StatusDescription);
486      }
487      XmlRpcSerializer serializer = new XmlRpcSerializer();
488      serializer.NonStandard = _nonStandard;
489      Type retType = returnType;
490      if (retType == null)
491        retType = req.mi.ReturnType;
492      XmlRpcResponse xmlRpcResp
493        = serializer.DeserializeResponse(respStm, retType);
494      return xmlRpcResp;
495    }
496
497    MethodInfo GetMethodInfoFromName(object clientObj, string methodName, 
498      object[] parameters)
499    {
500      Type[] paramTypes = new Type[0];
501      if (parameters != null)
502      {
503        paramTypes = new Type[parameters.Length];
504        for (int i = 0; i < paramTypes.Length; i++)
505        {
506          if (parameters[i] == null)
507            throw new XmlRpcNullParameterException("Null parameters are invalid");
508          paramTypes[i] = parameters[i].GetType();
509        }
510      }
511      Type type = clientObj.GetType();
512      MethodInfo mi = type.GetMethod(methodName, paramTypes);
513      if (mi == null)
514      {
515        try
516        {
517          mi = type.GetMethod(methodName);
518        }
519        catch (System.Reflection.AmbiguousMatchException)
520        {
521          throw new XmlRpcInvalidParametersException("Method parameters match "
522            + "the signature of more than one method");
523        }
524        if (mi == null)
525          throw new Exception(
526            "Invoke on non-existent or non-public proxy method");
527        else
528          throw new XmlRpcInvalidParametersException("Method parameters do "
529            + "not match signature of any method called " + methodName);
530      }
531      return mi;
532    }
533
534    string GetRpcMethodName(object clientObj, MethodInfo mi)
535    {
536      string rpcMethod;
537      string MethodName = mi.Name;
538      Attribute attr = Attribute.GetCustomAttribute(mi,
539        typeof(XmlRpcBeginAttribute));
540      if (attr != null)
541      {
542        rpcMethod = ((XmlRpcBeginAttribute)attr).Method;
543        if (rpcMethod == "")
544        {
545          if (!MethodName.StartsWith("Begin") || MethodName.Length <= 5)
546            throw new Exception(String.Format(
547              "method {0} has invalid signature for begin method",
548              MethodName));
549          rpcMethod = MethodName.Substring(5);
550        }
551        return rpcMethod;
552      }
553      // if no XmlRpcBegin attribute, must have XmlRpcMethod attribute   
554      attr = Attribute.GetCustomAttribute(mi, typeof(XmlRpcMethodAttribute));
555      if (attr == null)
556      {
557        throw new Exception("missing method attribute");
558      }
559      XmlRpcMethodAttribute xrmAttr = attr as XmlRpcMethodAttribute;
560      rpcMethod = xrmAttr.Method;
561      if (rpcMethod == "")
562      {
563        rpcMethod = mi.Name;
564      }
565      return rpcMethod;
566    }
567
568    public IAsyncResult BeginInvoke(
569      MethodBase mb,
570      object[] parameters,
571      AsyncCallback callback,
572      object outerAsyncState)
573    {
574      return BeginInvoke(mb as MethodInfo, parameters, this, callback,
575        outerAsyncState);
576    }
577
578    public IAsyncResult BeginInvoke(
579      MethodInfo mi,
580      object[] parameters,
581      AsyncCallback callback,
582      object outerAsyncState)
583    {
584      return BeginInvoke(mi, parameters, this, callback,
585        outerAsyncState);
586    }
587
588    public IAsyncResult BeginInvoke(
589      string methodName,
590      object[] parameters,
591      object clientObj,
592      AsyncCallback callback,
593      object outerAsyncState)
594    {
595      MethodInfo mi = GetMethodInfoFromName(clientObj, methodName, parameters);
596      return BeginInvoke(mi, parameters, this, callback,
597        outerAsyncState);
598    }
599
600    public IAsyncResult BeginInvoke(
601      MethodInfo mi,
602      object[] parameters,
603      object clientObj,
604      AsyncCallback callback,
605      object outerAsyncState)
606    {
607      string useUrl = GetEffectiveUrl(clientObj);
608      WebRequest webReq = GetWebRequest(new Uri(useUrl));
609      XmlRpcRequest xmlRpcReq = MakeXmlRpcRequest(webReq, mi,
610        parameters, clientObj, _xmlRpcMethod, _id);
611      SetProperties(webReq);
612      SetRequestHeaders(_headers, webReq);
613#if (!COMPACT_FRAMEWORK)
614      SetClientCertificates(_clientCertificates, webReq);
615#endif
616      Encoding useEncoding = null;
617      if (_xmlEncoding != null)
618        useEncoding = _xmlEncoding;
619      XmlRpcAsyncResult asr = new XmlRpcAsyncResult(this, xmlRpcReq,
620        useEncoding, _useEmptyParamsTag, _useIndentation, _indentation, 
621        _useIntTag, _useStringTag, webReq, callback, outerAsyncState, 0);
622      webReq.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback),
623        asr);
624      if (!asr.IsCompleted)
625        asr.CompletedSynchronously = false;
626      return asr;
627    }
628
629    static void GetRequestStreamCallback(IAsyncResult asyncResult)
630    {
631      XmlRpcAsyncResult clientResult
632        = (XmlRpcAsyncResult)asyncResult.AsyncState;
633      clientResult.CompletedSynchronously = asyncResult.CompletedSynchronously;
634      try
635      {
636        Stream serStream = null;
637        Stream reqStream = null;
638        bool logging = (clientResult.ClientProtocol.RequestEvent != null);
639        if (!logging)
640        {
641          serStream = reqStream
642            = clientResult.Request.EndGetRequestStream(asyncResult);
643        }
644        else
645          serStream = new MemoryStream(2000);
646        try
647        {
648          XmlRpcRequest req = clientResult.XmlRpcRequest;
649          XmlRpcSerializer serializer = new XmlRpcSerializer();
650          if (clientResult.XmlEncoding != null)
651            serializer.XmlEncoding = clientResult.XmlEncoding;
652          serializer.UseEmptyParamsTag = clientResult.UseEmptyParamsTag;
653          serializer.UseIndentation = clientResult.UseIndentation;
654          serializer.Indentation = clientResult.Indentation;
655          serializer.UseIntTag = clientResult.UseIntTag;
656          serializer.UseStringTag = clientResult.UseStringTag;
657          serializer.SerializeRequest(serStream, req);
658          if (logging)
659          {
660            reqStream = clientResult.Request.EndGetRequestStream(asyncResult);
661            serStream.Position = 0;
662            Util.CopyStream(serStream, reqStream);
663            reqStream.Flush();
664            serStream.Position = 0;
665            clientResult.ClientProtocol.OnRequest(
666              new XmlRpcRequestEventArgs(req.proxyId, req.number, serStream));
667          }
668        }
669        finally
670        {
671          if (reqStream != null)
672            reqStream.Close();
673        }
674        clientResult.Request.BeginGetResponse(
675          new AsyncCallback(GetResponseCallback), clientResult);
676      }
677      catch (Exception ex)
678      {
679        ProcessAsyncException(clientResult, ex);
680      }
681    }
682
683    static void GetResponseCallback(IAsyncResult asyncResult)
684    {
685      XmlRpcAsyncResult result = (XmlRpcAsyncResult)asyncResult.AsyncState;
686      result.CompletedSynchronously = asyncResult.CompletedSynchronously;
687      try
688      {
689        result.Response = result.ClientProtocol.GetWebResponse(result.Request,
690          asyncResult);
691      }
692      catch (Exception ex)
693      {
694        ProcessAsyncException(result, ex);
695        if (result.Response == null)
696          return;
697      }
698      ReadAsyncResponse(result);
699    }
700
701    static void ReadAsyncResponse(XmlRpcAsyncResult result)
702    {
703      if (result.Response.ContentLength == 0)
704      {
705        result.Complete();
706        return;
707      }
708      try
709      {
710        result.ResponseStream = result.Response.GetResponseStream();
711        ReadAsyncResponseStream(result);
712      }
713      catch (Exception ex)
714      {
715        ProcessAsyncException(result, ex);
716      }
717    }
718
719    static void ReadAsyncResponseStream(XmlRpcAsyncResult result)
720    {
721      IAsyncResult asyncResult;
722      do
723      {
724        byte[] buff = result.Buffer;
725        long contLen = result.Response.ContentLength;
726        if (buff == null)
727        {
728          if (contLen == -1)
729            result.Buffer = new Byte[1024];
730          else
731            result.Buffer = new Byte[contLen];
732        }
733        else
734        {
735          if (contLen != -1 && contLen > result.Buffer.Length)
736            result.Buffer = new Byte[contLen];
737        }
738        buff = result.Buffer;
739        asyncResult = result.ResponseStream.BeginRead(buff, 0, buff.Length,
740          new AsyncCallback(ReadResponseCallback), result);
741        if (!asyncResult.CompletedSynchronously)
742          return;
743      }
744      while (!(ProcessAsyncResponseStreamResult(result, asyncResult)));
745    }
746
747    static bool ProcessAsyncResponseStreamResult(XmlRpcAsyncResult result,
748      IAsyncResult asyncResult)
749    {
750      int endReadLen = result.ResponseStream.EndRead(asyncResult);
751      long contLen = result.Response.ContentLength;
752      bool completed;
753      if (endReadLen == 0)
754        completed = true;
755      else if (contLen > 0 && endReadLen == contLen)
756      {
757        result.ResponseBufferedStream = new MemoryStream(result.Buffer);
758        completed = true;
759      }
760      else
761      {
762        if (result.ResponseBufferedStream == null)
763        {
764          result.ResponseBufferedStream = new MemoryStream(result.Buffer.Length);
765        }
766        result.ResponseBufferedStream.Write(result.Buffer, 0, endReadLen);
767        completed = false;
768      }
769      if (completed)
770        result.Complete();
771      return completed;
772    }
773
774
775    static void ReadResponseCallback(IAsyncResult asyncResult)
776    {
777      XmlRpcAsyncResult result = (XmlRpcAsyncResult)asyncResult.AsyncState;
778      result.CompletedSynchronously = asyncResult.CompletedSynchronously;
779      if (asyncResult.CompletedSynchronously)
780        return;
781      try
782      {
783        bool completed = ProcessAsyncResponseStreamResult(result, asyncResult);
784        if (!completed)
785          ReadAsyncResponseStream(result);
786      }
787      catch (Exception ex)
788      {
789        ProcessAsyncException(result, ex);
790      }
791    }
792
793    static void ProcessAsyncException(XmlRpcAsyncResult clientResult,
794      Exception ex)
795    {
796      WebException webex = ex as WebException;
797      if (webex != null && webex.Response != null)
798      {
799        clientResult.Response = webex.Response;
800        return;
801      }
802      if (clientResult.IsCompleted)
803        throw new Exception("error during async processing");
804      clientResult.Complete(ex);
805    }
806
807    public object EndInvoke(
808      IAsyncResult asr)
809    {
810      return EndInvoke(asr, null);
811    }
812
813    public object EndInvoke(
814      IAsyncResult asr,
815      Type returnType)
816    {
817      object reto = null;
818      Stream responseStream = null;
819      try
820      {
821        XmlRpcAsyncResult clientResult = (XmlRpcAsyncResult)asr;
822        if (clientResult.Exception != null)
823          throw clientResult.Exception;
824        if (clientResult.EndSendCalled)
825          throw new Exception("dup call to EndSend");
826        clientResult.EndSendCalled = true;
827        HttpWebResponse webResp = (HttpWebResponse)clientResult.WaitForResponse();
828#if (!COMPACT_FRAMEWORK)
829        clientResult._responseCookies = webResp.Cookies;
830        clientResult._responseHeaders = webResp.Headers;
831#endif
832        responseStream = clientResult.ResponseBufferedStream;
833        if (ResponseEvent != null)
834        {
835          OnResponse(new XmlRpcResponseEventArgs(
836            clientResult.XmlRpcRequest.proxyId,
837            clientResult.XmlRpcRequest.number,
838            responseStream));
839          responseStream.Position = 0;
840        }
841#if (!COMPACT_FRAMEWORK && !FX1_0)
842        responseStream = MaybeDecompressStream((HttpWebResponse)webResp, 
843          responseStream);
844#endif
845        XmlRpcResponse resp = ReadResponse(clientResult.XmlRpcRequest,
846          webResp, responseStream, returnType);
847        reto = resp.retVal;
848      }
849      finally
850      {
851        if (responseStream != null)
852          responseStream.Close();
853      }
854      return reto;
855    }
856
857    string GetEffectiveUrl(object clientObj)
858    {
859      Type type = clientObj.GetType();
860      // client can either have define URI in attribute or have set it
861      // via proxy's ServiceURI property - but must exist by now
862      string useUrl = "";
863      if (Url == "" || Url == null)
864      {
865        Attribute urlAttr = Attribute.GetCustomAttribute(type,
866          typeof(XmlRpcUrlAttribute));
867        if (urlAttr != null)
868        {
869          XmlRpcUrlAttribute xrsAttr = urlAttr as XmlRpcUrlAttribute;
870          useUrl = xrsAttr.Uri;
871        }
872      }
873      else
874      {
875        useUrl = Url;
876      }
877      if (useUrl == "")
878      {
879        throw new XmlRpcMissingUrl("Proxy XmlRpcUrl attribute or Url "
880          + "property not set.");
881      }
882      return useUrl;
883    }
884
885    #region Introspection Methods
886    [XmlRpcMethod("system.listMethods")]
887    public string[] SystemListMethods()
888    {
889      return (string[])Invoke("SystemListMethods", new Object[0]);
890    }
891
892    [XmlRpcMethod("system.listMethods")]
893    public IAsyncResult BeginSystemListMethods(
894      AsyncCallback Callback,
895      object State)
896    {
897      return BeginInvoke("SystemListMethods", new object[0], this, Callback,
898        State);
899    }
900
901    public string[] EndSystemListMethods(IAsyncResult AsyncResult)
902    {
903      return (string[])EndInvoke(AsyncResult);
904    }
905
906    [XmlRpcMethod("system.methodSignature")]
907    public object[] SystemMethodSignature(string MethodName)
908    {
909      return (object[])Invoke("SystemMethodSignature",
910        new Object[] { MethodName });
911    }
912
913    [XmlRpcMethod("system.methodSignature")]
914    public IAsyncResult BeginSystemMethodSignature(
915      string MethodName,
916      AsyncCallback Callback,
917      object State)
918    {
919      return BeginInvoke("SystemMethodSignature",
920        new Object[] { MethodName }, this, Callback, State);
921    }
922
923    public Array EndSystemMethodSignature(IAsyncResult AsyncResult)
924    {
925      return (Array)EndInvoke(AsyncResult);
926    }
927
928    [XmlRpcMethod("system.methodHelp")]
929    public string SystemMethodHelp(string MethodName)
930    {
931      return (string)Invoke("SystemMethodHelp",
932        new Object[] { MethodName });
933    }
934
935    [XmlRpcMethod("system.methodHelp")]
936    public IAsyncResult BeginSystemMethodHelp(
937      string MethodName,
938      AsyncCallback Callback,
939      object State)
940    {
941      return BeginInvoke("SystemMethodHelp",
942        new Object[] { MethodName }, this, Callback, State);
943    }
944
945    public string EndSystemMethodHelp(IAsyncResult AsyncResult)
946    {
947      return (string)EndInvoke(AsyncResult);
948    }
949    #endregion
950
951    #region Component Designer generated code
952    /// <summary>
953    /// Required method for Designer support - do not modify
954    /// the contents of this method with the code editor.
955    /// </summary>
956    private void InitializeComponent()
957    {
958    }
959    #endregion
960
961    protected virtual WebRequest GetWebRequest(Uri uri)
962    {
963      WebRequest req = WebRequest.Create(uri);
964      return req;
965    }
966
967    protected virtual WebResponse GetWebResponse(WebRequest request)
968    {
969      WebResponse ret = null;
970      try
971      {
972        ret = request.GetResponse();
973      }
974      catch (WebException ex)
975      {
976        if (ex.Response == null)
977          throw;
978        ret = ex.Response;
979      }
980      return ret;
981    }
982
983#if (!COMPACT_FRAMEWORK && !FX1_0)
984    // support for gzip and deflate
985    protected Stream MaybeDecompressStream(HttpWebResponse httpWebResp, 
986      Stream respStream)
987    {
988      Stream decodedStream;
989      string contentEncoding = httpWebResp.ContentEncoding.ToLower();
990      string coen = httpWebResp.Headers["Content-Encoding"];
991      if (contentEncoding.Contains("gzip"))
992      {
993        decodedStream = new System.IO.Compression.GZipStream(respStream,
994          System.IO.Compression.CompressionMode.Decompress);
995      }
996      else if (contentEncoding.Contains("deflate"))
997      {
998        decodedStream = new System.IO.Compression.DeflateStream(respStream,
999          System.IO.Compression.CompressionMode.Decompress);
1000      }
1001      else
1002        decodedStream = respStream;
1003      return decodedStream;
1004    }
1005#endif
1006
1007    protected virtual WebResponse GetWebResponse(WebRequest request,
1008      IAsyncResult result)
1009    {
1010      return request.EndGetResponse(result);
1011    }
1012
1013    public event XmlRpcRequestEventHandler RequestEvent;
1014    public event XmlRpcResponseEventHandler ResponseEvent;
1015
1016
1017    protected virtual void OnRequest(XmlRpcRequestEventArgs e)
1018    {
1019      if (RequestEvent != null)
1020      {
1021        RequestEvent(this, e);
1022      }
1023    }
1024
1025    internal bool LogResponse
1026    {
1027      get { return ResponseEvent != null; }
1028    }
1029
1030    protected virtual void OnResponse(XmlRpcResponseEventArgs e)
1031    {
1032      if (ResponseEvent != null)
1033      {
1034        ResponseEvent(this, e);
1035      }
1036    }
1037
1038    internal void InternalOnResponse(XmlRpcResponseEventArgs e)
1039    {
1040      OnResponse(e);
1041    }
1042  }
1043
1044#if (COMPACT_FRAMEWORK)
1045  // dummy attribute because System.ComponentModel.Browsable is not
1046  // support in the compact framework
1047  [AttributeUsage(AttributeTargets.Property)]
1048  public class BrowsableAttribute : Attribute
1049  {
1050    public BrowsableAttribute(bool dummy)
1051    {
1052    }
1053  }
1054#endif
1055
1056  public delegate void XmlRpcRequestEventHandler(object sender,
1057    XmlRpcRequestEventArgs args);
1058
1059  public delegate void XmlRpcResponseEventHandler(object sender,
1060    XmlRpcResponseEventArgs args);
1061}
1062
1063
Note: See TracBrowser for help on using the repository browser.