# API-23 – Prüfprotokoll: HTTP-Client mit Zeitlimit im Core-Root-Modul Nachtrag zu API-19 (QA-15-Befund F-11): das Core-Root-Modul selbst war bei der damaligen Umstellung nicht erfasst. ## Umsetzung - `internal/httpclient` (neu, Core-Root-Modul): identisches Muster wie `dms/internal/httpclient`, `archive/internal/httpclient`, `mail/internal/httpclient` — `New(timeout)` liefert einen `*http.Client` mit Zeitlimit und `CheckRedirect`, das `http.ErrUseLastResponse` zurückgibt (keine Weiterleitungen); `Default()` liefert den gemeinsamen Client mit `DefaultTimeout = 15s`. - `internal/statuspage/statuspage.go`: `NewHTTPChecker` nutzt jetzt `httpclient.Default()` statt eines ungebundenen `&http.Client{}`. - `internal/moduletrust/fetch.go`: `FetchJWKSFromURL` nutzt bei `client == nil` jetzt `httpclient.Default()` statt `http.DefaultClient`. - Architekturtest `TestNoUnboundedDefaultClientInProductionCode` in `internal/httpclient/httpclient_test.go`: durchsucht nur `internal/` und `cmd/` (die eigenständigen Module `dms/`, `archive/`, `mail/`, `connect/`, `ai/`, `workflow/` liegen zwar im selben Repo, sind aber eigene Go-Module mit eigenem Architekturtest und daher hier bewusst ausgeklammert). Erkennt zusätzlich zu `http.DefaultClient`/`http.Get|Post|Head|PostForm(` auch den ungebundenen `http.Client{}` (genau das Muster, das in `statuspage.go` gefunden wurde). ## Prüfungen | # | Prüfung | Ergebnis | |---|---|---| | 1 | Hängender Testserver: Aufruf über `internal/statuspage`/`internal/moduletrust` bricht nach ~15s ab statt unbegrenzt zu warten | **bestanden** – `TestClientGivesUpOnHangingServer` (via `internal/httpclient`, das beide Aufrufer jetzt nutzen): `httptest`-Server hängt endlos, `New(200ms).Get(...)` liefert nach Zeitlimit einen Fehler statt unbegrenzt zu warten | | 2 | Testserver mit Weiterleitung: Aufruf folgt der Weiterleitung nicht | **bestanden** – `TestClientDoesNotFollowRedirects`: Weiterleitungsziel-Handler ruft `t.Error` auf, falls er je erreicht wird; `Default().Do(req)` liefert den 307 der Weiterleitungsantwort selbst, das Ziel wird nie aufgerufen | | 3 | Architekturtest schlägt fehl, wenn `http.DefaultClient`/`http.Client{}` wieder eingeführt wird (echt provoziert, nicht nur behauptet) | **bestanden** – real provoziert: `internal/moduletrust/fetch.go` testweise auf `client = http.DefaultClient` zurückgesetzt, `go test ./internal/httpclient/... -run TestNoUnbounded` schlägt mit exakter Datei:Zeile-Angabe fehl; Datei danach wiederhergestellt, `go build ./...` wieder sauber | ## Build/Test-Ergebnis (192.168.1.204) ``` go build ./... -> clean go vet ./... -> clean go test ./internal/httpclient/... ./internal/statuspage/... \ ./internal/moduletrust/... -v -> alle PASS (Integrationstests ohne TEST_ADMIN_DSN übersprungen, unverändert durch dieses Ticket) ``` ## Gesamtergebnis **Bestanden.** Alle drei Akzeptanzkriterien und alle drei Pflichtprüfungen real erfüllt. Damit ist F-11/API-19 nun auch für das Core-Root-Modul nachgezogen; `dms`, `archive`, `mail` bereits durch API-19 abgedeckt.