aboutsummaryrefslogtreecommitdiff
path: root/src/bun.js/api/server.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/bun.js/api/server.zig')
-rw-r--r--src/bun.js/api/server.zig42
1 files changed, 38 insertions, 4 deletions
diff --git a/src/bun.js/api/server.zig b/src/bun.js/api/server.zig
index 4662ad0bc..58cdc8b63 100644
--- a/src/bun.js/api/server.zig
+++ b/src/bun.js/api/server.zig
@@ -921,6 +921,7 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
method: HTTP.Method,
aborted: bool = false,
finalized: bun.DebugOnly(bool) = bun.DebugOnlyDefault(false),
+ request_finalization_callback: ?*JSC.FinalizationCallback = null,
upgrade_context: ?*uws.uws_socket_context_t = null,
/// We can only safely free once the request body promise is finalized
@@ -975,6 +976,11 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
this.resp.onAborted(*RequestContext, RequestContext.onAbort, this);
}
+ pub fn onRequestFinalized(this: *RequestContext) void {
+ this.request_js_object = null;
+ this.request_finalization_callback = null;
+ }
+
pub fn onResolve(_: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) callconv(.C) JSValue {
ctxLog("onResolve", .{});
@@ -983,13 +989,13 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
const result = arguments.ptr[0];
result.ensureStillAlive();
+ // ctx.request_js_object is set to null by the finalization callback
if (ctx.request_js_object != null and ctx.signal == null) {
var request_js = ctx.request_js_object.?.value();
request_js.ensureStillAlive();
if (request_js.as(Request)) |request_object| {
if (request_object.signal) |signal| {
- ctx.signal = signal;
- _ = signal.ref();
+ ctx.signal = signal.ref();
}
}
}
@@ -1042,13 +1048,13 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
var ctx = arguments.ptr[1].asPromisePtr(@This());
const err = arguments.ptr[0];
+ // ctx.request_js_object is set to null by the finalization callback
if (ctx.request_js_object != null and ctx.signal == null) {
var request_js = ctx.request_js_object.?.value();
request_js.ensureStillAlive();
if (request_js.as(Request)) |request_object| {
if (request_object.signal) |signal| {
- ctx.signal = signal;
- _ = signal.ref();
+ ctx.signal = signal.ref();
}
}
}
@@ -1327,6 +1333,11 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
// User called .blob(), .json(), text(), or .arrayBuffer() on the Request object
// but we received nothing or the connection was aborted
if (request_js.as(Request)) |req| {
+ if (this.request_finalization_callback) |finalizer| {
+ finalizer.detach(this.server.vm.finalizationPool());
+ req.finalization_callback = null;
+ this.request_finalization_callback = null;
+ }
// the promise is pending
if (req.body == .Locked and (req.body.Locked.action != .none or req.body.Locked.promise != null)) {
@@ -1411,11 +1422,21 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
// User called .blob(), .json(), text(), or .arrayBuffer() on the Request object
// but we received nothing or the connection was aborted
if (request_js.as(Request)) |req| {
+ if (this.request_finalization_callback) |finalizer| {
+ finalizer.detach(this.server.vm.finalizationPool());
+ if (finalizer == this.request_finalization_callback)
+ req.finalization_callback = null;
+
+ this.request_finalization_callback = null;
+ }
+
// the promise is pending
if (req.body == .Locked and req.body.Locked.action != .none and req.body.Locked.promise != null) {
req.body.toErrorInstance(JSC.toTypeError(.ABORT_ERR, "Request aborted", .{}, this.server.globalThis), this.server.globalThis);
}
+
req.uws_request = null;
+ req.upgrader = null;
}
}
@@ -2118,6 +2139,19 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
// so we have to clear it in here too
request_object.uws_request = null;
+ if (ctx.signal == null) {
+ if (request_object.signal) |signal| {
+ ctx.signal = signal.ref();
+ } else if (ctx.request_finalization_callback == null and request_object.finalization_callback == null) {
+ request_object.finalization_callback = JSC.FinalizationCallback.create(
+ this.vm.finalizationPool(),
+ RequestContext,
+ ctx,
+ RequestContext.onRequestFinalized,
+ );
+ }
+ }
+
ctx.setAbortHandler();
ctx.pending_promises_for_abort += 1;