From b9460087e391c454f323390a42902a3ed024c8bc Mon Sep 17 00:00:00 2001 From: dave caruso Date: Thu, 29 Jun 2023 23:36:18 -0400 Subject: Fixes `node:http` and `node:stream` so `ytdl-core` works. (#3452) * fix crash in readablestate * make node:https request+get actually use https * use a native readablestream in IncomingMessage * tweaks * fix abort crash * emit close by default * remove abort. this isnt a real function * add validate functions, fixup some other requested changes. not done yet * Update WebCoreJSBuiltins.cpp * Update JSReadableState.cpp * Add some missing exports --------- Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> --- test/js/node/http/node-http.test.ts | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'test/js/node/http/node-http.test.ts') diff --git a/test/js/node/http/node-http.test.ts b/test/js/node/http/node-http.test.ts index b1910a1f7..3e7da9d34 100644 --- a/test/js/node/http/node-http.test.ts +++ b/test/js/node/http/node-http.test.ts @@ -1,5 +1,14 @@ // @ts-nocheck -import { createServer, request, get, Agent, globalAgent, Server } from "node:http"; +import { + createServer, + request, + get, + Agent, + globalAgent, + Server, + validateHeaderName, + validateHeaderValue, +} from "node:http"; import { createTest } from "node-harness"; const { describe, expect, it, beforeAll, afterAll, createDoneDotAll } = createTest(import.meta.path); @@ -624,4 +633,16 @@ describe("node:http", () => { }); }); }); + + test("validateHeaderName", () => { + validateHeaderName("Foo"); + expect(() => validateHeaderName("foo:")).toThrow(); + expect(() => validateHeaderName("foo:bar")).toThrow(); + }); + + test("validateHeaderValue", () => { + validateHeaderValue("Foo", "Bar"); + expect(() => validateHeaderValue("Foo", undefined as any)).toThrow(); + expect(() => validateHeaderValue("Foo", "Bar\r")).toThrow(); + }); }); -- cgit v1.2.3 From 438d54f1869a11a7219f6e93c3bb05f6c52ee27b Mon Sep 17 00:00:00 2001 From: Hanaasagi Date: Mon, 10 Jul 2023 22:04:39 +0900 Subject: add tests --- test/js/node/http/node-http.test.ts | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'test/js/node/http/node-http.test.ts') diff --git a/test/js/node/http/node-http.test.ts b/test/js/node/http/node-http.test.ts index 3e7da9d34..167cb9883 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("re-implemented writeHead, 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", () => { -- cgit v1.2.3 From 17031936c852c2973eacf0929e762972a76ec7bf Mon Sep 17 00:00:00 2001 From: Hanaasagi Date: Tue, 11 Jul 2023 20:10:25 +0900 Subject: small fix, check if the method has been reassigned. --- src/js/node/http.ts | 7 +++++-- src/js/out/modules/node/http.js | 8 ++++++-- test/js/node/http/node-http.test.ts | 2 +- 3 files changed, 12 insertions(+), 5 deletions(-) (limited to 'test/js/node/http/node-http.test.ts') diff --git a/src/js/node/http.ts b/src/js/node/http.ts index 253bcf4d8..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,7 +990,7 @@ export class ServerResponse extends Writable { _removedContLen = false; #deferred: (() => void) | undefined = undefined; #finished = false; - + #originalWriteHead: (statusCode, statusMessage, headers) => ServerResponse; // Express "compress" package uses this _implicitHeader() { // @ts-ignore @@ -1061,7 +1062,9 @@ export class ServerResponse extends Writable { var data = this.#firstWrite || ""; this.#firstWrite = undefined; this.#finished = true; - this._implicitHeader(); + 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 167cb9883..0e7b3ca13 100644 --- a/test/js/node/http/node-http.test.ts +++ b/test/js/node/http/node-http.test.ts @@ -530,7 +530,7 @@ describe("node:http", () => { req.end(); }); }); - it("re-implemented writeHead, issue#3585", done => { + 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"); -- cgit v1.2.3