From d0b421b085c9f502e455dcd8e63f88ce71869f2b Mon Sep 17 00:00:00 2001 From: Muki Kiboigo Date: Sun, 26 Apr 2026 21:41:59 -0700 Subject: [PATCH] partial auth challenge support --- src/cdp/domains/fetch.zig | 30 +++++------ src/network/layer/InterceptionLayer.zig | 71 +++++++++++++++---------- 2 files changed, 57 insertions(+), 44 deletions(-) diff --git a/src/cdp/domains/fetch.zig b/src/cdp/domains/fetch.zig index 2de7ee3d..0f638b81 100644 --- a/src/cdp/domains/fetch.zig +++ b/src/cdp/domains/fetch.zig @@ -300,7 +300,7 @@ fn continueWithAuth(cmd: *CDP.Command) !void { var intercept_state = &bc.intercept_state; const request_id = try idFromRequestId(params.requestId); - const request = intercept_state.remove(request_id) orelse return error.RequestNotFound; + var request = intercept_state.remove(request_id) orelse return error.RequestNotFound; log.debug(.cdp, "request intercept", .{ .state = "continue with auth", @@ -308,27 +308,27 @@ fn continueWithAuth(cmd: *CDP.Command) !void { .response = params.authChallengeResponse.response, }); + const client = bc.cdp.browser.http_client; + if (params.authChallengeResponse.response != .ProvideCredentials) { - // TODO: - // request.abortAuthChallenge(); + client.interception_layer.abortAuthChallenge(request); return cmd.sendResult(null, .{}); } - // TODO: // cancel the request, deinit the transfer on error. - // errdefer request.abortAuthChallenge(); + errdefer client.interception_layer.abortAuthChallenge(request); - // todo: - // restart the request with the provided credentials. - // const arena = request.params.arena.allocator(); - // request.updateCredentials( - // try std.fmt.allocPrintSentinel(arena, "{s}:{s}", .{ - // params.authChallengeResponse.username, - // params.authChallengeResponse.password, - // }, 0), - // ); + const arena = request.params.arena.allocator(); + request.params.credentials = try std.fmt.allocPrintSentinel( + arena, + "{s}:{s}", + .{ + params.authChallengeResponse.username, + params.authChallengeResponse.password, + }, + 0, + ); - const client = bc.cdp.browser.http_client; try client.interception_layer.continueRequest(client, request); return cmd.sendResult(null, .{}); } diff --git a/src/network/layer/InterceptionLayer.zig b/src/network/layer/InterceptionLayer.zig index 21225815..823a5314 100644 --- a/src/network/layer/InterceptionLayer.zig +++ b/src/network/layer/InterceptionLayer.zig @@ -126,40 +126,21 @@ pub const InterceptContext = struct { self.content_length = response.contentLength() orelse 0; - // switch (response.inner) { - // .transfer => |t| { - // const status = t.response_header.?.status; - // if (status == 401 or status == 407) { - // self.auth_challenge = Transfer.detectAuthChallenge(t._conn.?); - - // if (self.auth_challenge != null and self.tries < 10) { - // var wait_for_interception = false; - - // self.request.params.notification.dispatch(.http_request_auth_required, &.{ - // .request = &self.request, - // .intercept_ctx = self, - // .wait_for_interception = &wait_for_interception, - // }); - - // if (wait_for_interception) { - // log.debug(.http, "intercept auth required", .{ - // .url = self.request.params.url, - // .status = status, - // .intercepted = self.layer.intercepted, - // }); - // self.layer.intercepted += 1; - // return false; - // } - // } - // } - // }, - // else => {}, - // } + switch (response.inner) { + .transfer => |t| { + const status = t.response_header.?.status; + if (status == 401 or status == 407) { + self.auth_challenge = Transfer.detectAuthChallenge(t._conn.?); + } + }, + else => {}, + } self.request.params.notification.dispatch(.http_response_header_done, &.{ .request = &self.request, .response = &response, }); + return self.forward.forwardHeader(response); } @@ -184,6 +165,27 @@ pub const InterceptContext = struct { .url = self.request.params.url, .content_length = self.content_length, }); + + // if (self.auth_challenge != null and self.tries < 10) { + // var wait_for_interception = false; + // self.request.params.notification.dispatch(.http_request_auth_required, &.{ + // .request = &self.request, + // .intercept_ctx = self, + // .wait_for_interception = &wait_for_interception, + // }); + + // if (wait_for_interception) { + // log.debug(.http, "intercept auth required", .{ + // .url = self.request.params.url, + // .intercepted = self.layer.intercepted, + // }); + // self.layer.intercepted += 1; + // self.tries += 1; + // // Don't forward done — CDP owns this now, will retry via continueWithAuth + // return; + // } + // } + self.request.params.notification.dispatch(.http_request_done, &.{ .request = &self.request, .content_length = self.content_length, @@ -289,3 +291,14 @@ pub fn fulfillRequest( return err; }; } + +pub fn abortAuthChallenge(self: *InterceptionLayer, req: Request) void { + if (comptime IS_DEBUG) { + log.debug(.http, "abort auth transfer", .{ .intercepted = self.intercepted }); + } + + self.intercepted -= 1; + defer req.deinit(); + req.error_callback(req.ctx, error.AbortAuthChallenge); + return; +}