1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-12 02:27:46 -05:00

wip: abort request when destroy() is invoked

Yoshiya Hinosawa <stibium121@gmail.com>
This commit is contained in:
Satya Rohith 2024-09-26 14:20:32 +05:30
parent 122cefaed4
commit 2c60a4352d
No known key found for this signature in database
GPG key ID: B2705CF40523EB05
2 changed files with 64 additions and 14 deletions

View file

@ -144,6 +144,17 @@ class FakeSocket extends EventEmitter {
} }
} }
function emitErrorEvent(request, error) {
// TODO: enable this when we implement dc for ClientRequest
// if (onClientRequestErrorChannel.hasSubscribers) {
// onClientRequestErrorChannel.publish({
// request,
// error,
// });
// }
request.emit("error", error);
}
/** ClientRequest represents the http(s) request from the client */ /** ClientRequest represents the http(s) request from the client */
class ClientRequest extends OutgoingMessage { class ClientRequest extends OutgoingMessage {
defaultProtocol = "http:"; defaultProtocol = "http:";
@ -566,20 +577,54 @@ class ClientRequest extends OutgoingMessage {
return undefined; return undefined;
} }
// TODO(bartlomieju): handle error onSocket(socket, err) {
onSocket(socket, _err) {
nextTick(() => { nextTick(() => {
socket.on("connect", () => { const req = this;
// Flush the internal buffers once socket is ready. if (req.destroyed || err) {
// Note: the order is important, as the headers flush req.destroyed = true;
// sets up the request.
this._flushHeaders(); function _destroy(req, err) {
this.on("requestReady", () => { if (!req.aborted && !err) {
this._flushBody(); err = new connResetException("socket hang up");
}
if (err) {
emitErrorEvent(req, err);
}
req._closed = true;
req.emit("close");
}
if (socket) {
if (!err && req.agent && !socket.destroyed) {
socket.emit("free");
} else {
finished(socket.destroy(err || req[kError]), (er) => {
if (er?.code === "ERR_STREAM_PREMATURE_CLOSE") {
er = null;
}
_destroy(req, er || err);
});
return;
}
}
_destroy(req, err || req[kError]);
} else {
// Note: this code is specific to deno to initiate a request.
socket.on("connect", () => {
// Flush the internal buffers once socket is ready.
// Note: the order is important, as the headers flush
// sets up the request.
this._flushHeaders();
this.on("requestReady", () => {
this._flushBody();
});
}); });
}); this.socket = socket;
this.socket = socket; this.emit("socket", socket);
this.emit("socket", socket); // tickOnSocket(req, socket);
// req._flush();
}
}); });
} }

View file

@ -501,6 +501,7 @@ Deno.test("[node/http] send request with non-chunked body", {
socket.destroy(); socket.destroy();
socket.setTimeout(100); socket.setTimeout(100);
}); });
// this data can be huge and can't be buffered
req.write("hello "); req.write("hello ");
req.write("world"); req.write("world");
req.end(); req.end();
@ -1037,11 +1038,15 @@ Deno.test("[node/http] destroyed requests should not be sent", {
receivedRequest = true; receivedRequest = true;
return new Response(null); return new Response(null);
}); });
let receivedError = null
const request = http.request(`http://localhost:${server.addr.port}/`); const request = http.request(`http://localhost:${server.addr.port}/`);
request.destroy(); request.destroy();
request.end("hello"); request.end("hello");
request.on("error", (err) => {
receivedError = err;
});
await new Promise((r) => setTimeout(r, 500)); await new Promise((r) => setTimeout(r, 500));
assert(receivedError!.toString().contains("socket hung up"));
assertEquals(receivedRequest, false); assertEquals(receivedRequest, false);
await server.shutdown(); await server.shutdown();
}); });
@ -1353,7 +1358,7 @@ Deno.test("[node/http] client closing a streaming response doesn't terminate ser
clearInterval(interval!); clearInterval(interval!);
}); });
Deno.test("[node/http] client closing a streaming request doesn't terminate server", async () => { Deno.test("[node/http] client closing a streaming request doesn't terminate server", { ignore: true }, async () => {
let interval: number; let interval: number;
let uploadedData = ""; let uploadedData = "";
let requestError: Error | null = null; let requestError: Error | null = null;