Support unix:/foo/bar URLs for the client
[invirt/packages/python-jsonrpclib.git] / jsonrpclib / jsonrpc.py
index dc20fd6..b752450 100644 (file)
@@ -102,9 +102,11 @@ def jloads(json_string):
 class ProtocolError(Exception):
     pass
 
-class Transport(XMLTransport):
+class TransportMixIn(object):
     """ Just extends the XMLRPC transport where necessary. """
     user_agent = config.user_agent
+    # for Python 2.7 support
+    _connection = None
 
     def send_content(self, connection, request_body):
         connection.putheader("Content-Type", "application/json-rpc")
@@ -113,26 +115,53 @@ class Transport(XMLTransport):
         if request_body:
             connection.send(request_body)
 
-    def _parse_response(self, file_h, sock):
-        response_body = ''
-        while 1:
-            if sock:
-                response = sock.recv(1024)
-            else:
-                response = file_h.read(1024)
-            if not response:
-                break
-            response_body += response
-            if self.verbose:
-                print 'body: %s' % response
-        return response_body
-
-class SafeTransport(XMLSafeTransport):
-    """ Just extends for HTTPS calls """
-    user_agent = Transport.user_agent
-    send_content = Transport.send_content
-    _parse_response = Transport._parse_response
+    def getparser(self):
+        target = JSONTarget()
+        return JSONParser(target), target
+
+class JSONParser(object):
+    def __init__(self, target):
+        self.target = target
+
+    def feed(self, data):
+        self.target.feed(data)
+
+    def close(self):
+        pass
 
+class JSONTarget(object):
+    def __init__(self):
+        self.data = []
+
+    def feed(self, data):
+        self.data.append(data)
+
+    def close(self):
+        return ''.join(self.data)
+
+class Transport(TransportMixIn, XMLTransport):
+    pass
+
+class SafeTransport(TransportMixIn, XMLSafeTransport):
+    pass
+
+from httplib import HTTP, HTTPConnection
+from socket import socket, AF_UNIX, SOCK_STREAM
+class UnixHTTPConnection(HTTPConnection):
+    def connect(self):
+        self.sock = socket(AF_UNIX, SOCK_STREAM)
+        self.sock.connect(self.host)
+
+class UnixHTTP(HTTP):
+    _connection_class = UnixHTTPConnection
+
+class UnixTransport(TransportMixIn, XMLTransport):
+    def make_connection(self, host):
+        import httplib
+        host, extra_headers, x509 = self.get_host_info(host)
+        return UnixHTTP(host)
+
+    
 class ServerProxy(XMLServerProxy):
     """
     Unfortunately, much more of this class has to be copied since
@@ -146,15 +175,21 @@ class ServerProxy(XMLServerProxy):
             version = config.version
         self.__version = version
         schema, uri = urllib.splittype(uri)
-        if schema not in ('http', 'https'):
+        if schema not in ('http', 'https', 'unix'):
             raise IOError('Unsupported JSON-RPC protocol.')
-        self.__host, self.__handler = urllib.splithost(uri)
-        if not self.__handler:
-            # Not sure if this is in the JSON spec?
-            #self.__handler = '/'
-            self.__handler == '/'
+        if schema == 'unix':
+            self.__host = uri
+            self.__handler = '/'
+        else:
+            self.__host, self.__handler = urllib.splithost(uri)
+            if not self.__handler:
+                # Not sure if this is in the JSON spec?
+                #self.__handler = '/'
+                self.__handler == '/'
         if transport is None:
-            if schema == 'https':
+            if schema == 'unix':
+                transport = UnixTransport()
+            elif schema == 'https':
                 transport = SafeTransport()
             else:
                 transport = Transport()