From cc1ce0acaa17af0c4dd8b8b6bdcd06c1ac0a0953 Mon Sep 17 00:00:00 2001 From: flakey5 <73616808+flakey5@users.noreply.github.com> Date: Fri, 8 Nov 2024 07:27:45 -0800 Subject: [PATCH] src: send a 405 for anything other than GET or HEAD Signed-off-by: flakey5 <73616808+flakey5@users.noreply.github.com> --- src/middleware/methodNotAllowedMiddleware.ts | 7 +++++++ src/routes/index.ts | 3 +++ src/routes/router.ts | 8 ++++++++ tests/e2e/file.test.ts | 10 ++++++++++ 4 files changed, 28 insertions(+) create mode 100644 src/middleware/methodNotAllowedMiddleware.ts diff --git a/src/middleware/methodNotAllowedMiddleware.ts b/src/middleware/methodNotAllowedMiddleware.ts new file mode 100644 index 0000000..ea0459c --- /dev/null +++ b/src/middleware/methodNotAllowedMiddleware.ts @@ -0,0 +1,7 @@ +import type { Middleware } from './middleware'; + +export class MethodNotAllowedMiddleware implements Middleware { + handle(): Promise { + return Promise.resolve(new Response(undefined, { status: 405 })); + } +} diff --git a/src/routes/index.ts b/src/routes/index.ts index 5cdeda3..157adfa 100644 --- a/src/routes/index.ts +++ b/src/routes/index.ts @@ -1,5 +1,6 @@ import latestVersions from '../constants/latestVersions.json' assert { type: 'json' }; import { cached } from '../middleware/cacheMiddleware'; +import { MethodNotAllowedMiddleware } from '../middleware/methodNotAllowedMiddleware'; import { NotFoundMiddleware } from '../middleware/notFoundMiddleware'; import { OptionsMiddleware } from '../middleware/optionsMiddleware'; import { OriginMiddleware } from '../middleware/originMiddleware'; @@ -52,6 +53,8 @@ export function registerRoutes(router: Router): void { ]); router.get('*', [new NotFoundMiddleware()]); + + router.all('*', [new MethodNotAllowedMiddleware()]); } export * from './router'; diff --git a/src/routes/router.ts b/src/routes/router.ts index 2f8359a..c9cf507 100644 --- a/src/routes/router.ts +++ b/src/routes/router.ts @@ -17,6 +17,14 @@ export class Router { return this.itty.fetch(request, ctx); } + all(endpoint: string, middlewares: Middleware[]): void { + const middlewareChain = buildMiddlewareChain(middlewares); + + this.itty.all(endpoint, (req, ctx) => { + return callMiddlewareChain(middlewareChain, req, ctx); + }); + } + options(endpoint: string, middlewares: Middleware[]): void { const middlewareChain = buildMiddlewareChain(middlewares); diff --git a/tests/e2e/file.test.ts b/tests/e2e/file.test.ts index 2dea723..64ea892 100644 --- a/tests/e2e/file.test.ts +++ b/tests/e2e/file.test.ts @@ -172,6 +172,16 @@ describe('File Tests', () => { assert.strictEqual(body, '{ hello:'); }); + it('sends a 405 for anything other than GET or HEAD', async () => { + // Doesn't need to be all-inclusive + for (const method of ['POST', 'PATCH', 'DELETE', 'PROPFIND']) { + const res = await mf.dispatchFetch(`${url}`, { + method: method, + }); + assert.strictEqual(res.status, 405, method); + } + }); + // Cleanup Miniflare after(async () => mf.dispose()); });