Python 3 updates
authorThierry Florac <thierry.florac@onf.fr>
Fri, 29 Jan 2016 15:39:09 +0100
changeset 55 d20591346980
parent 54 044faae3d7ed
child 56 01de65ad00fb
Python 3 updates
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