aboutsummaryrefslogtreecommitdiff
path: root/src/javascript/jsc/api
diff options
context:
space:
mode:
Diffstat (limited to 'src/javascript/jsc/api')
-rw-r--r--src/javascript/jsc/api/bun.zig78
-rw-r--r--src/javascript/jsc/api/html_rewriter.zig15
-rw-r--r--src/javascript/jsc/api/server.zig29
3 files changed, 111 insertions, 11 deletions
diff --git a/src/javascript/jsc/api/bun.zig b/src/javascript/jsc/api/bun.zig
index 26faf75d7..8826acc2e 100644
--- a/src/javascript/jsc/api/bun.zig
+++ b/src/javascript/jsc/api/bun.zig
@@ -255,6 +255,75 @@ pub fn getOrigin(
return ZigString.init(VirtualMachine.vm.origin.origin).toValue(ctx.ptr()).asRef();
}
+pub fn getStdin(
+ _: void,
+ ctx: js.JSContextRef,
+ _: js.JSValueRef,
+ _: js.JSStringRef,
+ _: js.ExceptionRef,
+) js.JSValueRef {
+ var existing = ctx.ptr().getCachedObject(&ZigString.init("BunSTDIN"));
+ if (existing.isEmpty()) {
+ var rare_data = JSC.VirtualMachine.vm.rareData();
+ var store = rare_data.stdin();
+ var blob = bun.default_allocator.create(JSC.WebCore.Blob) catch unreachable;
+ blob.* = JSC.WebCore.Blob.initWithStore(store, ctx.ptr());
+
+ return ctx.ptr().putCachedObject(
+ &ZigString.init("BunSTDIN"),
+ JSC.JSValue.fromRef(JSC.WebCore.Blob.Class.make(ctx, blob)),
+ ).asObjectRef();
+ }
+
+ return existing.asObjectRef();
+}
+
+pub fn getStderr(
+ _: void,
+ ctx: js.JSContextRef,
+ _: js.JSValueRef,
+ _: js.JSStringRef,
+ _: js.ExceptionRef,
+) js.JSValueRef {
+ var existing = ctx.ptr().getCachedObject(&ZigString.init("BunSTDERR"));
+ if (existing.isEmpty()) {
+ var rare_data = JSC.VirtualMachine.vm.rareData();
+ var store = rare_data.stderr();
+ var blob = bun.default_allocator.create(JSC.WebCore.Blob) catch unreachable;
+ blob.* = JSC.WebCore.Blob.initWithStore(store, ctx.ptr());
+
+ return ctx.ptr().putCachedObject(
+ &ZigString.init("BunSTDERR"),
+ JSC.JSValue.fromRef(JSC.WebCore.Blob.Class.make(ctx, blob)),
+ ).asObjectRef();
+ }
+
+ return existing.asObjectRef();
+}
+
+pub fn getStdout(
+ _: void,
+ ctx: js.JSContextRef,
+ _: js.JSValueRef,
+ _: js.JSStringRef,
+ _: js.ExceptionRef,
+) js.JSValueRef {
+ var existing = ctx.ptr().getCachedObject(&ZigString.init("BunSTDOUT"));
+ if (existing.isEmpty()) {
+ var rare_data = JSC.VirtualMachine.vm.rareData();
+ var store = rare_data.stdout();
+ var blob = bun.default_allocator.create(JSC.WebCore.Blob) catch unreachable;
+ blob.* = JSC.WebCore.Blob.initWithStore(store, ctx.ptr());
+
+ return ctx.ptr().putCachedObject(
+ &ZigString.init("BunSTDOUT"),
+ JSC.JSValue.fromRef(JSC.WebCore.Blob.Class.make(ctx, blob)),
+ ).asObjectRef();
+ }
+
+ return existing.asObjectRef();
+}
+
pub fn enableANSIColors(
_: void,
ctx: js.JSContextRef,
@@ -1063,6 +1132,15 @@ pub const Class = NewClass(
.get = getOrigin,
.ts = d.ts{ .name = "origin", .@"return" = "string" },
},
+ .stdin = .{
+ .get = getStdin,
+ },
+ .stdout = .{
+ .get = getStdout,
+ },
+ .stderr = .{
+ .get = getStderr,
+ },
.routesDir = .{
.get = getRoutesDir,
.ts = d.ts{ .name = "routesDir", .@"return" = "string" },
diff --git a/src/javascript/jsc/api/html_rewriter.zig b/src/javascript/jsc/api/html_rewriter.zig
index f75829418..70406ace5 100644
--- a/src/javascript/jsc/api/html_rewriter.zig
+++ b/src/javascript/jsc/api/html_rewriter.zig
@@ -304,7 +304,7 @@ pub const HTMLRewriter = struct {
if (is_pending) {
input.doReadFileInternal(*BufferOutputSink, sink, onFinishedLoading, global);
- } else if (sink.runOutputSink(input.sharedView(), false)) |error_value| {
+ } else if (sink.runOutputSink(input.sharedView(), false, false)) |error_value| {
return error_value;
}
@@ -337,15 +337,24 @@ pub const HTMLRewriter = struct {
return;
},
.result => |data| {
- _ = sink.runOutputSink(data, true);
+ _ = sink.runOutputSink(data.buf, true, data.is_temporary);
},
}
}
- pub fn runOutputSink(sink: *BufferOutputSink, bytes: []const u8, is_async: bool) ?JSValue {
+ pub fn runOutputSink(
+ sink: *BufferOutputSink,
+ bytes: []const u8,
+ is_async: bool,
+ free_bytes_on_end: bool,
+ ) ?JSValue {
+ defer if (free_bytes_on_end)
+ bun.default_allocator.free(bun.constStrToU8(bytes));
+
sink.bytes.growBy(bytes.len) catch unreachable;
var global = sink.global;
var response = sink.response;
+
sink.rewriter.write(bytes) catch {
sink.deinit();
bun.default_allocator.destroy(sink);
diff --git a/src/javascript/jsc/api/server.zig b/src/javascript/jsc/api/server.zig
index 01854eecb..57fbe6d34 100644
--- a/src/javascript/jsc/api/server.zig
+++ b/src/javascript/jsc/api/server.zig
@@ -357,7 +357,9 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
sendfile: SendfileContext = undefined,
request_js_object: JSC.C.JSObjectRef = null,
request_body_buf: std.ArrayListUnmanaged(u8) = .{},
- fallback_buf: std.ArrayListUnmanaged(u8) = .{},
+ /// Used either for temporary blob data or fallback
+ /// When the response body is a temporary value
+ response_buf_owned: std.ArrayListUnmanaged(u8) = .{},
pub const RequestContextStackAllocator = std.heap.StackFallbackAllocator(@sizeOf(RequestContext) * 2048 + 4096);
@@ -478,15 +480,19 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
return;
}
- this.fallback_buf = std.ArrayListUnmanaged(u8){ .items = bb.items, .capacity = bb.capacity };
- this.resp.onWritable(*RequestContext, onWritableFallback, this);
+ this.response_buf_owned = std.ArrayListUnmanaged(u8){ .items = bb.items, .capacity = bb.capacity };
+ this.renderResponseBuffer();
}
- pub fn onWritableFallback(this: *RequestContext, write_offset: c_ulong, resp: *App.Response) callconv(.C) bool {
+ pub fn renderResponseBuffer(this: *RequestContext) void {
+ this.resp.onWritable(*RequestContext, onWritableResponseBuffer, this);
+ }
+
+ pub fn onWritableResponseBuffer(this: *RequestContext, write_offset: c_ulong, resp: *App.Response) callconv(.C) bool {
if (this.aborted) {
return false;
}
- return this.sendWritableBytes(this.fallback_buf.items, write_offset, resp);
+ return this.sendWritableBytes(this.response_buf_owned.items, write_offset, resp);
}
pub fn create(this: *RequestContext, server: *ThisServer, req: *uws.Request, resp: *App.Response) void {
@@ -542,7 +548,7 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
this.response_headers = null;
}
- this.fallback_buf.clearAndFree(bun.default_allocator);
+ this.response_buf_owned.clearAndFree(bun.default_allocator);
}
pub fn finalize(this: *RequestContext) void {
this.finalizeWithoutDeinit();
@@ -731,8 +737,15 @@ fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, comp
return;
}
- this.blob.resolveSize();
- this.doRenderBlob();
+ const is_temporary = result.result.is_temporary;
+ if (!is_temporary) {
+ this.blob.resolveSize();
+ this.doRenderBlob();
+ } else {
+ this.blob.size = @truncate(Blob.SizeType, result.result.buf.len);
+ this.response_buf_owned = .{ .items = result.result.buf, .capacity = result.result.buf.len };
+ this.renderResponseBuffer();
+ }
}
pub fn doRenderWithBodyLocked(this: *anyopaque, value: *JSC.WebCore.Body.Value) void {