mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-10-29 15:13:28 +00:00
proper fetch method and body setting
This commit is contained in:
@@ -38,8 +38,8 @@ pub const RequestInput = union(enum) {
|
||||
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/RequestInit
|
||||
pub const RequestInit = struct {
|
||||
method: []const u8 = "GET",
|
||||
body: []const u8 = "",
|
||||
method: ?[]const u8 = null,
|
||||
body: ?[]const u8 = null,
|
||||
};
|
||||
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/Request/Request
|
||||
@@ -47,7 +47,7 @@ const Request = @This();
|
||||
|
||||
method: Http.Method,
|
||||
url: [:0]const u8,
|
||||
body: []const u8,
|
||||
body: ?[]const u8,
|
||||
|
||||
pub fn constructor(input: RequestInput, _options: ?RequestInit, page: *Page) !Request {
|
||||
const arena = page.arena;
|
||||
@@ -62,15 +62,21 @@ pub fn constructor(input: RequestInput, _options: ?RequestInit, page: *Page) !Re
|
||||
},
|
||||
};
|
||||
|
||||
const method: Http.Method = blk: for (std.enums.values(Http.Method)) |method| {
|
||||
if (std.ascii.eqlIgnoreCase(options.method, @tagName(method))) {
|
||||
break :blk method;
|
||||
const method: Http.Method = blk: {
|
||||
if (options.method) |given_method| {
|
||||
for (std.enums.values(Http.Method)) |method| {
|
||||
if (std.ascii.eqlIgnoreCase(given_method, @tagName(method))) {
|
||||
break :blk method;
|
||||
}
|
||||
} else {
|
||||
return error.TypeError;
|
||||
}
|
||||
} else {
|
||||
break :blk Http.Method.GET;
|
||||
}
|
||||
} else {
|
||||
return error.InvalidMethod;
|
||||
};
|
||||
|
||||
const body = try arena.dupe(u8, options.body);
|
||||
const body = if (options.body) |body| try arena.dupe(u8, body) else null;
|
||||
|
||||
return .{
|
||||
.method = method,
|
||||
@@ -87,9 +93,9 @@ pub fn get_method(self: *const Request) []const u8 {
|
||||
return @tagName(self.method);
|
||||
}
|
||||
|
||||
pub fn get_body(self: *const Request) []const u8 {
|
||||
return self.body;
|
||||
}
|
||||
// pub fn get_body(self: *const Request) ?[]const u8 {
|
||||
// return self.body;
|
||||
// }
|
||||
|
||||
const FetchContext = struct {
|
||||
arena: std.mem.Allocator,
|
||||
@@ -123,13 +129,14 @@ pub fn fetch(input: RequestInput, options: ?RequestInit, page: *Page) !Env.Promi
|
||||
const arena = page.arena;
|
||||
|
||||
const req = try Request.constructor(input, options, page);
|
||||
|
||||
const resolver = Env.PromiseResolver{
|
||||
.js_context = page.main_context,
|
||||
.resolver = v8.PromiseResolver.init(page.main_context.v8_context),
|
||||
};
|
||||
|
||||
const client = page.http_client;
|
||||
const headers = try HttpClient.Headers.init();
|
||||
var headers = try Http.Headers.init();
|
||||
try page.requestCookie(.{}).headersForRequest(arena, req.url, &headers);
|
||||
|
||||
const fetch_ctx = try arena.create(FetchContext);
|
||||
fetch_ctx.* = .{
|
||||
@@ -143,47 +150,51 @@ pub fn fetch(input: RequestInput, options: ?RequestInit, page: *Page) !Env.Promi
|
||||
.url = req.url,
|
||||
};
|
||||
|
||||
try client.request(.{
|
||||
.method = req.method,
|
||||
try page.http_client.request(.{
|
||||
.ctx = @ptrCast(fetch_ctx),
|
||||
.url = req.url,
|
||||
.method = req.method,
|
||||
.headers = headers,
|
||||
.body = req.body,
|
||||
.cookie_jar = page.cookie_jar,
|
||||
.ctx = @ptrCast(fetch_ctx),
|
||||
.resource_type = .fetch,
|
||||
|
||||
.start_callback = struct {
|
||||
fn startCallback(transfer: *HttpClient.Transfer) !void {
|
||||
const self: *FetchContext = @alignCast(@ptrCast(transfer.ctx));
|
||||
log.debug(.http, "request start", .{ .method = self.method, .url = self.url, .source = "fetch" });
|
||||
|
||||
self.transfer = transfer;
|
||||
}
|
||||
}.startCallback,
|
||||
.header_callback = struct {
|
||||
fn headerCallback(transfer: *HttpClient.Transfer, header: []const u8) !void {
|
||||
const self: *FetchContext = @alignCast(@ptrCast(transfer.ctx));
|
||||
try self.headers.append(self.arena, try self.arena.dupe(u8, header));
|
||||
}
|
||||
}.headerCallback,
|
||||
.header_done_callback = struct {
|
||||
fn headerDoneCallback(transfer: *HttpClient.Transfer) !void {
|
||||
fn headerCallback(transfer: *HttpClient.Transfer) !void {
|
||||
const self: *FetchContext = @alignCast(@ptrCast(transfer.ctx));
|
||||
|
||||
const header = &transfer.response_header.?;
|
||||
|
||||
log.debug(.http, "request header", .{
|
||||
.source = "fetch",
|
||||
.method = self.method,
|
||||
.url = self.url,
|
||||
.status = header.status,
|
||||
});
|
||||
|
||||
if (header.contentType()) |ct| {
|
||||
self.mime = Mime.parse(ct) catch {
|
||||
return error.Todo;
|
||||
return error.MimeParsing;
|
||||
};
|
||||
}
|
||||
|
||||
var it = transfer.responseHeaderIterator();
|
||||
while (it.next()) |hdr| {
|
||||
const joined = try std.fmt.allocPrint(self.arena, "{s}: {s}", .{ hdr.name, hdr.value });
|
||||
try self.headers.append(self.arena, joined);
|
||||
}
|
||||
|
||||
self.status = header.status;
|
||||
}
|
||||
}.headerDoneCallback,
|
||||
}.headerCallback,
|
||||
.data_callback = struct {
|
||||
fn dataCallback(transfer: *HttpClient.Transfer, data: []const u8) !void {
|
||||
const self: *FetchContext = @alignCast(@ptrCast(transfer.ctx));
|
||||
@@ -196,6 +207,7 @@ pub fn fetch(input: RequestInput, options: ?RequestInit, page: *Page) !Env.Promi
|
||||
|
||||
log.info(.http, "request complete", .{
|
||||
.source = "fetch",
|
||||
.method = self.method,
|
||||
.url = self.url,
|
||||
.status = self.status,
|
||||
});
|
||||
@@ -212,6 +224,8 @@ pub fn fetch(input: RequestInput, options: ?RequestInit, page: *Page) !Env.Promi
|
||||
.error_callback = struct {
|
||||
fn errorCallback(ctx: *anyopaque, err: anyerror) void {
|
||||
const self: *FetchContext = @alignCast(@ptrCast(ctx));
|
||||
|
||||
self.transfer = null;
|
||||
const promise_resolver: Env.PromiseResolver = .{
|
||||
.js_context = self.js_ctx,
|
||||
.resolver = self.promise_resolver.castToPromiseResolver(),
|
||||
|
||||
@@ -19,6 +19,9 @@
|
||||
const std = @import("std");
|
||||
const URL = @import("../../url.zig").URL;
|
||||
const Page = @import("../page.zig").Page;
|
||||
const Env = @import("../env.zig").Env;
|
||||
|
||||
const v8 = @import("v8");
|
||||
|
||||
const Http = @import("../../http/Http.zig");
|
||||
const HttpClient = @import("../../http/Client.zig");
|
||||
@@ -36,13 +39,26 @@ const ResponseInput = union(enum) {
|
||||
string: []const u8,
|
||||
};
|
||||
|
||||
pub fn constructor(input: ResponseInput, page: *Page) !Response {
|
||||
const ResponseOptions = struct {
|
||||
status: u16 = 200,
|
||||
statusText: []const u8 = "",
|
||||
// List of header pairs.
|
||||
headers: []const []const u8 = &[][].{},
|
||||
};
|
||||
|
||||
pub fn constructor(_input: ?ResponseInput, page: *Page) !Response {
|
||||
const arena = page.arena;
|
||||
|
||||
const body = blk: switch (input) {
|
||||
.string => |str| {
|
||||
break :blk try arena.dupe(u8, str);
|
||||
},
|
||||
const body = blk: {
|
||||
if (_input) |input| {
|
||||
switch (input) {
|
||||
.string => |str| {
|
||||
break :blk try arena.dupe(u8, str);
|
||||
},
|
||||
}
|
||||
} else {
|
||||
break :blk "";
|
||||
}
|
||||
};
|
||||
|
||||
return .{
|
||||
@@ -55,6 +71,16 @@ pub fn get_ok(self: *const Response) bool {
|
||||
return self.status >= 200 and self.status <= 299;
|
||||
}
|
||||
|
||||
pub fn _text(self: *const Response, page: *Page) !Env.Promise {
|
||||
const resolver = Env.PromiseResolver{
|
||||
.js_context = page.main_context,
|
||||
.resolver = v8.PromiseResolver.init(page.main_context.v8_context),
|
||||
};
|
||||
|
||||
try resolver.resolve(self.body);
|
||||
return resolver.promise();
|
||||
}
|
||||
|
||||
const testing = @import("../../testing.zig");
|
||||
test "fetch: response" {
|
||||
var runner = try testing.jsRunner(testing.tracking_allocator, .{ .url = "https://lightpanda.io" });
|
||||
|
||||
@@ -200,6 +200,7 @@ pub fn requestIntercept(arena: Allocator, bc: anytype, intercept: *const Notific
|
||||
.script => "Script",
|
||||
.xhr => "XHR",
|
||||
.document => "Document",
|
||||
.fetch => "Fetch",
|
||||
},
|
||||
.networkId = try std.fmt.allocPrint(arena, "REQ-{d}", .{transfer.id}),
|
||||
}, .{ .session_id = session_id });
|
||||
|
||||
@@ -649,6 +649,7 @@ pub const Request = struct {
|
||||
document,
|
||||
xhr,
|
||||
script,
|
||||
fetch,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user