Skip to content

Commit 0fbfb06

Browse files
committed
fix(node/web): do not rely on Node's lazy IncomingMessage.headers accessor
1 parent 5f1ed2c commit 0fbfb06

1 file changed

Lines changed: 12 additions & 5 deletions

File tree

src/adapters/_node/web/incoming.ts

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,31 +27,38 @@ export class WebIncomingMessage extends IncomingMessage {
2727
// `rawHeaders` is the flat `[name, value, name, value, …]` list Node exposes.
2828
// Web `Headers` lower-cases names and has no wire order, so this is a
2929
// best-effort reconstruction; `set-cookie` is expanded to one entry each.
30+
//
31+
// The map is built locally and assigned once rather than mutated in place:
32+
// Node materializes `headers` lazily from `rawHeaders` behind a prototype
33+
// accessor, while Bun's `IncomingMessage` leaves it `undefined` until
34+
// something assigns it, so there is no object to mutate there at all.
35+
const headers: Record<string, string | string[]> = {};
3036
const rawHeaders = this.rawHeaders;
3137
for (const [key, value] of req.headers.entries()) {
3238
const lowerKey = key.toLowerCase();
3339
if (lowerKey === "set-cookie") {
3440
continue;
3541
}
36-
this.headers[lowerKey] = value;
42+
headers[lowerKey] = value;
3743
rawHeaders.push(key, value);
3844
}
3945
const setCookie = req.headers.getSetCookie?.() ?? [];
4046
if (setCookie.length > 0) {
4147
// Node keeps `set-cookie` as an array on `headers` and one raw entry each.
42-
(this.headers as Record<string, string | string[]>)["set-cookie"] = setCookie;
48+
headers["set-cookie"] = setCookie;
4349
for (const cookie of setCookie) {
4450
rawHeaders.push("set-cookie", cookie);
4551
}
4652
}
4753
if (
4854
req.method !== "GET" &&
4955
req.method !== "HEAD" &&
50-
!this.headers["content-length"] &&
51-
!this.headers["transfer-encoding"]
56+
!headers["content-length"] &&
57+
!headers["transfer-encoding"]
5258
) {
53-
this.headers["transfer-encoding"] = "chunked";
59+
headers["transfer-encoding"] = "chunked";
5460
}
61+
this.headers = headers;
5562

5663
const onData = (chunk: any) => {
5764
// Honor backpressure: if the readable buffer is full, pause the source

0 commit comments

Comments
 (0)