diff options
Diffstat (limited to 'src/url.zig')
-rw-r--r-- | src/url.zig | 102 |
1 files changed, 84 insertions, 18 deletions
diff --git a/src/url.zig b/src/url.zig index 550704491..605f438ee 100644 --- a/src/url.zig +++ b/src/url.zig @@ -906,10 +906,10 @@ pub const FormData = struct { this.allocator.destroy(this); } - pub fn toJS(this: *AsyncFormData, global: *bun.JSC.JSGlobalObject, data: []const u8, promise: bun.JSC.AnyPromise) void { + pub fn toJS(this: *AsyncFormData, global: *JSC.JSGlobalObject, data: []const u8, promise: JSC.AnyPromise) void { if (this.encoding == .Multipart and this.encoding.Multipart.len == 0) { log("AsnycFormData.toJS -> promise.reject missing boundary", .{}); - promise.reject(global, bun.JSC.ZigString.init("FormData missing boundary").toErrorInstance(global)); + promise.reject(global, JSC.ZigString.init("FormData missing boundary").toErrorInstance(global)); return; } @@ -955,47 +955,113 @@ pub const FormData = struct { }; pub const External = extern struct { - name: bun.JSC.ZigString, - value: bun.JSC.ZigString, - blob: ?*bun.JSC.WebCore.Blob = null, + name: JSC.ZigString, + value: JSC.ZigString, + blob: ?*JSC.WebCore.Blob = null, }; }; - pub fn toJS(globalThis: *bun.JSC.JSGlobalObject, input: []const u8, encoding: Encoding) !bun.JSC.JSValue { + pub fn toJS(globalThis: *JSC.JSGlobalObject, input: []const u8, encoding: Encoding) !JSC.JSValue { switch (encoding) { .URLEncoded => { - var str = bun.JSC.ZigString.fromUTF8(input); - return bun.JSC.DOMFormData.createFromURLQuery(globalThis, &str); + var str = JSC.ZigString.fromUTF8(input); + return JSC.DOMFormData.createFromURLQuery(globalThis, &str); }, .Multipart => |boundary| return toJSFromMultipartData(globalThis, input, boundary), } } + const JSC = bun.JSC; + + pub fn jsFunctionFromMultipartData( + globalThis: *JSC.JSGlobalObject, + callframe: *JSC.CallFrame, + ) callconv(.C) JSC.JSValue { + JSC.markBinding(@src()); + + const args_ = callframe.arguments(2); + + const args = args_.ptr[0..2]; + + const input_value = args[0]; + const boundary_value = args[1]; + var boundary_slice = JSC.ZigString.Slice.empty; + defer boundary_slice.deinit(); + + var encoding = Encoding{ + .URLEncoded = {}, + }; + + if (input_value.isEmptyOrUndefinedOrNull()) { + globalThis.throwInvalidArguments("input must not be empty", .{}); + return .zero; + } + + if (!boundary_value.isEmptyOrUndefinedOrNull()) { + if (boundary_value.asArrayBuffer(globalThis)) |array_buffer| { + if (array_buffer.byteSlice().len > 0) + encoding = .{ .Multipart = array_buffer.byteSlice() }; + } else if (boundary_value.isString()) { + boundary_slice = boundary_value.toSliceOrNull(globalThis) orelse return .zero; + if (boundary_slice.len > 0) { + encoding = .{ .Multipart = boundary_slice.slice() }; + } + } else { + globalThis.throwInvalidArguments("boundary must be a string or ArrayBufferView", .{}); + return .zero; + } + } + var input_slice = JSC.ZigString.Slice{}; + defer input_slice.deinit(); + var input: []const u8 = ""; + + if (input_value.asArrayBuffer(globalThis)) |array_buffer| { + input = array_buffer.byteSlice(); + } else if (input_value.isString()) { + input_slice = input_value.toSliceOrNull(globalThis) orelse return .zero; + input = input_slice.slice(); + } else if (input_value.as(JSC.WebCore.Blob)) |blob| { + input = blob.sharedView(); + } else { + globalThis.throwInvalidArguments("input must be a string or ArrayBufferView", .{}); + return .zero; + } + + return FormData.toJS(globalThis, input, encoding) catch |err| { + globalThis.throwError(err, "while parsing FormData"); + return .zero; + }; + } + + comptime { + if (!JSC.is_bindgen) + @export(jsFunctionFromMultipartData, .{ .name = "FormData__jsFunctionFromMultipartData" }); + } pub fn toJSFromMultipartData( - globalThis: *bun.JSC.JSGlobalObject, + globalThis: *JSC.JSGlobalObject, input: []const u8, boundary: []const u8, - ) !bun.JSC.JSValue { - const form_data_value = bun.JSC.DOMFormData.create(globalThis); + ) !JSC.JSValue { + const form_data_value = JSC.DOMFormData.create(globalThis); form_data_value.ensureStillAlive(); - var form = bun.JSC.DOMFormData.fromJS(form_data_value) orelse { + var form = JSC.DOMFormData.fromJS(form_data_value) orelse { log("failed to create DOMFormData.fromJS", .{}); return error.@"failed to parse multipart data"; }; const Wrapper = struct { - globalThis: *bun.JSC.JSGlobalObject, - form: *bun.JSC.DOMFormData, + globalThis: *JSC.JSGlobalObject, + form: *JSC.DOMFormData, pub fn onEntry(wrap: *@This(), name: bun.Semver.String, field: Field, buf: []const u8) void { var value_str = field.value.slice(buf); - var key = bun.JSC.ZigString.initUTF8(name.slice(buf)); + var key = JSC.ZigString.initUTF8(name.slice(buf)); if (field.is_file) { var filename_str = field.filename.slice(buf); - var blob = bun.JSC.WebCore.Blob.create(value_str, bun.default_allocator, wrap.globalThis, false); + var blob = JSC.WebCore.Blob.create(value_str, bun.default_allocator, wrap.globalThis, false); defer blob.detach(); - var filename = bun.JSC.ZigString.initUTF8(filename_str); + var filename = JSC.ZigString.initUTF8(filename_str); const content_type: []const u8 = brk: { if (!field.content_type.isEmpty()) { break :brk field.content_type.slice(buf); @@ -1027,7 +1093,7 @@ pub const FormData = struct { wrap.form.appendBlob(wrap.globalThis, &key, &blob, &filename); } else { - var value = bun.JSC.ZigString.initUTF8(value_str); + var value = JSC.ZigString.initUTF8(value_str); wrap.form.append(&key, &value); } } |