Skip to content

Commit 25dcae7

Browse files
authored
Merge pull request #529 from lightpanda-io/document-cookie
Document cookie
2 parents 9b6764a + ee6382e commit 25dcae7

File tree

2 files changed

+39
-21
lines changed

2 files changed

+39
-21
lines changed

src/html/document.zig

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ const Location = @import("location.zig").Location;
3333
const collection = @import("../dom/html_collection.zig");
3434
const Walker = @import("../dom/walker.zig").WalkerDepthFirst;
3535

36+
const UserContext = @import("../user_context.zig").UserContext;
37+
const Cookie = @import("../storage/cookie.zig").Cookie;
38+
3639
// WEB IDL https://html.spec.whatwg.org/#the-document-object
3740
pub const HTMLDocument = struct {
3841
pub const Self = parser.DocumentHTML;
@@ -81,14 +84,21 @@ pub const HTMLDocument = struct {
8184
}
8285
}
8386

84-
// TODO: not implemented by libdom
85-
pub fn get_cookie(_: *parser.DocumentHTML) ![]const u8 {
86-
return error.NotImplemented;
87+
pub fn get_cookie(_: *parser.DocumentHTML, arena: std.mem.Allocator, userctx: UserContext) ![]const u8 {
88+
var buf: std.ArrayListUnmanaged(u8) = .{};
89+
try userctx.cookie_jar.forRequest(&userctx.url.uri, buf.writer(arena), .{ .navigation = true });
90+
return buf.items;
8791
}
8892

89-
// TODO: not implemented by libdom
90-
pub fn set_cookie(_: *parser.DocumentHTML, _: []const u8) ![]const u8 {
91-
return error.NotImplemented;
93+
pub fn set_cookie(_: *parser.DocumentHTML, userctx: UserContext, cookie_str: []const u8) ![]const u8 {
94+
// we use the cookie jar's allocator to parse the cookie because it
95+
// outlives the page's arena.
96+
const c = try Cookie.parse(userctx.cookie_jar.allocator, &userctx.url.uri, cookie_str);
97+
errdefer c.deinit();
98+
99+
try userctx.cookie_jar.add(c, std.time.timestamp());
100+
101+
return cookie_str;
92102
}
93103

94104
pub fn get_title(self: *parser.DocumentHTML) ![]const u8 {
@@ -258,4 +268,12 @@ pub fn testExecFn(
258268
.{ .src = "list.length", .ex = "1" },
259269
};
260270
try checkCases(js_env, &getElementsByName);
271+
272+
var cookie = [_]Case{
273+
.{ .src = "document.cookie", .ex = "" },
274+
.{ .src = "document.cookie = 'name=Oeschger; SameSite=None; Secure'", .ex = "name=Oeschger; SameSite=None; Secure" },
275+
.{ .src = "document.cookie = 'favorite_food=tripe; SameSite=None; Secure'", .ex = "favorite_food=tripe; SameSite=None; Secure" },
276+
.{ .src = "document.cookie", .ex = "name=Oeschger; favorite_food=tripe" },
277+
};
278+
try checkCases(js_env, &cookie);
261279
}

src/storage/cookie.zig

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ pub const Jar = struct {
145145
if (first) {
146146
first = false;
147147
} else {
148-
try writer.writeAll(", ");
148+
try writer.writeAll("; ");
149149
}
150150
try writeCookie(cookie, writer);
151151
}
@@ -563,8 +563,8 @@ test "Jar: forRequest" {
563563
try jar.add(try Cookie.parse(testing.allocator, &test_uri_2, "domain1=9;domain=test.lightpanda.io"), now);
564564

565565
// nothing fancy here
566-
try expectCookies("global1=1, global2=2", &jar, test_uri, .{});
567-
try expectCookies("global1=1, global2=2", &jar, test_uri, .{ .origin_uri = &test_uri, .navigation = false });
566+
try expectCookies("global1=1; global2=2", &jar, test_uri, .{});
567+
try expectCookies("global1=1; global2=2", &jar, test_uri, .{ .origin_uri = &test_uri, .navigation = false });
568568

569569
// We have a cookie where Domain=lightpanda.io
570570
// This should _not_ match xyxlightpanda.io
@@ -573,47 +573,47 @@ test "Jar: forRequest" {
573573
});
574574

575575
// matching path without trailing /
576-
try expectCookies("global1=1, global2=2, path1=3", &jar, try std.Uri.parse("http://lightpanda.io/about"), .{
576+
try expectCookies("global1=1; global2=2; path1=3", &jar, try std.Uri.parse("http://lightpanda.io/about"), .{
577577
.origin_uri = &test_uri,
578578
});
579579

580580
// incomplete prefix path
581-
try expectCookies("global1=1, global2=2", &jar, try std.Uri.parse("http://lightpanda.io/abou"), .{
581+
try expectCookies("global1=1; global2=2", &jar, try std.Uri.parse("http://lightpanda.io/abou"), .{
582582
.origin_uri = &test_uri,
583583
});
584584

585585
// path doesn't match
586-
try expectCookies("global1=1, global2=2", &jar, try std.Uri.parse("http://lightpanda.io/aboutus"), .{
586+
try expectCookies("global1=1; global2=2", &jar, try std.Uri.parse("http://lightpanda.io/aboutus"), .{
587587
.origin_uri = &test_uri,
588588
});
589589

590590
// path doesn't match cookie directory
591-
try expectCookies("global1=1, global2=2", &jar, try std.Uri.parse("http://lightpanda.io/docs"), .{
591+
try expectCookies("global1=1; global2=2", &jar, try std.Uri.parse("http://lightpanda.io/docs"), .{
592592
.origin_uri = &test_uri,
593593
});
594594

595595
// exact directory match
596-
try expectCookies("global1=1, global2=2, path2=4", &jar, try std.Uri.parse("http://lightpanda.io/docs/"), .{
596+
try expectCookies("global1=1; global2=2; path2=4", &jar, try std.Uri.parse("http://lightpanda.io/docs/"), .{
597597
.origin_uri = &test_uri,
598598
});
599599

600600
// sub directory match
601-
try expectCookies("global1=1, global2=2, path2=4", &jar, try std.Uri.parse("http://lightpanda.io/docs/more"), .{
601+
try expectCookies("global1=1; global2=2; path2=4", &jar, try std.Uri.parse("http://lightpanda.io/docs/more"), .{
602602
.origin_uri = &test_uri,
603603
});
604604

605605
// secure
606-
try expectCookies("global1=1, global2=2, secure=5", &jar, try std.Uri.parse("https://lightpanda.io/"), .{
606+
try expectCookies("global1=1; global2=2; secure=5", &jar, try std.Uri.parse("https://lightpanda.io/"), .{
607607
.origin_uri = &test_uri,
608608
});
609609

610610
// navigational cross domain, secure
611-
try expectCookies("global1=1, global2=2, secure=5, sitenone=6, sitelax=7", &jar, try std.Uri.parse("https://lightpanda.io/x/"), .{
611+
try expectCookies("global1=1; global2=2; secure=5; sitenone=6; sitelax=7", &jar, try std.Uri.parse("https://lightpanda.io/x/"), .{
612612
.origin_uri = &(try std.Uri.parse("https://example.com/")),
613613
});
614614

615615
// navigational cross domain, insecure
616-
try expectCookies("global1=1, global2=2, sitelax=7", &jar, try std.Uri.parse("http://lightpanda.io/x/"), .{
616+
try expectCookies("global1=1; global2=2; sitelax=7", &jar, try std.Uri.parse("http://lightpanda.io/x/"), .{
617617
.origin_uri = &(try std.Uri.parse("https://example.com/")),
618618
});
619619

@@ -630,18 +630,18 @@ test "Jar: forRequest" {
630630
});
631631

632632
// non-navigational same origin
633-
try expectCookies("global1=1, global2=2, sitelax=7, sitestrict=8", &jar, try std.Uri.parse("http://lightpanda.io/x/"), .{
633+
try expectCookies("global1=1; global2=2; sitelax=7; sitestrict=8", &jar, try std.Uri.parse("http://lightpanda.io/x/"), .{
634634
.origin_uri = &(try std.Uri.parse("https://lightpanda.io/")),
635635
.navigation = false,
636636
});
637637

638638
// exact domain match + suffix
639-
try expectCookies("global2=2, domain1=9", &jar, try std.Uri.parse("http://test.lightpanda.io/"), .{
639+
try expectCookies("global2=2; domain1=9", &jar, try std.Uri.parse("http://test.lightpanda.io/"), .{
640640
.origin_uri = &test_uri,
641641
});
642642

643643
// domain suffix match + suffix
644-
try expectCookies("global2=2, domain1=9", &jar, try std.Uri.parse("http://1.test.lightpanda.io/"), .{
644+
try expectCookies("global2=2; domain1=9", &jar, try std.Uri.parse("http://1.test.lightpanda.io/"), .{
645645
.origin_uri = &test_uri,
646646
});
647647

0 commit comments

Comments
 (0)