checker: judge HTTPS redirect by chain, not FinalURL
All checks were successful
continuous-integration/drone/push Build is passing

The probe stops at scheme-changing redirects, so FinalURL keeps the
pre-redirect http:// URL while the chain records the real https://
target. Prefer the last redirect hop's destination so a correct
http→https redirect is no longer mis-flagged as no_https_redirect.
This commit is contained in:
nemunaire 2026-06-18 10:35:21 +09:00
commit f4b8941a3d
2 changed files with 22 additions and 1 deletions

View file

@ -38,8 +38,13 @@ func (r *httpsRedirectRule) Evaluate(ctx context.Context, obs sdk.ObservationGet
// simply not running is fine for redirect-purposes. // simply not running is fine for redirect-purposes.
return return
} }
// Prefer the last redirect hop's destination over FinalURL. When the
// probe stops at a scheme-changing redirect (http→https), it does not
// follow the hop, so FinalURL stays the pre-redirect http:// URL while
// the chain records the real https:// target. Judging by FinalURL alone
// would mis-flag a correct http→https redirect as no_https_redirect.
final := p.FinalURL final := p.FinalURL
if final == "" && len(p.RedirectChain) > 0 { if len(p.RedirectChain) > 0 {
final = p.RedirectChain[len(p.RedirectChain)-1].To final = p.RedirectChain[len(p.RedirectChain)-1].To
} }
isHTTPS := false isHTTPS := false

View file

@ -37,6 +37,22 @@ func TestHTTPSRedirectRule_OKViaRedirectChain(t *testing.T) {
mustStatus(t, states, sdk.StatusOK) mustStatus(t, states, sdk.StatusOK)
} }
func TestHTTPSRedirectRule_OKViaRedirectChain_FinalURLStillHTTP(t *testing.T) {
// Real-world case: the probe stops at the scheme-changing redirect, so it
// never follows the https:// hop. FinalURL therefore remains the original
// http:// URL while RedirectChain records the 308 to https. This must be
// treated as a correct redirect, not no_https_redirect.
p := httpProbe("a:80")
p.StatusCode = 308
p.FinalURL = "http://example.test/"
p.RedirectChain = []RedirectStep{{From: "http://example.test/", To: "https://example.test/", Status: 308}}
states := runRule(t, &httpsRedirectRule{}, &HTTPData{Probes: []HTTPProbe{p}}, sdk.CheckerOptions{OptionRequireHTTPS: true})
mustStatus(t, states, sdk.StatusOK)
if !hasCode(states, "http.https_redirect.ok") {
t.Errorf("expected redirect.ok, got %+v", states)
}
}
func TestHTTPSRedirectRule_NoRedirect_Required(t *testing.T) { func TestHTTPSRedirectRule_NoRedirect_Required(t *testing.T) {
p := httpProbe("a:80") p := httpProbe("a:80")
p.StatusCode = 200 p.StatusCode = 200