From d847e60249fd8183ba0998bc379ba20505643204 Mon Sep 17 00:00:00 2001 From: Taku Amano Date: Fri, 19 Apr 2024 14:48:36 +0900 Subject: [PATCH] fix: catch ERR_INVALID_URL error in listener (#162) --- src/listener.ts | 22 +++++++++++----------- test/listener.test.ts | 22 ++++++++++++++++++++++ 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/src/listener.ts b/src/listener.ts index 82655d2..67c3c26 100644 --- a/src/listener.ts +++ b/src/listener.ts @@ -159,18 +159,18 @@ export const getRequestListener = ( ) => { let res - // `fetchCallback()` requests a Request object, but global.Request is expensive to generate, - // so generate a pseudo Request object with only the minimum required information. - const req = newRequest(incoming) - - // Detect if request was aborted. - outgoing.on('close', () => { - if (incoming.destroyed) { - req[getAbortController]().abort() - } - }) - try { + // `fetchCallback()` requests a Request object, but global.Request is expensive to generate, + // so generate a pseudo Request object with only the minimum required information. + const req = newRequest(incoming) + + // Detect if request was aborted. + outgoing.on('close', () => { + if (incoming.destroyed) { + req[getAbortController]().abort() + } + }) + res = fetchCallback(req, { incoming, outgoing } as HttpBindings) as | Response | Promise diff --git a/test/listener.test.ts b/test/listener.test.ts index 58973a2..65ac1c0 100644 --- a/test/listener.test.ts +++ b/test/listener.test.ts @@ -4,6 +4,28 @@ import { getRequestListener } from '../src/listener' import { GlobalRequest, Request as LightweightRequest } from '../src/request' import { GlobalResponse, Response as LightweightResponse } from '../src/response' +describe('Invalid request', () => { + const requestListener = getRequestListener(jest.fn()) + const server = createServer(async (req, res) => { + await requestListener(req, res) + + if (!res.writableEnded) { + res.writeHead(500, { 'Content-Type': 'text/plain' }) + res.end('error handler did not return a response') + } + }) + + it('Should return server error for a request w/o host header', async () => { + const res = await request(server).get('/').set('Host', '').send() + expect(res.status).toBe(500) + }) + + it('Should return server error for a request invalid host header', async () => { + const res = await request(server).get('/').set('Host', 'a b').send() + expect(res.status).toBe(500) + }) +}) + describe('Error handling - sync fetchCallback', () => { const fetchCallback = jest.fn(() => { throw new Error('thrown error')