summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSatya Rohith <me@satyarohith.com>2024-06-25 17:02:40 +0530
committerGitHub <noreply@github.com>2024-06-25 17:02:40 +0530
commit13aa1d70e905f1e1ec57d7eb57ad57d09d09deb2 (patch)
tree1319fef940f019fce0acd80d7bb8b06bc693dd37
parentb71a85918815195a2a8ba070fb534e50938251bd (diff)
fix(ext/node): ignore stream error during enqueue (#24243)
-rw-r--r--ext/node/polyfills/http.ts12
-rw-r--r--tests/unit_node/http_test.ts49
2 files changed, 57 insertions, 4 deletions
diff --git a/ext/node/polyfills/http.ts b/ext/node/polyfills/http.ts
index f009d8a9e..6880f7cb8 100644
--- a/ext/node/polyfills/http.ts
+++ b/ext/node/polyfills/http.ts
@@ -1346,10 +1346,14 @@ export class ServerResponse extends NodeWritable {
#socketOverride: any | null = null;
static #enqueue(controller: ReadableStreamDefaultController, chunk: Chunk) {
- if (typeof chunk === "string") {
- controller.enqueue(ENCODER.encode(chunk));
- } else {
- controller.enqueue(chunk);
+ try {
+ if (typeof chunk === "string") {
+ controller.enqueue(ENCODER.encode(chunk));
+ } else {
+ controller.enqueue(chunk);
+ }
+ } catch (_) {
+ // The stream might have been closed. Ignore the error.
}
}
diff --git a/tests/unit_node/http_test.ts b/tests/unit_node/http_test.ts
index f17e57058..4c3d39780 100644
--- a/tests/unit_node/http_test.ts
+++ b/tests/unit_node/http_test.ts
@@ -1130,3 +1130,52 @@ Deno.test("[node/http] server closeIdleConnections shutdown", async () => {
await promise;
});
+
+Deno.test("[node/http] client closing a streaming response doesn't terminate server", async () => {
+ let interval: number;
+ const server = http.createServer((req, res) => {
+ res.writeHead(200, { "Content-Type": "text/plain" });
+ interval = setInterval(() => {
+ res.write("Hello, world!\n");
+ }, 100);
+ req.on("end", () => {
+ clearInterval(interval);
+ res.end();
+ });
+ req.on("error", (err) => {
+ console.error("Request error:", err);
+ clearInterval(interval);
+ res.end();
+ });
+ });
+
+ const deferred1 = Promise.withResolvers<void>();
+ server.listen(0, () => {
+ // deno-lint-ignore no-explicit-any
+ const port = (server.address() as any).port;
+
+ // Create a client connection to the server
+ const client = net.createConnection({ port }, () => {
+ console.log("Client connected to server");
+
+ // Write data to the server
+ client.write("GET / HTTP/1.1\r\n");
+ client.write("Host: localhost\r\n");
+ client.write("Connection: close\r\n");
+ client.write("\r\n");
+
+ // End the client connection prematurely while reading data
+ client.on("data", (data) => {
+ assert(data.length > 0);
+ client.end();
+ setTimeout(() => deferred1.resolve(), 100);
+ });
+ });
+ });
+
+ await deferred1.promise;
+ assertEquals(server.listening, true);
+ server.close();
+ assertEquals(server.listening, false);
+ clearInterval(interval!);
+});