1717// along with this program. If not, see <https://www.gnu.org/licenses/>.
1818
1919const std = @import ("std" );
20+ const Allocator = std .mem .Allocator ;
21+
2022const Notification = @import ("../../notification.zig" ).Notification ;
2123const log = @import ("../../log.zig" );
22-
23- const Allocator = std .mem .Allocator ;
24+ const CdpStorage = @import ("storage.zig" );
2425
2526pub fn processMessage (cmd : anytype ) ! void {
2627 const action = std .meta .stringToEnum (enum {
@@ -79,13 +80,7 @@ fn setExtraHTTPHeaders(cmd: anytype) !void {
7980 return cmd .sendResult (null , .{});
8081}
8182
82- const CookiePartitionKey = struct {
83- topLevelSite : []const u8 ,
84- hasCrossSiteAncestor : bool ,
85- };
86-
8783const Cookie = @import ("../../browser/storage/storage.zig" ).Cookie ;
88- const CookieJar = @import ("../../browser/storage/storage.zig" ).CookieJar ;
8984
9085fn cookieMatches (cookie : * const Cookie , name : []const u8 , domain : ? []const u8 , path : ? []const u8 ) bool {
9186 if (! std .mem .eql (u8 , cookie .name , name )) return false ;
@@ -116,7 +111,7 @@ fn deleteCookies(cmd: anytype) !void {
116111 while (index > 0 ) {
117112 index -= 1 ;
118113 const cookie = & cookies .items [index ];
119- const domain = try percentEncodedDomain (cmd .arena , params .url , params .domain );
114+ const domain = try CdpStorage . percentEncodedDomain (cmd .arena , params .url , params .domain );
120115 // TBD does chrome take the path from the url as default? (unlike setCookies)
121116 if (cookieMatches (cookie , params .name , domain , params .path )) {
122117 cookies .swapRemove (index ).deinit ();
@@ -134,130 +129,30 @@ fn clearBrowserCookies(cmd: anytype) !void {
134129 return cmd .sendResult (null , .{});
135130}
136131
137- const SameSite = enum {
138- Strict ,
139- Lax ,
140- None ,
141- };
142- const CookiePriority = enum {
143- Low ,
144- Medium ,
145- High ,
146- };
147- const CookieSourceScheme = enum {
148- Unset ,
149- NonSecure ,
150- Secure ,
151- };
152-
153- fn isHostChar (c : u8 ) bool {
154- return switch (c ) {
155- 'A' ... 'Z' , 'a' ... 'z' , '0' ... '9' , '-' , '.' , '_' , '~' = > true ,
156- '!' , '$' , '&' , '\' ' , '(' , ')' , '*' , '+' , ',' , ';' , '=' = > true ,
157- ':' = > true ,
158- '[' , ']' = > true ,
159- else = > false ,
160- };
161- }
162-
163- const CdpCookie = struct {
164- name : []const u8 ,
165- value : []const u8 ,
166- url : ? []const u8 = null ,
167- domain : ? []const u8 = null ,
168- path : ? []const u8 = null ,
169- secure : bool = false , // default: https://www.rfc-editor.org/rfc/rfc6265#section-5.3
170- httpOnly : bool = false , // default: https://www.rfc-editor.org/rfc/rfc6265#section-5.3
171- sameSite : SameSite = .None , // default: https://datatracker.ietf.org/doc/html/draft-west-first-party-cookies
172- expires : ? i64 = null , // -1? says google
173- priority : CookiePriority = .Medium , // default: https://datatracker.ietf.org/doc/html/draft-west-cookie-priority-00
174- sameParty : ? bool = null ,
175- sourceScheme : ? CookieSourceScheme = null ,
176- // sourcePort: Temporary ability and it will be removed from CDP
177- partitionKey : ? CookiePartitionKey = null ,
178- };
179-
180132fn setCookie (cmd : anytype ) ! void {
181133 const params = (try cmd .params (
182- CdpCookie ,
134+ CdpStorage . CdpCookie ,
183135 )) orelse return error .InvalidParams ;
184136
185137 const bc = cmd .browser_context orelse return error .BrowserContextNotLoaded ;
186- try setCdpCookie (& bc .session .cookie_jar , params );
138+ try CdpStorage . setCdpCookie (& bc .session .cookie_jar , params );
187139
188140 try cmd .sendResult (.{ .success = true }, .{});
189141}
190142
191143fn setCookies (cmd : anytype ) ! void {
192144 const params = (try cmd .params (struct {
193- cookies : []const CdpCookie ,
145+ cookies : []const CdpStorage. CdpCookie ,
194146 })) orelse return error .InvalidParams ;
195147
196148 const bc = cmd .browser_context orelse return error .BrowserContextNotLoaded ;
197149 for (params .cookies ) | param | {
198- try setCdpCookie (& bc .session .cookie_jar , param );
150+ try CdpStorage . setCdpCookie (& bc .session .cookie_jar , param );
199151 }
200152
201153 try cmd .sendResult (null , .{});
202154}
203155
204- fn setCdpCookie (cookie_jar : * CookieJar , param : CdpCookie ) ! void {
205- if (param .priority != .Medium or param .sameParty != null or param .sourceScheme != null or param .partitionKey != null ) {
206- return error .NotYetImplementedParams ;
207- }
208- if (param .name .len == 0 ) return error .InvalidParams ;
209- if (param .value .len == 0 ) return error .InvalidParams ;
210-
211- var arena = std .heap .ArenaAllocator .init (cookie_jar .allocator );
212- errdefer arena .deinit ();
213- const a = arena .allocator ();
214-
215- // NOTE: The param.url can affect the default domain, path, source port, and source scheme.
216- const domain = try percentEncodedDomain (a , param .url , param .domain ) orelse return error .InvalidParams ;
217-
218- const cookie = Cookie {
219- .arena = arena ,
220- .name = try a .dupe (u8 , param .name ),
221- .value = try a .dupe (u8 , param .value ),
222- .path = if (param .path ) | path | try a .dupe (u8 , path ) else "/" , // Chrome does not actually take the path from the url and just defaults to "/".
223- .domain = domain ,
224- .expires = param .expires ,
225- .secure = param .secure ,
226- .http_only = param .httpOnly ,
227- .same_site = switch (param .sameSite ) {
228- .Strict = > .strict ,
229- .Lax = > .lax ,
230- .None = > .none ,
231- },
232- };
233- try cookie_jar .add (cookie , std .time .timestamp ());
234- }
235-
236- // Note: Chrome does not apply rules like removing a leading `.` from the domain.
237- fn percentEncodedDomain (allocator : Allocator , default_url : ? []const u8 , domain : ? []const u8 ) ! ? []const u8 {
238- const toLower = @import ("../../browser/storage/cookie.zig" ).toLower ;
239- if (domain ) | domain_ | {
240- const output = try allocator .dupe (u8 , domain_ );
241- return toLower (output );
242- } else if (default_url ) | url | {
243- const uri = std .Uri .parse (url ) catch return error .InvalidParams ;
244-
245- var output : []u8 = undefined ;
246- switch (uri .host orelse return error .InvalidParams ) {
247- .raw = > | str | {
248- var list = std .ArrayList (u8 ).init (allocator );
249- try list .ensureTotalCapacity (str .len ); // Expect no precents needed
250- try std .Uri .Component .percentEncode (list .writer (), str , isHostChar );
251- output = list .items ; // @memory retains memory used before growing
252- },
253- .percent_encoded = > | str | {
254- output = try allocator .dupe (u8 , str );
255- },
256- }
257- return toLower (output );
258- } else return null ;
259- }
260-
261156// Upsert a header into the headers array.
262157// returns true if the header was added, false if it was updated
263158fn putAssumeCapacity (headers : * std .ArrayListUnmanaged (std.http.Header ), extra : std .http .Header ) bool {
0 commit comments