mirror of
https://github.com/oven-sh/bun
synced 2026-02-09 10:28:47 +00:00
finish
This commit is contained in:
@@ -197,7 +197,7 @@ pub const HTMLRewriter = struct {
|
||||
|
||||
if (kind != .other) {
|
||||
{
|
||||
const body_value = try jsc.WebCore.Body.extract(global, response_value);
|
||||
const body_value = try jsc.WebCore.Body.extract(global, response_value, null);
|
||||
const resp = bun.new(Response, Response{
|
||||
.init = .{
|
||||
.status_code = 200,
|
||||
|
||||
@@ -44,7 +44,7 @@ pub fn constructor(globalThis: *jsc.JSGlobalObject, callframe: *jsc.CallFrame, b
|
||||
}
|
||||
}
|
||||
|
||||
return Response.constructor(globalThis, callframe);
|
||||
return Response.constructor(globalThis, callframe, .zero);
|
||||
}
|
||||
|
||||
pub export fn BakeResponseClass__constructRedirect(globalObject: *jsc.JSGlobalObject, callFrame: *jsc.CallFrame) callconv(jsc.conv) jsc.JSValue {
|
||||
|
||||
@@ -16,9 +16,9 @@ pub fn use(this: *Body) Blob {
|
||||
return this.value.use();
|
||||
}
|
||||
|
||||
pub fn clone(this: *Body, globalThis: *JSGlobalObject) bun.JSError!Body {
|
||||
pub fn clone(this: *Body, owner: jsc.WebCore.ReadableStream.Ref.Owner, globalThis: *JSGlobalObject, readable_stream_tee: ?*[2]jsc.JSValue) bun.JSError!Body {
|
||||
return Body{
|
||||
.value = try this.value.clone(globalThis),
|
||||
.value = try this.value.clone(owner, globalThis, readable_stream_tee),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -504,6 +504,10 @@ pub const Value = union(Tag) {
|
||||
}
|
||||
|
||||
pub fn fromJS(globalThis: *JSGlobalObject, value: JSValue) bun.JSError!Value {
|
||||
return fromJSWithReadableStreamValue(globalThis, value, null);
|
||||
}
|
||||
|
||||
pub fn fromJSWithReadableStreamValue(globalThis: *JSGlobalObject, value: JSValue, readable_stream_value: ?*JSValue) bun.JSError!Value {
|
||||
value.ensureStillAlive();
|
||||
|
||||
if (value.isEmptyOrUndefinedOrNull()) {
|
||||
@@ -598,6 +602,11 @@ pub const Value = union(Tag) {
|
||||
else => {},
|
||||
}
|
||||
|
||||
if (readable_stream_value) |readable_stream_ptr| {
|
||||
readable_stream_ptr.* = readable.value;
|
||||
return .{ .Locked = .{ .global = globalThis, .readable = .empty } };
|
||||
}
|
||||
|
||||
return Body.Value.fromReadableStreamWithoutLockCheck(readable, globalThis);
|
||||
}
|
||||
|
||||
@@ -941,23 +950,32 @@ pub const Value = union(Tag) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tee(this: *Value, globalThis: *jsc.JSGlobalObject) bun.JSError!Value {
|
||||
pub fn tee(this: *Value, owner: jsc.WebCore.ReadableStream.Ref.Owner, globalThis: *jsc.JSGlobalObject, readable_stream_tee: ?*[2]jsc.JSValue) bun.JSError!Value {
|
||||
var locked = &this.Locked;
|
||||
|
||||
if (locked.readable.isDisturbed(.strong, globalThis)) {
|
||||
return Value{ .Used = {} };
|
||||
if (locked.readable.isDisturbed(owner, globalThis)) {
|
||||
return .Used;
|
||||
}
|
||||
|
||||
if (try locked.readable.tee(.{ .strong = {} }, globalThis)) |readable| {
|
||||
return Value{
|
||||
if (try locked.readable.tee(owner, globalThis, readable_stream_tee)) |result| {
|
||||
if (readable_stream_tee != null) {
|
||||
return .{
|
||||
.Locked = .{
|
||||
.global = globalThis,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return .{
|
||||
.Locked = .{
|
||||
.readable = .{ .strong = jsc.WebCore.ReadableStream.Strong.init(readable.@"0", globalThis) },
|
||||
.readable = .{ .strong = .init(result.@"1", globalThis) },
|
||||
.global = globalThis,
|
||||
},
|
||||
};
|
||||
}
|
||||
if (locked.promise != null or locked.action != .none or locked.readable.has(.strong, globalThis)) {
|
||||
return Value{ .Used = {} };
|
||||
|
||||
if (locked.promise != null or locked.action != .none or locked.readable.has(owner, globalThis)) {
|
||||
return .Used;
|
||||
}
|
||||
|
||||
var drain_result: jsc.WebCore.DrainResult = .{
|
||||
@@ -970,8 +988,8 @@ pub const Value = union(Tag) {
|
||||
}
|
||||
|
||||
if (drain_result == .empty or drain_result == .aborted) {
|
||||
this.* = .{ .Null = {} };
|
||||
return Value{ .Null = {} };
|
||||
this.* = .Null;
|
||||
return .Null;
|
||||
}
|
||||
|
||||
var reader = jsc.WebCore.ByteStream.Source.new(.{
|
||||
@@ -994,28 +1012,35 @@ pub const Value = union(Tag) {
|
||||
.ptr = .{ .Bytes = &reader.context },
|
||||
.value = stream_value,
|
||||
};
|
||||
locked.readable = .{ .strong = jsc.WebCore.ReadableStream.Strong.init(stream, globalThis) };
|
||||
locked.readable.set(.strong, stream, globalThis);
|
||||
|
||||
if (locked.onReadableStreamAvailable) |onReadableStreamAvailable| {
|
||||
onReadableStreamAvailable(locked.task.?, globalThis, locked.readable.get(.{ .strong = {} }, globalThis).?);
|
||||
onReadableStreamAvailable(locked.task.?, globalThis, locked.readable.get(owner, globalThis).?);
|
||||
}
|
||||
|
||||
const first, const second = (try locked.readable.tee(.strong, globalThis)) orelse return Value{ .Used = {} };
|
||||
locked.readable = .{ .strong = .init(first, globalThis) };
|
||||
const tee_result = (try locked.readable.tee(owner, globalThis, readable_stream_tee)) orelse return Value{ .Used = {} };
|
||||
|
||||
if (readable_stream_tee != null) {
|
||||
return .{
|
||||
.Locked = .{
|
||||
.global = globalThis,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return Value{
|
||||
.Locked = .{
|
||||
.readable = .{ .strong = .init(second, globalThis) },
|
||||
.readable = .{ .strong = .init(tee_result.@"1", globalThis) },
|
||||
.global = globalThis,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
pub fn clone(this: *Value, globalThis: *jsc.JSGlobalObject) bun.JSError!Value {
|
||||
this.toBlobIfPossible(.empty);
|
||||
pub fn clone(this: *Value, owner: jsc.WebCore.ReadableStream.Ref.Owner, globalThis: *jsc.JSGlobalObject, readable_stream_tee: ?*[2]jsc.JSValue) bun.JSError!Value {
|
||||
this.toBlobIfPossible(owner);
|
||||
|
||||
if (this.* == .Locked) {
|
||||
return this.tee(globalThis);
|
||||
return try this.tee(owner, globalThis, readable_stream_tee);
|
||||
}
|
||||
|
||||
if (this.* == .InternalBlob) {
|
||||
@@ -1054,10 +1079,11 @@ pub const Value = union(Tag) {
|
||||
pub fn extract(
|
||||
globalThis: *JSGlobalObject,
|
||||
value: JSValue,
|
||||
readable_stream_value: ?*JSValue,
|
||||
) bun.JSError!Body {
|
||||
var body = Body{ .value = Value{ .Null = {} } };
|
||||
|
||||
body.value = try Value.fromJS(globalThis, value);
|
||||
body.value = try Value.fromJSWithReadableStreamValue(globalThis, value, readable_stream_value);
|
||||
if (body.value == .Blob) {
|
||||
assert(!body.value.Blob.isHeapAllocated()); // owned by Body
|
||||
}
|
||||
@@ -1328,7 +1354,7 @@ pub const ValueBufferer = struct {
|
||||
js_sink: ?*ArrayBufferSink.JSSink = null,
|
||||
byte_stream: ?*jsc.WebCore.ByteStream = null,
|
||||
// readable stream strong ref to keep byte stream alive
|
||||
readable_stream_ref: jsc.WebCore.ReadableStream.Ref = .{ .empty = {} },
|
||||
readable_stream_ref: jsc.WebCore.ReadableStream.Strong = .{},
|
||||
stream_buffer: bun.MutableString,
|
||||
allocator: std.mem.Allocator,
|
||||
global: *JSGlobalObject,
|
||||
@@ -1564,14 +1590,15 @@ pub const ValueBufferer = struct {
|
||||
assert(value.* == .Locked);
|
||||
const locked = &value.Locked;
|
||||
if (locked.readable.get(.{ .empty = {} }, sink.global)) |stream| {
|
||||
// keep the stream alive until we're done with it
|
||||
sink.readable_stream_ref = locked.readable;
|
||||
value.* = .{ .Used = {} };
|
||||
|
||||
if (stream.isLocked(sink.global)) {
|
||||
return error.StreamAlreadyUsed;
|
||||
}
|
||||
|
||||
// keep the stream alive until we're done with it
|
||||
sink.readable_stream_ref = .init(stream, sink.global);
|
||||
value.deinit();
|
||||
value.* = .{ .Used = {} };
|
||||
|
||||
switch (stream.ptr) {
|
||||
.Invalid => {
|
||||
return error.InvalidStream;
|
||||
|
||||
@@ -29,7 +29,7 @@ pub const Ref = union(Type) {
|
||||
.Response => {
|
||||
if (owner == .Response) {
|
||||
if (owner.Response.as(jsc.WebCore.Response)) |_| {
|
||||
if (jsc.WebCore.Response.js.gc.body.get(owner.Response)) |body_value| {
|
||||
if (Response.js.gc.body.get(owner.Response)) |body_value| {
|
||||
return ReadableStream.fromJS(body_value, global) catch null;
|
||||
}
|
||||
}
|
||||
@@ -38,7 +38,7 @@ pub const Ref = union(Type) {
|
||||
.Request => {
|
||||
if (owner == .Request) {
|
||||
if (owner.Request.as(jsc.WebCore.Request)) |_| {
|
||||
if (jsc.WebCore.Request.js.gc.body.get(owner.Request)) |body_value| {
|
||||
if (Request.js.gc.body.get(owner.Request)) |body_value| {
|
||||
return ReadableStream.fromJS(body_value, global) catch null;
|
||||
}
|
||||
}
|
||||
@@ -55,9 +55,50 @@ pub const Ref = union(Type) {
|
||||
return stream.isDisturbed(global);
|
||||
}
|
||||
|
||||
pub fn tee(this: *const Ref, owner: Owner, global: *jsc.JSGlobalObject) bun.JSError!?struct { ReadableStream, ReadableStream } {
|
||||
pub fn setValue(this: *Ref, owner: Owner, stream_jsvalue: jsc.JSValue, global: *jsc.JSGlobalObject) void {
|
||||
switch (owner) {
|
||||
.Response => |jsvalue| {
|
||||
if (jsvalue != .zero) {
|
||||
Response.js.gc.body.set(jsvalue, global, stream_jsvalue);
|
||||
this.deinit();
|
||||
this.* = .Response;
|
||||
} else {
|
||||
this.deinit();
|
||||
this.* = .empty;
|
||||
}
|
||||
},
|
||||
.Request => |jsvalue| {
|
||||
if (jsvalue != .zero) {
|
||||
Request.js.gc.body.set(jsvalue, global, stream_jsvalue);
|
||||
this.deinit();
|
||||
this.* = .Request;
|
||||
} else {
|
||||
this.deinit();
|
||||
this.* = .empty;
|
||||
}
|
||||
},
|
||||
.strong => {
|
||||
this.deinit();
|
||||
this.* = .{ .strong = .init(stream_jsvalue, global) };
|
||||
},
|
||||
.empty => {},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set(this: *Ref, owner: Owner, stream: ReadableStream, global: *jsc.JSGlobalObject) void {
|
||||
this.setValue(owner, stream.value, global);
|
||||
}
|
||||
|
||||
pub fn tee(this: *Ref, owner: Owner, global: *jsc.JSGlobalObject, readable_stream_value: ?*[2]jsc.JSValue) bun.JSError!?struct { ReadableStream, ReadableStream } {
|
||||
const stream = get(this, owner, global) orelse return null;
|
||||
return stream.tee(global) catch null;
|
||||
|
||||
const result = try stream.tee(global) orelse return null;
|
||||
if (readable_stream_value) |value| {
|
||||
value.* = .{ result.@"0".value, result.@"1".value };
|
||||
} else {
|
||||
this.set(owner, result.@"0", global);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
pub fn has(this: *const Ref, owner: Owner, global: *jsc.JSGlobalObject) bool {
|
||||
@@ -77,16 +118,16 @@ pub const Ref = union(Type) {
|
||||
pub fn init(owner: Owner, global: *jsc.JSGlobalObject) Ref {
|
||||
switch (owner) {
|
||||
.Response => {
|
||||
return .{ .Response = {} };
|
||||
return .Response;
|
||||
},
|
||||
.Request => {
|
||||
return .{ .Request = {} };
|
||||
return .Request;
|
||||
},
|
||||
.strong => {
|
||||
return .{ .strong = .init(owner.strong, global) };
|
||||
},
|
||||
.empty => {
|
||||
return .{ .empty = {} };
|
||||
return .empty;
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -100,7 +141,7 @@ pub const Ref = union(Type) {
|
||||
.Request => {},
|
||||
.empty => {},
|
||||
}
|
||||
this.* = .{ .empty = {} };
|
||||
this.* = .empty;
|
||||
}
|
||||
|
||||
pub fn abort(this: *Ref, owner: Owner, global: *jsc.JSGlobalObject) bool {
|
||||
@@ -974,3 +1015,5 @@ const Blob = webcore.Blob;
|
||||
const streams = webcore.streams;
|
||||
|
||||
const std = @import("std");
|
||||
const Request = jsc.WebCore.Request;
|
||||
const Response = jsc.WebCore.Response;
|
||||
|
||||
@@ -175,7 +175,8 @@ pub export fn Bun__JSRequest__calculateEstimatedByteSize(this: *Request) void {
|
||||
|
||||
pub fn toJS(this: *Request, globalObject: *JSGlobalObject) JSValue {
|
||||
this.calculateEstimatedByteSize();
|
||||
return js.toJSUnchecked(globalObject, this);
|
||||
const value = js.toJSUnchecked(globalObject, this);
|
||||
return value;
|
||||
}
|
||||
|
||||
extern "C" fn Bun__JSRequest__createForBake(globalObject: *jsc.JSGlobalObject, requestPtr: *Request) callconv(jsc.conv) jsc.JSValue;
|
||||
@@ -522,7 +523,7 @@ const Fields = enum {
|
||||
url,
|
||||
};
|
||||
|
||||
pub fn constructInto(globalThis: *jsc.JSGlobalObject, arguments: []const jsc.JSValue) bun.JSError!Request {
|
||||
pub fn constructInto(globalThis: *jsc.JSGlobalObject, arguments: []const jsc.JSValue, readable_stream_tee: ?*[2]jsc.JSValue) bun.JSError!Request {
|
||||
var success = false;
|
||||
const vm = globalThis.bunVM();
|
||||
const body = try vm.initRequestBodyValue(.{ .Null = {} });
|
||||
@@ -582,7 +583,7 @@ pub fn constructInto(globalThis: *jsc.JSGlobalObject, arguments: []const jsc.JSV
|
||||
if (value_type == .DOMWrapper) {
|
||||
if (value.asDirect(Request)) |request| {
|
||||
if (values_to_try.len == 1) {
|
||||
try request.cloneInto(&req, bun.default_allocator, globalThis, fields.contains(.url));
|
||||
try request.cloneInto(&req, bun.default_allocator, globalThis, fields.contains(.url), value, readable_stream_tee);
|
||||
success = true;
|
||||
return req;
|
||||
}
|
||||
@@ -610,7 +611,7 @@ pub fn constructInto(globalThis: *jsc.JSGlobalObject, arguments: []const jsc.JSV
|
||||
switch (request.body.value) {
|
||||
.Null, .Empty, .Used => {},
|
||||
else => {
|
||||
req.body.value = try request.body.value.clone(globalThis);
|
||||
req.body.value = try request.body.value.clone(.{ .Request = value }, globalThis, readable_stream_tee);
|
||||
fields.insert(.body);
|
||||
},
|
||||
}
|
||||
@@ -641,7 +642,11 @@ pub fn constructInto(globalThis: *jsc.JSGlobalObject, arguments: []const jsc.JSV
|
||||
switch (response.body.value) {
|
||||
.Null, .Empty, .Used => {},
|
||||
else => {
|
||||
req.body.value = try response.body.value.clone(globalThis);
|
||||
req.body.value = try response.body.value.clone(.empty, globalThis, readable_stream_tee);
|
||||
if (readable_stream_tee) |tee_value| {
|
||||
Response.js.gc.body.set(value, globalThis, tee_value[1]);
|
||||
}
|
||||
|
||||
fields.insert(.body);
|
||||
},
|
||||
}
|
||||
@@ -654,7 +659,7 @@ pub fn constructInto(globalThis: *jsc.JSGlobalObject, arguments: []const jsc.JSV
|
||||
if (!fields.contains(.body)) {
|
||||
if (try value.fastGet(globalThis, .body)) |body_| {
|
||||
fields.insert(.body);
|
||||
req.body.value = try Body.Value.fromJS(globalThis, body_);
|
||||
req.body.value = try Body.Value.fromJSWithReadableStreamValue(globalThis, body_, if (readable_stream_tee) |tee| &tee[1] else null);
|
||||
}
|
||||
|
||||
if (globalThis.hasException()) return error.JSError;
|
||||
@@ -775,12 +780,23 @@ pub fn constructInto(globalThis: *jsc.JSGlobalObject, arguments: []const jsc.JSV
|
||||
return req;
|
||||
}
|
||||
|
||||
pub fn constructor(globalThis: *jsc.JSGlobalObject, callframe: *jsc.CallFrame) bun.JSError!*Request {
|
||||
pub fn constructor(
|
||||
globalThis: *jsc.JSGlobalObject,
|
||||
callframe: *jsc.CallFrame,
|
||||
thisValue: JSValue,
|
||||
) bun.JSError!*Request {
|
||||
const arguments_ = callframe.arguments_old(2);
|
||||
const arguments = arguments_.ptr[0..arguments_.len];
|
||||
var readable_stream_tee: [2]JSValue = .{ .zero, .zero };
|
||||
|
||||
const request = try constructInto(globalThis, arguments);
|
||||
return Request.new(request);
|
||||
const request = try constructInto(globalThis, arguments, &readable_stream_tee);
|
||||
const result = Request.new(request);
|
||||
|
||||
if (readable_stream_tee[1] != .zero and result.body.value == .Locked) {
|
||||
js.gc.body.set(thisValue, globalThis, readable_stream_tee[1]);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
pub fn getBodyValue(
|
||||
@@ -795,22 +811,16 @@ pub fn doClone(
|
||||
callframe: *jsc.CallFrame,
|
||||
) bun.JSError!jsc.JSValue {
|
||||
const this_value = callframe.this();
|
||||
const cloned = try this.clone(bun.default_allocator, globalThis);
|
||||
|
||||
var readable_stream_tee: [2]JSValue = .{ .zero, .zero };
|
||||
const cloned = try this.clone(bun.default_allocator, globalThis, this_value, &readable_stream_tee);
|
||||
const js_wrapper = cloned.toJS(globalThis);
|
||||
if (js_wrapper != .zero) {
|
||||
if (cloned.body.value == .Locked) {
|
||||
if (cloned.body.value.Locked.readable.get(.{ .Request = js_wrapper }, globalThis)) |readable| {
|
||||
// If we are teed, then we need to update the cached .body
|
||||
// value to point to the new readable stream
|
||||
// We must do this on both the original and cloned request
|
||||
// but especially the original request since it will have a stale .body value now.
|
||||
js.bodySetCached(js_wrapper, globalThis, readable.value);
|
||||
const this_js = this.toJS(globalThis);
|
||||
if (this.body.value.Locked.readable.get(.{ .Request = this_js }, globalThis)) |other_readable| {
|
||||
js.bodySetCached(this_value, globalThis, other_readable.value);
|
||||
}
|
||||
}
|
||||
if (this.body.value == .Locked and readable_stream_tee[0] != .zero) {
|
||||
js.gc.body.set(js_wrapper, globalThis, readable_stream_tee[0]);
|
||||
}
|
||||
|
||||
if (cloned.body.value == .Locked and readable_stream_tee[1] != .zero) {
|
||||
js.gc.body.set(js_wrapper, globalThis, readable_stream_tee[1]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -928,11 +938,13 @@ pub fn cloneInto(
|
||||
allocator: std.mem.Allocator,
|
||||
globalThis: *JSGlobalObject,
|
||||
preserve_url: bool,
|
||||
this_value: jsc.JSValue,
|
||||
readable_stream_tee: ?*[2]jsc.JSValue,
|
||||
) bun.JSError!void {
|
||||
_ = allocator;
|
||||
this.ensureURL() catch {};
|
||||
const vm = globalThis.bunVM();
|
||||
var body_ = try this.body.value.clone(globalThis);
|
||||
var body_ = try this.body.value.clone(.{ .Request = this_value }, globalThis, readable_stream_tee);
|
||||
errdefer body_.deinit();
|
||||
const body = try vm.initRequestBodyValue(body_);
|
||||
const url = if (preserve_url) req.url else this.url.dupeRef();
|
||||
@@ -953,10 +965,10 @@ pub fn cloneInto(
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clone(this: *Request, allocator: std.mem.Allocator, globalThis: *JSGlobalObject) bun.JSError!*Request {
|
||||
pub fn clone(this: *Request, allocator: std.mem.Allocator, globalThis: *JSGlobalObject, this_value: jsc.JSValue, readable_stream_tee: ?*[2]jsc.JSValue) bun.JSError!*Request {
|
||||
const req = Request.new(undefined);
|
||||
errdefer bun.destroy(req);
|
||||
try this.cloneInto(req, allocator, globalThis, false);
|
||||
try this.cloneInto(req, allocator, globalThis, false, this_value, readable_stream_tee);
|
||||
return req;
|
||||
}
|
||||
|
||||
|
||||
@@ -298,8 +298,10 @@ pub fn makeMaybePooled(globalObject: *jsc.JSGlobalObject, ptr: *Response) JSValu
|
||||
pub fn cloneValue(
|
||||
this: *Response,
|
||||
globalThis: *JSGlobalObject,
|
||||
this_value: jsc.JSValue,
|
||||
readable_stream_tee: ?*[2]jsc.JSValue,
|
||||
) bun.JSError!Response {
|
||||
var body = try this.body.clone(globalThis);
|
||||
var body = try this.body.clone(.{ .Response = this_value }, globalThis, readable_stream_tee);
|
||||
errdefer body.deinit(bun.default_allocator);
|
||||
var init = try this.init.clone(globalThis);
|
||||
errdefer init.deinit(bun.default_allocator);
|
||||
@@ -311,8 +313,8 @@ pub fn cloneValue(
|
||||
};
|
||||
}
|
||||
|
||||
pub fn clone(this: *Response, globalThis: *JSGlobalObject) bun.JSError!*Response {
|
||||
return bun.new(Response, try this.cloneValue(globalThis));
|
||||
pub fn clone(this: *Response, globalThis: *JSGlobalObject, this_value: jsc.JSValue, readable_stream_tee: ?*[2]jsc.JSValue) bun.JSError!*Response {
|
||||
return bun.new(Response, try this.cloneValue(globalThis, this_value, readable_stream_tee));
|
||||
}
|
||||
|
||||
pub fn getStatus(
|
||||
@@ -538,7 +540,7 @@ pub fn constructError(
|
||||
return response.toJS(globalThis);
|
||||
}
|
||||
|
||||
pub fn constructor(globalThis: *jsc.JSGlobalObject, callframe: *jsc.CallFrame) bun.JSError!*Response {
|
||||
pub fn constructor(globalThis: *jsc.JSGlobalObject, callframe: *jsc.CallFrame, thisValue: JSValue) bun.JSError!*Response {
|
||||
var arguments = callframe.argumentsAsArray(2);
|
||||
|
||||
if (!arguments[0].isUndefinedOrNull() and arguments[0].isObject()) {
|
||||
@@ -566,10 +568,11 @@ pub fn constructor(globalThis: *jsc.JSGlobalObject, callframe: *jsc.CallFrame) b
|
||||
return s3.throwSignError(sign_err, globalThis);
|
||||
};
|
||||
defer result.deinit();
|
||||
response.init.headers = try response.getOrCreateHeaders(globalThis);
|
||||
const headers = try response.getOrCreateHeaders(globalThis);
|
||||
errdefer headers.deref();
|
||||
try headers.put(.Location, result.url, globalThis);
|
||||
response.redirected = true;
|
||||
var headers_ref = response.init.headers.?;
|
||||
try headers_ref.put(.Location, result.url, globalThis);
|
||||
response.init.headers = headers;
|
||||
return bun.new(Response, response);
|
||||
}
|
||||
}
|
||||
@@ -595,13 +598,15 @@ pub fn constructor(globalThis: *jsc.JSGlobalObject, callframe: *jsc.CallFrame) b
|
||||
return error.JSError;
|
||||
}
|
||||
|
||||
var readable_stream_value: JSValue = .zero;
|
||||
|
||||
var body: Body = brk: {
|
||||
if (arguments[0].isUndefinedOrNull()) {
|
||||
break :brk Body{
|
||||
.value = Body.Value{ .Null = {} },
|
||||
};
|
||||
}
|
||||
break :brk try Body.extract(globalThis, arguments[0]);
|
||||
break :brk try Body.extract(globalThis, arguments[0], &readable_stream_value);
|
||||
};
|
||||
errdefer body.deinit(bun.default_allocator);
|
||||
|
||||
@@ -609,21 +614,23 @@ pub fn constructor(globalThis: *jsc.JSGlobalObject, callframe: *jsc.CallFrame) b
|
||||
return error.JSError;
|
||||
}
|
||||
|
||||
if (body.value == .Blob and
|
||||
init.headers != null and
|
||||
body.value.Blob.content_type.len > 0 and
|
||||
!init.headers.?.fastHas(.ContentType))
|
||||
{
|
||||
try init.headers.?.put(.ContentType, body.value.Blob.content_type, globalThis);
|
||||
}
|
||||
|
||||
var response = bun.new(Response, Response{
|
||||
.body = body,
|
||||
.init = init,
|
||||
});
|
||||
|
||||
if (response.body.value == .Blob and
|
||||
response.init.headers != null and
|
||||
response.body.value.Blob.content_type.len > 0 and
|
||||
!response.init.headers.?.fastHas(.ContentType))
|
||||
{
|
||||
try response.init.headers.?.put(.ContentType, response.body.value.Blob.content_type, globalThis);
|
||||
}
|
||||
|
||||
response.calculateEstimatedByteSize();
|
||||
|
||||
if (thisValue != .zero and readable_stream_value != .zero) {
|
||||
response.body.value.Locked.readable.set(.{ .Response = thisValue }, response.body.value.Locked.global, readable_stream_value);
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ export default [
|
||||
define({
|
||||
name: "Request",
|
||||
construct: true,
|
||||
constructNeedsThis: true,
|
||||
finalize: true,
|
||||
final: false,
|
||||
klass: {},
|
||||
@@ -68,6 +69,7 @@ export default [
|
||||
define({
|
||||
name: "Response",
|
||||
construct: true,
|
||||
constructNeedsThis: true,
|
||||
finalize: true,
|
||||
final: false,
|
||||
JSType: "0b11101110",
|
||||
|
||||
@@ -1710,7 +1710,7 @@ size_t ${name}::memoryCost(void* ptr) {
|
||||
size_t ${name}::estimatedSize(JSC::JSCell* cell, JSC::VM& vm) {
|
||||
auto* thisObject = jsCast<${name}*>(cell);
|
||||
auto* wrapped = thisObject->wrapped();
|
||||
return Base::estimatedSize(cell, vm) + ${name}::memoryCost(wrapped);
|
||||
return Base::estimatedSize(cell, vm) + (wrapped ? ${name}::memoryCost(wrapped) : 0);
|
||||
}
|
||||
|
||||
void ${name}::destroy(JSCell* cell)
|
||||
|
||||
@@ -424,7 +424,8 @@ size_t ${controller}::memoryCost(void* sinkPtr) {
|
||||
}
|
||||
|
||||
size_t ${controller}::estimatedSize(JSCell* cell, JSC::VM& vm) {
|
||||
return Base::estimatedSize(cell, vm) + ${controller}::memoryCost(jsCast<${controller}*>(cell)->wrapped());
|
||||
auto* wrapped = jsCast<${controller}*>(cell)->wrapped();
|
||||
return Base::estimatedSize(cell, vm) + (wrapped ? ${controller}::memoryCost(wrapped) : 0);
|
||||
}
|
||||
|
||||
JSC_DECLARE_HOST_FUNCTION(${controller}__close);
|
||||
|
||||
Reference in New Issue
Block a user