deleteCookies

This commit is contained in:
sjorsdonkers
2025-06-11 10:40:26 +02:00
committed by Sjors
parent 9b35736be3
commit 0c6fc68eae
2 changed files with 116 additions and 61 deletions

View File

@@ -32,6 +32,13 @@ pub const Jar = struct {
self.cookies.deinit(self.allocator); self.cookies.deinit(self.allocator);
} }
pub fn clear(self: *Jar) void {
for (self.cookies.items) |c| {
c.deinit();
}
self.cookies.clearRetainingCapacity();
}
pub fn add( pub fn add(
self: *Jar, self: *Jar,
cookie: Cookie, cookie: Cookie,
@@ -173,43 +180,43 @@ pub const Jar = struct {
} }
}; };
pub const CookieList = struct { // pub const CookieList = struct {
_cookies: std.ArrayListUnmanaged(*const Cookie) = .{}, // _cookies: std.ArrayListUnmanaged(*const Cookie) = .{},
pub fn deinit(self: *CookieList, allocator: Allocator) void { // pub fn deinit(self: *CookieList, allocator: Allocator) void {
self._cookies.deinit(allocator); // self._cookies.deinit(allocator);
} // }
pub fn cookies(self: *const CookieList) []*const Cookie { // pub fn cookies(self: *const CookieList) []*const Cookie {
return self._cookies.items; // return self._cookies.items;
} // }
pub fn len(self: *const CookieList) usize { // pub fn len(self: *const CookieList) usize {
return self._cookies.items.len; // return self._cookies.items.len;
} // }
pub fn write(self: *const CookieList, writer: anytype) !void { // pub fn write(self: *const CookieList, writer: anytype) !void {
const all = self._cookies.items; // const all = self._cookies.items;
if (all.len == 0) { // if (all.len == 0) {
return; // return;
} // }
try writeCookie(all[0], writer); // try writeCookie(all[0], writer);
for (all[1..]) |cookie| { // for (all[1..]) |cookie| {
try writer.writeAll("; "); // try writer.writeAll("; ");
try writeCookie(cookie, writer); // try writeCookie(cookie, writer);
} // }
} // }
fn writeCookie(cookie: *const Cookie, writer: anytype) !void { // fn writeCookie(cookie: *const Cookie, writer: anytype) !void {
if (cookie.name.len > 0) { // if (cookie.name.len > 0) {
try writer.writeAll(cookie.name); // try writer.writeAll(cookie.name);
try writer.writeByte('='); // try writer.writeByte('=');
} // }
if (cookie.value.len > 0) { // if (cookie.value.len > 0) {
try writer.writeAll(cookie.value); // try writer.writeAll(cookie.value);
} // }
} // }
}; // };
fn isCookieExpired(cookie: *const Cookie, now: i64) bool { fn isCookieExpired(cookie: *const Cookie, now: i64) bool {
const ce = cookie.expires orelse return false; const ce = cookie.expires orelse return false;
@@ -660,39 +667,39 @@ test "Jar: forRequest" {
// the 'global2' cookie // the 'global2' cookie
} }
test "CookieList: write" { // test "CookieList: write" {
var arr: std.ArrayListUnmanaged(u8) = .{}; // var arr: std.ArrayListUnmanaged(u8) = .{};
defer arr.deinit(testing.allocator); // defer arr.deinit(testing.allocator);
var cookie_list = CookieList{}; // var cookie_list = CookieList{};
defer cookie_list.deinit(testing.allocator); // defer cookie_list.deinit(testing.allocator);
const c1 = try Cookie.parse(testing.allocator, &test_uri, "cookie_name=cookie_value"); // const c1 = try Cookie.parse(testing.allocator, &test_uri, "cookie_name=cookie_value");
defer c1.deinit(); // defer c1.deinit();
{ // {
try cookie_list._cookies.append(testing.allocator, &c1); // try cookie_list._cookies.append(testing.allocator, &c1);
try cookie_list.write(arr.writer(testing.allocator)); // try cookie_list.write(arr.writer(testing.allocator));
try testing.expectEqual("cookie_name=cookie_value", arr.items); // try testing.expectEqual("cookie_name=cookie_value", arr.items);
} // }
const c2 = try Cookie.parse(testing.allocator, &test_uri, "x84"); // const c2 = try Cookie.parse(testing.allocator, &test_uri, "x84");
defer c2.deinit(); // defer c2.deinit();
{ // {
arr.clearRetainingCapacity(); // arr.clearRetainingCapacity();
try cookie_list._cookies.append(testing.allocator, &c2); // try cookie_list._cookies.append(testing.allocator, &c2);
try cookie_list.write(arr.writer(testing.allocator)); // try cookie_list.write(arr.writer(testing.allocator));
try testing.expectEqual("cookie_name=cookie_value; x84", arr.items); // try testing.expectEqual("cookie_name=cookie_value; x84", arr.items);
} // }
const c3 = try Cookie.parse(testing.allocator, &test_uri, "nope="); // const c3 = try Cookie.parse(testing.allocator, &test_uri, "nope=");
defer c3.deinit(); // defer c3.deinit();
{ // {
arr.clearRetainingCapacity(); // arr.clearRetainingCapacity();
try cookie_list._cookies.append(testing.allocator, &c3); // try cookie_list._cookies.append(testing.allocator, &c3);
try cookie_list.write(arr.writer(testing.allocator)); // try cookie_list.write(arr.writer(testing.allocator));
try testing.expectEqual("cookie_name=cookie_value; x84; nope=", arr.items); // try testing.expectEqual("cookie_name=cookie_value; x84; nope=", arr.items);
} // }
} // }
test "Cookie: parse key=value" { test "Cookie: parse key=value" {
try expectError(error.Empty, null, ""); try expectError(error.Empty, null, "");

View File

@@ -28,6 +28,7 @@ pub fn processMessage(cmd: anytype) !void {
disable, disable,
setCacheDisabled, setCacheDisabled,
setExtraHTTPHeaders, setExtraHTTPHeaders,
deleteCookies,
}, cmd.input.action) orelse return error.UnknownMethod; }, cmd.input.action) orelse return error.UnknownMethod;
switch (action) { switch (action) {
@@ -35,6 +36,7 @@ pub fn processMessage(cmd: anytype) !void {
.disable => return disable(cmd), .disable => return disable(cmd),
.setCacheDisabled => return cmd.sendResult(null, .{}), .setCacheDisabled => return cmd.sendResult(null, .{}),
.setExtraHTTPHeaders => return setExtraHTTPHeaders(cmd), .setExtraHTTPHeaders => return setExtraHTTPHeaders(cmd),
.deleteCookies => return deleteCookies(cmd),
} }
} }
@@ -71,6 +73,52 @@ fn setExtraHTTPHeaders(cmd: anytype) !void {
return cmd.sendResult(null, .{}); return cmd.sendResult(null, .{});
} }
// const CookiePartitionKey = struct {
// topLevelSite: []const u8,
// hasCrossSiteAncestor: bool,
// };
const Cookie = @import("../../browser/storage/storage.zig").Cookie;
const CookieJar = @import("../../browser/storage/storage.zig").CookieJar;
fn cookieMatches(cookie: *const Cookie, name: []const u8, url: ?[]const u8, domain: ?[]const u8, path: ?[]const u8) bool {
if (!std.mem.eql(u8, cookie.name, name)) return false;
_ = url; // TODO
if (domain) |domain_| {
if (!std.mem.eql(u8, cookie.domain, domain_)) return false;
}
if (path) |path_| {
if (!std.mem.eql(u8, cookie.path, path_)) return false;
}
return true;
}
fn deleteCookies(cmd: anytype) !void {
const params = (try cmd.params(struct {
name: []const u8,
url: ?[]const u8 = null,
domain: ?[]const u8 = null,
path: ?[]const u8 = null,
// partitionKey: ?CookiePartitionKey,
})) orelse return error.InvalidParams;
const bc = cmd.browser_context orelse return error.BrowserContextNotLoaded;
const cookies = &bc.session.cookie_jar.cookies;
var index = cookies.items.len;
while (index > 0) {
index -= 1;
const cookie = &cookies.items[index];
if (cookieMatches(cookie, params.name, params.url, params.domain, params.path)) {
cookies.swapRemove(index).deinit();
}
}
return cmd.sendResult(null, .{});
}
// Upsert a header into the headers array. // Upsert a header into the headers array.
// returns true if the header was added, false if it was updated // returns true if the header was added, false if it was updated
fn putAssumeCapacity(headers: *std.ArrayListUnmanaged(std.http.Header), extra: std.http.Header) bool { fn putAssumeCapacity(headers: *std.ArrayListUnmanaged(std.http.Header), extra: std.http.Header) bool {