diff --git a/.github/workflows/go-critic.yml b/.github/workflows/go-critic.yml deleted file mode 100644 index deaac68..0000000 --- a/.github/workflows/go-critic.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: Gocritic Scan - -on: - push: - branches: - - "master" - - "main" - paths-ignore: - - "**.md" - pull_request: - branches: - - "*" - paths-ignore: - - "**.md" - -jobs: - gocritic-scan: - runs-on: ubuntu-latest - env: - GO111MODULE: on - steps: - - name: Fetch Repository - uses: actions/checkout@v4 - - name: Install Go - uses: actions/setup-go@v5 - with: - go-version: '1.21.x' - check-latest: true - cache: false - - name: Install go-critic - run: go install -v github.com/go-critic/go-critic/cmd/gocritic@latest - - name: Run gocritic - run: gocritic check -checkTests=False ./... \ No newline at end of file diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml deleted file mode 100644 index b0c20ca..0000000 --- a/.github/workflows/golangci-lint.yml +++ /dev/null @@ -1,25 +0,0 @@ -name: Golangci-Lint Check - -on: - push: - branches: - - "master" - - "main" - paths-ignore: - - "**.md" - pull_request: - branches: - - "*" - paths-ignore: - - "**.md" - -jobs: - golangci-lint: - runs-on: ubuntu-latest - steps: - - name: Fetch Repository - uses: actions/checkout@v4 - - name: Run golangci-lint - uses: reviewdog/action-golangci-lint@v2 - with: - golangci_lint_flags: "--tests=false --timeout=5m" diff --git a/.github/workflows/gosec.yml b/.github/workflows/gosec.yml deleted file mode 100644 index d341337..0000000 --- a/.github/workflows/gosec.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: Gosec Security Scan - -on: - push: - branches: - - "master" - - "main" - paths-ignore: - - "**.md" - pull_request: - branches: - - "*" - paths-ignore: - - "**.md" - -jobs: - gosec-scan: - runs-on: ubuntu-latest - env: - GO111MODULE: on - steps: - - name: Fetch Repository - uses: actions/checkout@v4 - - name: Install Go - uses: actions/setup-go@v5 - with: - go-version: 'stable' - check-latest: true - cache: false - - name: Install Gosec - run: go install github.com/securego/gosec/v2/cmd/gosec@latest - - name: Run Gosec - run: gosec ./... diff --git a/.github/workflows/govulncheck.yml b/.github/workflows/govulncheck.yml deleted file mode 100644 index 6701f99..0000000 --- a/.github/workflows/govulncheck.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: Govulncheck Security Scan - -on: - push: - branches: - - "master" - - "main" - paths-ignore: - - "**.md" - pull_request: - branches: - - "*" - paths-ignore: - - "**.md" - -jobs: - govulncheck-check: - runs-on: ubuntu-latest - env: - GO111MODULE: on - steps: - - name: Fetch Repository - uses: actions/checkout@v4 - - name: Install Go - uses: actions/setup-go@v5 - with: - go-version: 'stable' - check-latest: true - cache: false - - name: Install Govulncheck - run: go install golang.org/x/vuln/cmd/govulncheck@latest - - name: Run Govulncheck - run: govulncheck ./... diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..4ae74b3 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,61 @@ +name: Lint + +on: + push: + branches: + - master + - main + paths-ignore: + - "**.md" + pull_request: + branches: + - master + - main + paths-ignore: + - "**.md" + +permissions: + contents: read + +jobs: + # From https://github.com/golangci/golangci-lint-action + golangci: + permissions: + contents: read # for actions/checkout to fetch code + pull-requests: read # for golangci/golangci-lint-action to fetch pull requests + name: lint + strategy: + matrix: + os: + - linux + - windows + + include: + - os: linux + OS_LABEL: ubuntu-latest + + - os: windows + OS_LABEL: windows-latest + runs-on: ${{ matrix.OS_LABEL }} + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 + with: + go-version: '~1.22.0' + check-latest: true + cache: false + + - name: golangci-lint + uses: golangci/golangci-lint-action@v3 + with: + version: v1.55.2 + args: --timeout 10m + + govulncheck: + runs-on: ubuntu-latest + steps: + - name: govulncheck + uses: golang/govulncheck-action@v1 + with: + go-version-input: '~1.22.0' + check-latest: true \ No newline at end of file diff --git a/.golanci-lint.yml b/.golanci-lint.yml new file mode 100644 index 0000000..d144395 --- /dev/null +++ b/.golanci-lint.yml @@ -0,0 +1,168 @@ +linters-settings: + errcheck: + ignore: fmt:.*,go.uber.org/zap/zapcore:^Add.* + ignoretests: true + gci: + sections: + - standard # Standard section: captures all standard packages. + - default # Default section: contains all imports that could not be matched to another section type. + - prefix(github.com/caddyserver/caddy/v2/cmd) # ensure that this is always at the top and always has a line break. + - prefix(github.com/caddyserver/caddy) # Custom section: groups all imports with the specified Prefix. + # Skip generated files. + # Default: true + skip-generated: true + # Enable custom order of sections. + # If `true`, make the section order the same as the order of `sections`. + # Default: false + custom-order: true + exhaustive: + ignore-enum-types: reflect.Kind|svc.Cmd + +linters: + disable-all: true + enable: + - asasalint + - asciicheck + - bidichk + - bodyclose + - decorder + - dogsled + - dupl + - dupword + - durationcheck + - errcheck + - errname + - exhaustive + - exportloopref + - gci + - gofmt + - goimports + - gofumpt + - gosec + - gosimple + - govet + - ineffassign + - importas + - misspell + - prealloc + - promlinter + - sloglint + - sqlclosecheck + - staticcheck + - tenv + - testableexamples + - testifylint + - tparallel + - typecheck + - unconvert + - unused + - wastedassign + - whitespace + - zerologlint + # these are implicitly disabled: + # - containedctx + # - contextcheck + # - cyclop + # - depguard + # - errchkjson + # - errorlint + # - exhaustruct + # - execinquery + # - exhaustruct + # - forbidigo + # - forcetypeassert + # - funlen + # - ginkgolinter + # - gocheckcompilerdirectives + # - gochecknoglobals + # - gochecknoinits + # - gochecksumtype + # - gocognit + # - goconst + # - gocritic + # - gocyclo + # - godot + # - godox + # - goerr113 + # - goheader + # - gomnd + # - gomoddirectives + # - gomodguard + # - goprintffuncname + # - gosmopolitan + # - grouper + # - inamedparam + # - interfacebloat + # - ireturn + # - lll + # - loggercheck + # - maintidx + # - makezero + # - mirror + # - musttag + # - nakedret + # - nestif + # - nilerr + # - nilnil + # - nlreturn + # - noctx + # - nolintlint + # - nonamedreturns + # - nosprintfhostport + # - paralleltest + # - perfsprint + # - predeclared + # - protogetter + # - reassign + # - revive + # - rowserrcheck + # - stylecheck + # - tagalign + # - tagliatelle + # - testpackage + # - thelper + # - unparam + # - usestdlibvars + # - varnamelen + # - wrapcheck + # - wsl + +run: + # default concurrency is a available CPU number. + # concurrency: 4 # explicitly omit this value to fully utilize available resources. + deadline: 5m + issues-exit-code: 1 + tests: false + +# output configuration options +output: + format: 'colored-line-number' + print-issued-lines: true + print-linter-name: true + +issues: + exclude-rules: + # we aren't calling unknown URL + - text: 'G107' # G107: Url provided to HTTP request as taint input + linters: + - gosec + # as a web server that's expected to handle any template, this is totally in the hands of the user. + - text: 'G203' # G203: Use of unescaped data in HTML templates + linters: + - gosec + # we're shelling out to known commands, not relying on user-defined input. + - text: 'G204' # G204: Audit use of command execution + linters: + - gosec + # the choice of weakrand is deliberate, hence the named import "weakrand" + - path: modules/caddyhttp/reverseproxy/selectionpolicies.go + text: 'G404' # G404: Insecure random number source (rand) + linters: + - gosec + - path: modules/caddyhttp/reverseproxy/streaming.go + text: 'G404' # G404: Insecure random number source (rand) + linters: + - gosec + - path: modules/logging/filters.go + linters: + - dupl diff --git a/common_test.go b/common_test.go index 4880d3b..8f1341b 100644 --- a/common_test.go +++ b/common_test.go @@ -3,13 +3,9 @@ package forwardproxy import ( "context" "crypto/tls" - "encoding/hex" "encoding/json" - "fmt" - "io" "net" "net/http" - "net/http/httputil" "os" "strconv" "testing" @@ -68,7 +64,7 @@ type caddyTestServer struct { httpRedirPort string // used in probe-resist tests to simulate default Caddy's http->https redirect root string // expected to have index.html and pic.png - directives []string + _ []string proxyHandler *Handler contents map[string][]byte } @@ -365,7 +361,7 @@ func TestMain(m *testing.M) { retCode := m.Run() - caddy.Stop() + caddy.Stop() // nolint:errcheck // ignore error on shutdown os.Exit(retCode) } @@ -416,66 +412,6 @@ func TestTheTest(t *testing.T) { } } -func debugIoCopy(dst io.Writer, src io.Reader, prefix string) (written int64, err error) { - buf := make([]byte, 32*1024) - flusher, ok := dst.(http.Flusher) - for { - nr, er := src.Read(buf) - fmt.Printf("[%s] Read err %#v\n%s", prefix, er, hex.Dump(buf[0:nr])) - if nr > 0 { - nw, ew := dst.Write(buf[0:nr]) - if ok { - flusher.Flush() - } - fmt.Printf("[%s] Wrote %v %v\n", prefix, nw, ew) - if nw > 0 { - written += int64(nw) - } - if ew != nil { - err = ew - break - } - if nr != nw { - err = io.ErrShortWrite - break - } - } - if er != nil { - if er != io.EOF { - err = er - } - break - } - } - fmt.Printf("[%s] Returning with %#v %#v\n", prefix, written, err) - return -} - -func httpdump(r interface{}) string { - switch v := r.(type) { - case *http.Request: - if v == nil { - return "httpdump: nil" - } - b, err := httputil.DumpRequest(v, true) - if err != nil { - return err.Error() - } - return string(b) - case *http.Response: - if v == nil { - return "httpdump: nil" - } - b, err := httputil.DumpResponse(v, true) - if err != nil { - return err.Error() - } - return string(b) - default: - return "httpdump: wrong type" - } -} - var testTransport = &http.Transport{ ResponseHeaderTimeout: 2 * time.Second, DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) { diff --git a/forwardproxy_test.go b/forwardproxy_test.go index ebb6f98..beb1158 100644 --- a/forwardproxy_test.go +++ b/forwardproxy_test.go @@ -88,7 +88,7 @@ func connectAndGetViaProxy(targetHost, resource, proxyAddr, httpTargetVer, proxy case "HTTP/1.1": req.ProtoMajor = 1 req.ProtoMinor = 1 - req.Write(proxyConn) + req.Write(proxyConn) // nolint:errcheck // we don't care about the error here resp, err = http.ReadResponse(bufio.NewReader(proxyConn), req) if err != nil { return resp, err diff --git a/httpclient_test.go b/httpclient_test.go index af75379..700a5a1 100644 --- a/httpclient_test.go +++ b/httpclient_test.go @@ -103,6 +103,7 @@ func TestHttpClientH2Multiplexing(t *testing.T) { _test() // do serially at least once for i := 0; i < retries; i++ { + // nolint:govet // this is a test go _test() time.Sleep(sleepInterval) }