# HG changeset patch # User Thierry Florac # Date 1454078349 -3600 # Node ID d2059134698091614e5131bd8002512cc7545c7f # Parent 044faae3d7ede7f0a3182ab4bc2aaf0a32bcfe99 Python 3 updates diff -r 044faae3d7ed -r d20591346980 src/pyams_utils/protocol/xmlrpc.py --- a/src/pyams_utils/protocol/xmlrpc.py Mon Jan 18 18:47:43 2016 +0100 +++ b/src/pyams_utils/protocol/xmlrpc.py Fri Jan 29 15:39:09 2016 +0100 @@ -21,6 +21,11 @@ import urllib.request import xmlrpc.client +try: + import gzip +except ImportError: + gzip = None #python can be built without zlib/gzip support + # import interfaces # import packages @@ -30,6 +35,7 @@ """An XML-RPC transport handling authentication via cookies""" _http_connection = http.client.HTTPConnection + verbose = False def __init__(self, user_agent, credentials=(), cookies=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT, headers=None): xmlrpc.client.Transport.__init__(self) @@ -39,6 +45,13 @@ self.timeout = timeout self.headers = headers + def request(self, host, handler, request_body, verbose=False): + self.verbose = verbose + # issue XML-RPC request + connection = self.send_request(host, handler, request_body, verbose) + # get response + return self.get_response(connection, host, handler) + def make_connection(self, host): # This is the make_connection that runs under Python 2.7 and newer. # The code is pulled straight from 2.7 xmlrpclib, except replacing @@ -49,16 +62,37 @@ self._connection = host, self._http_connection(chost, timeout=self.timeout) return self._connection[1] + def send_request(self, host, handler, request_body, debug): + connection = self.make_connection(host) + headers = self._extra_headers[:] + if debug: + connection.set_debuglevel(1) + if self.accept_gzip_encoding and gzip: + connection.putrequest("POST", handler, skip_accept_encoding=True) + headers.append(("Accept-Encoding", "gzip")) + else: + connection.putrequest("POST", handler) + self.send_auth(connection) + self.send_content_type(connection) + self.send_user_agent(connection) + self.send_headers(connection, headers) + self.send_content(connection, request_body) + return connection + # override the send_host hook to also send authentication info - def send_host(self, connection, host): - connection.putheader('Host', host) + def send_auth(self, connection): if (self.cookies is not None) and (len(self.cookies) > 0): for cookie in self.cookies: connection.putheader('Cookie', '%s=%s' % (cookie.name, cookie.value)) elif self.credentials: - auth = 'Basic %s' % base64.encodebytes("%s:%s" % self.credentials).strip() + creds = base64.encodebytes(("%s:%s" % self.credentials).encode()).strip().decode() + auth = 'Basic %s' % creds connection.putheader('Authorization', auth) + # send content type + def send_content_type(self, connection): + connection.putheader('Content-Type', 'text/xml') + # send user agent def send_user_agent(self, connection): connection.putheader('User-Agent', self.user_agent) @@ -66,7 +100,7 @@ # send custom headers def send_headers(self, connection, headers): xmlrpc.client.Transport.send_headers(self, connection, headers) - for k, v in (self.headers or {}).iteritems(): + for k, v in (self.headers or {}).items(): connection.putheader(k, v) # dummy request class for extracting cookies @@ -87,20 +121,6 @@ def info(self): return XMLRPCCookieAuthTransport.CookieResponseHelper(self.response) - def request(self, host, handler, request_body, verbose=False): - # issue XML-RPC request - connection = self.make_connection(host) - self.verbose = verbose - if verbose: - connection.set_debuglevel(1) - self.send_request(connection, handler, request_body) - self.send_host(connection, host) - self.send_user_agent(connection) - self.send_headers(connection) - self.send_content(connection, request_body) - # get response - return self.get_response(connection, host, handler) - def get_response(self, connection, host, handler): response = connection.getresponse() # extract cookies from response headers