fetch with body

This commit is contained in:
Karl Seguin
2025-12-04 16:10:56 +08:00
parent aa3a402f70
commit ff9f9bae1d
3 changed files with 27 additions and 12 deletions

View File

@@ -69,7 +69,8 @@ pub fn init(input: Input, options: ?InitOpts, page: *Page) !js.Promise {
try http_client.request(.{ try http_client.request(.{
.ctx = fetch, .ctx = fetch,
.url = request._url, .url = request._url,
.method = .GET, .method = request._method,
.body = request._body,
.headers = headers, .headers = headers,
.resource_type = .fetch, .resource_type = .fetch,
.cookie_jar = &page._session.cookie_jar, .cookie_jar = &page._session.cookie_jar,

View File

@@ -19,6 +19,7 @@
const std = @import("std"); const std = @import("std");
const js = @import("../../js/js.zig"); const js = @import("../../js/js.zig");
const Http = @import("../../../http/Http.zig");
const URL = @import("../URL.zig"); const URL = @import("../URL.zig");
const Page = @import("../../Page.zig"); const Page = @import("../../Page.zig");
@@ -28,8 +29,9 @@ const Allocator = std.mem.Allocator;
const Request = @This(); const Request = @This();
_url: [:0]const u8, _url: [:0]const u8,
_method: std.http.Method, _method: Http.Method,
_headers: ?*Headers, _headers: ?*Headers,
_body: ?[]const u8,
_arena: Allocator, _arena: Allocator,
pub const Input = union(enum) { pub const Input = union(enum) {
@@ -40,6 +42,7 @@ pub const Input = union(enum) {
pub const InitOpts = struct { pub const InitOpts = struct {
method: ?[]const u8 = null, method: ?[]const u8 = null,
headers: ?Headers.InitOpts = null, headers: ?Headers.InitOpts = null,
body: ?[]const u8 = null,
}; };
pub fn init(input: Input, opts_: ?InitOpts, page: *Page) !*Request { pub fn init(input: Input, opts_: ?InitOpts, page: *Page) !*Request {
@@ -65,30 +68,39 @@ pub fn init(input: Input, opts_: ?InitOpts, page: *Page) !*Request {
.request => |r| r._headers, .request => |r| r._headers,
}; };
const body = if (opts.body) |b|
try arena.dupe(u8, b)
else switch (input) {
.url => null,
.request => |r| r._body,
};
return page._factory.create(Request{ return page._factory.create(Request{
._url = url, ._url = url,
._arena = arena, ._arena = arena,
._method = method, ._method = method,
._headers = headers, ._headers = headers,
._body = body,
}); });
} }
fn parseMethod(method: []const u8, page: *Page) !std.http.Method { fn parseMethod(method: []const u8, page: *Page) !Http.Method {
if (method.len > "options".len) { if (method.len > "options".len) {
return error.InvalidMethod; return error.InvalidMethod;
} }
const lower = std.ascii.lowerString(&page.buf, method); const lower = std.ascii.lowerString(&page.buf, method);
if (std.mem.eql(u8, lower, "get")) return .GET; const method_lookup = std.StaticStringMap(Http.Method).initComptime(.{
if (std.mem.eql(u8, lower, "post")) return .POST; .{ "get", .GET },
if (std.mem.eql(u8, lower, "delete")) return .DELETE; .{ "post", .POST },
if (std.mem.eql(u8, lower, "put")) return .PUT; .{ "delete", .DELETE },
if (std.mem.eql(u8, lower, "patch")) return .PATCH; .{ "put", .PUT },
if (std.mem.eql(u8, lower, "head")) return .HEAD; .{ "patch", .PATCH },
if (std.mem.eql(u8, lower, "options")) return .OPTIONS; .{ "head", .HEAD },
.{ "options", .OPTIONS },
return error.InvalidMethod; });
return method_lookup.get(lower) orelse return error.InvalidMethod;
} }
pub fn getUrl(self: *const Request) []const u8 { pub fn getUrl(self: *const Request) []const u8 {

View File

@@ -222,6 +222,7 @@ pub const Connection = struct {
.DELETE => "DELETE", .DELETE => "DELETE",
.HEAD => "HEAD", .HEAD => "HEAD",
.OPTIONS => "OPTIONS", .OPTIONS => "OPTIONS",
.PATCH => "PATCH",
}; };
try errorCheck(c.curl_easy_setopt(easy, c.CURLOPT_CUSTOMREQUEST, m.ptr)); try errorCheck(c.curl_easy_setopt(easy, c.CURLOPT_CUSTOMREQUEST, m.ptr));
} }
@@ -360,6 +361,7 @@ pub const Method = enum(u8) {
DELETE = 3, DELETE = 3,
HEAD = 4, HEAD = 4,
OPTIONS = 5, OPTIONS = 5,
PATCH = 6,
}; };
// TODO: on BSD / Linux, we could just read the PEM file directly. // TODO: on BSD / Linux, we could just read the PEM file directly.