diff --git a/.golangci.reference.yml b/.golangci.reference.yml index 5557717a162b..a156bcf0cf64 100644 --- a/.golangci.reference.yml +++ b/.golangci.reference.yml @@ -2323,6 +2323,7 @@ linters: - asciicheck - bidichk - bodyclose + - canonicalheader - containedctx - contextcheck - cyclop @@ -2443,6 +2444,7 @@ linters: - asciicheck - bidichk - bodyclose + - canonicalheader - containedctx - contextcheck - cyclop diff --git a/go.mod b/go.mod index 6b2f513e5044..d3287980b22d 100644 --- a/go.mod +++ b/go.mod @@ -64,6 +64,7 @@ require ( github.com/kulti/thelper v0.6.3 github.com/kunwardeep/paralleltest v1.0.8 github.com/kyoh86/exportloopref v0.1.11 + github.com/lasiar/canonicalheader v1.0.3 github.com/ldez/gomoddirectives v0.2.3 github.com/ldez/tagliatelle v0.5.0 github.com/leonklingele/grouper v1.1.1 diff --git a/go.sum b/go.sum index a6a8f61ea30d..91683fef820c 100644 --- a/go.sum +++ b/go.sum @@ -348,6 +348,8 @@ github.com/kunwardeep/paralleltest v1.0.8 h1:Ul2KsqtzFxTlSU7IP0JusWlLiNqQaloB9vg github.com/kunwardeep/paralleltest v1.0.8/go.mod h1:2C7s65hONVqY7Q5Efj5aLzRCNLjw2h4eMc9EcypGjcY= github.com/kyoh86/exportloopref v0.1.11 h1:1Z0bcmTypkL3Q4k+IDHMWTcnCliEZcaPiIe0/ymEyhQ= github.com/kyoh86/exportloopref v0.1.11/go.mod h1:qkV4UF1zGl6EkF1ox8L5t9SwyeBAZ3qLMd6up458uqA= +github.com/lasiar/canonicalheader v1.0.3 h1:JdHhsHSdmgmaDy8BDrhMrUULqjrdPp1eSKtweawNwxs= +github.com/lasiar/canonicalheader v1.0.3/go.mod h1:pQMsk8oSSY86hn3FmntqqGDzAWqqgmP2mrkArFOqMTQ= github.com/ldez/gomoddirectives v0.2.3 h1:y7MBaisZVDYmKvt9/l1mjNCiSA1BVn34U0ObUcJwlhA= github.com/ldez/gomoddirectives v0.2.3/go.mod h1:cpgBogWITnCfRq2qGoDkKMEVSaarhdBr6g8G04uz6d0= github.com/ldez/tagliatelle v0.5.0 h1:epgfuYt9v0CG3fms0pEgIMNPuFf/LpPIfjk4kyqSioo= diff --git a/pkg/golinters/canonicalheader.go b/pkg/golinters/canonicalheader.go new file mode 100644 index 000000000000..c03458cdeab3 --- /dev/null +++ b/pkg/golinters/canonicalheader.go @@ -0,0 +1,19 @@ +package golinters + +import ( + "github.com/lasiar/canonicalheader" + "golang.org/x/tools/go/analysis" + + "github.com/golangci/golangci-lint/pkg/golinters/goanalysis" +) + +func NewCanonicalheder() *goanalysis.Linter { + a := canonicalheader.Analyzer + + return goanalysis.NewLinter( + a.Name, + a.Doc, + []*analysis.Analyzer{canonicalheader.Analyzer}, + nil, + ).WithLoadMode(goanalysis.LoadModeTypesInfo) +} diff --git a/pkg/lint/lintersdb/manager.go b/pkg/lint/lintersdb/manager.go index 4f7848005964..537c4a062c3f 100644 --- a/pkg/lint/lintersdb/manager.go +++ b/pkg/lint/lintersdb/manager.go @@ -285,6 +285,12 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config { WithPresets(linter.PresetPerformance, linter.PresetBugs). WithURL("https://github.com/timakin/bodyclose"), + linter.NewConfig(golinters.NewCanonicalheder()). + WithSince("v1.56.0"). + WithPresets(linter.PresetStyle). + WithLoadForGoAnalysis(). + WithURL("https://github.com/lasiar/canonicalHeader"), + linter.NewConfig(golinters.NewContainedCtx()). WithSince("1.44.0"). WithLoadForGoAnalysis(). diff --git a/test/testdata/canonicalheader.go b/test/testdata/canonicalheader.go new file mode 100644 index 000000000000..07e149522cbe --- /dev/null +++ b/test/testdata/canonicalheader.go @@ -0,0 +1,19 @@ +//golangcitest:args -Ecanonicalheader +package testdata + +import "net/http" + +func canonicalheader() { + v := http.Header{} + + v.Get("Test-HEader") // want `non-canonical header "Test-HEader", instead use: "Test-Header"` + v.Set("Test-HEader", "value") // want `non-canonical header "Test-HEader", instead use: "Test-Header"` + v.Add("Test-HEader", "value") // want `non-canonical header "Test-HEader", instead use: "Test-Header"` + v.Del("Test-HEader") // want `non-canonical header "Test-HEader", instead use: "Test-Header"` + v.Values("Test-HEader") // want `non-canonical header "Test-HEader", instead use: "Test-Header"` + + v.Set("Test-Header", "value") + v.Add("Test-Header", "value") + v.Del("Test-Header") + v.Values("Test-Header") +}