@@ -41,7 +41,7 @@ pub fn processMessage(cmd: anytype) !void {
4141fn clearCookies (cmd : anytype ) ! void {
4242 const bc = cmd .browser_context orelse return error .BrowserContextNotLoaded ;
4343 const params = (try cmd .params (struct {
44- browserContextId : ? []const u8 ,
44+ browserContextId : ? []const u8 = null ,
4545 })) orelse return error .InvalidParams ;
4646
4747 if (params .browserContextId ) | browser_context_id | {
@@ -58,7 +58,7 @@ fn clearCookies(cmd: anytype) !void {
5858fn getCookies (cmd : anytype ) ! void {
5959 const bc = cmd .browser_context orelse return error .BrowserContextNotLoaded ;
6060 const params = (try cmd .params (struct {
61- browserContextId : ? []const u8 ,
61+ browserContextId : ? []const u8 = null ,
6262 })) orelse return error .InvalidParams ;
6363
6464 if (params .browserContextId ) | browser_context_id | {
@@ -75,7 +75,7 @@ fn setCookies(cmd: anytype) !void {
7575 const bc = cmd .browser_context orelse return error .BrowserContextNotLoaded ;
7676 const params = (try cmd .params (struct {
7777 cookies : []const CdpCookie ,
78- browserContextId : ? []const u8 ,
78+ browserContextId : ? []const u8 = null ,
7979 })) orelse return error .InvalidParams ;
8080
8181 if (params .browserContextId ) | browser_context_id | {
@@ -118,7 +118,7 @@ pub const CdpCookie = struct {
118118 url : ? []const u8 = null ,
119119 domain : ? []const u8 = null ,
120120 path : ? []const u8 = null ,
121- secure : bool = false , // default: https://www.rfc-editor.org/rfc/rfc6265#section-5.3
121+ secure : ? bool = null , // default: https://www.rfc-editor.org/rfc/rfc6265#section-5.3
122122 httpOnly : bool = false , // default: https://www.rfc-editor.org/rfc/rfc6265#section-5.3
123123 sameSite : SameSite = .None , // default: https://datatracker.ietf.org/doc/html/draft-west-first-party-cookies
124124 expires : ? i64 = null , // -1? says google
@@ -140,11 +140,13 @@ pub fn setCdpCookie(cookie_jar: *CookieJar, param: CdpCookie) !void {
140140 errdefer arena .deinit ();
141141 const a = arena .allocator ();
142142
143- // NOTE: The param.url can affect the default domain, path, source port, and source scheme.
143+ // NOTE: The param.url can affect the default domain, (NOT path), secure , source port, and source scheme.
144144 const uri = if (param .url ) | url | std .Uri .parse (url ) catch return error .InvalidParams else null ;
145145 const uri_ptr = if (uri ) | * u | u else null ;
146146 const domain = try Cookie .parseDomain (a , uri_ptr , param .domain );
147- const path = try Cookie .parsePath (a , uri_ptr , param .path );
147+ const path = if (param .path == null ) "/" else try Cookie .parsePath (a , null , param .path );
148+
149+ const secure = if (param .secure ) | s | s else if (uri ) | uri_ | std .mem .eql (u8 , uri_ .scheme , "https" ) else false ;
148150
149151 const cookie = Cookie {
150152 .arena = arena ,
@@ -153,7 +155,7 @@ pub fn setCdpCookie(cookie_jar: *CookieJar, param: CdpCookie) !void {
153155 .path = path ,
154156 .domain = domain ,
155157 .expires = param .expires ,
156- .secure = param . secure ,
158+ .secure = secure ,
157159 .http_only = param .httpOnly ,
158160 .same_site = switch (param .sameSite ) {
159161 .Strict = > .strict ,
@@ -181,7 +183,7 @@ pub const CookieWriter = struct {
181183 if (self .urls ) | urls | {
182184 for (self .cookies ) | * cookie | {
183185 for (urls ) | * url | {
184- if (cookie .appliesTo (url , false , false )) { // TBD same_site, should we compare to the pages url?
186+ if (cookie .appliesTo (url , true , true )) { // TBD same_site, should we compare to the pages url?
185187 try writeCookie (cookie , w );
186188 break ;
187189 }
@@ -234,3 +236,69 @@ pub fn writeCookie(cookie: *const Cookie, w: anytype) !void {
234236 }
235237 try w .endObject ();
236238}
239+
240+ const testing = @import ("../testing.zig" );
241+
242+ test "cdp.Storage: cookies" {
243+ var ctx = testing .context ();
244+ defer ctx .deinit ();
245+ _ = try ctx .loadBrowserContext (.{ .id = "BID-S" });
246+
247+ // Initially empty
248+ try ctx .processMessage (.{
249+ .id = 3 ,
250+ .method = "Storage.getCookies" ,
251+ .params = .{ .browserContextId = "BID-S" },
252+ });
253+ try ctx .expectSentResult (.{ .cookies = &[_ ]ResCookie {} }, .{ .id = 3 });
254+
255+ // Has cookies after setting them
256+ try ctx .processMessage (.{
257+ .id = 4 ,
258+ .method = "Storage.setCookies" ,
259+ .params = .{
260+ .cookies = &[_ ]CdpCookie {
261+ .{ .name = "test" , .value = "value" , .domain = "example.com" , .path = "/mango" },
262+ .{ .name = "test2" , .value = "value2" , .url = "https://car.example.com/pancakes" },
263+ },
264+ .browserContextId = "BID-S" ,
265+ },
266+ });
267+ try ctx .expectSentResult (null , .{ .id = 4 });
268+ try ctx .processMessage (.{
269+ .id = 5 ,
270+ .method = "Storage.getCookies" ,
271+ .params = .{ .browserContextId = "BID-S" },
272+ });
273+ try ctx .expectSentResult (.{
274+ .cookies = &[_ ]ResCookie {
275+ .{ .name = "test" , .value = "value" , .domain = ".example.com" , .path = "/mango" },
276+ .{ .name = "test2" , .value = "value2" , .domain = "car.example.com" , .path = "/" , .secure = true }, // No Pancakes!
277+ },
278+ }, .{ .id = 5 });
279+
280+ // Empty after clearing cookies
281+ try ctx .processMessage (.{
282+ .id = 6 ,
283+ .method = "Storage.clearCookies" ,
284+ .params = .{ .browserContextId = "BID-S" },
285+ });
286+ try ctx .expectSentResult (null , .{ .id = 6 });
287+ try ctx .processMessage (.{
288+ .id = 7 ,
289+ .method = "Storage.getCookies" ,
290+ .params = .{ .browserContextId = "BID-S" },
291+ });
292+ try ctx .expectSentResult (.{ .cookies = &[_ ]ResCookie {} }, .{ .id = 7 });
293+ }
294+
295+ pub const ResCookie = struct {
296+ name : []const u8 ,
297+ value : []const u8 ,
298+ domain : []const u8 ,
299+ path : []const u8 = "/" ,
300+ expires : i32 = -1 ,
301+ httpOnly : bool = false ,
302+ secure : bool = false ,
303+ sameSite : []const u8 = "None" ,
304+ };
0 commit comments