Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion jsonrpclib/SimpleJSONRPCServer.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
from jsonrpclib import Fault
import SimpleXMLRPCServer
import SocketServer
import socket
import os
import types
import traceback
import sys
Expand Down Expand Up @@ -182,12 +184,22 @@ class SimpleJSONRPCServer(SocketServer.TCPServer, SimpleJSONRPCDispatcher):
allow_reuse_address = True

def __init__(self, addr, requestHandler=SimpleJSONRPCRequestHandler,
logRequests=True, encoding=None, bind_and_activate=True):
logRequests=True, encoding=None, bind_and_activate=True,
address_family=socket.AF_INET):
self.logRequests = logRequests
SimpleJSONRPCDispatcher.__init__(self, encoding)
# TCPServer.__init__ has an extra parameter on 2.6+, so
# check Python version and decide on how to call it
vi = sys.version_info
self.address_family = address_family
if address_family == socket.AF_UNIX:
# Unix sockets can't be bound if they already exist in the
# filesystem. The convention of e.g. X11 is to unlink
# before binding again.
try:
os.unlink(addr)
except OSError:
pass
# if python 2.5 and lower
if vi[0] < 3 and vi[1] < 6:
SocketServer.TCPServer.__init__(self, addr, requestHandler)
Expand Down
37 changes: 30 additions & 7 deletions jsonrpclib/jsonrpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,23 @@ class Transport(TransportMixIn, XMLTransport):

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):
"""
Expand All @@ -158,15 +175,21 @@ def __init__(self, uri, transport=None, encoding=None,
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()
Expand Down
21 changes: 17 additions & 4 deletions tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
from jsonrpclib import Server, MultiCall, history, config, ProtocolError
from jsonrpclib.SimpleJSONRPCServer import SimpleJSONRPCServer
from jsonrpclib.SimpleJSONRPCServer import SimpleJSONRPCRequestHandler
import socket
import unittest
import os
try:
Expand All @@ -40,7 +41,7 @@ class TestCompatibility(unittest.TestCase):

def setUp(self):
self.port = PORTS.pop()
self.server = server_set_up(port=self.port)
self.server = server_set_up(addr=('', self.port))
self.client = Server('http://localhost:%d' % self.port)

# v1 tests forthcoming
Expand Down Expand Up @@ -261,7 +262,7 @@ class InternalTests(unittest.TestCase):

def setUp(self):
self.port = PORTS.pop()
self.server = server_set_up(port=self.port)
self.server = server_set_up(addr=('', self.port))

def get_client(self):
return Server('http://localhost:%d' % self.port)
Expand Down Expand Up @@ -344,6 +345,18 @@ def func():
self.assertRaises(raises[i], func)


class UnixSocketInternalTests(InternalTests):
"""
These tests run the same internal communication tests, but over a
Unix socket instead of a TCP socket.
"""
def setUp(self):
self.port = "/tmp/jsonrpc%d.sock" % (PORTS.pop())
self.server = server_set_up(addr=self.port, address_family=socket.AF_UNIX)

def get_client(self):
return Server('unix:%s' % self.port)

""" Test Methods """
def subtract(minuend, subtrahend):
""" Using the keywords from the JSON-RPC v2 doc """
Expand All @@ -367,14 +380,14 @@ def get_data():
def ping():
return True

def server_set_up(port):
def server_set_up(addr, address_family=socket.AF_INET):
# Not sure this is a good idea to spin up a new server thread
# for each test... but it seems to work fine.
def log_request(self, *args, **kwargs):
""" Making the server output 'quiet' """
pass
SimpleJSONRPCRequestHandler.log_request = log_request
server = SimpleJSONRPCServer(('', port))
server = SimpleJSONRPCServer(addr, address_family=address_family)
server.register_function(summation, 'sum')
server.register_function(summation, 'notify_sum')
server.register_function(notify_hello)
Expand Down