aboutsummaryrefslogtreecommitdiff
path: root/src/bun.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/bun.js')
-rw-r--r--src/bun.js/bindings/URLSearchParams.cpp24
-rw-r--r--src/bun.js/bindings/bindings.zig40
-rw-r--r--src/bun.js/webcore/blob.zig28
-rw-r--r--src/bun.js/webcore/body.zig6
-rw-r--r--src/bun.js/webcore/request.zig15
-rw-r--r--src/bun.js/webcore/response.zig18
6 files changed, 131 insertions, 0 deletions
diff --git a/src/bun.js/bindings/URLSearchParams.cpp b/src/bun.js/bindings/URLSearchParams.cpp
index 9c168b4f6..2b0ffef67 100644
--- a/src/bun.js/bindings/URLSearchParams.cpp
+++ b/src/bun.js/bindings/URLSearchParams.cpp
@@ -26,9 +26,33 @@
#include "DOMURL.h"
#include "wtf/URLParser.h"
+#include "helpers.h"
+#include "JSURLSearchParams.h"
namespace WebCore {
+extern "C" JSC::EncodedJSValue URLSearchParams__create(JSDOMGlobalObject* globalObject, const ZigString* input)
+{
+ String str = Zig::toString(*input);
+ auto result = URLSearchParams::create(str, nullptr);
+ return JSC::JSValue::encode(WebCore::toJSNewlyCreated(globalObject, globalObject, WTFMove(result)));
+}
+
+extern "C" WebCore::URLSearchParams* URLSearchParams__fromJS(JSC::EncodedJSValue value)
+{
+ return WebCoreCast<WebCore::JSURLSearchParams, WebCore::URLSearchParams>(value);
+}
+
+// callback accepting a void* and a const ZigString*, returning void
+typedef void (*URLSearchParams__toStringCallback)(void* ctx, const ZigString* str);
+
+extern "C" void URLSearchParams__toString(WebCore::URLSearchParams* urlSearchParams, void* ctx, URLSearchParams__toStringCallback callback)
+{
+ String str = urlSearchParams->toString();
+ auto zig = Zig::toZigString(str);
+ callback(ctx, &zig);
+}
+
URLSearchParams::URLSearchParams(const String& init, DOMURL* associatedURL)
: m_associatedURL(associatedURL)
, m_pairs(init.startsWith('?') ? WTF::URLParser::parseURLEncodedForm(StringView(init).substring(1)) : WTF::URLParser::parseURLEncodedForm(init))
diff --git a/src/bun.js/bindings/bindings.zig b/src/bun.js/bindings/bindings.zig
index d0ccacd06..4c1469564 100644
--- a/src/bun.js/bindings/bindings.zig
+++ b/src/bun.js/bindings/bindings.zig
@@ -4365,6 +4365,46 @@ pub fn untrackFunction(
return private.Bun__untrackFFIFunction(globalObject, value);
}
+pub const URLSearchParams = opaque {
+ extern fn URLSearchParams__create(globalObject: *JSGlobalObject, *const ZigString) JSValue;
+ pub fn create(globalObject: *JSGlobalObject, init: ZigString) JSValue {
+ JSC.markBinding(@src());
+ return URLSearchParams__create(globalObject, &init);
+ }
+
+ extern fn URLSearchParams__fromJS(JSValue) ?*URLSearchParams;
+ pub fn fromJS(value: JSValue) ?*URLSearchParams {
+ JSC.markBinding(@src());
+ return URLSearchParams__fromJS(value);
+ }
+
+ extern fn URLSearchParams__toString(
+ self: *URLSearchParams,
+ ctx: *anyopaque,
+ callback: *const fn (ctx: *anyopaque, str: *const ZigString) void,
+ ) void;
+
+ pub fn toString(
+ self: *URLSearchParams,
+ comptime Ctx: type,
+ ctx: *Ctx,
+ comptime callback: *const fn (ctx: *Ctx, str: ZigString) void,
+ ) void {
+ JSC.markBinding(@src());
+ const Wrap = struct {
+ const cb_ = callback;
+ pub fn cb(c: *anyopaque, str: *const ZigString) void {
+ cb_(
+ bun.cast(*Ctx, c),
+ str.*,
+ );
+ }
+ };
+
+ URLSearchParams__toString(self, ctx, Wrap.cb);
+ }
+};
+
pub const WTF = struct {
extern fn WTF__copyLCharsFromUCharSource(dest: [*]u8, source: *const anyopaque, len: usize) void;
extern fn WTF__toBase64URLStringValue(bytes: [*]const u8, length: usize, globalObject: *JSGlobalObject) JSValue;
diff --git a/src/bun.js/webcore/blob.zig b/src/bun.js/webcore/blob.zig
index a1b848397..de0ec1cb2 100644
--- a/src/bun.js/webcore/blob.zig
+++ b/src/bun.js/webcore/blob.zig
@@ -196,6 +196,34 @@ pub const Blob = struct {
return null;
}
+ const URLSearchParamsConverter = struct {
+ allocator: std.mem.Allocator,
+ buf: []u8 = "",
+ globalThis: *JSC.JSGlobalObject,
+ pub fn convert(this: *URLSearchParamsConverter, str: ZigString) void {
+ var out = str.toSlice(this.allocator).cloneIfNeeded(this.allocator) catch unreachable;
+ this.buf = bun.constStrToU8(out.slice());
+ }
+ };
+
+ pub fn fromURLSearchParams(
+ globalThis: *JSC.JSGlobalObject,
+ allocator: std.mem.Allocator,
+ search_params: *JSC.URLSearchParams,
+ ) Blob {
+ var converter = URLSearchParamsConverter{
+ .allocator = allocator,
+ .globalThis = globalThis,
+ };
+ search_params.toString(URLSearchParamsConverter, &converter, URLSearchParamsConverter.convert);
+ var store = Blob.Store.init(converter.buf, allocator) catch unreachable;
+ store.mime_type = MimeType.all.@"application/x-www-form-urlencoded";
+
+ var blob = Blob.initWithStore(store, globalThis);
+ blob.content_type = store.mime_type.value;
+ return blob;
+ }
+
pub fn fromDOMFormData(
globalThis: *JSC.JSGlobalObject,
allocator: std.mem.Allocator,
diff --git a/src/bun.js/webcore/body.zig b/src/bun.js/webcore/body.zig
index b96686265..23f00d16e 100644
--- a/src/bun.js/webcore/body.zig
+++ b/src/bun.js/webcore/body.zig
@@ -558,6 +558,12 @@ pub const Body = struct {
};
}
+ if (value.as(JSC.URLSearchParams)) |search_params| {
+ return Body.Value{
+ .Blob = Blob.fromURLSearchParams(globalThis, globalThis.allocator(), search_params),
+ };
+ }
+
if (js_type == .DOMWrapper) {
if (value.as(Blob)) |blob| {
return Body.Value{
diff --git a/src/bun.js/webcore/request.zig b/src/bun.js/webcore/request.zig
index 1248767c3..fb0e40d2e 100644
--- a/src/bun.js/webcore/request.zig
+++ b/src/bun.js/webcore/request.zig
@@ -422,6 +422,14 @@ pub const Request = struct {
},
}
+ if (request.body == .Blob and
+ request.headers != null and
+ request.body.Blob.content_type.len > 0 and
+ !request.headers.?.fastHas(.ContentType))
+ {
+ request.headers.?.put("content-type", request.body.Blob.content_type);
+ }
+
return request;
}
@@ -462,6 +470,13 @@ pub const Request = struct {
this.headers = FetchHeaders.createFromUWS(globalThis, req);
} else {
this.headers = FetchHeaders.createEmpty();
+
+ if (this.body == .Blob) {
+ const content_type = this.body.Blob.content_type;
+ if (content_type.len > 0) {
+ this.headers.?.put("content-type", content_type);
+ }
+ }
}
}
diff --git a/src/bun.js/webcore/response.zig b/src/bun.js/webcore/response.zig
index 53e1f3fb6..8af1c3958 100644
--- a/src/bun.js/webcore/response.zig
+++ b/src/bun.js/webcore/response.zig
@@ -203,7 +203,15 @@ pub const Response = struct {
fn getOrCreateHeaders(this: *Response) *FetchHeaders {
if (this.body.init.headers == null) {
this.body.init.headers = FetchHeaders.createEmpty();
+
+ if (this.body.value == .Blob) {
+ const content_type = this.body.value.Blob.content_type;
+ if (content_type.len > 0) {
+ this.body.init.headers.?.put("content-type", content_type);
+ }
+ }
}
+
return this.body.init.headers.?;
}
@@ -501,11 +509,21 @@ pub const Response = struct {
}) orelse return null;
var response = getAllocator(globalThis).create(Response) catch unreachable;
+
response.* = Response{
.body = body,
.allocator = getAllocator(globalThis),
.url = "",
};
+
+ if (response.body.value == .Blob and
+ response.body.init.headers != null and
+ response.body.value.Blob.content_type.len > 0 and
+ !response.body.init.headers.?.fastHas(.ContentType))
+ {
+ response.body.init.headers.?.put("content-type", response.body.value.Blob.content_type);
+ }
+
return response;
}
};