From d322f566334b90e6b070f251052a64f56dd22df3 Mon Sep 17 00:00:00 2001 From: Lucas Kruger Date: Sat, 5 Jul 2025 16:51:59 -0300 Subject: [PATCH] fix(http): allow HEAD method in file-server This fixes an inconsistency where serveFile() supported HEAD requests but serveDir() returned 405 Method Not Allowed. Now both functions consistently support GET and HEAD methods. The fix changes line 658 in serveDir() to allow HEAD requests, which then properly delegate to serveFile() that already has correct HEAD implementation. Fixes #6750 --- http/file_server.ts | 2 +- http/file_server_test.ts | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/http/file_server.ts b/http/file_server.ts index 135ae046df7c..2ce827ae43d4 100644 --- a/http/file_server.ts +++ b/http/file_server.ts @@ -655,7 +655,7 @@ export async function serveDir( req: Request, opts: ServeDirOptions = {}, ): Promise { - if (req.method !== METHOD.Get) { + if (req.method !== METHOD.Get && req.method !== METHOD.Head) { return createStandardResponse(STATUS_CODE.MethodNotAllowed); } diff --git a/http/file_server_test.ts b/http/file_server_test.ts index f3384705ff77..80dbb82f76d1 100644 --- a/http/file_server_test.ts +++ b/http/file_server_test.ts @@ -1152,6 +1152,30 @@ Deno.test(async function serveFileHeadRequest() { assertEquals(res.headers.get("content-length"), "10034"); }); +Deno.test(async function serveDirHeadRequest() { + const req = new Request("http://localhost/test_file.txt", { + method: "HEAD", + }); + const res = await serveDir(req, serveDirOptions); + assert(!res.body); + assertEquals(res.status, 200); + assertEquals(res.statusText, "OK"); + assertEquals(res.headers.get("content-type"), "text/plain; charset=UTF-8"); + assertEquals(res.headers.get("content-length"), "10034"); +}); + +Deno.test(async function serveDirHeadRequestForDirectoryWithIndex() { + const req = new Request("http://localhost/subdir-with-index/", { + method: "HEAD", + }); + const res = await serveDir(req, serveDirOptions); + assert(!res.body); + assertEquals(res.status, 200); + assertEquals(res.statusText, "OK"); + assertEquals(res.headers.get("content-type"), "text/html; charset=UTF-8"); + assert(res.headers.has("content-length")); +}); + Deno.test("(unstable) serveDir() serves files without the need of html extension when cleanUrls=true", async () => { const req = new Request("http://localhost/hello"); const res = await unstableServeDir(req, {