summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--jsonrpclib/SimpleJSONRPCServer.py13
-rw-r--r--jsonrpclib/jsonrpc.py45
-rw-r--r--tests.py69
3 files changed, 99 insertions, 28 deletions
diff --git a/jsonrpclib/SimpleJSONRPCServer.py b/jsonrpclib/SimpleJSONRPCServer.py
index 854697b..d76da73 100644
--- a/jsonrpclib/SimpleJSONRPCServer.py
+++ b/jsonrpclib/SimpleJSONRPCServer.py
@@ -1,8 +1,10 @@
import jsonrpclib
from jsonrpclib import Fault
+from jsonrpclib.jsonrpc import USE_UNIX_SOCKETS
import SimpleXMLRPCServer
import SocketServer
import socket
+import logging
import os
import types
import traceback
@@ -192,14 +194,15 @@ class SimpleJSONRPCServer(SocketServer.TCPServer, SimpleJSONRPCDispatcher):
# 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:
+ if USE_UNIX_SOCKETS and 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 os.path.exists(addr):
+ try:
+ os.unlink(addr)
+ except OSError:
+ logging.warning("Could not unlink socket %s", addr)
# if python 2.5 and lower
if vi[0] < 3 and vi[1] < 6:
SocketServer.TCPServer.__init__(self, addr, requestHandler)
diff --git a/jsonrpclib/jsonrpc.py b/jsonrpclib/jsonrpc.py
index ae5c75f..0655e38 100644
--- a/jsonrpclib/jsonrpc.py
+++ b/jsonrpclib/jsonrpc.py
@@ -81,6 +81,12 @@ except ImportError:
IDCHARS = string.ascii_lowercase+string.digits
+class UnixSocketMissing(Exception):
+ """
+ Just a properly named Exception if Unix Sockets usage is
+ attempted on a platform that doesn't support them (Windows)
+ """
+ pass
#JSON Abstractions
@@ -147,22 +153,32 @@ 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)
+from socket import socket
+
+USE_UNIX_SOCKETS = False
+
+try:
+ from socket import AF_UNIX, SOCK_STREAM
+ USE_UNIX_SOCKETS = True
+except ImportError:
+ pass
+
+if (USE_UNIX_SOCKETS):
+
+ 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 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 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):
@@ -181,6 +197,9 @@ class ServerProxy(XMLServerProxy):
if schema not in ('http', 'https', 'unix'):
raise IOError('Unsupported JSON-RPC protocol.')
if schema == 'unix':
+ if not USE_UNIX_SOCKETS:
+ # Don't like the "generic" Exception...
+ raise UnixSocketMissing("Unix sockets not available.")
self.__host = uri
self.__handler = '/'
else:
diff --git a/tests.py b/tests.py
index 7c568b0..3ce1009 100644
--- a/tests.py
+++ b/tests.py
@@ -20,11 +20,14 @@ TODO:
"""
from jsonrpclib import Server, MultiCall, history, config, ProtocolError
+from jsonrpclib import jsonrpc
from jsonrpclib.SimpleJSONRPCServer import SimpleJSONRPCServer
from jsonrpclib.SimpleJSONRPCServer import SimpleJSONRPCRequestHandler
import socket
+import tempfile
import unittest
import os
+import time
try:
import json
except ImportError:
@@ -345,17 +348,60 @@ class InternalTests(unittest.TestCase):
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.
+if jsonrpc.USE_UNIX_SOCKETS:
+ # We won't do these tests unless Unix Sockets are supported
+
+ class UnixSocketInternalTests(InternalTests):
+ """
+ These tests run the same internal communication tests,
+ but over a Unix socket instead of a TCP socket.
+ """
+ def setUp(self):
+ suffix = "%d.sock" % PORTS.pop()
+
+ # Open to safer, alternative processes
+ # for getting a temp file name...
+ temp = tempfile.NamedTemporaryFile(
+ suffix=suffix
+ )
+ self.port = temp.name
+ temp.close()
+
+ self.server = server_set_up(
+ addr=self.port,
+ address_family=socket.AF_UNIX
+ )
+
+ def get_client(self):
+ return Server('unix:/%s' % self.port)
+
+ def tearDown(self):
+ """ Removes the tempory socket file """
+ os.unlink(self.port)
+
+class UnixSocketErrorTests(unittest.TestCase):
+ """
+ Simply tests that the proper exceptions fire if
+ Unix sockets are attempted to be used on a platform
+ that doesn't support them.
"""
+
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)
+ self.original_value = jsonrpc.USE_UNIX_SOCKETS
+ if (jsonrpc.USE_UNIX_SOCKETS):
+ jsonrpc.USE_UNIX_SOCKETS = False
+
+ def test_client(self):
+ address = "unix://shouldnt/work.sock"
+ self.assertRaises(
+ jsonrpc.UnixSocketMissing,
+ Server,
+ address
+ )
+
+ def tearDown(self):
+ jsonrpc.USE_UNIX_SOCKETS = self.original_value
+
""" Test Methods """
def subtract(minuend, subtrahend):
@@ -403,5 +449,8 @@ def server_set_up(addr, address_family=socket.AF_INET):
return server_proc
if __name__ == '__main__':
+ print "==============================================================="
+ print " NOTE: There may be threading exceptions after tests finish. "
+ print "==============================================================="
+ time.sleep(2)
unittest.main()
-