diff --git a/src/browser/HttpClient.zig b/src/browser/HttpClient.zig index 650ab2b8..546bcecd 100644 --- a/src/browser/HttpClient.zig +++ b/src/browser/HttpClient.zig @@ -642,6 +642,11 @@ fn makeTransfer(self: *Client, req: Request) !*Transfer { fn makeRequest(self: *Client, conn: *http.Connection, transfer: *Transfer) anyerror!void { { + // Reset per-response state for retries (auth challenge, queue). + const auth = transfer._auth_challenge; + transfer.reset(); + transfer._auth_challenge = auth; + transfer._conn = conn; errdefer { transfer._conn = null; @@ -726,7 +731,9 @@ fn perform(self: *Client, timeout_ms: c_int) anyerror!PerformStatus { fn processOneMessage(self: *Client, msg: http.Handles.MultiMessage, transfer: *Transfer) !bool { // Detect auth challenge from response headers. - if (msg.err == null) { + // Also check on RecvError: proxy may send 407 with headers before + // closing the connection (CONNECT tunnel not yet established). + if (msg.err == null or msg.err.? == error.RecvError) { transfer.detectAuthChallenge(&msg.conn); } @@ -1127,7 +1134,8 @@ pub const Transfer = struct { } pub fn reset(self: *Transfer) void { - self._auth_challenge = null; + // Note: do NOT reset _auth_challenge here. It is needed by makeRequest + // to determine whether to use setProxyCredentials vs setCredentials. self._notified_fail = false; self.response_header = null; self.bytes_received = 0; diff --git a/src/browser/Page.zig b/src/browser/Page.zig index b6f1b370..e3c6bcac 100644 --- a/src/browser/Page.zig +++ b/src/browser/Page.zig @@ -1027,6 +1027,7 @@ fn pageDoneCallback(ctx: *anyopaque) !void { }); parser.parse(html); + self._parse_state = .complete; self.documentIsComplete(); }, else => unreachable,