diff options
Diffstat (limited to 'src/javascript/jsc/api')
-rw-r--r-- | src/javascript/jsc/api/bun.zig | 78 | ||||
-rw-r--r-- | src/javascript/jsc/api/html_rewriter.zig | 15 | ||||
-rw-r--r-- | src/javascript/jsc/api/server.zig | 29 |
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 { |