@@ -144,12 +144,8 @@ fn enable(cmd: anytype) !void {
144144 return cmd .sendResult (null , .{});
145145 }
146146
147- if (params .handleAuthRequests ) {
148- log .warn (.cdp , "not implemented" , .{ .feature = "Fetch.enable handleAuthRequests is not supported yet" });
149- }
150-
151147 const bc = cmd .browser_context orelse return error .BrowserContextNotLoaded ;
152- try bc .fetchEnable ();
148+ try bc .fetchEnable (params . handleAuthRequests );
153149
154150 return cmd .sendResult (null , .{});
155151}
@@ -346,6 +342,92 @@ fn failRequest(cmd: anytype) !void {
346342 return cmd .sendResult (null , .{});
347343}
348344
345+ const AuthChallenge = struct {
346+ scheme : enum { basic , digest },
347+ realm : []const u8 ,
348+
349+ // https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/WWW-Authenticate
350+ // Supports only basic and digest schemes.
351+ pub fn parse (header : []const u8 ) ! AuthChallenge {
352+ var ac : AuthChallenge = .{
353+ .scheme = undefined ,
354+ .realm = "" ,
355+ };
356+
357+ const pos = std .mem .indexOfPos (u8 , std .mem .trim (u8 , header , std .ascii .whitespace [0.. ]), 0 , " " ) orelse header .len ;
358+ const _scheme = header [0.. pos ];
359+ if (std .ascii .eqlIgnoreCase (_scheme , "basic" )) {
360+ ac .scheme = .basic ;
361+ } else if (std .ascii .eqlIgnoreCase (_scheme , "digest" )) {
362+ ac .scheme = .digest ;
363+ } else {
364+ return error .UnknownAuthChallengeScheme ;
365+ }
366+
367+ // TODO get the realm
368+
369+ return ac ;
370+ }
371+ };
372+
373+ pub fn requestAuthRequired (arena : Allocator , bc : anytype , intercept : * const Notification.RequestAuthRequired ) ! void {
374+ // unreachable because we _have_ to have a page.
375+ const session_id = bc .session_id orelse unreachable ;
376+ const target_id = bc .target_id orelse unreachable ;
377+ const page = bc .session .currentPage () orelse unreachable ;
378+
379+ // We keep it around to wait for modifications to the request.
380+ // NOTE: we assume whomever created the request created it with a lifetime of the Page.
381+ // TODO: What to do when receiving replies for a previous page's requests?
382+
383+ const transfer = intercept .transfer ;
384+ try bc .intercept_state .put (transfer );
385+
386+ var challenge : AuthChallenge = undefined ;
387+ var source : enum { server , proxy } = undefined ;
388+ var it = transfer .responseHeaderIterator ();
389+ while (it .next ()) | hdr | {
390+ if (std .ascii .eqlIgnoreCase ("WWW-Authenticate" , hdr .name )) {
391+ source = .server ;
392+ challenge = try AuthChallenge .parse (hdr .value );
393+ break ;
394+ }
395+ if (std .ascii .eqlIgnoreCase ("Proxy-Authenticate" , hdr .name )) {
396+ source = .proxy ;
397+ challenge = try AuthChallenge .parse (hdr .value );
398+ break ;
399+ }
400+ }
401+
402+ try bc .cdp .sendEvent ("Fetch.authRequired" , .{
403+ .requestId = try std .fmt .allocPrint (arena , "INTERCEPT-{d}" , .{transfer .id }),
404+ .request = network .TransferAsRequestWriter .init (transfer ),
405+ .frameId = target_id ,
406+ .resourceType = switch (transfer .req .resource_type ) {
407+ .script = > "Script" ,
408+ .xhr = > "XHR" ,
409+ .document = > "Document" ,
410+ },
411+ .authChallenge = .{
412+ .source = if (source == .server ) "Server" else "Proxy" ,
413+ .origin = "" , // TODO get origin, could be the proxy address for example.
414+ .scheme = if (challenge .scheme == .digest ) "digest" else "basic" ,
415+ .realm = challenge .realm ,
416+ },
417+ .networkId = try std .fmt .allocPrint (arena , "REQ-{d}" , .{transfer .id }),
418+ }, .{ .session_id = session_id });
419+
420+ log .debug (.cdp , "request auth required" , .{
421+ .state = "paused" ,
422+ .id = transfer .id ,
423+ .url = transfer .uri ,
424+ });
425+ // Await continueWithAuth
426+
427+ intercept .wait_for_interception .* = true ;
428+ page .request_intercepted = true ;
429+ }
430+
349431// Get u64 from requestId which is formatted as: "INTERCEPT-{d}"
350432fn idFromRequestId (request_id : []const u8 ) ! u64 {
351433 if (! std .mem .startsWith (u8 , request_id , "INTERCEPT-" )) {
0 commit comments