Skip to content

Commit cdada80

Browse files
committed
Return 400 Bad Request if the XML-RPC request body is invalid
1 parent 01309f7 commit cdada80

File tree

3 files changed

+63
-6
lines changed

3 files changed

+63
-6
lines changed

CHANGES.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
Next 3.x Release
2+
----------------
3+
4+
- 400 Bad Request is now returned if an XML-RPC request is received with
5+
invalid body data. In previous versions, 500 Internal Server Error
6+
was returned.
7+
18
3.2.2 (2016-03-04)
29
------------------
310

supervisor/tests/test_xmlrpc.py

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -175,9 +175,47 @@ def test_continue_request_400_if_method_name_is_empty(self):
175175
else:
176176
expected = 2
177177
self.assertEqual(len(logdata), expected)
178-
self.assertEqual(logdata[-1],
179-
u'XML-RPC request received with no method name')
180-
self.assertEqual(len(request.producers), 0)
178+
self.assertTrue(logdata[-1].startswith('XML-RPC request data'))
179+
self.assertTrue(repr(data) in logdata[-1])
180+
self.assertTrue(logdata[-1].endswith('is invalid: no method name'))
181+
self.assertEqual(request._error, 400)
182+
183+
def test_continue_request_400_if_loads_raises_not_xml(self):
184+
supervisor = DummySupervisor()
185+
subinterfaces = [('supervisor', DummySupervisorRPCNamespace())]
186+
handler = self._makeOne(supervisor, subinterfaces)
187+
data = 'this is not an xml-rpc request body'
188+
request = DummyRequest('/what/ever', None, None, None)
189+
handler.continue_request(data, request)
190+
logdata = supervisor.options.logger.data
191+
from supervisor.xmlrpc import loads
192+
if loads:
193+
expected = 1
194+
else:
195+
expected = 2
196+
self.assertEqual(len(logdata), expected)
197+
self.assertTrue(logdata[-1].startswith('XML-RPC request data'))
198+
self.assertTrue(repr(data) in logdata[-1])
199+
self.assertTrue(logdata[-1].endswith('is invalid: unmarshallable'))
200+
self.assertEqual(request._error, 400)
201+
202+
def test_continue_request_400_if_loads_raises_weird_xml(self):
203+
supervisor = DummySupervisor()
204+
subinterfaces = [('supervisor', DummySupervisorRPCNamespace())]
205+
handler = self._makeOne(supervisor, subinterfaces)
206+
data = '<methodName></methodName><junk></junk>'
207+
request = DummyRequest('/what/ever', None, None, None)
208+
handler.continue_request(data, request)
209+
logdata = supervisor.options.logger.data
210+
from supervisor.xmlrpc import loads
211+
if loads:
212+
expected = 1
213+
else:
214+
expected = 2
215+
self.assertEqual(len(logdata), expected)
216+
self.assertTrue(logdata[-1].startswith('XML-RPC request data'))
217+
self.assertTrue(repr(data) in logdata[-1])
218+
self.assertTrue(logdata[-1].endswith('is invalid: unmarshallable'))
181219
self.assertEqual(request._error, 400)
182220

183221
def test_continue_request_500_if_rpcinterface_method_call_raises(self):
@@ -228,6 +266,7 @@ def test_continue_request_500_if_xmlrpc_dumps_raises(self):
228266
self.assertTrue(repr(data) in logdata[-1])
229267
self.assertTrue("Traceback" in logdata[-1])
230268
self.assertTrue("TypeError: cannot marshal" in logdata[-1])
269+
self.assertEqual(request._error, 500)
231270

232271
class TraverseTests(unittest.TestCase):
233272
def test_underscore(self):

supervisor/xmlrpc.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -359,15 +359,26 @@ def __init__(self, supervisord, subinterfaces):
359359
def match(self, request):
360360
return request.uri.startswith(self.path)
361361

362-
def continue_request (self, data, request):
362+
def continue_request(self, data, request):
363363
logger = self.supervisord.options.logger
364364

365365
try:
366-
params, method = self.loads(data)
366+
try:
367+
params, method = self.loads(data)
368+
except:
369+
logger.error(
370+
'XML-RPC request data %r is invalid: unmarshallable' %
371+
(data,)
372+
)
373+
request.error(400)
374+
return
367375

368376
# no <methodName> in the request or name is an empty string
369377
if not method:
370-
logger.trace('XML-RPC request received with no method name')
378+
logger.error(
379+
'XML-RPC request data %r is invalid: no method name' %
380+
(data,)
381+
)
371382
request.error(400)
372383
return
373384

0 commit comments

Comments
 (0)