Remove std.Uri from cookies

Everything now works on a [:0]const u8, with browser/URL.zig for parsing
This commit is contained in:
Karl Seguin
2025-12-08 16:23:19 +08:00
parent 0beae3b1a6
commit 121c49e9c3
8 changed files with 485 additions and 525 deletions

View File

@@ -208,7 +208,7 @@ pub fn requestIntercept(arena: Allocator, bc: anytype, intercept: *const Notific
log.debug(.cdp, "request intercept", .{
.state = "paused",
.id = transfer.id,
.url = transfer.uri,
.url = transfer.url,
});
// Await either continueRequest, failRequest or fulfillRequest
@@ -237,7 +237,7 @@ fn continueRequest(cmd: anytype) !void {
log.debug(.cdp, "request intercept", .{
.state = "continue",
.id = transfer.id,
.url = transfer.uri,
.url = transfer.url,
.new_url = params.url,
});
@@ -342,7 +342,7 @@ fn fulfillRequest(cmd: anytype) !void {
log.debug(.cdp, "request intercept", .{
.state = "fulfilled",
.id = transfer.id,
.url = transfer.uri,
.url = transfer.url,
.status = params.responseCode,
.body = params.body != null,
});
@@ -376,7 +376,7 @@ fn failRequest(cmd: anytype) !void {
log.info(.cdp, "request intercept", .{
.state = "fail",
.id = request_id,
.url = transfer.uri,
.url = transfer.url,
.reason = params.errorReason,
});
return cmd.sendResult(null, .{});
@@ -420,7 +420,7 @@ pub fn requestAuthRequired(arena: Allocator, bc: anytype, intercept: *const Noti
log.debug(.cdp, "request auth required", .{
.state = "paused",
.id = transfer.id,
.url = transfer.uri,
.url = transfer.url,
});
// Await continueWithAuth

View File

@@ -20,6 +20,7 @@ const std = @import("std");
const Allocator = std.mem.Allocator;
const CdpStorage = @import("storage.zig");
const URL = @import("../../browser/URL.zig");
const Transfer = @import("../../http/Client.zig").Transfer;
const Notification = @import("../../Notification.zig");
@@ -107,7 +108,7 @@ fn cookieMatches(cookie: *const Cookie, name: []const u8, domain: ?[]const u8, p
fn deleteCookies(cmd: anytype) !void {
const params = (try cmd.params(struct {
name: []const u8,
url: ?[]const u8 = null,
url: ?[:0]const u8 = null,
domain: ?[]const u8 = null,
path: ?[]const u8 = null,
partitionKey: ?CdpStorage.CookiePartitionKey = null,
@@ -117,15 +118,12 @@ fn deleteCookies(cmd: anytype) !void {
const bc = cmd.browser_context orelse return error.BrowserContextNotLoaded;
const cookies = &bc.session.cookie_jar.cookies;
const uri = if (params.url) |url| std.Uri.parse(url) catch return error.InvalidParams else null;
const uri_ptr = if (uri) |u| &u else null;
var index = cookies.items.len;
while (index > 0) {
index -= 1;
const cookie = &cookies.items[index];
const domain = try Cookie.parseDomain(cmd.arena, uri_ptr, params.domain);
const path = try Cookie.parsePath(cmd.arena, uri_ptr, params.path);
const domain = try Cookie.parseDomain(cmd.arena, params.url, params.domain);
const path = try Cookie.parsePath(cmd.arena, params.url, params.path);
// We do not want to use Cookie.appliesTo here. As a Cookie with a shorter path would match.
// Similar to deduplicating with areCookiesEqual, except domain and path are optional.
@@ -167,23 +165,23 @@ fn setCookies(cmd: anytype) !void {
try cmd.sendResult(null, .{});
}
const GetCookiesParam = struct { urls: ?[]const []const u8 = null };
const GetCookiesParam = struct {
urls: ?[]const [:0]const u8 = null,
};
fn getCookies(cmd: anytype) !void {
const bc = cmd.browser_context orelse return error.BrowserContextNotLoaded;
const params = (try cmd.params(GetCookiesParam)) orelse GetCookiesParam{};
// If not specified, use the URLs of the page and all of its subframes. TODO subframes
const page_url = if (bc.session.page) |page| page.url else null;
const param_urls = params.urls orelse &[_][]const u8{page_url orelse return error.InvalidParams};
const param_urls = params.urls orelse &[_][:0]const u8{page_url orelse return error.InvalidParams};
var urls = try std.ArrayListUnmanaged(CdpStorage.PreparedUri).initCapacity(cmd.arena, param_urls.len);
for (param_urls) |url| {
const uri = std.Uri.parse(url) catch return error.InvalidParams;
urls.appendAssumeCapacity(.{
.host = try Cookie.parseDomain(cmd.arena, &uri, null),
.path = try Cookie.parsePath(cmd.arena, &uri, null),
.secure = std.mem.eql(u8, uri.scheme, "https"),
.host = try Cookie.parseDomain(cmd.arena, url, null),
.path = try Cookie.parsePath(cmd.arena, url, null),
.secure = URL.isHTTPS(url),
});
}
@@ -300,23 +298,19 @@ pub const TransferAsRequestWriter = struct {
try jws.objectField("url");
try jws.beginWriteRaw();
try writer.writeByte('\"');
try transfer.uri.writeToStream(writer, .{
.scheme = true,
.authentication = true,
.authority = true,
.path = true,
.query = true,
});
// #ZIGDOM shouldn't include the hash?
try writer.writeAll(transfer.url);
try writer.writeByte('\"');
jws.endWriteRaw();
}
{
if (transfer.uri.fragment) |frag| {
const frag = URL.getHash(transfer.url);
if (frag.len > 0) {
try jws.objectField("urlFragment");
try jws.beginWriteRaw();
try writer.writeAll("\"#");
try writer.writeAll(frag.percent_encoded);
try writer.writeAll(frag);
try writer.writeByte('\"');
jws.endWriteRaw();
}
@@ -370,13 +364,8 @@ const TransferAsResponseWriter = struct {
try jws.objectField("url");
try jws.beginWriteRaw();
try writer.writeByte('\"');
try transfer.uri.writeToStream(writer, .{
.scheme = true,
.authentication = true,
.authority = true,
.path = true,
.query = true,
});
// #ZIGDOM shouldn't include the hash?
try writer.writeAll(transfer.url);
try writer.writeByte('\"');
jws.endWriteRaw();
}

View File

@@ -19,9 +19,10 @@
const std = @import("std");
const log = @import("../../log.zig");
const URL = @import("../../browser/URL.zig");
const Cookie = @import("../../browser/webapi/storage/storage.zig").Cookie;
const CookieJar = @import("../../browser/webapi/storage/storage.zig").Jar;
pub const PreparedUri = @import("../../browser/webapi/storage/cookie.zig").PreparedUri;
const CookieJar = Cookie.Jar;
pub const PreparedUri = Cookie.PreparedUri;
pub fn processMessage(cmd: anytype) !void {
const action = std.meta.stringToEnum(enum {
@@ -112,9 +113,9 @@ pub const CookiePartitionKey = struct {
pub const CdpCookie = struct {
name: []const u8,
value: []const u8,
url: ?[]const u8 = null,
url: ?[:0]const u8 = null,
domain: ?[]const u8 = null,
path: ?[]const u8 = null,
path: ?[:0]const u8 = null,
secure: ?bool = null, // default: https://www.rfc-editor.org/rfc/rfc6265#section-5.3
httpOnly: bool = false, // default: https://www.rfc-editor.org/rfc/rfc6265#section-5.3
sameSite: SameSite = .None, // default: https://datatracker.ietf.org/doc/html/draft-west-first-party-cookies
@@ -136,12 +137,10 @@ pub fn setCdpCookie(cookie_jar: *CookieJar, param: CdpCookie) !void {
const a = arena.allocator();
// NOTE: The param.url can affect the default domain, (NOT path), secure, source port, and source scheme.
const uri = if (param.url) |url| std.Uri.parse(url) catch return error.InvalidParams else null;
const uri_ptr = if (uri) |*u| u else null;
const domain = try Cookie.parseDomain(a, uri_ptr, param.domain);
const domain = try Cookie.parseDomain(a, param.url, param.domain);
const path = if (param.path == null) "/" else try Cookie.parsePath(a, null, param.path);
const secure = if (param.secure) |s| s else if (uri) |uri_| std.mem.eql(u8, uri_.scheme, "https") else false;
const secure = if (param.secure) |s| s else if (param.url) |url| URL.isHTTPS(url) else false;
const cookie = Cookie{
.arena = arena,