Index: third_party/logilab/common/xmlrpcutils.py |
diff --git a/third_party/logilab/common/xmlrpcutils.py b/third_party/logilab/common/xmlrpcutils.py |
new file mode 100644 |
index 0000000000000000000000000000000000000000..1d30d829b0b013d4c4edffd0b459c0cd537d4646 |
--- /dev/null |
+++ b/third_party/logilab/common/xmlrpcutils.py |
@@ -0,0 +1,131 @@ |
+# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved. |
+# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr |
+# |
+# This file is part of logilab-common. |
+# |
+# logilab-common is free software: you can redistribute it and/or modify it under |
+# the terms of the GNU Lesser General Public License as published by the Free |
+# Software Foundation, either version 2.1 of the License, or (at your option) any |
+# later version. |
+# |
+# logilab-common 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 Lesser General Public License for more |
+# details. |
+# |
+# You should have received a copy of the GNU Lesser General Public License along |
+# with logilab-common. If not, see <http://www.gnu.org/licenses/>. |
+"""XML-RPC utilities.""" |
+__docformat__ = "restructuredtext en" |
+ |
+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 |