@marcel91200 / caddy Mirror · read-only / commits / e039a5bb
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 11, 23:30 UTC

chore: upgrade .golangci.yml and workflow to v2 (#6924)

* chore: upgrade .golangci.yml and workflow to v2 run `golangci-lint fmt` Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com> * run `golangci-lint run --fix` Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com> * more lint fixes Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com> * bring back comments to .golangci.yml Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com> * appease the linter some more Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com> * oops Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com> * use embedded structs Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com> * use embedded structs where they were used before Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com> * disable rule `-QF1006` Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com> * missed a spot Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com> --------- Signed-off-by: Mohammed Al Sahaf <msaa1990@gmail.com>

Mohammed Al Sahaf committed Jun 3, 2025 at 02:24 UTC e039a5bb5ca592f630ba482e3ee078575c93d53e
33 files changed +148 -213
.github/workflows/lint.yml
+1 -1
@@ -51,7 +51,7 @@ jobs:
51 check-latest: true
52
53 - name: golangci-lint
54 - uses: golangci/golangci-lint-action@v6
54 + uses: golangci/golangci-lint-action@v7
55 with:
56 version: latest
57
.golangci.yml
+87 -151
@@ -1,27 +1,15 @@
1 -linters-settings:
2 - errcheck:
3 - exclude-functions:
4 - - fmt.*
5 - - (go.uber.org/zap/zapcore.ObjectEncoder).AddObject
6 - - (go.uber.org/zap/zapcore.ObjectEncoder).AddArray
7 - gci:
8 - sections:
9 - - standard # Standard section: captures all standard packages.
10 - - default # Default section: contains all imports that could not be matched to another section type.
11 - - prefix(github.com/caddyserver/caddy/v2/cmd) # ensure that this is always at the top and always has a line break.
12 - - prefix(github.com/caddyserver/caddy) # Custom section: groups all imports with the specified Prefix.
13 - # Skip generated files.
14 - # Default: true
15 - skip-generated: true
16 - # Enable custom order of sections.
17 - # If `true`, make the section order the same as the order of `sections`.
18 - # Default: false
19 - custom-order: true
20 - exhaustive:
21 - ignore-enum-types: reflect.Kind|svc.Cmd
22 -
1 +version: "2"
2 +run:
3 + issues-exit-code: 1
4 + tests: false
5 +output:
6 + formats:
7 + text:
8 + path: stdout
9 + print-linter-name: true
10 + print-issued-lines: true
11 linters:
24 - disable-all: true
12 + default: none
13 enable:
14 - asasalint
15 - asciicheck
@@ -35,148 +23,96 @@ linters:
23 - errcheck
24 - errname
25 - exhaustive
38 - - gci
39 - - gofmt
40 - - goimports
41 - - gofumpt
26 - gosec
43 - - gosimple
27 - govet
45 - - ineffassign
28 - importas
29 + - ineffassign
30 - misspell
31 - prealloc
32 - promlinter
33 - sloglint
34 - sqlclosecheck
35 - staticcheck
53 - - tenv
36 - testableexamples
37 - testifylint
38 - tparallel
57 - - typecheck
39 - unconvert
40 - unused
41 - wastedassign
42 - whitespace
43 - zerologlint
63 - # these are implicitly disabled:
64 - # - containedctx
65 - # - contextcheck
66 - # - cyclop
67 - # - depguard
68 - # - errchkjson
69 - # - errorlint
70 - # - exhaustruct
71 - # - execinquery
72 - # - exhaustruct
73 - # - forbidigo
74 - # - forcetypeassert
75 - # - funlen
76 - # - ginkgolinter
77 - # - gocheckcompilerdirectives
78 - # - gochecknoglobals
79 - # - gochecknoinits
80 - # - gochecksumtype
81 - # - gocognit
82 - # - goconst
83 - # - gocritic
84 - # - gocyclo
85 - # - godot
86 - # - godox
87 - # - goerr113
88 - # - goheader
89 - # - gomnd
90 - # - gomoddirectives
91 - # - gomodguard
92 - # - goprintffuncname
93 - # - gosmopolitan
94 - # - grouper
95 - # - inamedparam
96 - # - interfacebloat
97 - # - ireturn
98 - # - lll
99 - # - loggercheck
100 - # - maintidx
101 - # - makezero
102 - # - mirror
103 - # - musttag
104 - # - nakedret
105 - # - nestif
106 - # - nilerr
107 - # - nilnil
108 - # - nlreturn
109 - # - noctx
110 - # - nolintlint
111 - # - nonamedreturns
112 - # - nosprintfhostport
113 - # - paralleltest
114 - # - perfsprint
115 - # - predeclared
116 - # - protogetter
117 - # - reassign
118 - # - revive
119 - # - rowserrcheck
120 - # - stylecheck
121 - # - tagalign
122 - # - tagliatelle
123 - # - testpackage
124 - # - thelper
125 - # - unparam
126 - # - usestdlibvars
127 - # - varnamelen
128 - # - wrapcheck
129 - # - wsl
130 -
131 -run:
132 - # default concurrency is a available CPU number.
133 - # concurrency: 4 # explicitly omit this value to fully utilize available resources.
134 - timeout: 5m
135 - issues-exit-code: 1
136 - tests: false
137 -
138 -# output configuration options
139 -output:
140 - formats:
141 - - format: 'colored-line-number'
142 - print-issued-lines: true
143 - print-linter-name: true
144 -
145 -issues:
146 - exclude-rules:
147 - - text: 'G115' # TODO: Either we should fix the issues or nuke the linter if it's bad
148 - linters:
149 - - gosec
150 - # we aren't calling unknown URL
151 - - text: 'G107' # G107: Url provided to HTTP request as taint input
152 - linters:
153 - - gosec
154 - # as a web server that's expected to handle any template, this is totally in the hands of the user.
155 - - text: 'G203' # G203: Use of unescaped data in HTML templates
156 - linters:
157 - - gosec
158 - # we're shelling out to known commands, not relying on user-defined input.
159 - - text: 'G204' # G204: Audit use of command execution
160 - linters:
161 - - gosec
162 - # the choice of weakrand is deliberate, hence the named import "weakrand"
163 - - path: modules/caddyhttp/reverseproxy/selectionpolicies.go
164 - text: 'G404' # G404: Insecure random number source (rand)
165 - linters:
166 - - gosec
167 - - path: modules/caddyhttp/reverseproxy/streaming.go
168 - text: 'G404' # G404: Insecure random number source (rand)
169 - linters:
170 - - gosec
171 - - path: modules/logging/filters.go
172 - linters:
173 - - dupl
174 - - path: modules/caddyhttp/matchers.go
175 - linters:
176 - - dupl
177 - - path: modules/caddyhttp/vars.go
178 - linters:
179 - - dupl
180 - - path: _test\.go
181 - linters:
182 - - errcheck
44 + settings:
45 + staticcheck:
46 + checks: ["all", "-ST1000", "-ST1003", "-ST1016", "-ST1020", "-ST1021", "-ST1022", "-QF1006", "-QF1008"] # default, and exclude 1 more undesired check
47 + errcheck:
48 + exclude-functions:
49 + - fmt.*
50 + - (go.uber.org/zap/zapcore.ObjectEncoder).AddObject
51 + - (go.uber.org/zap/zapcore.ObjectEncoder).AddArray
52 + exhaustive:
53 + ignore-enum-types: reflect.Kind|svc.Cmd
54 + exclusions:
55 + generated: lax
56 + presets:
57 + - comments
58 + - common-false-positives
59 + - legacy
60 + - std-error-handling
61 + rules:
62 + - linters:
63 + - gosec
64 + text: G115 # TODO: Either we should fix the issues or nuke the linter if it's bad
65 + - linters:
66 + - gosec
67 + text: G107 # we aren't calling unknown URL
68 + - linters:
69 + - gosec
70 + text: G203 # as a web server that's expected to handle any template, this is totally in the hands of the user.
71 + - linters:
72 + - gosec
73 + text: G204 # we're shelling out to known commands, not relying on user-defined input.
74 + - linters:
75 + - gosec
76 + # the choice of weakrand is deliberate, hence the named import "weakrand"
77 + path: modules/caddyhttp/reverseproxy/selectionpolicies.go
78 + text: G404
79 + - linters:
80 + - gosec
81 + path: modules/caddyhttp/reverseproxy/streaming.go
82 + text: G404
83 + - linters:
84 + - dupl
85 + path: modules/logging/filters.go
86 + - linters:
87 + - dupl
88 + path: modules/caddyhttp/matchers.go
89 + - linters:
90 + - dupl
91 + path: modules/caddyhttp/vars.go
92 + - linters:
93 + - errcheck
94 + path: _test\.go
95 + paths:
96 + - third_party$
97 + - builtin$
98 + - examples$
99 +formatters:
100 + enable:
101 + - gci
102 + - gofmt
103 + - gofumpt
104 + - goimports
105 + settings:
106 + gci:
107 + sections:
108 + - standard # Standard section: captures all standard packages.
109 + - default # Default section: contains all imports that could not be matched to another section type.
110 + - prefix(github.com/caddyserver/caddy/v2/cmd) # ensure that this is always at the top and always has a line break.
111 + - prefix(github.com/caddyserver/caddy) # Custom section: groups all imports with the specified Prefix.
112 + custom-order: true
113 + exclusions:
114 + generated: lax
115 + paths:
116 + - third_party$
117 + - builtin$
118 + - examples$
caddyconfig/caddyfile/adapter.go
+1 -1
@@ -68,7 +68,7 @@ func (a Adapter) Adapt(body []byte, options map[string]any) ([]byte, []caddyconf
68 // TODO: also perform this check on imported files
69 func FormattingDifference(filename string, body []byte) (caddyconfig.Warning, bool) {
70 // replace windows-style newlines to normalize comparison
71 - normalizedBody := bytes.Replace(body, []byte("\r\n"), []byte("\n"), -1)
71 + normalizedBody := bytes.ReplaceAll(body, []byte("\r\n"), []byte("\n"))
72
73 formatted := Format(normalizedBody)
74 if bytes.Equal(formatted, normalizedBody) {
caddyconfig/caddyfile/formatter.go
+1 -1
@@ -94,7 +94,7 @@ func Format(input []byte) []byte {
94 }
95
96 // detect whether we have the start of a heredoc
97 - if !quoted && !(heredoc != heredocClosed || heredocEscaped) &&
97 + if !quoted && (heredoc == heredocClosed && !heredocEscaped) &&
98 space && last == '<' && ch == '<' {
99 write(ch)
100 heredoc = heredocOpening
caddyconfig/caddyfile/lexer.go
+1 -1
@@ -137,7 +137,7 @@ func (l *lexer) next() (bool, error) {
137 }
138
139 // detect whether we have the start of a heredoc
140 - if !(quoted || btQuoted) && !(inHeredoc || heredocEscaped) &&
140 + if (!quoted && !btQuoted) && (!inHeredoc && !heredocEscaped) &&
141 len(val) > 1 && string(val[:2]) == "<<" {
142 // a space means it's just a regular token and not a heredoc
143 if ch == ' ' {
caddyconfig/httpcaddyfile/directives.go
+4 -2
@@ -174,10 +174,12 @@ func RegisterDirectiveOrder(dir string, position Positional, standardDir string)
174 if d != standardDir {
175 continue
176 }
177 - if position == Before {
177 + switch position {
178 + case Before:
179 newOrder = append(newOrder[:i], append([]string{dir}, newOrder[i:]...)...)
179 - } else if position == After {
180 + case After:
181 newOrder = append(newOrder[:i+1], append([]string{dir}, newOrder[i+1:]...)...)
182 + case First, Last:
183 }
184 break
185 }
caddytest/caddytest.go
+1 -1
@@ -281,7 +281,7 @@ func validateTestPrerequisites(tc *Tester) error {
281 tc.t.Cleanup(func() {
282 os.Remove(f.Name())
283 })
284 - if _, err := f.WriteString(fmt.Sprintf(initConfig, tc.config.AdminPort)); err != nil {
284 + if _, err := fmt.Fprintf(f, initConfig, tc.config.AdminPort); err != nil {
285 return err
286 }
287
caddytest/integration/acme_test.go
+3 -2
@@ -12,13 +12,14 @@ import (
12 "strings"
13 "testing"
14
15 - "github.com/caddyserver/caddy/v2"
16 - "github.com/caddyserver/caddy/v2/caddytest"
15 "github.com/mholt/acmez/v3"
16 "github.com/mholt/acmez/v3/acme"
17 smallstepacme "github.com/smallstep/certificates/acme"
18 "go.uber.org/zap"
19 "go.uber.org/zap/exp/zapslog"
20 +
21 + "github.com/caddyserver/caddy/v2"
22 + "github.com/caddyserver/caddy/v2/caddytest"
23 )
24
25 const acmeChallengePort = 9081
caddytest/integration/acmeserver_test.go
+2 -1
@@ -9,11 +9,12 @@ import (
9 "strings"
10 "testing"
11
12 - "github.com/caddyserver/caddy/v2/caddytest"
12 "github.com/mholt/acmez/v3"
13 "github.com/mholt/acmez/v3/acme"
14 "go.uber.org/zap"
15 "go.uber.org/zap/exp/zapslog"
16 +
17 + "github.com/caddyserver/caddy/v2/caddytest"
18 )
19
20 func TestACMEServerDirectory(t *testing.T) {
caddytest/integration/caddyfile_adapt_test.go
-1
@@ -10,7 +10,6 @@ import (
10 "testing"
11
12 "github.com/caddyserver/caddy/v2/caddytest"
13 -
13 _ "github.com/caddyserver/caddy/v2/internal/testmocks"
14 )
15
caddytest/integration/caddyfile_test.go
-1
@@ -615,7 +615,6 @@ func TestReplaceWithReplacementPlaceholder(t *testing.T) {
615 respond "{query}"`, "caddyfile")
616
617 tester.AssertGetResponse("http://localhost:9080/endpoint?placeholder=baz&foo=bar", 200, "foo=baz&placeholder=baz")
618 -
618 }
619
620 func TestReplaceWithKeyPlaceholder(t *testing.T) {
caddytest/integration/mockdns_test.go
+9 -6
@@ -3,10 +3,11 @@ package integration
3 import (
4 "context"
5
6 - "github.com/caddyserver/caddy/v2"
7 - "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
6 "github.com/caddyserver/certmagic"
7 "github.com/libdns/libdns"
8 +
9 + "github.com/caddyserver/caddy/v2"
10 + "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
11 )
12
13 func init() {
@@ -55,7 +56,9 @@ func (MockDNSProvider) SetRecords(ctx context.Context, zone string, recs []libdn
56 }
57
58 // Interface guard
58 -var _ caddyfile.Unmarshaler = (*MockDNSProvider)(nil)
59 -var _ certmagic.DNSProvider = (*MockDNSProvider)(nil)
60 -var _ caddy.Provisioner = (*MockDNSProvider)(nil)
61 -var _ caddy.Module = (*MockDNSProvider)(nil)
59 +var (
60 + _ caddyfile.Unmarshaler = (*MockDNSProvider)(nil)
61 + _ certmagic.DNSProvider = (*MockDNSProvider)(nil)
62 + _ caddy.Provisioner = (*MockDNSProvider)(nil)
63 + _ caddy.Module = (*MockDNSProvider)(nil)
64 +)
caddytest/integration/stream_test.go
+2 -1
@@ -13,9 +13,10 @@ import (
13 "testing"
14 "time"
15
16 - "github.com/caddyserver/caddy/v2/caddytest"
16 "golang.org/x/net/http2"
17 "golang.org/x/net/http2/h2c"
18 +
19 + "github.com/caddyserver/caddy/v2/caddytest"
20 )
21
22 // (see https://github.com/caddyserver/caddy/issues/3556 for use case)
cmd/main.go
+1 -1
@@ -418,7 +418,7 @@ func parseEnvFile(envInput io.Reader) (map[string]string, error) {
418 // quoted value: support newlines
419 if strings.HasPrefix(val, `"`) || strings.HasPrefix(val, "'") {
420 quote := string(val[0])
421 - for !(strings.HasSuffix(line, quote) && !strings.HasSuffix(line, `\`+quote)) {
421 + for !strings.HasSuffix(line, quote) || strings.HasSuffix(line, `\`+quote) {
422 val = strings.ReplaceAll(val, `\`+quote, quote)
423 if !scanner.Scan() {
424 break
cmd/main_test.go
-3
@@ -235,7 +235,6 @@ func Test_isCaddyfile(t *testing.T) {
235 wantErr: false,
236 },
237 {
238 -
238 name: "json is not caddyfile but not error",
239 args: args{
240 configFile: "./Caddyfile.json",
@@ -245,7 +244,6 @@ func Test_isCaddyfile(t *testing.T) {
244 wantErr: false,
245 },
246 {
248 -
247 name: "prefix of Caddyfile and ./ with any extension is Caddyfile",
248 args: args{
249 configFile: "./Caddyfile.prd",
@@ -255,7 +253,6 @@ func Test_isCaddyfile(t *testing.T) {
253 wantErr: false,
254 },
255 {
258 -
256 name: "prefix of Caddyfile without ./ with any extension is Caddyfile",
257 args: args{
258 configFile: "Caddyfile.prd",
cmd/packagesfuncs.go
+1 -1
@@ -84,7 +84,7 @@ func cmdAddPackage(fl Flags) (int, error) {
84 return caddy.ExitCodeFailedStartup, fmt.Errorf("invalid module name: %v", err)
85 }
86 // only allow a version to be specified if it's different from the existing version
87 - if _, ok := pluginPkgs[module]; ok && !(version != "" && pluginPkgs[module].Version != version) {
87 + if _, ok := pluginPkgs[module]; ok && (version == "" || pluginPkgs[module].Version == version) {
88 return caddy.ExitCodeFailedStartup, fmt.Errorf("package is already added")
89 }
90 pluginPkgs[module] = pluginPackage{Version: version, Path: module}
listeners_test.go
+6 -8
@@ -30,7 +30,7 @@ func TestSplitNetworkAddress(t *testing.T) {
30 expectErr bool
31 }{
32 {
33 - input: "",
33 + input: "",
34 expectHost: "",
35 },
36 {
@@ -41,7 +41,7 @@ func TestSplitNetworkAddress(t *testing.T) {
41 input: ":", // empty host & empty port
42 },
43 {
44 - input: "::",
44 + input: "::",
45 expectHost: "::",
46 },
47 {
@@ -184,9 +184,8 @@ func TestParseNetworkAddress(t *testing.T) {
184 expectErr bool
185 }{
186 {
187 - input: "",
188 - expectAddr: NetworkAddress{
189 - },
187 + input: "",
188 + expectAddr: NetworkAddress{},
189 },
190 {
191 input: ":",
@@ -311,9 +310,8 @@ func TestParseNetworkAddressWithDefaults(t *testing.T) {
310 expectErr bool
311 }{
312 {
314 - input: "",
315 - expectAddr: NetworkAddress{
316 - },
313 + input: "",
314 + expectAddr: NetworkAddress{},
315 },
316 {
317 input: ":",
modules/caddyhttp/autohttps.go
+1 -1
@@ -343,7 +343,7 @@ uniqueDomainsLoop:
343 // match on known domain names, unless it's our special case of a
344 // catch-all which is an empty string (common among catch-all sites
345 // that enable on-demand TLS for yet-unknown domain names)
346 - if !(len(domains) == 1 && domains[0] == "") {
346 + if len(domains) != 1 || domains[0] != "" {
347 matcherSet = append(matcherSet, MatchHost(domains))
348 }
349
modules/caddyhttp/fileserver/matcher.go
+5 -4
@@ -252,7 +252,7 @@ func celFileMatcherMacroExpander() parser.MacroExpander {
252 }
253
254 for _, arg := range args {
255 - if !(isCELStringLiteral(arg) || isCELCaddyPlaceholderCall(arg)) {
255 + if !isCELStringLiteral(arg) && !isCELCaddyPlaceholderCall(arg) {
256 return nil, &common.Error{
257 Location: eh.OffsetLocation(arg.ID()),
258 Message: "matcher only supports repeated string literal arguments",
@@ -616,15 +616,16 @@ func isCELTryFilesLiteral(e ast.Expr) bool {
616 return false
617 }
618 mapKeyStr := mapKey.AsLiteral().ConvertToType(types.StringType).Value()
619 - if mapKeyStr == "try_files" || mapKeyStr == "split_path" {
619 + switch mapKeyStr {
620 + case "try_files", "split_path":
621 if !isCELStringListLiteral(mapVal) {
622 return false
623 }
623 - } else if mapKeyStr == "try_policy" || mapKeyStr == "root" {
624 + case "try_policy", "root":
625 if !(isCELStringExpr(mapVal)) {
626 return false
627 }
627 - } else {
628 + default:
629 return false
630 }
631 }
modules/caddyhttp/matchers.go
-1
@@ -552,7 +552,6 @@ func (MatchPath) matchPatternWithEscapeSequence(escapedPath, matchPath string) b
552 if iPattern >= len(matchPath) || iPath >= len(escapedPath) {
553 break
554 }
555 -
555 // get the next character from the request path
556
557 pathCh := string(escapedPath[iPath])
modules/caddyhttp/metrics_test.go
+2 -1
@@ -9,8 +9,9 @@ import (
9 "sync"
10 "testing"
11
12 - "github.com/caddyserver/caddy/v2"
12 "github.com/prometheus/client_golang/prometheus/testutil"
13 +
14 + "github.com/caddyserver/caddy/v2"
15 )
16
17 func TestServerNameFromContext(t *testing.T) {
modules/caddyhttp/replacer.go
+3 -3
@@ -363,13 +363,13 @@ func addHTTPVarsToReplacer(repl *caddy.Replacer, req *http.Request, w http.Respo
363 }
364 }
365
366 - switch {
367 - case key == "http.shutting_down":
366 + switch key {
367 + case "http.shutting_down":
368 server := req.Context().Value(ServerCtxKey).(*Server)
369 server.shutdownAtMu.RLock()
370 defer server.shutdownAtMu.RUnlock()
371 return !server.shutdownAt.IsZero(), true
372 - case key == "http.time_until_shutdown":
372 + case "http.time_until_shutdown":
373 server := req.Context().Value(ServerCtxKey).(*Server)
374 server.shutdownAtMu.RLock()
375 defer server.shutdownAtMu.RUnlock()
modules/caddyhttp/reverseproxy/caddyfile.go
+3 -2
@@ -665,9 +665,10 @@ func (h *Handler) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
665 if d.NextArg() {
666 return d.ArgErr()
667 }
668 - if subdir == "request_buffers" {
668 + switch subdir {
669 + case "request_buffers":
670 h.RequestBuffers = size
670 - } else if subdir == "response_buffers" {
671 + case "response_buffers":
672 h.ResponseBuffers = size
673 }
674
modules/caddyhttp/reverseproxy/command.go
+3 -2
@@ -122,9 +122,10 @@ func cmdReverseProxy(fs caddycmd.Flags) (int, error) {
122 }
123 }
124 if fromAddr.Port == "" {
125 - if fromAddr.Scheme == "http" {
125 + switch fromAddr.Scheme {
126 + case "http":
127 fromAddr.Port = httpPort
127 - } else if fromAddr.Scheme == "https" {
128 + case "https":
129 fromAddr.Port = httpsPort
130 }
131 }
modules/caddyhttp/reverseproxy/healthchecks.go
+1 -1
@@ -484,7 +484,7 @@ func (h *Handler) doActiveHealthCheck(dialInfo DialInfo, hostAddr string, networ
484
485 markHealthy := func() {
486 // increment passes and then check if it has reached the threshold to be healthy
487 - err := upstream.Host.countHealthPass(1)
487 + err := upstream.countHealthPass(1)
488 if err != nil {
489 if c := h.HealthChecks.Active.logger.Check(zapcore.ErrorLevel, "could not count active health pass"); c != nil {
490 c.Write(
modules/caddyhttp/reverseproxy/reverseproxy.go
+1 -1
@@ -1150,7 +1150,7 @@ func (lb LoadBalancing) tryAgain(ctx caddy.Context, start time.Time, retries int
1150 // we have to assume the upstream received the request, and
1151 // retries need to be carefully decided, because some requests
1152 // are not idempotent
1153 - if !isDialError && !(isHandlerError && errors.Is(herr, errNoUpstream)) {
1153 + if !isDialError && (!isHandlerError || !errors.Is(herr, errNoUpstream)) {
1154 if lb.RetryMatch == nil && req.Method != "GET" {
1155 // by default, don't retry requests if they aren't GET
1156 return false
modules/caddyhttp/reverseproxy/selectionpolicies.go
+1 -1
@@ -808,7 +808,7 @@ func leastRequests(upstreams []*Upstream) *Upstream {
808 return nil
809 }
810 var best []*Upstream
811 - var bestReqs int = -1
811 + bestReqs := -1
812 for _, upstream := range upstreams {
813 if upstream == nil {
814 continue
modules/caddyhttp/reverseproxy/upstreams_test.go
-1
@@ -52,5 +52,4 @@ func TestResolveIpVersion(t *testing.T) {
52 t.Errorf("resolveIpVersion(): Expected %s got %s", test.expectedIpVersion, ipVersion)
53 }
54 }
55 -
55 }
modules/caddyhttp/rewrite/rewrite.go
+1 -5
@@ -377,11 +377,7 @@ func buildQueryString(qs string, repl *caddy.Replacer) string {
377 // performed in normalized/unescaped space.
378 func trimPathPrefix(escapedPath, prefix string) string {
379 var iPath, iPrefix int
380 - for {
381 - if iPath >= len(escapedPath) || iPrefix >= len(prefix) {
382 - break
383 - }
384 -
380 + for iPath < len(escapedPath) && iPrefix < len(prefix) {
381 prefixCh := prefix[iPrefix]
382 ch := string(escapedPath[iPath])
383
modules/caddyhttp/server_test.go
+1
@@ -171,6 +171,7 @@ func BenchmarkServer_LogRequest_WithTrace(b *testing.B) {
171 s.logRequest(accLog, req, wrec, &duration, repl, bodyReader, false)
172 }
173 }
174 +
175 func TestServer_TrustedRealClientIP_NoTrustedHeaders(t *testing.T) {
176 req := httptest.NewRequest("GET", "/", nil)
177 req.RemoteAddr = "192.0.2.1:12345"
modules/caddytls/automation.go
+2 -4
@@ -388,10 +388,8 @@ func (ap *AutomationPolicy) onlyInternalIssuer() bool {
388 // isWildcardOrDefault determines if the subjects include any wildcard domains,
389 // or is the "default" policy (i.e. no subjects) which is unbounded.
390 func (ap *AutomationPolicy) isWildcardOrDefault() bool {
391 - isWildcardOrDefault := false
392 - if len(ap.subjects) == 0 {
393 - isWildcardOrDefault = true
394 - }
391 + isWildcardOrDefault := len(ap.subjects) == 0
392 +
393 for _, sub := range ap.subjects {
394 if strings.HasPrefix(sub, "*") {
395 isWildcardOrDefault = true
modules/logging/filewriter_test.go
+2 -2
@@ -317,7 +317,7 @@ func TestFileModeToJSON(t *testing.T) {
317 }{
318 {
319 name: "none zero",
320 - mode: 0644,
320 + mode: 0o644,
321 want: `"0644"`,
322 wantErr: false,
323 },
@@ -358,7 +358,7 @@ func TestFileModeModification(t *testing.T) {
358 defer os.RemoveAll(dir)
359
360 fpath := path.Join(dir, "test.log")
361 - f_tmp, err := os.OpenFile(fpath, os.O_WRONLY|os.O_APPEND|os.O_CREATE, os.FileMode(0600))
361 + f_tmp, err := os.OpenFile(fpath, os.O_WRONLY|os.O_APPEND|os.O_CREATE, os.FileMode(0o600))
362 if err != nil {
363 t.Fatalf("failed to create test file: %v", err)
364 }
modules/logging/filters_test.go
+2 -1
@@ -3,9 +3,10 @@ package logging
3 import (
4 "testing"
5
6 + "go.uber.org/zap/zapcore"
7 +
8 "github.com/caddyserver/caddy/v2"
9 "github.com/caddyserver/caddy/v2/modules/caddyhttp"
8 - "go.uber.org/zap/zapcore"
10 )
11
12 func TestIPMaskSingleValue(t *testing.T) {