diff --git a/.golangci.yml b/.golangci.yml index 5f018970eb7..6b74098af5d 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,4 +1,74 @@ linters-settings: + revive: + enable-all-rules: true + # Do NOT whine about the following, full explanation found in: + # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md#description-of-available-rules + rules: + - name: use-any + disabled: true + - name: if-return + disabled: true + - name: max-public-structs + disabled: true + - name: cognitive-complexity + disabled: true + - name: argument-limit + disabled: true + - name: cyclomatic + disabled: true + - name: file-header + disabled: true + - name: function-length + disabled: true + - name: function-result-limit + disabled: true + - name: line-length-limit + disabled: true + - name: flag-parameter + disabled: true + - name: add-constant + disabled: true + - name: empty-lines + disabled: true + - name: banned-characters + disabled: true + - name: deep-exit + disabled: true + - name: confusing-results + disabled: true + - name: unused-parameter + disabled: true + - name: modifies-value-receiver + disabled: true + - name: early-return + disabled: true + - name: unnecessary-stmt + disabled: true + - name: import-shadowing + disabled: true + - name: defer + disabled: true + - name: confusing-naming + disabled: true + - name: nested-structs + disabled: true + - name: unhandled-error + disabled: true + # Arguments added below do not trigger the rule. + # arguments =["os\.(Create|WriteFile|Chmod)", "fmt\.Print", "myFunction", "net\..*", "bytes\.Buffer\.Write"] + arguments: + - 'fmt\..*' + - 'c.Conn.Close' + - 'server.Serve' + - 'http.ListenAndServe' + - 'conn.Close' + - 'os.Stderr.Write' + - 'buf\.(WriteString|Write)' + - 'csc.Close' + - 'cl.Close' + - 'out.WriteRune' + - 'sb\.(WriteRune|WriteString)' + - 'reconn.Conn.Close' errcheck: ignore: fmt:.*,go.uber.org/zap/zapcore:^Add.* ignoretests: true @@ -27,9 +97,12 @@ linters: - gosimple - govet - ineffassign + - nolintlint - misspell - prealloc + - revive - staticcheck + - thelper - typecheck - unconvert - unused @@ -51,7 +124,6 @@ linters: # - godot # - godox # - goerr113 - # - gofumpt # - goheader # - golint # - gomnd @@ -88,6 +160,8 @@ output: print-linter-name: true issues: + max-issues-per-linter: 0 + max-same-issues: 0 exclude-rules: # we aren't calling unknown URL - text: 'G107' # G107: Url provided to HTTP request as taint input diff --git a/admin.go b/admin.go index 335b8e89545..3bf828228ab 100644 --- a/admin.go +++ b/admin.go @@ -915,7 +915,7 @@ func (h adminHandler) checkOrigin(r *http.Request) (string, error) { return origin.String(), nil } -func (h adminHandler) getOrigin(r *http.Request) (string, *url.URL) { +func (adminHandler) getOrigin(r *http.Request) (string, *url.URL) { origin := r.Header.Get("Origin") if origin == "" { origin = r.Header.Get("Referer") @@ -961,9 +961,11 @@ func handleConfig(w http.ResponseWriter, r *http.Request) error { // Set the ETag as a trailer header. // The alternative is to write the config to a buffer, and // then hash that. + w.Header().Set("Trailer", "ETag") hash := etagHasher() + configWriter := io.MultiWriter(w, hash) err := readConfig(r.URL.Path, configWriter) if err != nil { @@ -1022,7 +1024,7 @@ func handleConfig(w http.ResponseWriter, r *http.Request) error { return nil } -func handleConfigID(w http.ResponseWriter, r *http.Request) error { +func handleConfigID(_ http.ResponseWriter, r *http.Request) error { idPath := r.URL.Path parts := strings.Split(idPath, "/") diff --git a/admin_test.go b/admin_test.go index 04aa8867fc3..e93d09b8d33 100644 --- a/admin_test.go +++ b/admin_test.go @@ -194,6 +194,9 @@ func TestETags(t *testing.T) { func BenchmarkLoad(b *testing.B) { for i := 0; i < b.N; i++ { - Load(testCfg, true) + err := Load(testCfg, true) + if err != nil { + b.Fatal(err) + } } } diff --git a/caddy.go b/caddy.go index 8e7dce50764..69e5652a5e4 100644 --- a/caddy.go +++ b/caddy.go @@ -884,11 +884,11 @@ func Version() (simple, full string) { if CustomVersion != "" { full = CustomVersion simple = CustomVersion - return + return full, simple } full = "unknown" simple = "unknown" - return + return full, simple } // find the Caddy module in the dependency list for _, dep := range bi.Deps { @@ -968,7 +968,7 @@ func Version() (simple, full string) { } } - return + return simple, full } // ActiveContext returns the currently-active context. diff --git a/caddyconfig/caddyfile/dispenser.go b/caddyconfig/caddyfile/dispenser.go index 215a1641f73..99a93a0f581 100644 --- a/caddyconfig/caddyfile/dispenser.go +++ b/caddyconfig/caddyfile/dispenser.go @@ -236,8 +236,8 @@ func (d *Dispenser) ScalarVal() any { if num, err := strconv.ParseFloat(text, 64); err == nil { return num } - if bool, err := strconv.ParseBool(text); err == nil { - return bool + if boolean, err := strconv.ParseBool(text); err == nil { + return boolean } return text } diff --git a/caddyconfig/caddyfile/dispenser_test.go b/caddyconfig/caddyfile/dispenser_test.go index b64a97354d4..0f6ee5043f4 100644 --- a/caddyconfig/caddyfile/dispenser_test.go +++ b/caddyconfig/caddyfile/dispenser_test.go @@ -305,7 +305,7 @@ func TestDispenser_ArgErr_Err(t *testing.T) { t.Errorf("Expected error message with custom message in it ('foobar'); got '%v'", err) } - var ErrBarIsFull = errors.New("bar is full") + ErrBarIsFull := errors.New("bar is full") bookingError := d.Errf("unable to reserve: %w", ErrBarIsFull) if !errors.Is(bookingError, ErrBarIsFull) { t.Errorf("Errf(): should be able to unwrap the error chain") diff --git a/caddyconfig/caddyfile/formatter.go b/caddyconfig/caddyfile/formatter.go index 82581a3d31e..814185c3c4e 100644 --- a/caddyconfig/caddyfile/formatter.go +++ b/caddyconfig/caddyfile/formatter.go @@ -81,10 +81,10 @@ func Format(input []byte) []byte { space = true nextLine() continue - } else { - write(ch) - continue } + write(ch) + continue + } if !escaped && ch == '\\' { @@ -125,13 +125,13 @@ func Format(input []byte) []byte { spacePrior := space space = false - ////////////////////////////////////////////////////////// + // //////////////////////////////////////////////////////// // I find it helpful to think of the formatting loop in two // main sections; by the time we reach this point, we // know we are in a "regular" part of the file: we know // the character is not a space, not in a literal segment // like a comment or quoted, it's not escaped, etc. - ////////////////////////////////////////////////////////// + // //////////////////////////////////////////////////////// if ch == '#' { comment = true diff --git a/caddyconfig/caddyfile/formatter_test.go b/caddyconfig/caddyfile/formatter_test.go index 8e5b3686069..d7bbb7ca543 100644 --- a/caddyconfig/caddyfile/formatter_test.go +++ b/caddyconfig/caddyfile/formatter_test.go @@ -375,7 +375,7 @@ block { if string(actual) != tc.expect { t.Errorf("\n[TEST %d: %s]\n====== EXPECTED ======\n%s\n====== ACTUAL ======\n%s^^^^^^^^^^^^^^^^^^^^^", - i, tc.description, string(tc.expect), string(actual)) + i, tc.description, tc.expect, string(actual)) } } } diff --git a/caddyconfig/caddyfile/lexer_test.go b/caddyconfig/caddyfile/lexer_test.go index 92acc4da9f3..ab55386f12b 100644 --- a/caddyconfig/caddyfile/lexer_test.go +++ b/caddyconfig/caddyfile/lexer_test.go @@ -468,6 +468,7 @@ EOF same-line-arg } func lexerCompare(t *testing.T, n int, expected, actual []Token) { + t.Helper() if len(expected) != len(actual) { t.Fatalf("Test case %d: expected %d token(s) but got %d", n, len(expected), len(actual)) } diff --git a/caddyconfig/caddyfile/parse.go b/caddyconfig/caddyfile/parse.go index 65d6ee92765..c4cb2b51ea4 100644 --- a/caddyconfig/caddyfile/parse.go +++ b/caddyconfig/caddyfile/parse.go @@ -446,7 +446,7 @@ func (p *parser) doImport(nesting int) error { var ( maybeSnippet bool - maybeSnippetId bool + maybeSnippetID bool index int ) @@ -472,16 +472,16 @@ func (p *parser) doImport(nesting int) error { } if index == 0 && len(token.Text) >= 3 && strings.HasPrefix(token.Text, "(") && strings.HasSuffix(token.Text, ")") { - maybeSnippetId = true + maybeSnippetID = true } } switch token.Text { case "{": nesting++ - if index == 1 && maybeSnippetId && nesting == 1 { + if index == 1 && maybeSnippetID && nesting == 1 { maybeSnippet = true - maybeSnippetId = false + maybeSnippetID = false } case "}": nesting-- diff --git a/caddyconfig/caddyfile/parse_test.go b/caddyconfig/caddyfile/parse_test.go index b1104edf943..675accec021 100644 --- a/caddyconfig/caddyfile/parse_test.go +++ b/caddyconfig/caddyfile/parse_test.go @@ -22,7 +22,7 @@ import ( ) func TestParseVariadic(t *testing.T) { - var args = make([]string, 10) + args := make([]string, 10) for i, tc := range []struct { input string result bool @@ -107,7 +107,6 @@ func TestAllTokens(t *testing.T) { input := []byte("a b c\nd e") expected := []string{"a", "b", "c", "d", "e"} tokens, err := allTokens("TestAllTokens", input) - if err != nil { t.Fatalf("Expected no error, got %v", err) } @@ -145,10 +144,11 @@ func TestParseOneAndImport(t *testing.T) { "localhost", }, []int{1}}, - {`localhost:1234 + { + `localhost:1234 dir1 foo bar`, false, []string{ - "localhost:1234", - }, []int{3}, + "localhost:1234", + }, []int{3}, }, {`localhost { @@ -403,13 +403,13 @@ func TestRecursiveImport(t *testing.T) { err = os.WriteFile(recursiveFile1, []byte( `localhost dir1 - import recursive_import_test2`), 0644) + import recursive_import_test2`), 0o600) if err != nil { t.Fatal(err) } defer os.Remove(recursiveFile1) - err = os.WriteFile(recursiveFile2, []byte("dir2 1"), 0644) + err = os.WriteFile(recursiveFile2, []byte("dir2 1"), 0o600) if err != nil { t.Fatal(err) } @@ -437,7 +437,7 @@ func TestRecursiveImport(t *testing.T) { err = os.WriteFile(recursiveFile1, []byte( `localhost dir1 - import `+recursiveFile2), 0644) + import `+recursiveFile2), 0o600) if err != nil { t.Fatal(err) } @@ -491,7 +491,7 @@ func TestDirectiveImport(t *testing.T) { } err = os.WriteFile(directiveFile, []byte(`prop1 1 - prop2 2`), 0644) + prop2 2`), 0o600) if err != nil { t.Fatal(err) } @@ -780,6 +780,7 @@ func TestSnippets(t *testing.T) { } func writeStringToTempFileOrDie(t *testing.T, str string) (pathToFile string) { + t.Helper() file, err := os.CreateTemp("", t.Name()) if err != nil { panic(err) // get a stack trace so we know where this was called from. diff --git a/caddyconfig/httpcaddyfile/addresses.go b/caddyconfig/httpcaddyfile/addresses.go index 658da48ed64..14b4671fb01 100644 --- a/caddyconfig/httpcaddyfile/addresses.go +++ b/caddyconfig/httpcaddyfile/addresses.go @@ -150,7 +150,7 @@ func (st *ServerType) mapAddressToServerBlocks(originalServerBlocks []serverBloc // entries are deleted from the addrToServerBlocks map. Essentially, each pairing (each // association from multiple addresses to multiple server blocks; i.e. each element of // the returned slice) becomes a server definition in the output JSON. -func (st *ServerType) consolidateAddrMappings(addrToServerBlocks map[string][]serverBlock) []sbAddrAssociation { +func (*ServerType) consolidateAddrMappings(addrToServerBlocks map[string][]serverBlock) []sbAddrAssociation { sbaddrs := make([]sbAddrAssociation, 0, len(addrToServerBlocks)) for addr, sblocks := range addrToServerBlocks { // we start with knowing that at least this address @@ -188,7 +188,7 @@ func (st *ServerType) consolidateAddrMappings(addrToServerBlocks map[string][]se // listenerAddrsForServerBlockKey essentially converts the Caddyfile // site addresses to Caddy listener addresses for each server block. -func (st *ServerType) listenerAddrsForServerBlockKey(sblock serverBlock, key string, +func (*ServerType) listenerAddrsForServerBlockKey(sblock serverBlock, key string, options map[string]any, ) ([]string, error) { addr, err := ParseAddress(key) diff --git a/caddyconfig/httpcaddyfile/directives.go b/caddyconfig/httpcaddyfile/directives.go index 13229ed5cd4..ca2004f2d35 100644 --- a/caddyconfig/httpcaddyfile/directives.go +++ b/caddyconfig/httpcaddyfile/directives.go @@ -272,7 +272,7 @@ func (h Helper) GroupRoutes(vals []ConfigValue) { // NewBindAddresses returns config values relevant to adding // listener bind addresses to the config. -func (h Helper) NewBindAddresses(addrs []string) []ConfigValue { +func (Helper) NewBindAddresses(addrs []string) []ConfigValue { return []ConfigValue{{Class: "bind", Value: addrs}} } diff --git a/caddyconfig/httpcaddyfile/directives_test.go b/caddyconfig/httpcaddyfile/directives_test.go index e46a6d2af7b..db028229950 100644 --- a/caddyconfig/httpcaddyfile/directives_test.go +++ b/caddyconfig/httpcaddyfile/directives_test.go @@ -31,20 +31,23 @@ func TestHostsFromKeys(t *testing.T) { []Address{ {Original: ":2015", Port: "2015"}, }, - []string{}, []string{}, + []string{}, + []string{}, }, { []Address{ {Original: ":443", Port: "443"}, }, - []string{}, []string{}, + []string{}, + []string{}, }, { []Address{ {Original: "foo", Host: "foo"}, {Original: ":2015", Port: "2015"}, }, - []string{}, []string{"foo"}, + []string{}, + []string{"foo"}, }, { []Address{ diff --git a/caddyconfig/httpcaddyfile/httptype.go b/caddyconfig/httpcaddyfile/httptype.go index 78fb7f062a1..87073aab676 100644 --- a/caddyconfig/httpcaddyfile/httptype.go +++ b/caddyconfig/httpcaddyfile/httptype.go @@ -1259,7 +1259,7 @@ func matcherSetFromMatcherToken( return nil, false, nil } -func (st *ServerType) compileEncodedMatcherSets(sblock serverBlock) ([]caddy.ModuleMap, error) { +func (*ServerType) compileEncodedMatcherSets(sblock serverBlock) ([]caddy.ModuleMap, error) { type hostPathPair struct { hostm caddyhttp.MatchHost pathm caddyhttp.MatchPath diff --git a/caddyconfig/httpcaddyfile/pkiapp.go b/caddyconfig/httpcaddyfile/pkiapp.go index b5c682187d9..366e60b2001 100644 --- a/caddyconfig/httpcaddyfile/pkiapp.go +++ b/caddyconfig/httpcaddyfile/pkiapp.go @@ -169,7 +169,7 @@ func parsePKIApp(d *caddyfile.Dispenser, existingVal any) (any, error) { return pki, nil } -func (st ServerType) buildPKIApp( +func (ServerType) buildPKIApp( pairings []sbAddrAssociation, options map[string]any, warnings []caddyconfig.Warning, diff --git a/caddyconfig/httpcaddyfile/tlsapp.go b/caddyconfig/httpcaddyfile/tlsapp.go index 927f225df3a..5b1d231af1e 100644 --- a/caddyconfig/httpcaddyfile/tlsapp.go +++ b/caddyconfig/httpcaddyfile/tlsapp.go @@ -32,7 +32,7 @@ import ( "github.com/caddyserver/caddy/v2/modules/caddytls" ) -func (st ServerType) buildTLSApp( +func (ServerType) buildTLSApp( pairings []sbAddrAssociation, options map[string]any, warnings []caddyconfig.Warning, diff --git a/caddyconfig/httploader.go b/caddyconfig/httploader.go index e0ce4ebf7a6..6397b7aa25a 100644 --- a/caddyconfig/httploader.go +++ b/caddyconfig/httploader.go @@ -105,7 +105,7 @@ func (hl HTTPLoader) LoadConfig(ctx caddy.Context) ([]byte, error) { } } - resp, err := doHttpCallWithRetries(ctx, client, req) + resp, err := doHTTPCallWithRetries(ctx, client, req) if err != nil { return nil, err } @@ -135,7 +135,7 @@ func (hl HTTPLoader) LoadConfig(ctx caddy.Context) ([]byte, error) { return result, nil } -func attemptHttpCall(client *http.Client, request *http.Request) (*http.Response, error) { +func attemptHTTPCall(client *http.Client, request *http.Request) (*http.Response, error) { resp, err := client.Do(request) if err != nil { return nil, fmt.Errorf("problem calling http loader url: %v", err) @@ -146,13 +146,13 @@ func attemptHttpCall(client *http.Client, request *http.Request) (*http.Response return resp, nil } -func doHttpCallWithRetries(ctx caddy.Context, client *http.Client, request *http.Request) (*http.Response, error) { +func doHTTPCallWithRetries(ctx caddy.Context, client *http.Client, request *http.Request) (*http.Response, error) { var resp *http.Response var err error const maxAttempts = 10 for i := 0; i < maxAttempts; i++ { - resp, err = attemptHttpCall(client, request) + resp, err = attemptHTTPCall(client, request) if err != nil && i < maxAttempts-1 { select { case <-time.After(time.Millisecond * 500): diff --git a/caddytest/caddytest.go b/caddytest/caddytest.go index 9c170703c57..60964bd69f5 100644 --- a/caddytest/caddytest.go +++ b/caddytest/caddytest.go @@ -64,6 +64,7 @@ type Tester struct { // NewTester will create a new testing client with an attached cookie jar func NewTester(t *testing.T) *Tester { + t.Helper() jar, err := cookiejar.New(nil) if err != nil { t.Fatalf("failed to create cookiejar: %s", err) @@ -230,6 +231,7 @@ const initConfig = `{ // validateTestPrerequisites ensures the certificates are available in the // designated path and Caddy sub-process is running. func validateTestPrerequisites(t *testing.T) error { + t.Helper() // check certificates are found for _, certName := range Default.Certifcates { if _, err := os.Stat(getIntegrationDir() + certName); os.IsNotExist(err) { @@ -327,6 +329,7 @@ func CreateTestingTransport() *http.Transport { // AssertLoadError will load a config and expect an error func AssertLoadError(t *testing.T, rawConfig string, configType string, expectedError string) { + t.Helper() tc := NewTester(t) err := tc.initServer(rawConfig, configType) @@ -374,6 +377,7 @@ func (tc *Tester) AssertRedirect(requestURI string, expectedToLocation string, e // CompareAdapt adapts a config and then compares it against an expected result func CompareAdapt(t *testing.T, filename, rawConfig string, adapterName string, expectedResponse string) bool { + t.Helper() cfgAdapter := caddyconfig.GetAdapter(adapterName) if cfgAdapter == nil { t.Logf("unrecognized config adapter '%s'", adapterName) @@ -433,6 +437,7 @@ func CompareAdapt(t *testing.T, filename, rawConfig string, adapterName string, // AssertAdapt adapts a config and then tests it against an expected result func AssertAdapt(t *testing.T, rawConfig string, adapterName string, expectedResponse string) { + t.Helper() ok := CompareAdapt(t, "Caddyfile", rawConfig, adapterName, expectedResponse) if !ok { t.Fail() @@ -442,6 +447,7 @@ func AssertAdapt(t *testing.T, rawConfig string, adapterName string, expectedRes // Generic request functions func applyHeaders(t *testing.T, req *http.Request, requestHeaders []string) { + t.Helper() requestContentType := "" for _, requestHeader := range requestHeaders { arr := strings.SplitAfterN(requestHeader, ":", 2) diff --git a/caddytest/integration/autohttps_test.go b/caddytest/integration/autohttps_test.go index 1dbdbcee209..f4195f218ea 100644 --- a/caddytest/integration/autohttps_test.go +++ b/caddytest/integration/autohttps_test.go @@ -20,7 +20,8 @@ func TestAutoHTTPtoHTTPSRedirectsImplicitPort(t *testing.T) { respond "Yahaha! You found me!" `, "caddyfile") - tester.AssertRedirect("http://localhost:9080/", "https://localhost/", http.StatusPermanentRedirect) + resp := tester.AssertRedirect("http://localhost:9080/", "https://localhost/", http.StatusPermanentRedirect) + resp.Body.Close() } func TestAutoHTTPtoHTTPSRedirectsExplicitPortSameAsHTTPSPort(t *testing.T) { @@ -36,7 +37,9 @@ func TestAutoHTTPtoHTTPSRedirectsExplicitPortSameAsHTTPSPort(t *testing.T) { respond "Yahaha! You found me!" `, "caddyfile") - tester.AssertRedirect("http://localhost:9080/", "https://localhost/", http.StatusPermanentRedirect) + resp := tester.AssertRedirect("http://localhost:9080/", "https://localhost/", http.StatusPermanentRedirect) + resp.Body.Close() + resp.Body.Close() } func TestAutoHTTPtoHTTPSRedirectsExplicitPortDifferentFromHTTPSPort(t *testing.T) { @@ -52,7 +55,8 @@ func TestAutoHTTPtoHTTPSRedirectsExplicitPortDifferentFromHTTPSPort(t *testing.T respond "Yahaha! You found me!" `, "caddyfile") - tester.AssertRedirect("http://localhost:9080/", "https://localhost:1234/", http.StatusPermanentRedirect) + resp := tester.AssertRedirect("http://localhost:9080/", "https://localhost:1234/", http.StatusPermanentRedirect) + resp.Body.Close() } func TestAutoHTTPRedirectsWithHTTPListenerFirstInAddresses(t *testing.T) { diff --git a/caddytest/integration/caddyfile_test.go b/caddytest/integration/caddyfile_test.go index 205bc5b914b..18b9ecc2d51 100644 --- a/caddytest/integration/caddyfile_test.go +++ b/caddytest/integration/caddyfile_test.go @@ -9,7 +9,6 @@ import ( ) func TestRespond(t *testing.T) { - // arrange tester := caddytest.NewTester(t) tester.InitServer(` @@ -32,7 +31,6 @@ func TestRespond(t *testing.T) { } func TestRedirect(t *testing.T) { - // arrange tester := caddytest.NewTester(t) tester.InitServer(` @@ -61,7 +59,6 @@ func TestRedirect(t *testing.T) { } func TestDuplicateHosts(t *testing.T) { - // act and assert caddytest.AssertLoadError(t, ` @@ -76,7 +73,6 @@ func TestDuplicateHosts(t *testing.T) { } func TestReadCookie(t *testing.T) { - localhost, _ := url.Parse("http://localhost") cookie := http.Cookie{ Name: "clientname", @@ -110,7 +106,6 @@ func TestReadCookie(t *testing.T) { } func TestReplIndex(t *testing.T) { - tester := caddytest.NewTester(t) tester.InitServer(` { @@ -133,7 +128,8 @@ func TestReplIndex(t *testing.T) { `, "caddyfile") // act and assert - tester.AssertGetResponse("http://localhost:9080/", 200, "") + resp, _ := tester.AssertGetResponse("http://localhost:9080/", 200, "") + resp.Body.Close() } func TestInvalidPrefix(t *testing.T) { diff --git a/caddytest/integration/reverseproxy_test.go b/caddytest/integration/reverseproxy_test.go index 4f4261b87d0..0beb71afcac 100644 --- a/caddytest/integration/reverseproxy_test.go +++ b/caddytest/integration/reverseproxy_test.go @@ -57,7 +57,6 @@ func TestSRVReverseProxy(t *testing.T) { } func TestDialWithPlaceholderUnix(t *testing.T) { - if runtime.GOOS == "windows" { t.SkipNow() } diff --git a/caddytest/integration/sni_test.go b/caddytest/integration/sni_test.go index 24dddc59afe..188f9354135 100644 --- a/caddytest/integration/sni_test.go +++ b/caddytest/integration/sni_test.go @@ -7,7 +7,6 @@ import ( ) func TestDefaultSNI(t *testing.T) { - // arrange tester := caddytest.NewTester(t) tester.InitServer(`{ @@ -107,7 +106,6 @@ func TestDefaultSNI(t *testing.T) { } func TestDefaultSNIWithNamedHostAndExplicitIP(t *testing.T) { - // arrange tester := caddytest.NewTester(t) tester.InitServer(` diff --git a/caddytest/integration/stream_test.go b/caddytest/integration/stream_test.go index 6bc612d3695..e67b61c13f6 100644 --- a/caddytest/integration/stream_test.go +++ b/caddytest/integration/stream_test.go @@ -13,9 +13,10 @@ import ( "testing" "time" - "github.com/caddyserver/caddy/v2/caddytest" "golang.org/x/net/http2" "golang.org/x/net/http2/h2c" + + "github.com/caddyserver/caddy/v2/caddytest" ) // (see https://github.com/caddyserver/caddy/issues/3556 for use case) @@ -150,6 +151,7 @@ func TestH2ToH2CStream(t *testing.T) { } func testH2ToH2CStreamServeH2C(t *testing.T) *http.Server { + t.Helper() h2s := &http2.Server{} handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { rstring, err := httputil.DumpRequest(r, false) @@ -359,8 +361,8 @@ func TestH2ToH1ChunkedResponse(t *testing.T) { } func testH2ToH1ChunkedResponseServeH1(t *testing.T) *http.Server { + t.Helper() handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if r.Host != "127.0.0.1:9443" { t.Errorf("r.Host doesn't match, %v!", r.Host) w.WriteHeader(http.StatusNotFound) diff --git a/cmd/commandfuncs.go b/cmd/commandfuncs.go index 8963988616e..4d215cd676e 100644 --- a/cmd/commandfuncs.go +++ b/cmd/commandfuncs.go @@ -650,7 +650,7 @@ func AdminAPIRequest(adminAddr, method, uri string, headers http.Header, body io if err != nil { return nil, fmt.Errorf("making request: %v", err) } - if parsedAddr.IsUnixNetwork() { + if parsedAddr.IsUnixNetwork() { //nolint:revive // We used to conform to RFC 2616 Section 14.26 which requires // an empty host header when there is no host, as is the case // with unix sockets. However, Go required a Host value so we diff --git a/cmd/main.go b/cmd/main.go index b4e3fdc87bf..c55ec8a61dd 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -211,7 +211,6 @@ func watchConfigFile(filename, adapterName string) { logger().Info("watching config file for changes") // begin poller - //nolint:staticcheck for range time.Tick(1 * time.Second) { // get current config newCfg, _, err := loadConfigWithLogger(nil, filename, adapterName) diff --git a/cmd/packagesfuncs.go b/cmd/packagesfuncs.go index 5d77e4d5451..c9170852a60 100644 --- a/cmd/packagesfuncs.go +++ b/cmd/packagesfuncs.go @@ -179,7 +179,7 @@ func getModules() (standard, nonstandard, unknown []moduleInfo, err error) { bi, ok := debug.ReadBuildInfo() if !ok { err = fmt.Errorf("no build info") - return + return standard, nonstandard, unknown, err } for _, modID := range caddy.Modules() { @@ -222,7 +222,7 @@ func getModules() (standard, nonstandard, unknown []moduleInfo, err error) { nonstandard = append(nonstandard, caddyModGoMod) } } - return + return standard, nonstandard, unknown, nil } func listModules(path string) error { diff --git a/listeners.go b/listeners.go index 768d977115c..756e39d7b05 100644 --- a/listeners.go +++ b/listeners.go @@ -392,11 +392,11 @@ func SplitNetworkAddress(a string) (network, host, port string, err error) { } if IsUnixNetwork(network) { host = a - return + return network, host, port, nil } host, port, err = net.SplitHostPort(a) if err == nil || a == "" { - return + return network, host, port, err } // in general, if there was an error, it was likely "missing port", // so try adding a bogus port to take advantage of standard library's @@ -408,7 +408,7 @@ func SplitNetworkAddress(a string) (network, host, port string, err error) { err = nil port = "" } - return + return network, host, port, err } // JoinNetworkAddress combines network, host, and port into a single @@ -479,8 +479,8 @@ func ListenQUIC(ln net.PacketConn, tlsConf *tls.Config, activeRequests *int64) ( sqtc := newSharedQUICTLSConfig(tlsConf) // http3.ConfigureTLSConfig only uses this field and tls App sets this field as well //nolint:gosec - quicTlsConfig := &tls.Config{GetConfigForClient: sqtc.getConfigForClient} - earlyLn, err := quic.ListenEarly(ln, http3.ConfigureTLSConfig(quicTlsConfig), &quic.Config{ + quicTLSConfig := &tls.Config{GetConfigForClient: sqtc.getConfigForClient} + earlyLn, err := quic.ListenEarly(ln, http3.ConfigureTLSConfig(quicTLSConfig), &quic.Config{ Allow0RTT: true, RequireAddressValidation: func(clientAddr net.Addr) bool { var highLoad bool @@ -539,14 +539,14 @@ type contextAndCancelFunc struct { type sharedQUICTLSConfig struct { rmu sync.RWMutex tlsConfs map[*tls.Config]contextAndCancelFunc - activeTlsConf *tls.Config + activeTLSConf *tls.Config } // newSharedQUICTLSConfig creates a new sharedQUICTLSConfig func newSharedQUICTLSConfig(tlsConfig *tls.Config) *sharedQUICTLSConfig { sqtc := &sharedQUICTLSConfig{ tlsConfs: make(map[*tls.Config]contextAndCancelFunc), - activeTlsConf: tlsConfig, + activeTLSConf: tlsConfig, } sqtc.addTLSConfig(tlsConfig) return sqtc @@ -556,7 +556,7 @@ func newSharedQUICTLSConfig(tlsConfig *tls.Config) *sharedQUICTLSConfig { func (sqtc *sharedQUICTLSConfig) getConfigForClient(ch *tls.ClientHelloInfo) (*tls.Config, error) { sqtc.rmu.RLock() defer sqtc.rmu.RUnlock() - return sqtc.activeTlsConf.GetConfigForClient(ch) + return sqtc.activeTLSConf.GetConfigForClient(ch) } // addTLSConfig adds tls.Config to the map if not present and returns the corresponding context and its cancelFunc @@ -577,11 +577,11 @@ func (sqtc *sharedQUICTLSConfig) addTLSConfig(tlsConfig *tls.Config) (context.Co defer sqtc.rmu.Unlock() delete(sqtc.tlsConfs, tlsConfig) - if sqtc.activeTlsConf == tlsConfig { + if sqtc.activeTLSConf == tlsConfig { // select another tls.Config, if there is none, // related sharedQuicListener will be destroyed anyway for tc := range sqtc.tlsConfs { - sqtc.activeTlsConf = tc + sqtc.activeTLSConf = tc break } } diff --git a/logging.go b/logging.go index 98b031c6a2a..e975c0b9307 100644 --- a/logging.go +++ b/logging.go @@ -627,7 +627,7 @@ func (DiscardWriter) OpenWriter() (io.WriteCloser, error) { // notClosable is an io.WriteCloser that can't be closed. type notClosable struct{ io.Writer } -func (fc notClosable) Close() error { return nil } +func (notClosable) Close() error { return nil } type defaultCustomLog struct { *CustomLog diff --git a/modules/caddyevents/app.go b/modules/caddyevents/app.go index 1684cfd2a6c..34c18c30d53 100644 --- a/modules/caddyevents/app.go +++ b/modules/caddyevents/app.go @@ -156,7 +156,7 @@ func (app *App) Start() error { } // Stop gracefully shuts down the app. -func (app *App) Stop() error { +func (*App) Stop() error { return nil } diff --git a/modules/caddyhttp/autohttps.go b/modules/caddyhttp/autohttps.go index aec43c7c7af..f75d805b401 100644 --- a/modules/caddyhttp/autohttps.go +++ b/modules/caddyhttp/autohttps.go @@ -68,7 +68,7 @@ type AutoHTTPSConfig struct { // Skipped returns true if name is in skipSlice, which // should be either the Skip or SkipCerts field on ahc. -func (ahc AutoHTTPSConfig) Skipped(name string, skipSlice []string) bool { +func (AutoHTTPSConfig) Skipped(name string, skipSlice []string) bool { for _, n := range skipSlice { if name == n { return true diff --git a/modules/caddyhttp/celmatcher.go b/modules/caddyhttp/celmatcher.go index e997336ff8a..3a5a3fb6688 100644 --- a/modules/caddyhttp/celmatcher.go +++ b/modules/caddyhttp/celmatcher.go @@ -228,7 +228,7 @@ func (cr celHTTPRequest) ResolveName(name string) (any, bool) { return nil, false } -func (cr celHTTPRequest) Parent() interpreter.Activation { +func (celHTTPRequest) Parent() interpreter.Activation { return nil } diff --git a/modules/caddyhttp/encode/encode.go b/modules/caddyhttp/encode/encode.go index ed3e59dae1d..18dd129bc4a 100644 --- a/modules/caddyhttp/encode/encode.go +++ b/modules/caddyhttp/encode/encode.go @@ -269,9 +269,8 @@ func (rw *responseWriter) Write(p []byte) (int, error) { if rw.w != nil { return rw.w.Write(p) - } else { - return rw.ResponseWriter.Write(p) } + return rw.ResponseWriter.Write(p) } // Close writes any remaining buffered response and diff --git a/modules/caddyhttp/encode/encode_test.go b/modules/caddyhttp/encode/encode_test.go index 3374ee3b5c0..d76945498dd 100644 --- a/modules/caddyhttp/encode/encode_test.go +++ b/modules/caddyhttp/encode/encode_test.go @@ -105,7 +105,6 @@ func TestPreferOrder(t *testing.T) { for _, test := range testCases { t.Run(test.name, func(t *testing.T) { - if test.accept == "" { r.Header.Del("Accept-Encoding") } else { @@ -258,7 +257,6 @@ func TestValidate(t *testing.T) { t.Errorf("Validate() error = %v, wantErr = %v", err, test.wantErr) } }) - } } diff --git a/modules/caddyhttp/encode/zstd/zstd.go b/modules/caddyhttp/encode/zstd/zstd.go index b5a0299d1ae..df472964a76 100644 --- a/modules/caddyhttp/encode/zstd/zstd.go +++ b/modules/caddyhttp/encode/zstd/zstd.go @@ -38,7 +38,7 @@ func (Zstd) CaddyModule() caddy.ModuleInfo { } // UnmarshalCaddyfile sets up the handler from Caddyfile tokens. -func (z *Zstd) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { +func (*Zstd) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { return nil } @@ -47,7 +47,7 @@ func (z *Zstd) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { func (Zstd) AcceptEncoding() string { return "zstd" } // NewEncoder returns a new Zstandard writer. -func (z Zstd) NewEncoder() encode.Encoder { +func (Zstd) NewEncoder() encode.Encoder { // The default of 8MB for the window is // too large for many clients, so we limit // it to 128K to lighten their load. diff --git a/modules/caddyhttp/fileserver/browse.go b/modules/caddyhttp/fileserver/browse.go index 81eb0859299..bc299c3ff0a 100644 --- a/modules/caddyhttp/fileserver/browse.go +++ b/modules/caddyhttp/fileserver/browse.go @@ -158,7 +158,7 @@ func (fsrv *FileServer) loadDirectoryContents(ctx context.Context, dir fs.ReadDi // browseApplyQueryParams applies query parameters to the listing. // It mutates the listing and may set cookies. -func (fsrv *FileServer) browseApplyQueryParams(w http.ResponseWriter, r *http.Request, listing *browseTemplateContext) { +func (*FileServer) browseApplyQueryParams(w http.ResponseWriter, r *http.Request, listing *browseTemplateContext) { layoutParam := r.URL.Query().Get("layout") sortParam := r.URL.Query().Get("sort") orderParam := r.URL.Query().Get("order") diff --git a/modules/caddyhttp/fileserver/command.go b/modules/caddyhttp/fileserver/command.go index 895c4f06d08..da3de51c5c2 100644 --- a/modules/caddyhttp/fileserver/command.go +++ b/modules/caddyhttp/fileserver/command.go @@ -131,12 +131,12 @@ func cmdFileServer(fs caddycmd.Flags) (int, error) { Servers: map[string]*caddyhttp.Server{"static": server}, } - var false bool + var falseBool bool cfg := &caddy.Config{ Admin: &caddy.AdminConfig{ Disabled: true, Config: &caddy.ConfigSettings{ - Persist: &false, + Persist: &falseBool, }, }, AppsRaw: caddy.ModuleMap{ diff --git a/modules/caddyhttp/fileserver/matcher.go b/modules/caddyhttp/fileserver/matcher.go index c8f5b226e90..bc687a0e7da 100644 --- a/modules/caddyhttp/fileserver/matcher.go +++ b/modules/caddyhttp/fileserver/matcher.go @@ -181,7 +181,7 @@ func (MatchFile) CELLibrary(ctx caddy.Context) (cel.Library, error) { root = values["root"][0] } - var try_policy string + var tryPolicy string if len(values["try_policy"]) > 0 { root = values["try_policy"][0] } @@ -189,7 +189,7 @@ func (MatchFile) CELLibrary(ctx caddy.Context) (cel.Library, error) { m := MatchFile{ Root: root, TryFiles: values["try_files"], - TryPolicy: try_policy, + TryPolicy: tryPolicy, SplitPath: values["split_path"], } @@ -406,7 +406,7 @@ func (m MatchFile) selectFile(r *http.Request) (matched bool) { for _, pattern := range m.TryFiles { if err := parseErrorCode(pattern); err != nil { caddyhttp.SetVar(r.Context(), caddyhttp.MatcherErrorVarKey, err) - return + return false } candidates := makeCandidates(pattern) for _, c := range candidates { @@ -480,7 +480,7 @@ func (m MatchFile) selectFile(r *http.Request) (matched bool) { return true } - return + return false } // parseErrorCode checks if the input is a status diff --git a/modules/caddyhttp/fileserver/matcher_test.go b/modules/caddyhttp/fileserver/matcher_test.go index bab34cc63e9..3daaa8fc5e6 100644 --- a/modules/caddyhttp/fileserver/matcher_test.go +++ b/modules/caddyhttp/fileserver/matcher_test.go @@ -276,83 +276,81 @@ func TestFirstSplit(t *testing.T) { } } -var ( - expressionTests = []struct { - name string - expression *caddyhttp.MatchExpression - urlTarget string - httpMethod string - httpHeader *http.Header - wantErr bool - wantResult bool - clientCertificate []byte - }{ - { - name: "file error no args (MatchFile)", - expression: &caddyhttp.MatchExpression{ - Expr: `file()`, - }, - urlTarget: "https://example.com/foo.txt", - wantResult: true, +var expressionTests = []struct { + name string + expression *caddyhttp.MatchExpression + urlTarget string + httpMethod string + httpHeader *http.Header + wantErr bool + wantResult bool + clientCertificate []byte +}{ + { + name: "file error no args (MatchFile)", + expression: &caddyhttp.MatchExpression{ + Expr: `file()`, }, - { - name: "file error bad try files (MatchFile)", - expression: &caddyhttp.MatchExpression{ - Expr: `file({"try_file": ["bad_arg"]})`, - }, - urlTarget: "https://example.com/foo", - wantErr: true, + urlTarget: "https://example.com/foo.txt", + wantResult: true, + }, + { + name: "file error bad try files (MatchFile)", + expression: &caddyhttp.MatchExpression{ + Expr: `file({"try_file": ["bad_arg"]})`, }, - { - name: "file match short pattern index.php (MatchFile)", - expression: &caddyhttp.MatchExpression{ - Expr: `file("index.php")`, - }, - urlTarget: "https://example.com/foo", - wantResult: true, + urlTarget: "https://example.com/foo", + wantErr: true, + }, + { + name: "file match short pattern index.php (MatchFile)", + expression: &caddyhttp.MatchExpression{ + Expr: `file("index.php")`, }, - { - name: "file match short pattern foo.txt (MatchFile)", - expression: &caddyhttp.MatchExpression{ - Expr: `file({http.request.uri.path})`, - }, - urlTarget: "https://example.com/foo.txt", - wantResult: true, + urlTarget: "https://example.com/foo", + wantResult: true, + }, + { + name: "file match short pattern foo.txt (MatchFile)", + expression: &caddyhttp.MatchExpression{ + Expr: `file({http.request.uri.path})`, }, - { - name: "file match index.php (MatchFile)", - expression: &caddyhttp.MatchExpression{ - Expr: `file({"root": "./testdata", "try_files": [{http.request.uri.path}, "/index.php"]})`, - }, - urlTarget: "https://example.com/foo", - wantResult: true, + urlTarget: "https://example.com/foo.txt", + wantResult: true, + }, + { + name: "file match index.php (MatchFile)", + expression: &caddyhttp.MatchExpression{ + Expr: `file({"root": "./testdata", "try_files": [{http.request.uri.path}, "/index.php"]})`, }, - { - name: "file match long pattern foo.txt (MatchFile)", - expression: &caddyhttp.MatchExpression{ - Expr: `file({"root": "./testdata", "try_files": [{http.request.uri.path}]})`, - }, - urlTarget: "https://example.com/foo.txt", - wantResult: true, + urlTarget: "https://example.com/foo", + wantResult: true, + }, + { + name: "file match long pattern foo.txt (MatchFile)", + expression: &caddyhttp.MatchExpression{ + Expr: `file({"root": "./testdata", "try_files": [{http.request.uri.path}]})`, }, - { - name: "file match long pattern foo.txt with concatenation (MatchFile)", - expression: &caddyhttp.MatchExpression{ - Expr: `file({"root": ".", "try_files": ["./testdata" + {http.request.uri.path}]})`, - }, - urlTarget: "https://example.com/foo.txt", - wantResult: true, + urlTarget: "https://example.com/foo.txt", + wantResult: true, + }, + { + name: "file match long pattern foo.txt with concatenation (MatchFile)", + expression: &caddyhttp.MatchExpression{ + Expr: `file({"root": ".", "try_files": ["./testdata" + {http.request.uri.path}]})`, }, - { - name: "file not match long pattern (MatchFile)", - expression: &caddyhttp.MatchExpression{ - Expr: `file({"root": "./testdata", "try_files": [{http.request.uri.path}]})`, - }, - urlTarget: "https://example.com/nopenope.txt", - wantResult: false, + urlTarget: "https://example.com/foo.txt", + wantResult: true, + }, + { + name: "file not match long pattern (MatchFile)", + expression: &caddyhttp.MatchExpression{ + Expr: `file({"root": "./testdata", "try_files": [{http.request.uri.path}]})`, }, - } -) + urlTarget: "https://example.com/nopenope.txt", + wantResult: false, + }, +} func TestMatchExpressionMatch(t *testing.T) { for _, tst := range expressionTests { diff --git a/modules/caddyhttp/headers/headers.go b/modules/caddyhttp/headers/headers.go index ed503ef5633..f1ed77633c8 100644 --- a/modules/caddyhttp/headers/headers.go +++ b/modules/caddyhttp/headers/headers.go @@ -132,7 +132,7 @@ type HeaderOps struct { } // Provision sets up the header operations. -func (ops *HeaderOps) Provision(_ caddy.Context) error { +func (ops *HeaderOps) Provision(ctx caddy.Context) error { for fieldName, replacements := range ops.Replace { for i, r := range replacements { if r.SearchRegexp != "" { diff --git a/modules/caddyhttp/http2listener.go b/modules/caddyhttp/http2listener.go index 51b356a7779..7a3634e9701 100644 --- a/modules/caddyhttp/http2listener.go +++ b/modules/caddyhttp/http2listener.go @@ -40,7 +40,7 @@ func (h *http2Listener) Accept() (net.Conn, error) { if csc, ok := conn.(connectionStateConn); ok { // *tls.Conn will return empty string because it's only populated after handshake is complete if csc.ConnectionState().NegotiatedProtocol == http2.NextProtoTLS { - go h.serveHttp2(csc) + go h.serveHTTP2(csc) continue } } @@ -49,7 +49,7 @@ func (h *http2Listener) Accept() (net.Conn, error) { } } -func (h *http2Listener) serveHttp2(csc connectionStateConn) { +func (h *http2Listener) serveHTTP2(csc connectionStateConn) { atomic.AddUint64(&h.cnt, 1) h.runHook(csc, http.StateNew) defer func() { diff --git a/modules/caddyhttp/httpredirectlistener.go b/modules/caddyhttp/httpredirectlistener.go index 3ff79ff8c91..e8653e53b0e 100644 --- a/modules/caddyhttp/httpredirectlistener.go +++ b/modules/caddyhttp/httpredirectlistener.go @@ -51,11 +51,11 @@ func (HTTPRedirectListenerWrapper) CaddyModule() caddy.ModuleInfo { } } -func (h *HTTPRedirectListenerWrapper) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { +func (*HTTPRedirectListenerWrapper) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { return nil } -func (h *HTTPRedirectListenerWrapper) WrapListener(l net.Listener) net.Listener { +func (*HTTPRedirectListenerWrapper) WrapListener(l net.Listener) net.Listener { return &httpRedirectListener{l} } diff --git a/modules/caddyhttp/ip_range.go b/modules/caddyhttp/ip_range.go index b1db254752f..a1d74afc4ed 100644 --- a/modules/caddyhttp/ip_range.go +++ b/modules/caddyhttp/ip_range.go @@ -86,16 +86,16 @@ func (s *StaticIPRange) GetIPRanges(_ *http.Request) []netip.Prefix { } // UnmarshalCaddyfile implements caddyfile.Unmarshaler. -func (m *StaticIPRange) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { +func (s *StaticIPRange) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { if !d.Next() { return nil } for d.NextArg() { if d.Val() == "private_ranges" { - m.Ranges = append(m.Ranges, PrivateRangesCIDR()...) + s.Ranges = append(s.Ranges, PrivateRangesCIDR()...) continue } - m.Ranges = append(m.Ranges, d.Val()) + s.Ranges = append(s.Ranges, d.Val()) } return nil } diff --git a/modules/caddyhttp/logging.go b/modules/caddyhttp/logging.go index 8ecc49a63db..298dd2859ff 100644 --- a/modules/caddyhttp/logging.go +++ b/modules/caddyhttp/logging.go @@ -134,11 +134,11 @@ func errLogValues(err error) (status int, msg string, fields []zapcore.Field) { zap.String("err_id", handlerErr.ID), zap.String("err_trace", handlerErr.Trace), } - return + return status, msg, fields } status = http.StatusInternalServerError msg = err.Error() - return + return status, msg, fields } // ExtraLogFields is a list of extra fields to log with every request. diff --git a/modules/caddyhttp/map/map.go b/modules/caddyhttp/map/map.go index 336f2572319..289934354ac 100644 --- a/modules/caddyhttp/map/map.go +++ b/modules/caddyhttp/map/map.go @@ -61,7 +61,7 @@ func (Handler) CaddyModule() caddy.ModuleInfo { } // Provision sets up h. -func (h *Handler) Provision(_ caddy.Context) error { +func (h *Handler) Provision(ctx caddy.Context) error { for j, dest := range h.Destinations { if strings.Count(dest, "{") != 1 || !strings.HasPrefix(dest, "{") { return fmt.Errorf("destination must be a placeholder and only a placeholder") diff --git a/modules/caddyhttp/matchers.go b/modules/caddyhttp/matchers.go index b3859797083..85d14de8c41 100644 --- a/modules/caddyhttp/matchers.go +++ b/modules/caddyhttp/matchers.go @@ -234,7 +234,7 @@ func (m *MatchHost) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { } // Provision sets up and validates m, including making it more efficient for large lists. -func (m MatchHost) Provision(_ caddy.Context) error { +func (m MatchHost) Provision(ctx caddy.Context) error { // check for duplicates; they are nonsensical and reduce efficiency // (we could just remove them, but the user should know their config is erroneous) seen := make(map[string]int) @@ -370,7 +370,7 @@ func (MatchPath) CaddyModule() caddy.ModuleInfo { } // Provision lower-cases the paths in m to ensure case-insensitive matching. -func (m MatchPath) Provision(_ caddy.Context) error { +func (m MatchPath) Provision(ctx caddy.Context) error { for i := range m { if m[i] == "*" && i > 0 { // will always match, so just put it first @@ -740,7 +740,7 @@ func (m MatchMethod) Match(r *http.Request) bool { // Example: // // expression method('PUT', 'POST') -func (MatchMethod) CELLibrary(_ caddy.Context) (cel.Library, error) { +func (MatchMethod) CELLibrary(ctx caddy.Context) (cel.Library, error) { return CELMatcherImpl( "method", "method_request_list", @@ -827,7 +827,7 @@ func (m MatchQuery) Match(r *http.Request) bool { // Example: // // expression query({'sort': 'asc'}) || query({'foo': ['*bar*', 'baz']}) -func (MatchQuery) CELLibrary(_ caddy.Context) (cel.Library, error) { +func (MatchQuery) CELLibrary(ctx caddy.Context) (cel.Library, error) { return CELMatcherImpl( "query", "query_matcher_request_map", @@ -904,7 +904,7 @@ func (m MatchHeader) Match(r *http.Request) bool { // // expression header({'content-type': 'image/png'}) // expression header({'foo': ['bar', 'baz']}) // match bar or baz -func (MatchHeader) CELLibrary(_ caddy.Context) (cel.Library, error) { +func (MatchHeader) CELLibrary(ctx caddy.Context) (cel.Library, error) { return CELMatcherImpl( "header", "header_matcher_request_map", @@ -1169,7 +1169,7 @@ func (m *MatchProtocol) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { // Example: // // expression protocol('https') -func (MatchProtocol) CELLibrary(_ caddy.Context) (cel.Library, error) { +func (MatchProtocol) CELLibrary(ctx caddy.Context) (cel.Library, error) { return CELMatcherImpl( "protocol", "protocol_request_string", diff --git a/modules/caddyhttp/matchers_test.go b/modules/caddyhttp/matchers_test.go index 041975d80b5..100813096b6 100644 --- a/modules/caddyhttp/matchers_test.go +++ b/modules/caddyhttp/matchers_test.go @@ -862,7 +862,6 @@ func TestHeaderREMatcher(t *testing.T) { } func BenchmarkHeaderREMatcher(b *testing.B) { - i := 0 match := MatchHeaderRE{"Field": &MatchRegexp{Pattern: "^foo(.*)$", Name: "name"}} input := http.Header{"Field": []string{"foobar"}} @@ -1086,6 +1085,7 @@ func TestNotMatcher(t *testing.T) { } } } + func BenchmarkLargeHostMatcher(b *testing.B) { // this benchmark simulates a large host matcher (thousands of entries) where each // value is an exact hostname (not a placeholder or wildcard) - compare the results diff --git a/modules/caddyhttp/push/handler.go b/modules/caddyhttp/push/handler.go index 031a8991fb5..b1be9f2fe9d 100644 --- a/modules/caddyhttp/push/handler.go +++ b/modules/caddyhttp/push/handler.go @@ -122,11 +122,7 @@ func (h Handler) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhtt } // serve only after pushing! - if err := next.ServeHTTP(lp, r); err != nil { - return err - } - - return nil + return next.ServeHTTP(lp, r) } func (h Handler) initializePushHeaders(r *http.Request, repl *caddy.Replacer) http.Header { @@ -159,7 +155,7 @@ func (h Handler) initializePushHeaders(r *http.Request, repl *caddy.Replacer) ht // resources described by them. If a resource has the "nopush" // attribute or describes an external entity (meaning, the resource // URI includes a scheme), it will not be pushed. -func (h Handler) servePreloadLinks(pusher http.Pusher, hdr http.Header, resources []string) { +func (Handler) servePreloadLinks(pusher http.Pusher, hdr http.Header, resources []string) { for _, resource := range resources { for _, resource := range parseLinkHeader(resource) { if _, ok := resource.params["nopush"]; ok { diff --git a/modules/caddyhttp/requestbody/requestbody.go b/modules/caddyhttp/requestbody/requestbody.go index dfc0fd92891..ccd8a2bbc3c 100644 --- a/modules/caddyhttp/requestbody/requestbody.go +++ b/modules/caddyhttp/requestbody/requestbody.go @@ -62,7 +62,7 @@ func (ew errorWrapper) Read(p []byte) (n int, err error) { if err != nil && err.Error() == "http: request body too large" { err = caddyhttp.Error(http.StatusRequestEntityTooLarge, err) } - return + return n, err } // Interface guard diff --git a/modules/caddyhttp/reverseproxy/ascii_test.go b/modules/caddyhttp/reverseproxy/ascii_test.go index d1f0c1da903..de67963bd7c 100644 --- a/modules/caddyhttp/reverseproxy/ascii_test.go +++ b/modules/caddyhttp/reverseproxy/ascii_test.go @@ -26,7 +26,7 @@ package reverseproxy import "testing" func TestEqualFold(t *testing.T) { - var tests = []struct { + tests := []struct { name string a, b string want bool @@ -64,7 +64,7 @@ func TestEqualFold(t *testing.T) { } func TestIsPrint(t *testing.T) { - var tests = []struct { + tests := []struct { name string in string want bool diff --git a/modules/caddyhttp/reverseproxy/command.go b/modules/caddyhttp/reverseproxy/command.go index 11f935cf96a..464bccfb320 100644 --- a/modules/caddyhttp/reverseproxy/command.go +++ b/modules/caddyhttp/reverseproxy/command.go @@ -284,12 +284,12 @@ func cmdReverseProxy(fs caddycmd.Flags) (int, error) { appsRaw["tls"] = caddyconfig.JSON(tlsApp, nil) } - var false bool + var falseBool bool cfg := &caddy.Config{ Admin: &caddy.AdminConfig{ Disabled: true, Config: &caddy.ConfigSettings{ - Persist: &false, + Persist: &falseBool, }, }, AppsRaw: appsRaw, diff --git a/modules/caddyhttp/reverseproxy/fastcgi/client.go b/modules/caddyhttp/reverseproxy/fastcgi/client.go index 04513dd85f3..d9530397e37 100644 --- a/modules/caddyhttp/reverseproxy/fastcgi/client.go +++ b/modules/caddyhttp/reverseproxy/fastcgi/client.go @@ -142,13 +142,13 @@ func (c *client) Do(p map[string]string, req io.Reader) (r io.Reader, err error) err = writer.writeBeginRequest(uint16(Responder), 0) if err != nil { - return + return nil, err } writer.recType = Params err = writer.writePairs(p) if err != nil { - return + return nil, err } writer.recType = Stdin @@ -164,7 +164,7 @@ func (c *client) Do(p map[string]string, req io.Reader) (r io.Reader, err error) } r = &streamReader{c: c} - return + return r, nil } // clientCloser is a io.ReadCloser. It wraps a io.Reader with a Closer @@ -198,7 +198,7 @@ func (f clientCloser) Close() error { func (c *client) Request(p map[string]string, req io.Reader) (resp *http.Response, err error) { r, err := c.Do(p, req) if err != nil { - return + return nil, err } rb := bufio.NewReader(r) @@ -208,7 +208,7 @@ func (c *client) Request(p map[string]string, req io.Reader) (resp *http.Respons // Parse the response headers. mimeHeader, err := tp.ReadMIMEHeader() if err != nil && err != io.EOF { - return + return nil, err } resp.Header = http.Header(mimeHeader) @@ -216,7 +216,7 @@ func (c *client) Request(p map[string]string, req io.Reader) (resp *http.Respons statusNumber, statusInfo, statusIsCut := strings.Cut(resp.Header.Get("Status"), " ") resp.StatusCode, err = strconv.Atoi(statusNumber) if err != nil { - return + return nil, err } if statusIsCut { resp.Status = statusInfo @@ -246,7 +246,7 @@ func (c *client) Request(p map[string]string, req io.Reader) (resp *http.Respons } resp.Body = closer - return + return resp, nil } // Get issues a GET request to the fcgi responder. @@ -315,7 +315,7 @@ func (c *client) PostFile(p map[string]string, data url.Values, file map[string] for _, v0 := range val { err = writer.WriteField(key, v0) if err != nil { - return + return nil, err } } } @@ -333,13 +333,13 @@ func (c *client) PostFile(p map[string]string, data url.Values, file map[string] } _, err = io.Copy(part, fd) if err != nil { - return + return nil, err } } err = writer.Close() if err != nil { - return + return nil, err } return c.Post(p, "POST", bodyType, buf, int64(buf.Len())) diff --git a/modules/caddyhttp/reverseproxy/fastcgi/client_test.go b/modules/caddyhttp/reverseproxy/fastcgi/client_test.go index 29bb5785b18..256ce414b31 100644 --- a/modules/caddyhttp/reverseproxy/fastcgi/client_test.go +++ b/modules/caddyhttp/reverseproxy/fastcgi/client_test.go @@ -48,7 +48,7 @@ import ( // and output "FAILED" in response const ( scriptFile = "/tank/www/fcgic_test.php" - //ipPort = "remote-php-serv:59000" + // ipPort = "remote-php-serv:59000" ipPort = "127.0.0.1:59000" ) @@ -57,7 +57,6 @@ var globalt *testing.T type FastCGIServer struct{} func (s FastCGIServer) ServeHTTP(resp http.ResponseWriter, req *http.Request) { - if err := req.ParseMultipartForm(100000000); err != nil { log.Printf("[ERROR] failed to parse: %v", err) } @@ -84,7 +83,7 @@ func (s FastCGIServer) ServeHTTP(resp http.ResponseWriter, req *http.Request) { if req.MultipartForm != nil { fileNum = len(req.MultipartForm.File) for kn, fns := range req.MultipartForm.File { - //fmt.Fprintln(resp, "server:filekey ", kn ) + // fmt.Fprintln(resp, "server:filekey ", kn ) length += len(kn) for _, f := range fns { fd, err := f.Open() @@ -101,13 +100,13 @@ func (s FastCGIServer) ServeHTTP(resp http.ResponseWriter, req *http.Request) { length += int(l0) defer fd.Close() md5 := fmt.Sprintf("%x", h.Sum(nil)) - //fmt.Fprintln(resp, "server:filemd5 ", md5 ) + // fmt.Fprintln(resp, "server:filemd5 ", md5 ) if kn != md5 { fmt.Fprintln(resp, "server:err ", md5, kn) stat = "FAILED" } - //fmt.Fprintln(resp, "server:filename ", f.Filename ) + // fmt.Fprintln(resp, "server:filename ", f.Filename ) } } } @@ -121,7 +120,7 @@ func sendFcgi(reqType int, fcgiParams map[string]string, data []byte, posts map[ conn, err := net.Dial("tcp", ipPort) if err != nil { log.Println("err:", err) - return + return nil } fcgi := client{rwc: conn, reqID: 1} @@ -135,6 +134,7 @@ func sendFcgi(reqType int, fcgiParams map[string]string, data []byte, posts map[ length = len(data) rd := bytes.NewReader(data) resp, err = fcgi.Post(fcgiParams, "", "", rd, int64(rd.Len())) + resp.Body.Close() } else if len(posts) > 0 { values := url.Values{} for k, v := range posts { @@ -142,9 +142,11 @@ func sendFcgi(reqType int, fcgiParams map[string]string, data []byte, posts map[ length += len(k) + 2 + len(v) } resp, err = fcgi.PostForm(fcgiParams, values) + resp.Body.Close() } else { rd := bytes.NewReader(data) resp, err = fcgi.Get(fcgiParams, rd, int64(rd.Len())) + resp.Body.Close() } default: @@ -159,11 +161,12 @@ func sendFcgi(reqType int, fcgiParams map[string]string, data []byte, posts map[ length += len(k) + int(fi.Size()) } resp, err = fcgi.PostFile(fcgiParams, values, files) + resp.Body.Close() } if err != nil { log.Println("err:", err) - return + return nil } defer resp.Body.Close() @@ -177,11 +180,10 @@ func sendFcgi(reqType int, fcgiParams map[string]string, data []byte, posts map[ globalt.Error("Server return failed message") } - return + return content } func generateRandFile(size int) (p string, m string) { - p = filepath.Join(os.TempDir(), "fcgict"+strconv.Itoa(rand.Int())) // open output file @@ -212,6 +214,7 @@ func generateRandFile(size int) (p string, m string) { } func DisabledTest(t *testing.T) { + t.Helper() // TODO: test chunked reader globalt = t @@ -236,7 +239,7 @@ func DisabledTest(t *testing.T) { fcgiParams := make(map[string]string) fcgiParams["REQUEST_METHOD"] = "GET" fcgiParams["SERVER_PROTOCOL"] = "HTTP/1.1" - //fcgi_params["GATEWAY_INTERFACE"] = "CGI/1.1" + // fcgi_params["GATEWAY_INTERFACE"] = "CGI/1.1" fcgiParams["SCRIPT_FILENAME"] = scriptFile // simple GET diff --git a/modules/caddyhttp/reverseproxy/fastcgi/record.go b/modules/caddyhttp/reverseproxy/fastcgi/record.go index 46c1f17bb4d..9132ca64792 100644 --- a/modules/caddyhttp/reverseproxy/fastcgi/record.go +++ b/modules/caddyhttp/reverseproxy/fastcgi/record.go @@ -30,23 +30,23 @@ func (rec *record) fill(r io.Reader) (err error) { rec.lr.N = rec.padding rec.lr.R = r if _, err = io.Copy(io.Discard, rec); err != nil { - return + return err } if err = binary.Read(r, binary.BigEndian, &rec.h); err != nil { - return + return err } if rec.h.Version != 1 { err = errors.New("fcgi: invalid header version") - return + return err } if rec.h.Type == EndRequest { err = io.EOF - return + return err } rec.lr.N = int64(rec.h.ContentLength) rec.padding = int64(rec.h.PaddingLength) - return + return nil } func (rec *record) Read(p []byte) (n int, err error) { diff --git a/modules/caddyhttp/reverseproxy/reverseproxy.go b/modules/caddyhttp/reverseproxy/reverseproxy.go index f11c8e33a6b..95e439923eb 100644 --- a/modules/caddyhttp/reverseproxy/reverseproxy.go +++ b/modules/caddyhttp/reverseproxy/reverseproxy.go @@ -630,7 +630,7 @@ func (h Handler) prepareRequest(req *http.Request, repl *caddy.Replacer) (*http. if err != nil { // OK; probably didn't have a port addr, err := netip.ParseAddr(address) - if err != nil { + if err != nil { //nolint:revive // Doesn't seem like a valid ip address at all } else { // Ok, only the port was missing @@ -1097,7 +1097,7 @@ func (h Handler) provisionUpstream(upstream *Upstream) { // then returns a reader for the buffer along with how many bytes were buffered. Always close // the return value when done with it, just like if it was the original body! If limit is 0 // (which it shouldn't be), this function returns its input; i.e. is a no-op, for safety. -func (h Handler) bufferedBody(originalBody io.ReadCloser, limit int64) (io.ReadCloser, int64) { +func (Handler) bufferedBody(originalBody io.ReadCloser, limit int64) (io.ReadCloser, int64) { if limit == 0 { return originalBody, 0 } @@ -1410,15 +1410,15 @@ type ignoreClientGoneContext struct { context.Context } -func (c ignoreClientGoneContext) Deadline() (deadline time.Time, ok bool) { - return +func (ignoreClientGoneContext) Deadline() (deadline time.Time, ok bool) { + return deadline, ok } -func (c ignoreClientGoneContext) Done() <-chan struct{} { +func (ignoreClientGoneContext) Done() <-chan struct{} { return nil } -func (c ignoreClientGoneContext) Err() error { +func (ignoreClientGoneContext) Err() error { return nil } diff --git a/modules/caddyhttp/reverseproxy/selectionpolicies.go b/modules/caddyhttp/reverseproxy/selectionpolicies.go index bc6de35160e..276bb3973d7 100644 --- a/modules/caddyhttp/reverseproxy/selectionpolicies.go +++ b/modules/caddyhttp/reverseproxy/selectionpolicies.go @@ -62,12 +62,12 @@ func (RandomSelection) CaddyModule() caddy.ModuleInfo { } // Select returns an available host, if any. -func (r RandomSelection) Select(pool UpstreamPool, request *http.Request, _ http.ResponseWriter) *Upstream { +func (RandomSelection) Select(pool UpstreamPool, req *http.Request, res http.ResponseWriter) *Upstream { return selectRandomHost(pool) } // UnmarshalCaddyfile sets up the module from Caddyfile tokens. -func (r *RandomSelection) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { +func (*RandomSelection) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { for d.Next() { if d.NextArg() { return d.ArgErr() @@ -220,7 +220,7 @@ func (r RandomChoiceSelection) Select(pool UpstreamPool, _ *http.Request, _ http if !upstream.Available() { continue } - j := weakrand.Intn(i + 1) //nolint:gosec + j := weakrand.Intn(i + 1) if j < k { choices[j] = upstream } @@ -269,7 +269,7 @@ func (LeastConnSelection) Select(pool UpstreamPool, _ *http.Request, _ http.Resp // sample: https://en.wikipedia.org/wiki/Reservoir_sampling if numReqs == leastReqs { count++ - if count > 1 || (weakrand.Int()%count) == 0 { //nolint:gosec + if count > 1 || (weakrand.Int()%count) == 0 { bestHost = host } } @@ -279,7 +279,7 @@ func (LeastConnSelection) Select(pool UpstreamPool, _ *http.Request, _ http.Resp } // UnmarshalCaddyfile sets up the module from Caddyfile tokens. -func (r *LeastConnSelection) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { +func (*LeastConnSelection) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { for d.Next() { if d.NextArg() { return d.ArgErr() @@ -319,7 +319,7 @@ func (r *RoundRobinSelection) Select(pool UpstreamPool, _ *http.Request, _ http. } // UnmarshalCaddyfile sets up the module from Caddyfile tokens. -func (r *RoundRobinSelection) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { +func (*RoundRobinSelection) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { for d.Next() { if d.NextArg() { return d.ArgErr() @@ -351,7 +351,7 @@ func (FirstSelection) Select(pool UpstreamPool, _ *http.Request, _ http.Response } // UnmarshalCaddyfile sets up the module from Caddyfile tokens. -func (r *FirstSelection) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { +func (*FirstSelection) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { for d.Next() { if d.NextArg() { return d.ArgErr() @@ -382,7 +382,7 @@ func (IPHashSelection) Select(pool UpstreamPool, req *http.Request, _ http.Respo } // UnmarshalCaddyfile sets up the module from Caddyfile tokens. -func (r *IPHashSelection) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { +func (*IPHashSelection) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { for d.Next() { if d.NextArg() { return d.ArgErr() @@ -415,7 +415,7 @@ func (ClientIPHashSelection) Select(pool UpstreamPool, req *http.Request, _ http } // UnmarshalCaddyfile sets up the module from Caddyfile tokens. -func (r *ClientIPHashSelection) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { +func (*ClientIPHashSelection) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { for d.Next() { if d.NextArg() { return d.ArgErr() @@ -442,7 +442,7 @@ func (URIHashSelection) Select(pool UpstreamPool, req *http.Request, _ http.Resp } // UnmarshalCaddyfile sets up the module from Caddyfile tokens. -func (r *URIHashSelection) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { +func (*URIHashSelection) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { for d.Next() { if d.NextArg() { return d.ArgErr() @@ -753,7 +753,7 @@ func selectRandomHost(pool []*Upstream) *Upstream { // upstream will always be chosen if there is at // least one available count++ - if (weakrand.Int() % count) == 0 { //nolint:gosec + if (weakrand.Int() % count) == 0 { randomHost = upstream } } @@ -770,7 +770,7 @@ func leastRequests(upstreams []*Upstream) *Upstream { return nil } var best []*Upstream - var bestReqs int = -1 + bestReqs := -1 for _, upstream := range upstreams { if upstream == nil { continue @@ -792,7 +792,7 @@ func leastRequests(upstreams []*Upstream) *Upstream { if len(best) == 1 { return best[0] } - return best[weakrand.Intn(len(best))] //nolint:gosec + return best[weakrand.Intn(len(best))] } // hostByHashing returns an available host from pool based on a hashable string s. diff --git a/modules/caddyhttp/reverseproxy/selectionpolicies_test.go b/modules/caddyhttp/reverseproxy/selectionpolicies_test.go index dc613a53896..62e6548b931 100644 --- a/modules/caddyhttp/reverseproxy/selectionpolicies_test.go +++ b/modules/caddyhttp/reverseproxy/selectionpolicies_test.go @@ -120,7 +120,7 @@ func TestWeightedRoundRobinPolicy(t *testing.T) { h = wrrPolicy.Select(pool, req, nil) if h != pool[0] { - t.Error("Expected to select first host on availablity.") + t.Error("Expected to select first host on availability.") } // mark host as full pool[1].countRequest(1) @@ -629,7 +629,6 @@ func TestRandomChoicePolicy(t *testing.T) { if h == pool[0] { t.Error("RandomChoicePolicy should not choose pool[0]") } - } func TestCookieHashPolicy(t *testing.T) { diff --git a/modules/caddyhttp/reverseproxy/streaming.go b/modules/caddyhttp/reverseproxy/streaming.go index c5369d8c3c5..10bb6b90c74 100644 --- a/modules/caddyhttp/reverseproxy/streaming.go +++ b/modules/caddyhttp/reverseproxy/streaming.go @@ -170,7 +170,7 @@ func (h Handler) flushInterval(req *http.Request, res *http.Response) time.Durat // isBidirectionalStream returns whether we should work in bi-directional stream mode. // // See https://github.com/caddyserver/caddy/pull/3620 for discussion of nuances. -func (h Handler) isBidirectionalStream(req *http.Request, res *http.Response) bool { +func (Handler) isBidirectionalStream(req *http.Request, res *http.Response) bool { // We have to check the encoding here; only flush headers with identity encoding. // Non-identity encoding might combine with "encode" directive, and in that case, // if body size larger than enc.MinLength, upper level encode handle might have @@ -459,12 +459,11 @@ func (m *maxLatencyWriter) Write(p []byte) (n int, err error) { defer m.mu.Unlock() n, err = m.dst.Write(p) if m.latency < 0 { - //nolint:errcheck - m.flush() - return + err = m.flush() + return n, err } if m.flushPending { - return + return n, err } if m.t == nil { m.t = time.AfterFunc(m.latency, m.delayedFlush) @@ -472,7 +471,7 @@ func (m *maxLatencyWriter) Write(p []byte) (n int, err error) { m.t.Reset(m.latency) } m.flushPending = true - return + return n, err } func (m *maxLatencyWriter) delayedFlush() { diff --git a/modules/caddyhttp/reverseproxy/upstreams.go b/modules/caddyhttp/reverseproxy/upstreams.go index 528e2c5ef72..49d0a1e23c2 100644 --- a/modules/caddyhttp/reverseproxy/upstreams.go +++ b/modules/caddyhttp/reverseproxy/upstreams.go @@ -189,12 +189,12 @@ func (su SRVUpstreams) expandedAddr(r *http.Request) (addr, service, proto, name name = repl.ReplaceAll(su.Name, "") if su.Service == "" && su.Proto == "" { addr = name - return + return addr, service, proto, name } service = repl.ReplaceAll(su.Service, "") proto = repl.ReplaceAll(su.Proto, "") addr = su.formattedAddr(service, proto, name) - return + return addr, service, proto, name } // formattedAddr the RFC 2782 representation of the SRV domain, in @@ -261,7 +261,7 @@ func (AUpstreams) CaddyModule() caddy.ModuleInfo { } } -func (au *AUpstreams) Provision(_ caddy.Context) error { +func (au *AUpstreams) Provision(ctx caddy.Context) error { if au.Refresh == 0 { au.Refresh = caddy.Duration(time.Minute) } diff --git a/modules/caddyhttp/rewrite/rewrite_test.go b/modules/caddyhttp/rewrite/rewrite_test.go index bb937ec5bad..605c4acf849 100644 --- a/modules/caddyhttp/rewrite/rewrite_test.go +++ b/modules/caddyhttp/rewrite/rewrite_test.go @@ -333,7 +333,7 @@ func TestRewrite(t *testing.T) { input: newRequest(t, "GET", "/foo/findme%2Fbar"), expect: newRequest(t, "GET", "/foo/replaced%2Fbar"), }, - + { rule: Rewrite{PathRegexp: []*regexReplacer{{Find: "/{2,}", Replace: "/"}}}, input: newRequest(t, "GET", "/foo//bar///baz?a=b//c"), @@ -388,6 +388,7 @@ func TestRewrite(t *testing.T) { } func newRequest(t *testing.T, method, uri string) *http.Request { + t.Helper() req, err := http.NewRequest(method, uri, nil) if err != nil { t.Fatalf("error creating request: %v", err) diff --git a/modules/caddyhttp/staticerror.go b/modules/caddyhttp/staticerror.go index 7cf1a3e9543..ae26ddef2c2 100644 --- a/modules/caddyhttp/staticerror.go +++ b/modules/caddyhttp/staticerror.go @@ -95,7 +95,7 @@ func (e *StaticError) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { return nil } -func (e StaticError) ServeHTTP(w http.ResponseWriter, r *http.Request, _ Handler) error { +func (e StaticError) ServeHTTP(w http.ResponseWriter, r *http.Request, h Handler) error { repl := r.Context().Value(caddy.ReplacerCtxKey).(*caddy.Replacer) statusCode := http.StatusInternalServerError diff --git a/modules/caddyhttp/staticresp.go b/modules/caddyhttp/staticresp.go index 4fe5910e40e..9b7754eba84 100644 --- a/modules/caddyhttp/staticresp.go +++ b/modules/caddyhttp/staticresp.go @@ -394,12 +394,12 @@ func cmdRespond(fl caddycmd.Flags) (int, error) { } // finish building the config - var false bool + var falseBool bool cfg := &caddy.Config{ Admin: &caddy.AdminConfig{ Disabled: true, Config: &caddy.ConfigSettings{ - Persist: &false, + Persist: &falseBool, }, }, AppsRaw: caddy.ModuleMap{ diff --git a/modules/caddyhttp/staticresp_test.go b/modules/caddyhttp/staticresp_test.go index 5844f43f354..554c7f2a7f7 100644 --- a/modules/caddyhttp/staticresp_test.go +++ b/modules/caddyhttp/staticresp_test.go @@ -44,6 +44,7 @@ func TestStaticResponseHandler(t *testing.T) { } resp := w.Result() + resp.Body.Close() respBody, _ := io.ReadAll(resp.Body) if resp.StatusCode != http.StatusNotFound { diff --git a/modules/caddyhttp/templates/tplcontext.go b/modules/caddyhttp/templates/tplcontext.go index 6b2b4954d39..eb1cbb6688c 100644 --- a/modules/caddyhttp/templates/tplcontext.go +++ b/modules/caddyhttp/templates/tplcontext.go @@ -430,7 +430,7 @@ func (c TemplateContext) funcFileStat(filename string) (fs.FileInfo, error) { // funcHTTPError returns a structured HTTP handler error. EXPERIMENTAL; SUBJECT TO CHANGE. // Example usage: `{{if not (fileExists $includeFile)}}{{httpError 404}}{{end}}` -func (c TemplateContext) funcHTTPError(statusCode int) (bool, error) { +func (TemplateContext) funcHTTPError(statusCode int) (bool, error) { return false, caddyhttp.Error(statusCode, nil) } @@ -442,7 +442,7 @@ func (c TemplateContext) funcHTTPError(statusCode int) (bool, error) { // Time inputs are parsed using the given layout (default layout is RFC1123Z) // and are formatted as a relative time, such as "2 weeks ago". // See https://pkg.go.dev/time#pkg-constants for time layout docs. -func (c TemplateContext) funcHumanize(formatType, data string) (string, error) { +func (TemplateContext) funcHumanize(formatType, data string) (string, error) { // The format type can optionally be followed // by a colon to provide arguments for the format parts := strings.Split(formatType, ":") diff --git a/modules/caddyhttp/templates/tplcontext_test.go b/modules/caddyhttp/templates/tplcontext_test.go index fdf2c1065b6..94997bcd30b 100644 --- a/modules/caddyhttp/templates/tplcontext_test.go +++ b/modules/caddyhttp/templates/tplcontext_test.go @@ -30,8 +30,7 @@ import ( "github.com/caddyserver/caddy/v2/modules/caddyhttp" ) -type handle struct { -} +type handle struct{} func (h *handle) ServeHTTP(w http.ResponseWriter, r *http.Request) { if r.Header.Get("Accept-Encoding") == "identity" { @@ -176,7 +175,6 @@ func TestImport(t *testing.T) { } else if !templateWasDefined && actual != "" { // template should be defined, return value should be an empty string t.Errorf("Test %d: Expected template %s to be define but got %s", i, test.expect, tplContext.tpl.DefinedTemplates()) - } if absFilePath != "" { @@ -255,7 +253,6 @@ func TestNestedInclude(t *testing.T) { } else if buf.String() != test.expect { // t.Errorf("Test %d: Expected '%s' but got '%s'", i, test.expect, buf.String()) - } if absFilePath != "" { @@ -342,7 +339,6 @@ func TestInclude(t *testing.T) { t.Errorf("Test %d: Expected error but had none", i) } else if actual != test.expect { t.Errorf("Test %d: Expected %s but got %s", i, test.expect, actual) - } if absFilePath != "" { @@ -602,7 +598,6 @@ title = "Welcome" t.Errorf("Test %d: Expected body %s, found %s. Input was SplitFrontMatter(%s)", i, test.body, result.Body, test.input) } } - } func TestHumanize(t *testing.T) { @@ -655,6 +650,7 @@ func TestHumanize(t *testing.T) { } func getContextOrFail(t *testing.T) TemplateContext { + t.Helper() tplContext, err := initTestContext() t.Cleanup(func() { os.RemoveAll(string(tplContext.Root.(http.Dir))) diff --git a/modules/caddyhttp/tracing/tracer.go b/modules/caddyhttp/tracing/tracer.go index ecd415fa0cd..4065aa96c2c 100644 --- a/modules/caddyhttp/tracing/tracer.go +++ b/modules/caddyhttp/tracing/tracer.go @@ -107,12 +107,12 @@ func (ot *openTelemetryWrapper) ServeHTTP(w http.ResponseWriter, r *http.Request } // cleanup flush all remaining data and shutdown a tracerProvider -func (ot *openTelemetryWrapper) cleanup(logger *zap.Logger) error { +func (*openTelemetryWrapper) cleanup(logger *zap.Logger) error { return globalTracerProvider.cleanupTracerProvider(logger) } // newResource creates a resource that describe current handler instance and merge it with a default attributes value. -func (ot *openTelemetryWrapper) newResource( +func (*openTelemetryWrapper) newResource( webEngineName, webEngineVersion string, ) (*resource.Resource, error) { @@ -123,6 +123,6 @@ func (ot *openTelemetryWrapper) newResource( } // spanNameFormatter performs the replacement of placeholders in the span name -func (ot *openTelemetryWrapper) spanNameFormatter(operation string, r *http.Request) string { +func (*openTelemetryWrapper) spanNameFormatter(operation string, r *http.Request) string { return r.Context().Value(caddy.ReplacerCtxKey).(*caddy.Replacer).ReplaceAll(operation, "") } diff --git a/modules/caddyhttp/tracing/tracerprovider_test.go b/modules/caddyhttp/tracing/tracerprovider_test.go index cb2e5936f9a..5a5df0a23f2 100644 --- a/modules/caddyhttp/tracing/tracerprovider_test.go +++ b/modules/caddyhttp/tracing/tracerprovider_test.go @@ -28,7 +28,6 @@ func Test_tracersProvider_cleanupTracerProvider(t *testing.T) { tp.getTracerProvider() err := tp.cleanupTracerProvider(zap.NewNop()) - if err != nil { t.Errorf("There should be no error: %v", err) } diff --git a/modules/caddypki/adminapi.go b/modules/caddypki/adminapi.go index 435af349a4a..9cd4a2554ec 100644 --- a/modules/caddypki/adminapi.go +++ b/modules/caddypki/adminapi.go @@ -217,13 +217,13 @@ func (a *adminAPI) getCAFromAPIRequestPath(r *http.Request) (*CA, error) { func rootAndIntermediatePEM(ca *CA) (root, inter []byte, err error) { root, err = pemEncodeCert(ca.RootCertificate().Raw) if err != nil { - return + return nil, nil, err } inter, err = pemEncodeCert(ca.IntermediateCertificate().Raw) if err != nil { - return + return nil, nil, err } - return + return root, inter, nil } // caInfo is the response structure for the CA info API endpoint. diff --git a/modules/caddypki/pki.go b/modules/caddypki/pki.go index 9f974a956bb..b1063f24232 100644 --- a/modules/caddypki/pki.go +++ b/modules/caddypki/pki.go @@ -116,7 +116,7 @@ func (p *PKI) Start() error { } // Stop stops the PKI app. -func (p *PKI) Stop() error { +func (*PKI) Stop() error { return nil } diff --git a/modules/caddytls/certmanagers.go b/modules/caddytls/certmanagers.go index ad26468a9dd..fa98b367fbc 100644 --- a/modules/caddytls/certmanagers.go +++ b/modules/caddytls/certmanagers.go @@ -52,7 +52,7 @@ func (ts Tailscale) GetCertificate(ctx context.Context, hello *tls.ClientHelloIn } // canHazCertificate returns true if Tailscale reports it can get a certificate for the given ClientHello. -func (ts Tailscale) canHazCertificate(ctx context.Context, hello *tls.ClientHelloInfo) (bool, error) { +func (Tailscale) canHazCertificate(ctx context.Context, hello *tls.ClientHelloInfo) (bool, error) { if !strings.HasSuffix(strings.ToLower(hello.ServerName), tailscaleDomainAliasEnding) { return false, nil } @@ -103,7 +103,7 @@ type HTTPCertGetter struct { } // CaddyModule returns the Caddy module information. -func (hcg HTTPCertGetter) CaddyModule() caddy.ModuleInfo { +func (HTTPCertGetter) CaddyModule() caddy.ModuleInfo { return caddy.ModuleInfo{ ID: "tls.get_certificate.http", New: func() caddy.Module { return new(HTTPCertGetter) }, diff --git a/modules/caddytls/connpolicy.go b/modules/caddytls/connpolicy.go index 64fdd513861..b896b0e6379 100644 --- a/modules/caddytls/connpolicy.go +++ b/modules/caddytls/connpolicy.go @@ -81,7 +81,7 @@ func (cp ConnectionPolicies) Provision(ctx caddy.Context) error { // TLSConfig returns a standard-lib-compatible TLS configuration which // selects the first matching policy based on the ClientHello. -func (cp ConnectionPolicies) TLSConfig(_ caddy.Context) *tls.Config { +func (cp ConnectionPolicies) TLSConfig(ctx caddy.Context) *tls.Config { // using ServerName to match policies is extremely common, especially in configs // with lots and lots of different policies; we can fast-track those by indexing // them by SNI, so we don't have to iterate potentially thousands of policies diff --git a/modules/caddytls/sessiontickets.go b/modules/caddytls/sessiontickets.go index bfc5628ac2d..762cfac6a16 100644 --- a/modules/caddytls/sessiontickets.go +++ b/modules/caddytls/sessiontickets.go @@ -216,7 +216,7 @@ func (s SessionTicketService) RotateSTEKs(keys [][32]byte) ([][32]byte, error) { // generateSTEK generates key material suitable for use as a // session ticket ephemeral key. -func (s *SessionTicketService) generateSTEK() ([32]byte, error) { +func (*SessionTicketService) generateSTEK() ([32]byte, error) { var newTicketKey [32]byte _, err := io.ReadFull(rand.Reader, newTicketKey[:]) return newTicketKey, err diff --git a/modules/logging/encoders.go b/modules/logging/encoders.go index a4409e7e459..d127c6332f7 100644 --- a/modules/logging/encoders.go +++ b/modules/logging/encoders.go @@ -45,7 +45,7 @@ func (ConsoleEncoder) CaddyModule() caddy.ModuleInfo { } // Provision sets up the encoder. -func (ce *ConsoleEncoder) Provision(_ caddy.Context) error { +func (ce *ConsoleEncoder) Provision(ctx caddy.Context) error { if ce.LevelFormat == "" { ce.LevelFormat = "color" } @@ -92,7 +92,7 @@ func (JSONEncoder) CaddyModule() caddy.ModuleInfo { } // Provision sets up the encoder. -func (je *JSONEncoder) Provision(_ caddy.Context) error { +func (je *JSONEncoder) Provision(ctx caddy.Context) error { je.Encoder = zapcore.NewJSONEncoder(je.ZapcoreEncoderConfig()) return nil } diff --git a/modules/logging/filewriter.go b/modules/logging/filewriter.go index 11c051d783f..a8b852ba954 100644 --- a/modules/logging/filewriter.go +++ b/modules/logging/filewriter.go @@ -73,7 +73,7 @@ func (FileWriter) CaddyModule() caddy.ModuleInfo { } // Provision sets up the module -func (fw *FileWriter) Provision(ctx caddy.Context) error { +func (fw *FileWriter) Provision(caddy.Context) error { // Replace placeholder in filename repl := caddy.NewReplacer() filename, err := repl.ReplaceOrErr(fw.Filename, true, true) diff --git a/modules/logging/filters.go b/modules/logging/filters.go index 233d5d7133e..cd12d135c92 100644 --- a/modules/logging/filters.go +++ b/modules/logging/filters.go @@ -93,12 +93,12 @@ func (HashFilter) CaddyModule() caddy.ModuleInfo { } // UnmarshalCaddyfile sets up the module from Caddyfile tokens. -func (f *HashFilter) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { +func (*HashFilter) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { return nil } // Filter filters the input field with the replacement value. -func (f *HashFilter) Filter(in zapcore.Field) zapcore.Field { +func (*HashFilter) Filter(in zapcore.Field) zapcore.Field { if array, ok := in.Interface.(caddyhttp.LoggableStringArray); ok { newArray := make(caddyhttp.LoggableStringArray, len(array)) for i, s := range array { @@ -327,7 +327,7 @@ func (QueryFilter) CaddyModule() caddy.ModuleInfo { } // UnmarshalCaddyfile sets up the module from Caddyfile tokens. -func (m *QueryFilter) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { +func (f *QueryFilter) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { for d.Next() { for d.NextBlock(0) { qfa := queryFilterAction{} @@ -365,35 +365,35 @@ func (m *QueryFilter) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { return d.Errf("unrecognized subdirective %s", d.Val()) } - m.Actions = append(m.Actions, qfa) + f.Actions = append(f.Actions, qfa) } } return nil } // Filter filters the input field. -func (m QueryFilter) Filter(in zapcore.Field) zapcore.Field { +func (f QueryFilter) Filter(in zapcore.Field) zapcore.Field { if array, ok := in.Interface.(caddyhttp.LoggableStringArray); ok { newArray := make(caddyhttp.LoggableStringArray, len(array)) for i, s := range array { - newArray[i] = m.processQueryString(s) + newArray[i] = f.processQueryString(s) } in.Interface = newArray } else { - in.String = m.processQueryString(in.String) + in.String = f.processQueryString(in.String) } return in } -func (m QueryFilter) processQueryString(s string) string { +func (f QueryFilter) processQueryString(s string) string { u, err := url.Parse(s) if err != nil { return s } q := u.Query() - for _, a := range m.Actions { + for _, a := range f.Actions { switch a.Type { case replaceAction: for i := range q[a.Parameter] { @@ -459,7 +459,7 @@ func (CookieFilter) CaddyModule() caddy.ModuleInfo { } // UnmarshalCaddyfile sets up the module from Caddyfile tokens. -func (m *CookieFilter) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { +func (f *CookieFilter) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { for d.Next() { for d.NextBlock(0) { cfa := cookieFilterAction{} @@ -497,14 +497,14 @@ func (m *CookieFilter) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { return d.Errf("unrecognized subdirective %s", d.Val()) } - m.Actions = append(m.Actions, cfa) + f.Actions = append(f.Actions, cfa) } } return nil } // Filter filters the input field. -func (m CookieFilter) Filter(in zapcore.Field) zapcore.Field { +func (f CookieFilter) Filter(in zapcore.Field) zapcore.Field { cookiesSlice, ok := in.Interface.(caddyhttp.LoggableStringArray) if !ok { return in @@ -517,7 +517,7 @@ func (m CookieFilter) Filter(in zapcore.Field) zapcore.Field { OUTER: for _, c := range cookies { - for _, a := range m.Actions { + for _, a := range f.Actions { if c.Name != a.Name { continue } @@ -583,13 +583,13 @@ func (f *RegexpFilter) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { } // Provision compiles m's regexp. -func (m *RegexpFilter) Provision(ctx caddy.Context) error { - r, err := regexp.Compile(m.RawRegexp) +func (f *RegexpFilter) Provision(ctx caddy.Context) error { + r, err := regexp.Compile(f.RawRegexp) if err != nil { return err } - m.regexp = r + f.regexp = r return nil } diff --git a/modules/logging/filters_test.go b/modules/logging/filters_test.go index 8f7ba0d7071..294652c914c 100644 --- a/modules/logging/filters_test.go +++ b/modules/logging/filters_test.go @@ -3,14 +3,18 @@ package logging import ( "testing" + "go.uber.org/zap/zapcore" + "github.com/caddyserver/caddy/v2" "github.com/caddyserver/caddy/v2/modules/caddyhttp" - "go.uber.org/zap/zapcore" ) func TestIPMaskSingleValue(t *testing.T) { f := IPMaskFilter{IPv4MaskRaw: 16, IPv6MaskRaw: 32} - f.Provision(caddy.Context{}) + err := f.Provision(caddy.Context{}) + if err != nil { + t.Fatalf("provisioning failed: %v", err) + } out := f.Filter(zapcore.Field{String: "255.255.255.255"}) if out.String != "255.255.0.0" { @@ -30,7 +34,10 @@ func TestIPMaskSingleValue(t *testing.T) { func TestIPMaskCommaValue(t *testing.T) { f := IPMaskFilter{IPv4MaskRaw: 16, IPv6MaskRaw: 32} - f.Provision(caddy.Context{}) + err := f.Provision(caddy.Context{}) + if err != nil { + t.Fatalf("provisioning failed: %v", err) + } out := f.Filter(zapcore.Field{String: "255.255.255.255, 244.244.244.244"}) if out.String != "255.255.0.0, 244.244.0.0" { @@ -50,7 +57,10 @@ func TestIPMaskCommaValue(t *testing.T) { func TestIPMaskMultiValue(t *testing.T) { f := IPMaskFilter{IPv4MaskRaw: 16, IPv6MaskRaw: 32} - f.Provision(caddy.Context{}) + err := f.Provision(caddy.Context{}) + if err != nil { + t.Fatalf("provisioning failed: %v", err) + } out := f.Filter(zapcore.Field{Interface: caddyhttp.LoggableStringArray{ "255.255.255.255", @@ -189,7 +199,10 @@ func TestValidateCookieFilter(t *testing.T) { func TestRegexpFilterSingleValue(t *testing.T) { f := RegexpFilter{RawRegexp: `secret`, Value: "REDACTED"} - f.Provision(caddy.Context{}) + err := f.Provision(caddy.Context{}) + if err != nil { + t.Fatalf("provisioning failed: %v", err) + } out := f.Filter(zapcore.Field{String: "foo-secret-bar"}) if out.String != "foo-REDACTED-bar" { @@ -199,7 +212,10 @@ func TestRegexpFilterSingleValue(t *testing.T) { func TestRegexpFilterMultiValue(t *testing.T) { f := RegexpFilter{RawRegexp: `secret`, Value: "REDACTED"} - f.Provision(caddy.Context{}) + err := f.Provision(caddy.Context{}) + if err != nil { + t.Fatalf("provisioning failed: %v", err) + } out := f.Filter(zapcore.Field{Interface: caddyhttp.LoggableStringArray{"foo-secret-bar", "bar-secret-foo"}}) arr, ok := out.Interface.(caddyhttp.LoggableStringArray) diff --git a/modules/logging/netwriter.go b/modules/logging/netwriter.go index 1939cb711dc..65f9c1ab1c7 100644 --- a/modules/logging/netwriter.go +++ b/modules/logging/netwriter.go @@ -170,7 +170,7 @@ func (reconn *redialerConn) Write(b []byte) (n int, err error) { reconn.connMu.RUnlock() if conn != nil { if n, err = conn.Write(b); err == nil { - return + return n, nil } } @@ -182,7 +182,7 @@ func (reconn *redialerConn) Write(b []byte) (n int, err error) { // one of them might have already re-dialed by now; try writing again if reconn.Conn != nil { if n, err = reconn.Conn.Write(b); err == nil { - return + return n, nil } } @@ -196,7 +196,7 @@ func (reconn *redialerConn) Write(b []byte) (n int, err error) { if err2 != nil { // logger socket still offline; instead of discarding the log, dump it to stderr os.Stderr.Write(b) - return + return 0, err2 } if n, err = conn2.Write(b); err == nil { if reconn.Conn != nil { @@ -209,7 +209,7 @@ func (reconn *redialerConn) Write(b []byte) (n int, err error) { os.Stderr.Write(b) } - return + return n, err } func (reconn *redialerConn) dial() (net.Conn, error) { diff --git a/modules/metrics/adminmetrics.go b/modules/metrics/adminmetrics.go index 1cf398e4cb6..f20521e0163 100644 --- a/modules/metrics/adminmetrics.go +++ b/modules/metrics/adminmetrics.go @@ -40,7 +40,7 @@ func (AdminMetrics) CaddyModule() caddy.ModuleInfo { } // Routes returns a route for the /metrics endpoint. -func (m *AdminMetrics) Routes() []caddy.AdminRoute { +func (*AdminMetrics) Routes() []caddy.AdminRoute { metricsHandler := createMetricsHandler(nil, false) h := caddy.AdminHandlerFunc(func(w http.ResponseWriter, r *http.Request) error { metricsHandler.ServeHTTP(w, r) diff --git a/modules/metrics/metrics.go b/modules/metrics/metrics.go index a9e0f0efa54..0fd6fe77d32 100644 --- a/modules/metrics/metrics.go +++ b/modules/metrics/metrics.go @@ -96,7 +96,7 @@ func (m *Metrics) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { return nil } -func (m Metrics) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhttp.Handler) error { +func (m Metrics) ServeHTTP(w http.ResponseWriter, r *http.Request, _ caddyhttp.Handler) error { m.metricsHandler.ServeHTTP(w, r) return nil } diff --git a/usagepool.go b/usagepool.go index 7007849fb95..7c019b537e1 100644 --- a/usagepool.go +++ b/usagepool.go @@ -106,7 +106,7 @@ func (up *UsagePool) LoadOrNew(key any, construct Constructor) (value any, loade } upv.Unlock() } - return + return value, loaded, err } // LoadOrStore loads the value associated with key from the pool if it @@ -134,7 +134,7 @@ func (up *UsagePool) LoadOrStore(key, val any) (value any, loaded bool) { up.Unlock() value = val } - return + return value, loaded } // Range iterates the pool similarly to how sync.Map.Range() does: @@ -191,7 +191,7 @@ func (up *UsagePool) Delete(key any) (deleted bool, err error) { upv.value, upv.refs)) } } - return + return deleted, err } // References returns the number of references (count of usages) to a