Skip to content

Commit 8d3ad24

Browse files
ShibaniMahapatraalexchamberlain
authored andcommitted
Add support for 'application/x-www-form-urlencoded'
Add support for Content-Type: application/x-www-form-urlencoded, so that `python-github-webhook` supports both Content-Types supported by GitHub webhooks. Signed-Off-By: Shibani Mahapatra <[email protected]>
1 parent 1a4590b commit 8d3ad24

File tree

3 files changed

+43
-3
lines changed

3 files changed

+43
-3
lines changed

github_webhook/webhook.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import hashlib
33
import hmac
44
import logging
5-
5+
import json
66
import six
77
from flask import abort, request
88

@@ -58,7 +58,12 @@ def _postreceive(self):
5858
abort(400, "Invalid signature")
5959

6060
event_type = _get_header("X-Github-Event")
61-
data = request.get_json()
61+
content_type = _get_header("content-type")
62+
data = (
63+
json.loads(request.form.to_dict(flat=True)["payload"])
64+
if content_type == "application/x-www-form-urlencoded"
65+
else request.get_json()
66+
)
6267

6368
if data is None:
6469
abort(400, "Request body must contain json")

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
setup(
44
name="github-webhook",
5-
version="1.0.2",
5+
version="1.0.3",
66
description="Very simple, but powerful, microframework for writing Github webhooks in Python",
77
url="https://github.com/bloomberg/python-github-webhook",
88
author="Alex Chamberlain, Fred Phillips, Daniel Kiss, Daniel Beer",

tests/test_webhook.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import pytest
66
import werkzeug
7+
import json
78

89
try:
910
from unittest import mock
@@ -23,6 +24,14 @@ def mock_request():
2324
@pytest.fixture
2425
def push_request(mock_request):
2526
mock_request.headers["X-Github-Event"] = "push"
27+
mock_request.headers["content-type"] = "application/json"
28+
yield mock_request
29+
30+
31+
@pytest.fixture
32+
def push_request_encoded(mock_request):
33+
mock_request.headers["X-Github-Event"] = "push"
34+
mock_request.headers["content-type"] = "application/x-www-form-urlencoded"
2635
yield mock_request
2736

2837

@@ -64,9 +73,35 @@ def test_run_push_hook(webhook, handler, push_request):
6473
handler.assert_called_once_with(push_request.get_json.return_value)
6574

6675

76+
def test_run_push_hook_urlencoded(webhook, handler, push_request_encoded):
77+
github_mock_payload = {"payload": '{"key": "value"}'}
78+
push_request_encoded.form.to_dict.return_value = github_mock_payload
79+
payload = json.loads(github_mock_payload["payload"])
80+
81+
# WHEN
82+
webhook._postreceive()
83+
84+
# THEN
85+
handler.assert_called_once_with(payload)
86+
87+
6788
def test_do_not_run_push_hook_on_ping(webhook, handler, mock_request):
6889
# GIVEN
6990
mock_request.headers["X-Github-Event"] = "ping"
91+
mock_request.headers["content-type"] = "application/json"
92+
93+
# WHEN
94+
webhook._postreceive()
95+
96+
# THEN
97+
handler.assert_not_called()
98+
99+
100+
def test_do_not_run_push_hook_on_ping_urlencoded(webhook, handler, mock_request):
101+
# GIVEN
102+
mock_request.headers["X-Github-Event"] = "ping"
103+
mock_request.headers["content-type"] = "application/x-www-form-urlencoded"
104+
mock_request.form.to_dict.return_value = {"payload": '{"key": "value"}'}
70105

71106
# WHEN
72107
webhook._postreceive()

0 commit comments

Comments
 (0)