fix(haproxy): check-alpn http/1.1 für HTTPS-Backends mit Healthcheck
L7TOUT-Bug: server-Stmt setzt `alpn h2,http/1.1` → Server handelt h2 aus → `option httpchk` sendet HTTP/1.x → Server antwortet nicht → HAProxy markiert Backend DOWN → 503 für alle Requests. Fix: explizit `check-alpn http/1.1` an die Server-Direktive wenn Scheme=https UND Healthcheck aktiv. HTTP-only-Backends bleiben unverändert. Bonus 1: Inter-Font lokal in public/fonts/ (DSGVO, Performance, Offline- Dev) — Pattern 1:1 aus netcell-webpanel. Kein Google-CDN-Roundtrip mehr. Test: TestRender_HTTPSHealthcheckPinsAlpnHTTP1 stellt sicher dass der Pin gesetzt wird und HTTP-Backends KEIN check-alpn bekommen. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -102,6 +102,48 @@ func TestRender_HealthCheckPathAddsCheckInter(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRender_HTTPSHealthcheckPinsAlpnHTTP1(t *testing.T) {
|
||||
// L7TOUT-Bug: ohne `check-alpn http/1.1` handelt der Check h2
|
||||
// aus (vom server-Stmt geerbt) und hängt, weil option httpchk
|
||||
// HTTP/1.x sendet. Test stellt sicher dass HTTPS+Healthcheck
|
||||
// das ALPN für den Check pinnt.
|
||||
hcp := "/"
|
||||
v := View{
|
||||
Backends: []BackendView{
|
||||
{
|
||||
Backend: models.Backend{ID: 9, Name: "tls-app", Scheme: "https",
|
||||
LBAlgorithm: "roundrobin", HealthCheckPath: &hcp, Active: true},
|
||||
Servers: []models.BackendServer{
|
||||
{BackendID: 9, Name: "tls-1", Address: "10.0.0.30", Port: 8443, Weight: 100, Active: true},
|
||||
},
|
||||
},
|
||||
{
|
||||
// Gegenprobe: HTTP-Backend mit Healthcheck darf KEIN
|
||||
// check-alpn bekommen (ALPN gibt's nur bei SSL).
|
||||
Backend: models.Backend{ID: 10, Name: "plain-app", Scheme: "http",
|
||||
LBAlgorithm: "roundrobin", HealthCheckPath: &hcp, Active: true},
|
||||
Servers: []models.BackendServer{
|
||||
{BackendID: 10, Name: "plain-1", Address: "10.0.0.31", Port: 80, Weight: 100, Active: true},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
out := renderView(t, v)
|
||||
idxTLS := strings.Index(out, "backend eg_backend_9")
|
||||
idxPlain := strings.Index(out, "backend eg_backend_10")
|
||||
if idxTLS < 0 || idxPlain < 0 {
|
||||
t.Fatalf("backend sections missing:\n%s", out)
|
||||
}
|
||||
tlsBlock := out[idxTLS:idxPlain]
|
||||
plainBlock := out[idxPlain:]
|
||||
if !strings.Contains(tlsBlock, "check-alpn http/1.1") {
|
||||
t.Errorf("HTTPS+healthcheck soll check-alpn http/1.1 pinnen:\n%s", tlsBlock)
|
||||
}
|
||||
if strings.Contains(plainBlock, "check-alpn") {
|
||||
t.Errorf("HTTP-Backend darf KEIN check-alpn bekommen:\n%s", plainBlock)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRender_WebSocketEmitsTunnelTimeout(t *testing.T) {
|
||||
v := View{
|
||||
Backends: []BackendView{
|
||||
|
||||
Reference in New Issue
Block a user