Skip to content

Commit

Permalink
Throw if user specified an invalid or unsupported Content-Type when
Browse files Browse the repository at this point in the history
submitting a webhook.
  • Loading branch information
Kami committed Feb 9, 2016
1 parent aefd002 commit 8950d27
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 17 deletions.
9 changes: 3 additions & 6 deletions st2api/st2api/controllers/v1/webhooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ def post(self, *args, **kwargs):
try:
body = self._parse_request_body(content_type=content_type, body=body)
except Exception as e:
self._log_request('Invalid request body: %s.' % (str(e)), pecan.request)
msg = 'Invalid request body "%s": %s' % (body, str(e))
self._log_request('Failed to parse request body: %s.' % (str(e)), pecan.request)
msg = 'Failed to parse request body "%s": %s' % (body, str(e))
return pecan.abort(http_client.BAD_REQUEST, msg)

headers = self._get_headers_as_dict(pecan.request.headers)
Expand Down Expand Up @@ -123,10 +123,7 @@ def _parse_request_body(self, content_type, body):
self._log_request('Parsing request body as form encoded data', request=pecan.request)
body = urlparse.parse_qs(body)
else:
# For backward compatibility reasons, try to parse any other content
# type as JSON
self._log_request('Parsing request body as JSON', request=pecan.request)
body = json.loads(body)
raise ValueError('Unsupported Content-Type: "%s"' % (content_type))

return body

Expand Down
22 changes: 11 additions & 11 deletions st2api/tests/unit/controllers/v1/test_webhooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,23 +119,13 @@ def test_json_request_body(self, dispatch_mock):
self.assertEqual(dispatch_mock.call_args[1]['payload']['body'], data)
self.assertEqual(dispatch_mock.call_args[1]['trace_context'].trace_tag, 'tag1')

# 2. Send JSON with invalid content type - make sure we still try to parse it as
# JSON for backward compatibility reasons
data = WEBHOOK_1
headers = {'St2-Trace-Tag': 'tag1', 'Content-Type': 'foo'}
self.app.post('/v1/webhooks/git', json.dumps(data), headers=headers)
self.assertEqual(dispatch_mock.call_args[1]['payload']['headers']['Content-Type'],
'foo')
self.assertEqual(dispatch_mock.call_args[1]['payload']['body'], data)
self.assertEqual(dispatch_mock.call_args[1]['trace_context'].trace_tag, 'tag1')

# 3. JSON content type, invalid JSON body
data = 'invalid'
headers = {'St2-Trace-Tag': 'tag1', 'Content-Type': 'application/json'}
post_resp = self.app.post('/v1/webhooks/git', data, headers=headers,
expect_errors=True)
self.assertEqual(post_resp.status_int, http_client.BAD_REQUEST)
self.assertTrue('Invalid request body' in post_resp)
self.assertTrue('Failed to parse request body' in post_resp)

@mock.patch.object(TriggerInstancePublisher, 'publish_trigger', mock.MagicMock(
return_value=True))
Expand All @@ -153,6 +143,16 @@ def test_form_encoded_request_body(self, dispatch_mock):
self.assertEqual(dispatch_mock.call_args[1]['payload']['body'], data)
self.assertEqual(dispatch_mock.call_args[1]['trace_context'].trace_tag, 'tag1')

def test_unsupported_content_type(self):
# Invalid / unsupported content type - should throw
data = WEBHOOK_1
headers = {'St2-Trace-Tag': 'tag1', 'Content-Type': 'foo/invalid'}
post_resp = self.app.post('/v1/webhooks/git', json.dumps(data), headers=headers,
expect_errors=True)
self.assertEqual(post_resp.status_int, http_client.BAD_REQUEST)
self.assertTrue('Failed to parse request body' in post_resp)
self.assertTrue('Unsupported Content-Type' in post_resp)

def __do_post(self, hook, webhook, expect_errors=False, headers=None):
return self.app.post_json('/v1/webhooks/' + hook,
params=webhook,
Expand Down

0 comments on commit 8950d27

Please sign in to comment.