--- 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