Skip to content

Commit b7aee15

Browse files
authored
fix: return helpful error when Content-Type header is not application/json (#795)
1 parent a4fbb26 commit b7aee15

File tree

2 files changed

+60
-1
lines changed

2 files changed

+60
-1
lines changed

src/middleware/node/middleware.ts

+17-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// remove type imports from http for Deno compatibility
2-
// see https://github.com/octokit/octokit.js/issues/24#issuecomment-817361886
2+
// see https://github.com/octokit/octokit.js/issues/2075#issuecomment-817361886
33
// import { IncomingMessage, ServerResponse } from "http";
44
type IncomingMessage = any;
55
type ServerResponse = any;
@@ -44,6 +44,22 @@ export async function middleware(
4444
}
4545
}
4646

47+
// Check if the Content-Type header is `application/json` and allow for charset to be specified in it
48+
// Otherwise, return a 415 Unsupported Media Type error
49+
// See https://github.com/octokit/webhooks.js/issues/158
50+
if (!request.headers["content-type"].startsWith("application/json")) {
51+
response.writeHead(415, {
52+
"content-type": "application/json",
53+
accept: "application/json",
54+
});
55+
response.end(
56+
JSON.stringify({
57+
error: `Unsupported "Content-Type" header value. Must be "application/json"`,
58+
})
59+
);
60+
return;
61+
}
62+
4763
const missingHeaders = getMissingHeaders(request).join(", ");
4864

