honojs/hono

When the response is rewritten, the set-cookie header multiplies.

Closed this issue · 2 comments

tsctx commented

What version of Hono are you using?

4.2.8

What runtime/platform is your app running on?

Node

What steps can reproduce the bug?

import { Hono } from "hono";

const app = new Hono();

app.get("/", async (c) => {
  c.res = new Response(null, {
    headers: [
      ["set-cookie", "a"],
      ["set-cookie", "b"],
      ["set-cookie", "c"],
    ],
  });
  return c.text("Hi");
});
console.log([...(await app.request("/")).headers])

What is the expected behavior?

[
  [ 'content-type', 'text/plain; charset=UTF-8' ],
  [ 'set-cookie', 'a' ],
  [ 'set-cookie', 'b' ],
  [ 'set-cookie', 'c' ]
]

What do you see instead?

[
  [ 'content-type', 'text/plain; charset=UTF-8' ],
  [ 'set-cookie', 'a' ],
  [ 'set-cookie', 'b' ],
  [ 'set-cookie', 'c' ],
  [ 'set-cookie', 'a' ],
  [ 'set-cookie', 'b' ],
  [ 'set-cookie', 'c' ],
  [ 'set-cookie', 'a' ],
  [ 'set-cookie', 'b' ],
  [ 'set-cookie', 'c' ]
]

Additional information

How to fix it?

hono/src/context.ts

Lines 384 to 393 in 347ef12

this.#res.headers.forEach((v, k) => {
if (k === 'set-cookie' && this.#res) {
const cookies = this.#res.headers.getSetCookie()
for (const cookie of cookies) {
this.#headers?.append('set-cookie', cookie)
}
return
}
this.#headers?.set(k, v)
})

Let's do it like this.

 this.#res.headers.forEach((v, k) => { 
   if (k === 'set-cookie') { 
     this.#headers?.append(k, v)
   } else {
     this.#headers?.set(k, v)
   }
 }) 

@tsctx

Fixed it and released the new version, v4.2.9, including the change. Thanks!

Nice and thanks you both! This was an unintended side-effect of my previous patch, this fix is also a lot cleaner!