From 337d27a6c5f570b68030c3468869d76cdb5af862 Mon Sep 17 00:00:00 2001 From: Zhi Date: Fri, 12 Jun 2026 03:48:39 +0800 Subject: [PATCH 1/2] fix: correct response handling edge cases MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three fixes for HTTP response correctness: 1. HEAD requests: Deno.serve already strips bodies from HEAD responses. The explicit \ ew Response(null, result)\ wrapper was unnecessary and could produce incorrect Content-Length headers (RFC 7231 ยง4.3.2). Remove the special case and let Deno handle it. 2. Malformed URI params: \decodeURI()\ throws a URIError on malformed percent-encoding (e.g. %GG), causing an uncaught 500 error instead of a proper 400. Wrap in try/catch and fall back to the raw value. 3. DiskBuildCache.readFile(): Replace the \sync\ + lint-ignore pattern with an explicit \Promise.reject()\ to cleanly signal the intentional not-implemented status. --- packages/fresh/src/app.ts | 4 ---- packages/fresh/src/dev/dev_build_cache.ts | 5 ++--- packages/fresh/src/router.ts | 10 +++++++++- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/packages/fresh/src/app.ts b/packages/fresh/src/app.ts index c591007586b..c14d64e2b4d 100644 --- a/packages/fresh/src/app.ts +++ b/packages/fresh/src/app.ts @@ -483,10 +483,6 @@ export class App { ); } - if (method === "HEAD") { - return new Response(null, result); - } - return result; } catch (err) { ctx.error = err; diff --git a/packages/fresh/src/dev/dev_build_cache.ts b/packages/fresh/src/dev/dev_build_cache.ts index 3678d0ffba4..559e463e488 100644 --- a/packages/fresh/src/dev/dev_build_cache.ts +++ b/packages/fresh/src/dev/dev_build_cache.ts @@ -296,9 +296,8 @@ export class DiskBuildCache implements DevBuildCache { await Deno.writeFile(filePath, content); } - // deno-lint-ignore require-await - async readFile(_pathname: string): Promise { - throw new Error("Not implemented in build mode"); + readFile(_pathname: string): Promise { + return Promise.reject(new Error("Not implemented in build mode")); } async prepare(): Promise { diff --git a/packages/fresh/src/router.ts b/packages/fresh/src/router.ts index c0bbfa9293a..f750c856dc0 100644 --- a/packages/fresh/src/router.ts +++ b/packages/fresh/src/router.ts @@ -174,7 +174,15 @@ export class UrlPatternRouter implements Router { // Decode matched params for (const [key, value] of Object.entries(match.pathname.groups)) { - result.params[key] = value === undefined ? "" : decodeURI(value); + if (value === undefined) { + result.params[key] = ""; + } else { + try { + result.params[key] = decodeURI(value); + } catch { + result.params[key] = value; + } + } } } From 469d13661c51c2285c20defbb449c2c87fe2b6b4 Mon Sep 17 00:00:00 2001 From: Zhi Date: Sat, 13 Jun 2026 01:48:02 +0800 Subject: [PATCH 2/2] fix: revert HEAD body-stripping change The previous commit removed the explicit HEAD body-stripping (\ ew Response(null, result)\), assuming Deno.serve handles it automatically. However: 1. \pp_test.tsx:810,814\ asserts \ es.body === null\ for HEAD via FakeServer which bypasses Deno's HTTP stack. 2. \handlers.ts:80-82\ documents the contract that HEAD auto-strips the body. 3. Fresh's own \static_files.ts:121\ also explicitly handles HEAD body stripping. Revert this specific change. The other two fixes in this PR (URI decode try/catch, DiskBuildCache Promise.reject) remain valid. --- packages/fresh/src/app.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/fresh/src/app.ts b/packages/fresh/src/app.ts index c14d64e2b4d..c591007586b 100644 --- a/packages/fresh/src/app.ts +++ b/packages/fresh/src/app.ts @@ -483,6 +483,10 @@ export class App { ); } + if (method === "HEAD") { + return new Response(null, result); + } + return result; } catch (err) { ctx.error = err;