Skip to content

Commit c09ef05

Browse files
committed
Fixed the CGI request handler and added a test for it
1 parent 95a318a commit c09ef05

File tree

3 files changed

+102
-6
lines changed

3 files changed

+102
-6
lines changed

jsonrpclib/SimpleJSONRPCServer.py

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
# variant of this package.
4242
SimpleXMLRPCDispatcher = xmlrpcserver.SimpleXMLRPCDispatcher
4343
SimpleXMLRPCRequestHandler = xmlrpcserver.SimpleXMLRPCRequestHandler
44+
CGIXMLRPCRequestHandler = xmlrpcserver.CGIXMLRPCRequestHandler
4445
resolve_dotted_attribute = xmlrpcserver.resolve_dotted_attribute
4546
import socketserver
4647
except (ImportError, AttributeError):
@@ -49,6 +50,7 @@
4950
import SimpleXMLRPCServer as xmlrpcserver
5051
SimpleXMLRPCDispatcher = xmlrpcserver.SimpleXMLRPCDispatcher
5152
SimpleXMLRPCRequestHandler = xmlrpcserver.SimpleXMLRPCRequestHandler
53+
CGIXMLRPCRequestHandler = xmlrpcserver.CGIXMLRPCRequestHandler
5254
resolve_dotted_attribute = xmlrpcserver.resolve_dotted_attribute
5355
import SocketServer as socketserver
5456

@@ -585,7 +587,7 @@ def server_close(self):
585587
# ------------------------------------------------------------------------------
586588

587589

588-
class CGIJSONRPCRequestHandler(SimpleJSONRPCDispatcher):
590+
class CGIJSONRPCRequestHandler(SimpleJSONRPCDispatcher, CGIXMLRPCRequestHandler):
589591
"""
590592
JSON-RPC CGI handler (and dispatcher)
591593
"""
@@ -597,17 +599,23 @@ def __init__(self, encoding=None, config=jsonrpclib.config.DEFAULT):
597599
:param config: A JSONRPClib Config instance
598600
"""
599601
SimpleJSONRPCDispatcher.__init__(self, encoding, config)
602+
CGIXMLRPCRequestHandler.__init__(self)
600603

601604
def handle_jsonrpc(self, request_text):
602605
"""
603606
Handle a JSON-RPC request
604607
"""
608+
try:
609+
writer = sys.stdout.buffer
610+
except AttributeError:
611+
writer = sys.stdout
612+
605613
response = self._marshaled_dispatch(request_text)
606-
sys.stdout.write('Content-Type: {0}\r\n'
607-
.format(self.json_config.content_type))
608-
sys.stdout.write('Content-Length: {0:d}\r\n'.format(len(response)))
609-
sys.stdout.write('\r\n')
610-
sys.stdout.write(response)
614+
print('Content-Type: {0}'.format(self.json_config.content_type))
615+
print('Content-Length: {0:d}'.format(len(response)))
616+
print()
617+
writer.write(response.encode(self.encoding))
618+
writer.flush()
611619

612620
# XML-RPC alias
613621
handle_xmlrpc = handle_jsonrpc

tests/cgi-bin/cgi_server.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#!/usr/bin/python
2+
"""
3+
Sample CGI server
4+
"""
5+
6+
import os
7+
import sys
8+
9+
current_dir = os.path.dirname(__file__)
10+
root_dir = os.path.dirname(os.path.dirname(current_dir))
11+
sys.path.insert(0, root_dir)
12+
13+
from jsonrpclib.SimpleJSONRPCServer import CGIJSONRPCRequestHandler
14+
15+
16+
def add(a, b):
17+
return a + b
18+
19+
20+
handler = CGIJSONRPCRequestHandler()
21+
handler.register_function(add)
22+
handler.handle_request()

tests/test_cgi.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#!/usr/bin/python
2+
# -- Content-Encoding: UTF-8 --
3+
"""
4+
Tests the CGI request handler
5+
6+
:license: Apache License 2.0
7+
"""
8+
9+
# Standard library
10+
import os
11+
import random
12+
import threading
13+
import unittest
14+
15+
try:
16+
from http.server import HTTPServer, CGIHTTPRequestHandler
17+
except ImportError:
18+
from SimpleHTTPServer import HTTPServer
19+
from CGIHTTPServer import CGIHTTPRequestHandler
20+
21+
# JSON-RPC library
22+
from jsonrpclib import ServerProxy
23+
24+
# ------------------------------------------------------------------------------
25+
26+
27+
class CGIHandlerTests(unittest.TestCase):
28+
"""
29+
These tests verify that the CGI request handler works correctly
30+
"""
31+
32+
def test_server(self):
33+
"""
34+
Tests the CGI request handler
35+
"""
36+
# Move the parent directory of "cgi-bin"
37+
old_dir = os.getcwd()
38+
try:
39+
# Setup server
40+
os.chdir(os.path.dirname(__file__))
41+
server = HTTPServer(("localhost", 0), CGIHTTPRequestHandler)
42+
43+
# Serve in a thread
44+
thread = threading.Thread(target=server.serve_forever)
45+
thread.daemon = True
46+
thread.start()
47+
48+
# Find its port
49+
port = server.socket.getsockname()[1]
50+
51+
# Make the client
52+
client = ServerProxy(
53+
"http://localhost:{0}/cgi-bin/cgi_server.py".format(port)
54+
)
55+
56+
# Check calls
57+
for _ in range(3):
58+
a, b = random.random(), random.random()
59+
result = client.add(a, b)
60+
self.assertEqual(result, a + b)
61+
62+
# Close server
63+
server.server_close()
64+
thread.join()
65+
finally:
66+
os.chdir(old_dir)

0 commit comments

Comments
 (0)