aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/javascript/jsc/api/server.zig72
-rw-r--r--src/javascript/jsc/webcore/response.zig15
2 files changed, 60 insertions, 27 deletions
diff --git a/src/javascript/jsc/api/server.zig b/src/javascript/jsc/api/server.zig
index b81a0da4e..2d5462c77 100644
--- a/src/javascript/jsc/api/server.zig
+++ b/src/javascript/jsc/api/server.zig
@@ -769,29 +769,41 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
return this.onSendfile();
}
- pub fn onPrepareSendfileWrap(this: *anyopaque, fd: i32, size: anyerror!Blob.SizeType, _: *JSGlobalObject) void {
- onPrepareSendfile(bun.cast(*RequestContext, this), fd, size);
+ pub fn onPrepareSendfileWrap(this: *anyopaque, fd: i32, size: Blob.SizeType, err: ?JSC.SystemError, globalThis: *JSGlobalObject) void {
+ onPrepareSendfile(bun.cast(*RequestContext, this), fd, size, err, globalThis);
}
- fn onPrepareSendfile(this: *RequestContext, fd: i32, size: anyerror!Blob.SizeType) void {
+ fn onPrepareSendfile(this: *RequestContext, fd: i32, size: Blob.SizeType, err: ?JSC.SystemError, globalThis: *JSGlobalObject) void {
this.setAbortHandler();
- if (this.aborted) return;
- const size_ = size catch {
- this.req.setYield(true);
- this.finalize();
+
+ if (err) |system_error| {
+ if (system_error.errno == @enumToInt(std.os.E.NOENT)) {
+ this.runErrorHandlerWithStatusCode(system_error.toErrorInstance(globalThis), 404);
+ } else {
+ this.runErrorHandlerWithStatusCode(system_error.toErrorInstance(globalThis), 500);
+ }
+
return;
- };
- this.blob.size = size_;
+ }
+
+ this.blob.size = size;
this.needs_content_length = true;
+
this.sendfile = .{
.fd = fd,
- .remain = size_,
- .socket_fd = this.resp.getNativeHandle(),
+ .remain = size,
+ .socket_fd = if (!this.aborted) this.resp.getNativeHandle() else -999,
};
+ if (this.aborted) {
+ _ = JSC.Node.Syscall.close(this.sendfile.fd);
+ this.finalize();
+ return;
+ }
+
this.resp.runCorked(*RequestContext, renderMetadata, this);
- if (size_ == 0) {
+ if (size == 0) {
this.cleanupAfterSendfile();
this.finalize();
@@ -900,15 +912,34 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
this.doRenderWithBody(&response.body.value);
}
- pub fn renderProductionError(this: *RequestContext) void {
- this.resp.writeStatus("500 Internal Server Error");
- this.resp.writeHeader("content-type", "text/plain");
- this.resp.end("Something went wrong!", true);
+ pub fn renderProductionError(this: *RequestContext, status: u16) void {
+ switch (status) {
+ 404 => {
+ this.resp.writeStatus("404 Not Found");
+ this.resp.endWithoutBody();
+ },
+ else => {
+ this.resp.writeStatus("500 Internal Server Error");
+ this.resp.writeHeader("content-type", "text/plain");
+ this.resp.end("Something went wrong!", true);
+ },
+ }
this.finalize();
}
- pub fn runErrorHandler(this: *RequestContext, value: JSC.JSValue) void {
+ pub fn runErrorHandler(
+ this: *RequestContext,
+ value: JSC.JSValue,
+ ) void {
+ runErrorHandlerWithStatusCode(this, value, 500);
+ }
+
+ pub fn runErrorHandlerWithStatusCode(
+ this: *RequestContext,
+ value: JSC.JSValue,
+ status: u16,
+ ) void {
if (this.resp.hasResponded()) return;
var exception_list: std.ArrayList(Api.JsException) = std.ArrayList(Api.JsException).init(bun.default_allocator);
@@ -919,10 +950,8 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
const result = JSC.C.JSObjectCallAsFunctionReturnValue(this.server.globalThis.ref(), this.server.config.onError.asObjectRef(), null, 1, &args);
if (!result.isEmptyOrUndefinedOrNull()) {
- JSC.C.JSValueProtect(this.server.globalThis.ref(), result.asObjectRef());
if (result.isError() or result.isAggregateError(this.server.globalThis)) {
this.runErrorHandler(result);
- JSC.C.JSValueUnprotect(this.server.globalThis.ref(), result.asObjectRef());
return;
} else if (result.as(Response)) |response| {
this.render(response);
@@ -942,8 +971,9 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
.{ std.mem.span(@tagName(this.method)), this.url },
);
} else {
- JSC.VirtualMachine.vm.defaultErrorHandler(value, &exception_list);
- this.renderProductionError();
+ if (status != 404)
+ JSC.VirtualMachine.vm.defaultErrorHandler(value, &exception_list);
+ this.renderProductionError(status);
}
JSC.VirtualMachine.vm.log.reset();
return;
diff --git a/src/javascript/jsc/webcore/response.zig b/src/javascript/jsc/webcore/response.zig
index 16122721f..a72c1d134 100644
--- a/src/javascript/jsc/webcore/response.zig
+++ b/src/javascript/jsc/webcore/response.zig
@@ -1714,7 +1714,8 @@ pub const Blob = struct {
pub const OnCompleteCallback = fn (
ctx: *anyopaque,
fd: JSC.Node.FileDescriptor,
- size: anyerror!SizeType,
+ size: SizeType,
+ system_error: ?SystemError,
global: *JSGlobalObject,
) void;
@@ -1759,15 +1760,16 @@ pub const Blob = struct {
var cb_ctx = this.onCompleteCtx;
const fd = this.opened_fd;
const _size = this.size;
- const errno = this.errno;
- this.store.deref();
+ const system_error_ = this.system_error;
+ var store = this.store;
bun.default_allocator.destroy(this);
- if (errno) |err| {
- cb(cb_ctx, fd, err, globalThis);
+ if (system_error_) |err| {
+ cb(cb_ctx, -1, 0, err, globalThis);
} else {
- cb(cb_ctx, fd, _size, globalThis);
+ cb(cb_ctx, fd, _size, null, globalThis);
}
+ store.deref();
}
fn _runAsync(this: *OpenAndStatFile) void {
@@ -1785,6 +1787,7 @@ pub const Blob = struct {
.result => |result| result,
.err => |err| {
this.errno = AsyncIO.asError(err.errno);
+ this.system_error = err.toSystemError();
return;
},
};