fix(ext/node): ignore stream error during enqueue (#24243)

This commit is contained in:
Satya Rohith 2024-06-25 17:02:40 +05:30 committed by GitHub
parent b71a859188
commit 13aa1d70e9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 57 additions and 4 deletions

View File

@ -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.
}
}

View File

@ -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!);
});