diff options
-rw-r--r-- | src/js/node/http.ts | 11 | ||||
-rw-r--r-- | src/js/out/modules/node/http.js | 8 | ||||
-rw-r--r-- | test/js/node/http/node-http.test.ts | 33 |
3 files changed, 48 insertions, 4 deletions
diff --git a/src/js/node/http.ts b/src/js/node/http.ts index a745f9b32..3a283912e 100644 --- a/src/js/node/http.ts +++ b/src/js/node/http.ts @@ -972,6 +972,7 @@ export class ServerResponse extends Writable { this.#firstWrite = undefined; this._writableState.decodeStrings = false; this.#deferred = undefined; + this.#originalWriteHead = this.writeHead; } req; @@ -989,9 +990,12 @@ export class ServerResponse extends Writable { _removedContLen = false; #deferred: (() => void) | undefined = undefined; #finished = false; - + #originalWriteHead: (statusCode, statusMessage, headers) => ServerResponse; // Express "compress" package uses this - _implicitHeader() {} + _implicitHeader() { + // @ts-ignore + this.writeHead(this.statusCode); + } _write(chunk, encoding, callback) { if (!this.#firstWrite && !this.headersSent) { @@ -1058,6 +1062,9 @@ export class ServerResponse extends Writable { var data = this.#firstWrite || ""; this.#firstWrite = undefined; this.#finished = true; + if (this.writeHead !== this.#originalWriteHead) { + this._implicitHeader(); + } this._reply( new Response(data, { headers: this.#headers, diff --git a/src/js/out/modules/node/http.js b/src/js/out/modules/node/http.js index 13ee7fded..9cfaccd04 100644 --- a/src/js/out/modules/node/http.js +++ b/src/js/out/modules/node/http.js @@ -630,7 +630,7 @@ class OutgoingMessage extends Writable { class ServerResponse extends Writable { constructor({ req, reply }) { super(); - this.req = req, this._reply = reply, this.sendDate = !0, this.statusCode = 200, this.headersSent = !1, this.statusMessage = void 0, this.#controller = void 0, this.#firstWrite = void 0, this._writableState.decodeStrings = !1, this.#deferred = void 0; + this.req = req, this._reply = reply, this.sendDate = !0, this.statusCode = 200, this.headersSent = !1, this.statusMessage = void 0, this.#controller = void 0, this.#firstWrite = void 0, this._writableState.decodeStrings = !1, this.#deferred = void 0, this.#originalWriteHead = this.writeHead; } req; _reply; @@ -647,7 +647,9 @@ class ServerResponse extends Writable { _removedContLen = !1; #deferred = void 0; #finished = !1; + #originalWriteHead; _implicitHeader() { + this.writeHead(this.statusCode); } _write(chunk, encoding, callback) { if (!this.#firstWrite && !this.headersSent) { @@ -694,7 +696,9 @@ class ServerResponse extends Writable { _final(callback) { if (!this.headersSent) { var data = this.#firstWrite || ""; - this.#firstWrite = void 0, this.#finished = !0, this._reply(new Response(data, { + if (this.#firstWrite = void 0, this.#finished = !0, this.writeHead !== this.#originalWriteHead) + this._implicitHeader(); + this._reply(new Response(data, { headers: this.#headers, status: this.statusCode, statusText: this.statusMessage ?? STATUS_CODES[this.statusCode] diff --git a/test/js/node/http/node-http.test.ts b/test/js/node/http/node-http.test.ts index 3e7da9d34..0e7b3ca13 100644 --- a/test/js/node/http/node-http.test.ts +++ b/test/js/node/http/node-http.test.ts @@ -146,6 +146,29 @@ describe("node:http", () => { res.end("Path correct!\n"); return; } + if (reqUrl.pathname === "/customWriteHead") { + function createWriteHead(prevWriteHead, listener) { + let fired = false; + return function writeHead() { + if (!fired) { + fired = true; + listener.call(this); + } + return prevWriteHead.apply(this, arguments); + }; + } + + function addPoweredBy() { + if (!this.getHeader("X-Powered-By")) { + this.setHeader("X-Powered-By", "Bun"); + } + } + + res.writeHead = createWriteHead(res.writeHead, addPoweredBy); + res.setHeader("Content-Type", "text/plain"); + res.end("Hello World"); + return; + } } res.writeHead(200, { "Content-Type": "text/plain" }); @@ -507,6 +530,16 @@ describe("node:http", () => { req.end(); }); }); + it("reassign writeHead method, issue#3585", done => { + runTest(done, (server, serverPort, done) => { + const req = request(`http://localhost:${serverPort}/customWriteHead`, res => { + expect(res.headers["content-type"]).toBe("text/plain"); + expect(res.headers["x-powered-by"]).toBe("Bun"); + done(); + }); + req.end(); + }); + }); }); describe("signal", () => { |