Skip to content

Commit 7843cb2

Browse files
fix: handle invalid URL (#611)
Co-authored-by: wolfy1339 <[email protected]>
1 parent 976c7c4 commit 7843cb2

File tree

2 files changed

+56
-1
lines changed

2 files changed

+56
-1
lines changed

src/middleware/node/middleware.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,20 @@ export async function middleware(
1919
response: ServerResponse,
2020
next?: Function
2121
) {
22-
const { pathname } = new URL(request.url as string, "http://localhost");
22+
let pathname: string;
23+
try {
24+
pathname = new URL(request.url as string, "http://localhost").pathname;
25+
} catch (error) {
26+
response.writeHead(422, {
27+
"content-type": "application/json",
28+
});
29+
response.end(
30+
JSON.stringify({
31+
error: `Request URL could not be parsed: ${request.url}`,
32+
})
33+
);
34+
return;
35+
}
2336

2437
const isUnknownRoute = request.method !== "POST" || pathname !== options.path;
2538
const isExpressMiddleware = typeof next === "function";

test/integration/node-middleware.test.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,4 +458,46 @@ describe("createNodeMiddleware(webhooks)", () => {
458458

459459
server.close();
460460
});
461+
462+
test("Handles invalid URL", async () => {
463+
const webhooks = new Webhooks({
464+
secret: "mySecret",
465+
});
466+
467+
let middlewareWasRan: () => void;
468+
const untilMiddlewareIsRan = new Promise<void>(function (resolve) {
469+
middlewareWasRan = resolve;
470+
});
471+
const actualMiddleware = createNodeMiddleware(webhooks);
472+
const mockedMiddleware = async function (
473+
...[req, ...rest]: Parameters<typeof actualMiddleware>
474+
) {
475+
req.url = "//";
476+
await actualMiddleware(req, ...rest);
477+
middlewareWasRan();
478+
};
479+
const server = createServer(mockedMiddleware).listen();
480+
481+
// @ts-expect-error complains about { port } although it's included in returned AddressInfo interface
482+
const { port } = server.address();
483+
484+
const response = await fetch(
485+
`http://localhost:${port}/api/github/webhooks`,
486+
{
487+
method: "POST",
488+
headers: {
489+
"X-GitHub-Delivery": "123e4567-e89b-12d3-a456-426655440000",
490+
"X-GitHub-Event": "push",
491+
"X-Hub-Signature-256": signatureSha256,
492+
},
493+
body: pushEventPayload,
494+
}
495+
);
496+
497+
await untilMiddlewareIsRan;
498+
expect(response.status).toEqual(422);
499+
expect(await response.text()).toMatch(/Request URL could not be parsed/);
500+
501+
server.close();
502+
});
461503
});

0 commit comments

Comments
 (0)