Package logilab :: Package common :: Module xmlrpcutils
[frames] | no frames]

Source Code for Module logilab.common.xmlrpcutils

  1  # copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved. 
  2  # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr 
  3  # 
  4  # This file is part of logilab-common. 
  5  # 
  6  # logilab-common is free software: you can redistribute it and/or modify it under 
  7  # the terms of the GNU Lesser General Public License as published by the Free 
  8  # Software Foundation, either version 2.1 of the License, or (at your option) any 
  9  # later version. 
 10  # 
 11  # logilab-common is distributed in the hope that it will be useful, but WITHOUT 
 12  # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
 13  # FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more 
 14  # details. 
 15  # 
 16  # You should have received a copy of the GNU Lesser General Public License along 
 17  # with logilab-common.  If not, see <http://www.gnu.org/licenses/>. 
 18  """XML-RPC utilities.""" 
 19  __docformat__ = "restructuredtext en" 
 20   
 21  import xmlrpclib 
 22  from base64 import encodestring 
 23  #from cStringIO import StringIO 
 24   
 25  ProtocolError = xmlrpclib.ProtocolError 
 26   
 27  ## class BasicAuthTransport(xmlrpclib.Transport): 
 28  ##     def __init__(self, username=None, password=None): 
 29  ##         self.username = username 
 30  ##         self.password = password 
 31  ##         self.verbose = None 
 32  ##         self.has_ssl = httplib.__dict__.has_key("HTTPConnection") 
 33   
 34  ##     def request(self, host, handler, request_body, verbose=None): 
 35  ##         # issue XML-RPC request 
 36  ##         if self.has_ssl: 
 37  ##             if host.startswith("https:"): h = httplib.HTTPSConnection(host) 
 38  ##             else: h = httplib.HTTPConnection(host) 
 39  ##         else: h = httplib.HTTP(host) 
 40   
 41  ##         h.putrequest("POST", handler) 
 42   
 43  ##         # required by HTTP/1.1 
 44  ##         if not self.has_ssl: # HTTPConnection already does 1.1 
 45  ##             h.putheader("Host", host) 
 46  ##         h.putheader("Connection", "close") 
 47   
 48  ##         if request_body: h.send(request_body) 
 49  ##         if self.has_ssl: 
 50  ##             response = h.getresponse() 
 51  ##             if response.status != 200: 
 52  ##                 raise xmlrpclib.ProtocolError(host + handler, 
 53  ##                                               response.status, 
 54  ##                                               response.reason, 
 55  ##                                               response.msg) 
 56  ##             file = response.fp 
 57  ##         else: 
 58  ##             errcode, errmsg, headers = h.getreply() 
 59  ##             if errcode != 200: 
 60  ##                 raise xmlrpclib.ProtocolError(host + handler, errcode, 
 61  ##                                               errmsg, headers) 
 62   
 63  ##             file = h.getfile() 
 64   
 65  ##         return self.parse_response(file) 
 66   
 67   
 68   
69 -class AuthMixin:
70 """basic http authentication mixin for xmlrpc transports""" 71
72 - def __init__(self, username, password, encoding):
73 self.verbose = 0 74 self.username = username 75 self.password = password 76 self.encoding = encoding
77
78 - def request(self, host, handler, request_body, verbose=0):
79 """issue XML-RPC request""" 80 h = self.make_connection(host) 81 h.putrequest("POST", handler) 82 # required by XML-RPC 83 h.putheader("User-Agent", self.user_agent) 84 h.putheader("Content-Type", "text/xml") 85 h.putheader("Content-Length", str(len(request_body))) 86 h.putheader("Host", host) 87 h.putheader("Connection", "close") 88 # basic auth 89 if self.username is not None and self.password is not None: 90 h.putheader("AUTHORIZATION", "Basic %s" % encodestring( 91 "%s:%s" % (self.username, self.password)).replace("\012", "")) 92 h.endheaders() 93 # send body 94 if request_body: 95 h.send(request_body) 96 # get and check reply 97 errcode, errmsg, headers = h.getreply() 98 if errcode != 200: 99 raise ProtocolError(host + handler, errcode, errmsg, headers) 100 file = h.getfile() 101 ## # FIXME: encoding ??? iirc, this fix a bug in xmlrpclib but... 102 ## data = h.getfile().read() 103 ## if self.encoding != 'UTF-8': 104 ## data = data.replace("version='1.0'", 105 ## "version='1.0' encoding='%s'" % self.encoding) 106 ## result = StringIO() 107 ## result.write(data) 108 ## result.seek(0) 109 ## return self.parse_response(result) 110 return self.parse_response(file)
111
112 -class BasicAuthTransport(AuthMixin, xmlrpclib.Transport):
113 """basic http authentication transport"""
114
115 -class BasicAuthSafeTransport(AuthMixin, xmlrpclib.SafeTransport):
116 """basic https authentication transport"""
117 118
119 -def connect(url, user=None, passwd=None, encoding='ISO-8859-1'):
120 """return an xml rpc server on <url>, using user / password if specified 121 """ 122 if user or passwd: 123 assert user and passwd is not None 124 if url.startswith('https://'): 125 transport = BasicAuthSafeTransport(user, passwd, encoding) 126 else: 127 transport = BasicAuthTransport(user, passwd, encoding) 128 else: 129 transport = None 130 server = xmlrpclib.ServerProxy(url, transport, encoding=encoding) 131 return server
132