@
v0.129.0: CAMPAIGN-4 fixes — rate-limiter key (F-B) + volume-blind estimate (F-A) + no-op claim status (F-C) F-B (MED, security): shared clientIP(r) helper (XFF first-hop, else SplitHostPort host, else raw) replaces requestIP + the duplicated inline derivation in handleLogin, so login AND escrow re-auth key on the port-stripped host IP — distinct direct connections no longer evade the failed-attempt counter. XFF-trust out of scope (commented). F-A (MED, honesty): volumeSizer seam reads volume size from a container view (docker run --rm -v vol:/vol:ro alpine du -sb /vol), replacing the host-path du that returned 0 inside the containerized controller. Failed read -> size_unknown + fits_on_dest forced false (never "fits"). Export pre-flight hard-aborts only on a KNOWN doesn.t-fit. HDD branch unchanged. F-C (LOW-MED): escrowClaimAPIHandler relays agent 404 -> clean 404 and 409 -> 409; 410 and genuine-unreachable 502 unchanged (was: 404 fell through to 502). Tests + red-proofs: ratelimit_ip_test.go (F-B x6), estimate_volsize_test.go (F-A x3), TestEscrowClaim_ProxySemantics +3 (F-C). Alpine busybox du -sb verified prod-valid. Claude-Session: https://claude.ai/code/session_01LbMm4T7Ayzs1unB9pN6Uqd @
This commit is contained in:
@@ -286,6 +286,43 @@ func TestEscrowClaim_ProxySemantics(t *testing.T) {
|
||||
t.Fatalf("gone: got %d %s", w.Code, w.Body.String())
|
||||
}
|
||||
})
|
||||
// Scenario I (F-C fix): agent 404 "no ceremony has run" → a clean 404, NOT 502.
|
||||
t.Run("no_active_ceremony_404_not_502", func(t *testing.T) {
|
||||
h := newEscrowWizardHarness(t)
|
||||
h.agent.claimStatus = http.StatusNotFound
|
||||
h.agent.claimErr = fmt.Errorf("no ceremony has run")
|
||||
w := httptest.NewRecorder()
|
||||
h.s.escrowClaimAPIHandler(w, httptest.NewRequest("POST", "/api/escrow/claim", nil))
|
||||
if w.Code != http.StatusNotFound {
|
||||
t.Fatalf("no-ceremony claim must be 404, got %d %s", w.Code, w.Body.String())
|
||||
}
|
||||
if !strings.Contains(w.Body.String(), "Nincs aktív helyreállítási folyamat") {
|
||||
t.Fatalf("expected honest Hungarian no-ceremony message, got %s", w.Body.String())
|
||||
}
|
||||
})
|
||||
// Scenario J (regression): agent 409 → passed through as 409, not 502.
|
||||
t.Run("conflict_409", func(t *testing.T) {
|
||||
h := newEscrowWizardHarness(t)
|
||||
h.agent.claimStatus = http.StatusConflict
|
||||
h.agent.claimErr = fmt.Errorf("conflict")
|
||||
w := httptest.NewRecorder()
|
||||
h.s.escrowClaimAPIHandler(w, httptest.NewRequest("POST", "/api/escrow/claim", nil))
|
||||
if w.Code != http.StatusConflict {
|
||||
t.Fatalf("409 must pass through, got %d", w.Code)
|
||||
}
|
||||
})
|
||||
// Scenario K (regression): a genuinely-unreachable agent (status 0) stays 502 — that IS a real
|
||||
// bad gateway; the fix must NOT over-correct it to a 4xx.
|
||||
t.Run("unreachable_stays_502", func(t *testing.T) {
|
||||
h := newEscrowWizardHarness(t)
|
||||
h.agent.claimStatus = 0
|
||||
h.agent.claimErr = fmt.Errorf("dial tcp: connection refused")
|
||||
w := httptest.NewRecorder()
|
||||
h.s.escrowClaimAPIHandler(w, httptest.NewRequest("POST", "/api/escrow/claim", nil))
|
||||
if w.Code != http.StatusBadGateway {
|
||||
t.Fatalf("unreachable agent must stay 502, got %d", w.Code)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// The status proxy relays the agent's non-secret job view verbatim.
|
||||
|
||||
Reference in New Issue
Block a user