diff --git a/src/browser/storage/cookie.zig b/src/browser/storage/cookie.zig index bdd93e3f..1b565046 100644 --- a/src/browser/storage/cookie.zig +++ b/src/browser/storage/cookie.zig @@ -32,6 +32,13 @@ pub const Jar = struct { self.cookies.deinit(self.allocator); } + pub fn clear(self: *Jar) void { + for (self.cookies.items) |c| { + c.deinit(); + } + self.cookies.clearRetainingCapacity(); + } + pub fn add( self: *Jar, cookie: Cookie, @@ -173,43 +180,43 @@ pub const Jar = struct { } }; -pub const CookieList = struct { - _cookies: std.ArrayListUnmanaged(*const Cookie) = .{}, +// pub const CookieList = struct { +// _cookies: std.ArrayListUnmanaged(*const Cookie) = .{}, - pub fn deinit(self: *CookieList, allocator: Allocator) void { - self._cookies.deinit(allocator); - } +// pub fn deinit(self: *CookieList, allocator: Allocator) void { +// self._cookies.deinit(allocator); +// } - pub fn cookies(self: *const CookieList) []*const Cookie { - return self._cookies.items; - } +// pub fn cookies(self: *const CookieList) []*const Cookie { +// return self._cookies.items; +// } - pub fn len(self: *const CookieList) usize { - return self._cookies.items.len; - } +// pub fn len(self: *const CookieList) usize { +// return self._cookies.items.len; +// } - pub fn write(self: *const CookieList, writer: anytype) !void { - const all = self._cookies.items; - if (all.len == 0) { - return; - } - try writeCookie(all[0], writer); - for (all[1..]) |cookie| { - try writer.writeAll("; "); - try writeCookie(cookie, writer); - } - } +// pub fn write(self: *const CookieList, writer: anytype) !void { +// const all = self._cookies.items; +// if (all.len == 0) { +// return; +// } +// try writeCookie(all[0], writer); +// for (all[1..]) |cookie| { +// try writer.writeAll("; "); +// try writeCookie(cookie, writer); +// } +// } - fn writeCookie(cookie: *const Cookie, writer: anytype) !void { - if (cookie.name.len > 0) { - try writer.writeAll(cookie.name); - try writer.writeByte('='); - } - if (cookie.value.len > 0) { - try writer.writeAll(cookie.value); - } - } -}; +// fn writeCookie(cookie: *const Cookie, writer: anytype) !void { +// if (cookie.name.len > 0) { +// try writer.writeAll(cookie.name); +// try writer.writeByte('='); +// } +// if (cookie.value.len > 0) { +// try writer.writeAll(cookie.value); +// } +// } +// }; fn isCookieExpired(cookie: *const Cookie, now: i64) bool { const ce = cookie.expires orelse return false; @@ -660,39 +667,39 @@ test "Jar: forRequest" { // the 'global2' cookie } -test "CookieList: write" { - var arr: std.ArrayListUnmanaged(u8) = .{}; - defer arr.deinit(testing.allocator); +// test "CookieList: write" { +// var arr: std.ArrayListUnmanaged(u8) = .{}; +// defer arr.deinit(testing.allocator); - var cookie_list = CookieList{}; - defer cookie_list.deinit(testing.allocator); +// var cookie_list = CookieList{}; +// defer cookie_list.deinit(testing.allocator); - const c1 = try Cookie.parse(testing.allocator, &test_uri, "cookie_name=cookie_value"); - defer c1.deinit(); - { - try cookie_list._cookies.append(testing.allocator, &c1); - try cookie_list.write(arr.writer(testing.allocator)); - try testing.expectEqual("cookie_name=cookie_value", arr.items); - } +// const c1 = try Cookie.parse(testing.allocator, &test_uri, "cookie_name=cookie_value"); +// defer c1.deinit(); +// { +// try cookie_list._cookies.append(testing.allocator, &c1); +// try cookie_list.write(arr.writer(testing.allocator)); +// try testing.expectEqual("cookie_name=cookie_value", arr.items); +// } - const c2 = try Cookie.parse(testing.allocator, &test_uri, "x84"); - defer c2.deinit(); - { - arr.clearRetainingCapacity(); - try cookie_list._cookies.append(testing.allocator, &c2); - try cookie_list.write(arr.writer(testing.allocator)); - try testing.expectEqual("cookie_name=cookie_value; x84", arr.items); - } +// const c2 = try Cookie.parse(testing.allocator, &test_uri, "x84"); +// defer c2.deinit(); +// { +// arr.clearRetainingCapacity(); +// try cookie_list._cookies.append(testing.allocator, &c2); +// try cookie_list.write(arr.writer(testing.allocator)); +// try testing.expectEqual("cookie_name=cookie_value; x84", arr.items); +// } - const c3 = try Cookie.parse(testing.allocator, &test_uri, "nope="); - defer c3.deinit(); - { - arr.clearRetainingCapacity(); - try cookie_list._cookies.append(testing.allocator, &c3); - try cookie_list.write(arr.writer(testing.allocator)); - try testing.expectEqual("cookie_name=cookie_value; x84; nope=", arr.items); - } -} +// const c3 = try Cookie.parse(testing.allocator, &test_uri, "nope="); +// defer c3.deinit(); +// { +// arr.clearRetainingCapacity(); +// try cookie_list._cookies.append(testing.allocator, &c3); +// try cookie_list.write(arr.writer(testing.allocator)); +// try testing.expectEqual("cookie_name=cookie_value; x84; nope=", arr.items); +// } +// } test "Cookie: parse key=value" { try expectError(error.Empty, null, ""); diff --git a/src/cdp/domains/network.zig b/src/cdp/domains/network.zig index a161f589..db3b2392 100644 --- a/src/cdp/domains/network.zig +++ b/src/cdp/domains/network.zig @@ -28,6 +28,7 @@ pub fn processMessage(cmd: anytype) !void { disable, setCacheDisabled, setExtraHTTPHeaders, + deleteCookies, }, cmd.input.action) orelse return error.UnknownMethod; switch (action) { @@ -35,6 +36,7 @@ pub fn processMessage(cmd: anytype) !void { .disable => return disable(cmd), .setCacheDisabled => return cmd.sendResult(null, .{}), .setExtraHTTPHeaders => return setExtraHTTPHeaders(cmd), + .deleteCookies => return deleteCookies(cmd), } } @@ -71,6 +73,52 @@ fn setExtraHTTPHeaders(cmd: anytype) !void { 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. // 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 {