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