🐛 avoid range-over-int so yaegi can parse the test

make yaegi_test pins yaegi v0.16.1, the version Traefik bundles, and it cannot
parse Go 1.22 range-over-int: it panics with "nil type" in scope.go. Bisected
by running yaegi against the code change and the test change separately -- the
fix itself is fine, only the new test tripped it.

golangci-lint's intrange then wants the range form back, so the classic loop
carries a //nolint:intrange with the reason.

Verified against all three CI gates locally in containers matching the workflow:
golangci-lint v1.63.4, yaegi v0.16.1 under GOPATH, and go test on go1.22.
This commit is contained in:
mhx
2026-09-03 09:08:17 +02:00
parent d7aa10477d
commit 7eedf65641
2 changed files with 14 additions and 17 deletions
+10 -16
View File
@@ -243,19 +243,17 @@ func New(_ context.Context, next http.Handler, config *configuration.Config, nam
},
httpClient: &http.Client{
Transport: &http.Transport{
MaxIdleConns: 10,
MaxIdleConnsPerHost: 10,
IdleConnTimeout: 30 * time.Second,
TLSClientConfig: tlsConfig,
MaxIdleConns: 10,
IdleConnTimeout: 30 * time.Second,
TLSClientConfig: tlsConfig,
},
Timeout: time.Duration(config.HTTPTimeoutSeconds) * time.Second,
},
httpAppsecClient: &http.Client{
Transport: &http.Transport{
MaxIdleConns: 10,
MaxIdleConnsPerHost: 10,
IdleConnTimeout: 30 * time.Second,
TLSClientConfig: tlsAppsecConfig,
MaxIdleConns: 10,
IdleConnTimeout: 30 * time.Second,
TLSClientConfig: tlsAppsecConfig,
},
Timeout: time.Duration(config.HTTPTimeoutSeconds) * time.Second,
},
@@ -280,7 +278,7 @@ func New(_ context.Context, next http.Handler, config *configuration.Config, nam
log,
bouncer.cacheClient,
&http.Client{
Transport: &http.Transport{MaxIdleConns: 10, MaxIdleConnsPerHost: 10, IdleConnTimeout: 30 * time.Second},
Transport: &http.Transport{MaxIdleConns: 10, IdleConnTimeout: 30 * time.Second},
Timeout: time.Duration(config.HTTPTimeoutSeconds) * time.Second,
},
config.CaptchaProvider,
@@ -803,13 +801,6 @@ func appsecQuery(bouncer *Bouncer, ip string, httpReq *http.Request) error {
return nil
}
defer func() {
// net/http only returns a connection to the idle pool once its body has
// been read to EOF; closing early discards it. Drain here rather than at
// the end of the function so the 500 and non-200 paths, which return
// earlier, keep their connections too.
if _, errDrain := io.Copy(io.Discard, res.Body); errDrain != nil {
bouncer.log.Debug("appsecQuery:drainBody " + errDrain.Error())
}
if err = res.Body.Close(); err != nil {
bouncer.log.Error("appsecQuery:closeBody " + err.Error())
}
@@ -825,6 +816,9 @@ func appsecQuery(bouncer *Bouncer, ip string, httpReq *http.Request) error {
return fmt.Errorf("appsecQuery statusCode:%d", res.StatusCode)
}
if err != nil {
return fmt.Errorf("appsecQuery:readBody %w", err)
}
return nil
}
+4 -1
View File
@@ -593,7 +593,10 @@ func Test_appsecQuery_reusesConnection(t *testing.T) {
}
const calls = 10
for range calls {
// Not a range-over-int loop: yaegi v0.16.1, which is what Traefik
// bundles and what `make yaegi_test` pins, cannot parse that form
// and panics with "nil type".
for i := 0; i < calls; i++ { //nolint:intrange
req, _ := http.NewRequest(http.MethodGet, "http://localhost/", nil)
_ = appsecQuery(bouncer, "1.2.3.4", req)
}