4965
if (missingHeaders) {

test/integration/node-middleware.test.ts

+43
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ describe("createNodeMiddleware(webhooks)", () => {
4848
{
4949
method: "POST",
5050
headers: {
51+
"Content-Type": "application/json",
5152
"X-GitHub-Delivery": "123e4567-e89b-12d3-a456-426655440000",
5253
"X-GitHub-Event": "push",
5354
"X-Hub-Signature-256": signatureSha256,
@@ -92,6 +93,7 @@ describe("createNodeMiddleware(webhooks)", () => {
9293
{
9394
method: "POST",
9495
headers: {
96+
"Content-Type": "application/json",
9597
"X-GitHub-Delivery": "123e4567-e89b-12d3-a456-426655440000",
9698
"X-GitHub-Event": "push",
9799
"X-Hub-Signature-256": signatureSha256,
@@ -106,6 +108,37 @@ describe("createNodeMiddleware(webhooks)", () => {
106108
server.close();
107109
});
108110

111+
test("Handles invalid Content-Type", async () => {
112+
const webhooks = new Webhooks({
113+
secret: "mySecret",
114+
});
115+
116+
const server = createServer(createNodeMiddleware(webhooks)).listen();
117+
118+
// @ts-expect-error complains about { port } although it's included in returned AddressInfo interface
119+
const { port } = server.address();
120+
const response = await fetch(
121+
`http://localhost:${port}/api/github/webhooks`,
122+
{
123+
method: "POST",
124+
headers: {
125+
"Content-Type": "text/plain",
126+
"X-GitHub-Delivery": "123e4567-e89b-12d3-a456-426655440000",
127+
"X-GitHub-Event": "push",
128+
"X-Hub-Signature-256": signatureSha256,
129+
},
130+
body: pushEventPayload,
131+
}
132+
);
133+
134+
await expect(response.text()).resolves.toBe(
135+
'{"error":"Unsupported \\"Content-Type\\" header value. Must be \\"application/json\\""}'
136+
);
137+
expect(response.status).toEqual(415);
138+
139+
server.close();
140+
});
141+
109142
test("Handles invalid JSON", async () => {
110143
const webhooks = new Webhooks({
111144
secret: "mySecret",
@@ -121,6 +154,7 @@ describe("createNodeMiddleware(webhooks)", () => {
121154
{
122155
method: "POST",
123156
headers: {
157+
"Content-Type": "application/json",
124158
"X-GitHub-Delivery": "123e4567-e89b-12d3-a456-426655440000",
125159
"X-GitHub-Event": "push",
126160
"X-Hub-Signature-256": signatureSha256,
@@ -151,6 +185,7 @@ describe("createNodeMiddleware(webhooks)", () => {
151185
{
152186
method: "PUT",
153187
headers: {
188+
"Content-Type": "application/json",
154189
"X-GitHub-Delivery": "123e4567-e89b-12d3-a456-426655440000",
155190
"X-GitHub-Event": "push",
156191
"X-Hub-Signature-256": signatureSha256,
@@ -183,6 +218,7 @@ describe("createNodeMiddleware(webhooks)", () => {
183218
{
184219
method: "POST",
185220
headers: {
221+
"Content-Type": "application/json",
186222
"X-GitHub-Delivery": "123e4567-e89b-12d3-a456-426655440000",
187223
// "X-GitHub-Event": "push",
188224
"X-Hub-Signature-256": signatureSha256,
@@ -219,6 +255,7 @@ describe("createNodeMiddleware(webhooks)", () => {
219255
{
220256
method: "POST",
221257
headers: {
258+
"Content-Type": "application/json",
222259
"X-GitHub-Delivery": "123e4567-e89b-12d3-a456-426655440000",
223260
"X-GitHub-Event": "push",
224261
"X-Hub-Signature-256": signatureSha256,
@@ -252,6 +289,7 @@ describe("createNodeMiddleware(webhooks)", () => {
252289
{
253290
method: "POST",
254291
headers: {
292+
"Content-Type": "application/json",
255293
"X-GitHub-Delivery": "123e4567-e89b-12d3-a456-426655440000",
256294
"X-GitHub-Event": "push",
257295
"X-Hub-Signature-256": signatureSha256,
@@ -290,6 +328,7 @@ describe("createNodeMiddleware(webhooks)", () => {
290328
{
291329
method: "POST",
292330
headers: {
331+
"Content-Type": "application/json",
293332
"X-GitHub-Delivery": "123e4567-e89b-12d3-a456-426655440000",
294333
"X-GitHub-Event": "push",
295334
"X-Hub-Signature-256": signatureSha256,
@@ -325,6 +364,7 @@ describe("createNodeMiddleware(webhooks)", () => {
325364
{
326365
method: "POST",
327366
headers: {
367+
"Content-Type": "application/json",
328368
"X-GitHub-Delivery": "123e4567-e89b-12d3-a456-426655440000",
329369
"X-GitHub-Event": "push",
330370
"X-Hub-Signature-256": signatureSha256,
@@ -413,6 +453,7 @@ describe("createNodeMiddleware(webhooks)", () => {
413453
const response = await fetch(`http://localhost:${port}/test`, {
414454
method: "POST",
415455
headers: {
456+
"Content-Type": "application/json",
416457
"X-GitHub-Delivery": "123e4567-e89b-12d3-a456-426655440000",
417458
"X-GitHub-Event": "push",
418459
"X-Hub-Signature-256": signatureSha256,
@@ -444,6 +485,7 @@ describe("createNodeMiddleware(webhooks)", () => {
444485
const response = await fetch(`http://localhost:${port}/test`, {
445486
method: "POST",
446487
headers: {
488+
"Content-Type": "application/json",
447489
"X-GitHub-Delivery": "123e4567-e89b-12d3-a456-426655440000",
448490
"X-GitHub-Event": "push",
449491
"X-Hub-Signature-256": signatureSha256,
@@ -484,6 +526,7 @@ describe("createNodeMiddleware(webhooks)", () => {
484526
{
485527
method: "POST",
486528
headers: {
529+
"Content-Type": "application/json",
487530
"X-GitHub-Delivery": "123e4567-e89b-12d3-a456-426655440000",
488531
"X-GitHub-Event": "push",
489532
"X-Hub-Signature-256": signatureSha256,

0 commit comments

Comments
 (0)