🐛 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{ httpClient: &http.Client{
Transport: &http.Transport{ Transport: &http.Transport{
MaxIdleConns: 10, MaxIdleConns: 10,
MaxIdleConnsPerHost: 10, IdleConnTimeout: 30 * time.Second,
IdleConnTimeout: 30 * time.Second, TLSClientConfig: tlsConfig,
TLSClientConfig: tlsConfig,
}, },
Timeout: time.Duration(config.HTTPTimeoutSeconds) * time.Second, Timeout: time.Duration(config.HTTPTimeoutSeconds) * time.Second,
}, },
httpAppsecClient: &http.Client{ httpAppsecClient: &http.Client{
Transport: &http.Transport{ Transport: &http.Transport{
MaxIdleConns: 10, MaxIdleConns: 10,
MaxIdleConnsPerHost: 10, IdleConnTimeout: 30 * time.Second,
IdleConnTimeout: 30 * time.Second, TLSClientConfig: tlsAppsecConfig,
TLSClientConfig: tlsAppsecConfig,
}, },
Timeout: time.Duration(config.HTTPTimeoutSeconds) * time.Second, Timeout: time.Duration(config.HTTPTimeoutSeconds) * time.Second,
}, },
@@ -280,7 +278,7 @@ func New(_ context.Context, next http.Handler, config *configuration.Config, nam
log, log,
bouncer.cacheClient, bouncer.cacheClient,
&http.Client{ &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, Timeout: time.Duration(config.HTTPTimeoutSeconds) * time.Second,
}, },
config.CaptchaProvider, config.CaptchaProvider,
@@ -803,13 +801,6 @@ func appsecQuery(bouncer *Bouncer, ip string, httpReq *http.Request) error {
return nil return nil
} }
defer func() { 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 { if err = res.Body.Close(); err != nil {
bouncer.log.Error("appsecQuery:closeBody " + err.Error()) 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) return fmt.Errorf("appsecQuery statusCode:%d", res.StatusCode)
} }
if err != nil {
return fmt.Errorf("appsecQuery:readBody %w", err)
}
return nil return nil
} }
+4 -1
View File
@@ -593,7 +593,10 @@ func Test_appsecQuery_reusesConnection(t *testing.T) {
} }
const calls = 10 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) req, _ := http.NewRequest(http.MethodGet, "http://localhost/", nil)
_ = appsecQuery(bouncer, "1.2.3.4", req) _ = appsecQuery(bouncer, "1.2.3.4", req)
} }