diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index beed2126..2f7f8c84 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -37,4 +37,7 @@ jobs: uses: golangci/golangci-lint-action@v6 with: # NOTE: Keep this in sync with the version from .golangci.yml - version: v1.62.2 + version: v1.64.7 + # NOTE(ldez): temporary workaround + install-mode: goinstall + diff --git a/.golangci.yml b/.golangci.yml index 8b8d27b8..357676f7 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -7,7 +7,6 @@ run: output: sort-results: true - uniq-by-line: false linters-settings: depguard: @@ -187,7 +186,7 @@ linters-settings: - name: unchecked-type-assertion disabled: true # TODO: Do not disable - name: unhandled-error - arguments: ['bytes\.Buffer\.Write'] + disabled: true stylecheck: checks: @@ -250,7 +249,10 @@ issues: max-issues-per-linter: 0 max-same-issues: 0 exclude-dirs: - - internal # TODO: Do not ignore interal packages + - internal # TODO: Do not ignore internal packages + exclude-files: + - '_msgp\.go' + - '_msgp_test\.go' exclude-rules: - linters: - err113 @@ -263,7 +265,10 @@ issues: linters: - bodyclose - err113 - # fix: true + - source: 'fmt.Fprintf?' + linters: + - errcheck + - revive linters: enable: @@ -358,7 +363,6 @@ linters: - stylecheck # - tagalign # TODO: Enable - tagliatelle - - tenv - testableexamples - testifylint # - testpackage # TODO: Enable diff --git a/Makefile b/Makefile index 669b3fbe..7e67dbc2 100644 --- a/Makefile +++ b/Makefile @@ -35,7 +35,7 @@ markdown: ## lint: 🚨 Run lint checks .PHONY: lint lint: - go run github.com/golangci/golangci-lint/cmd/golangci-lint@v1.62.2 run ./... + golangci-lint run ## test: 🚦 Execute all tests .PHONY: test diff --git a/app.go b/app.go index ec55f06a..84059e79 100644 --- a/app.go +++ b/app.go @@ -1024,7 +1024,7 @@ func (app *App) Test(req *http.Request, config ...TestConfig) (*http.Response, e select { case err = <-channel: case <-time.After(cfg.Timeout): - conn.Close() //nolint:errcheck, revive // It is fine to ignore the error here + conn.Close() //nolint:errcheck // It is fine to ignore the error here if cfg.FailOnTimeout { return nil, os.ErrDeadlineExceeded } diff --git a/app_test.go b/app_test.go index 97d48fce..84606e6b 100644 --- a/app_test.go +++ b/app_test.go @@ -403,7 +403,7 @@ func Test_App_serverErrorHandler_Internal_Error(t *testing.T) { t.Parallel() app := New() msg := "test err" - c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed + c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck,forcetypeassert // not needed app.serverErrorHandler(c.fasthttp, errors.New(msg)) require.Equal(t, string(c.fasthttp.Response.Body()), msg) @@ -413,7 +413,7 @@ func Test_App_serverErrorHandler_Internal_Error(t *testing.T) { func Test_App_serverErrorHandler_Network_Error(t *testing.T) { t.Parallel() app := New() - c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed + c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck,forcetypeassert // not needed app.serverErrorHandler(c.fasthttp, &net.DNSError{ Err: "test error", diff --git a/bind_test.go b/bind_test.go index b01086e6..89839e13 100644 --- a/bind_test.go +++ b/bind_test.go @@ -1378,7 +1378,7 @@ func Benchmark_Bind_URI(b *testing.B) { var err error app := New() - c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed + c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck,forcetypeassert // not needed c.route = &Route{ Params: []string{ @@ -1415,7 +1415,7 @@ func Benchmark_Bind_URI_Map(b *testing.B) { var err error app := New() - c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed + c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck,forcetypeassert // not needed c.route = &Route{ Params: []string{ diff --git a/client/helper_test.go b/client/helper_test.go index f25d0af1..1b644cbd 100644 --- a/client/helper_test.go +++ b/client/helper_test.go @@ -131,7 +131,7 @@ func testRequestFail(t *testing.T, handler fiber.Handler, wrapAgent func(agent * } } -func testClient(t *testing.T, handler fiber.Handler, wrapAgent func(agent *Client), excepted string, count ...int) { //nolint: unparam // maybe needed +func testClient(t *testing.T, handler fiber.Handler, wrapAgent func(agent *Client), excepted string, count ...int) { //nolint:unparam // maybe needed t.Helper() app, ln, start := createHelperServer(t) diff --git a/client/hooks.go b/client/hooks.go index ca6f5d6c..3d86930d 100644 --- a/client/hooks.go +++ b/client/hooks.go @@ -199,7 +199,7 @@ func parserRequestBody(c *Client, req *Request) error { case filesBody: return parserRequestBodyFile(req) case rawBody: - if body, ok := req.body.([]byte); ok { + if body, ok := req.body.([]byte); ok { //nolint:revive // ignore simplicity req.RawRequest.SetBody(body) } else { return ErrBodyType diff --git a/client/request.go b/client/request.go index 80a03b09..daa7e60b 100644 --- a/client/request.go +++ b/client/request.go @@ -298,11 +298,12 @@ func (r *Request) Cookie(key string) string { // Use maps.Collect() to gather them into a map if needed. func (r *Request) Cookies() iter.Seq2[string, string] { return func(yield func(string, string) bool) { - r.cookies.VisitAll(func(key, val string) { - if !yield(key, val) { + for k, v := range *r.cookies { + res := yield(k, v) + if !res { return } - }) + } } } @@ -343,11 +344,11 @@ func (r *Request) PathParam(key string) string { // Use maps.Collect() to gather them into a map if needed. func (r *Request) PathParams() iter.Seq2[string, string] { return func(yield func(string, string) bool) { - r.path.VisitAll(func(key, val string) { - if !yield(key, val) { + for k, v := range *r.path { + if !yield(k, v) { return } - }) + } } } diff --git a/client/request_test.go b/client/request_test.go index c13dbbd8..73bae29d 100644 --- a/client/request_test.go +++ b/client/request_test.go @@ -1,3 +1,4 @@ +//nolint:goconst // Much easier to just ignore memory leaks in tests package client import ( @@ -451,6 +452,14 @@ func Test_Request_Cookies(t *testing.T) { require.Equal(t, "bar", cookies["foo"]) require.Equal(t, "foo", cookies["bar"]) + require.NotPanics(t, func() { + for _, v := range req.Cookies() { + if v == "bar" { + break + } + } + }) + require.Len(t, cookies, 2) } @@ -564,6 +573,14 @@ func Test_Request_PathParams(t *testing.T) { require.Equal(t, "foo", pathParams["bar"]) require.Len(t, pathParams, 2) + + require.NotPanics(t, func() { + for _, v := range req.PathParams() { + if v == "bar" { + break + } + } + }) } func Benchmark_Request_PathParams(b *testing.B) { @@ -1579,7 +1596,7 @@ func Test_SetValWithStruct(t *testing.T) { require.True(t, func() bool { for _, v := range p.PeekMulti("TSlice") { - if string(v) == "bar" { //nolint:goconst // test + if string(v) == "bar" { return true } } diff --git a/ctx_test.go b/ctx_test.go index ee272d24..5040f4f8 100644 --- a/ctx_test.go +++ b/ctx_test.go @@ -192,7 +192,7 @@ func Test_Ctx_AcceptsCharsets(t *testing.T) { // go test -v -run=^$ -bench=Benchmark_Ctx_AcceptsCharsets -benchmem -count=4 func Benchmark_Ctx_AcceptsCharsets(b *testing.B) { app := New() - c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed + c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck,forcetypeassert // not needed c.Request().Header.Set("Accept-Charset", "utf-8, iso-8859-1;q=0.5") var res string @@ -218,7 +218,7 @@ func Test_Ctx_AcceptsEncodings(t *testing.T) { // go test -v -run=^$ -bench=Benchmark_Ctx_AcceptsEncodings -benchmem -count=4 func Benchmark_Ctx_AcceptsEncodings(b *testing.B) { app := New() - c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed + c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck,forcetypeassert // not needed c.Request().Header.Set(HeaderAcceptEncoding, "deflate, gzip;q=1.0, *;q=0.5") var res string @@ -243,7 +243,7 @@ func Test_Ctx_AcceptsLanguages(t *testing.T) { // go test -v -run=^$ -bench=Benchmark_Ctx_AcceptsLanguages -benchmem -count=4 func Benchmark_Ctx_AcceptsLanguages(b *testing.B) { app := New() - c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed + c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck,forcetypeassert // not needed c.Request().Header.Set(HeaderAcceptLanguage, "fr-CH, fr;q=0.9, en;q=0.8, de;q=0.7, *;q=0.5") var res string @@ -304,7 +304,7 @@ func Test_Ctx_Append(t *testing.T) { // go test -v -run=^$ -bench=Benchmark_Ctx_Append -benchmem -count=4 func Benchmark_Ctx_Append(b *testing.B) { app := New() - c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed + c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck,forcetypeassert // not needed b.ReportAllocs() b.ResetTimer() @@ -337,7 +337,7 @@ func Test_Ctx_Attachment(t *testing.T) { // go test -v -run=^$ -bench=Benchmark_Ctx_Attachment -benchmem -count=4 func Benchmark_Ctx_Attachment(b *testing.B) { app := New() - c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed + c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck,forcetypeassert // not needed b.ReportAllocs() b.ResetTimer() @@ -363,7 +363,7 @@ func Test_Ctx_BaseURL(t *testing.T) { // go test -v -run=^$ -bench=Benchmark_Ctx_BaseURL -benchmem func Benchmark_Ctx_BaseURL(b *testing.B) { app := New() - c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed + c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck,forcetypeassert // not needed c.Request().SetHost("google.com:1337") c.Request().URI().SetPath("/haha/oke/lol") @@ -380,7 +380,7 @@ func Benchmark_Ctx_BaseURL(b *testing.B) { func Test_Ctx_Body(t *testing.T) { t.Parallel() app := New() - c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed + c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck,forcetypeassert // not needed c.Request().SetBody([]byte("john=doe")) require.Equal(t, []byte("john=doe"), c.Body()) @@ -390,7 +390,7 @@ func Test_Ctx_Body(t *testing.T) { func Test_Ctx_BodyRaw(t *testing.T) { t.Parallel() app := New() - c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed + c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck,forcetypeassert // not needed c.Request().SetBodyRaw([]byte("john=doe")) require.Equal(t, []byte("john=doe"), c.BodyRaw()) @@ -400,7 +400,7 @@ func Test_Ctx_BodyRaw(t *testing.T) { func Test_Ctx_BodyRaw_Immutable(t *testing.T) { t.Parallel() app := New(Config{Immutable: true}) - c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed + c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck,forcetypeassert // not needed c.Request().SetBodyRaw([]byte("john=doe")) require.Equal(t, []byte("john=doe"), c.BodyRaw()) @@ -411,7 +411,7 @@ func Benchmark_Ctx_Body(b *testing.B) { const input = "john=doe" app := New() - c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed + c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck,forcetypeassert // not needed c.Request().SetBody([]byte(input)) b.ReportAllocs() @@ -428,7 +428,7 @@ func Benchmark_Ctx_BodyRaw(b *testing.B) { const input = "john=doe" app := New() - c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed + c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck,forcetypeassert // not needed c.Request().SetBodyRaw([]byte(input)) b.ReportAllocs() @@ -445,7 +445,7 @@ func Benchmark_Ctx_BodyRaw_Immutable(b *testing.B) { const input = "john=doe" app := New(Config{Immutable: true}) - c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed + c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck,forcetypeassert // not needed c.Request().SetBodyRaw([]byte(input)) b.ReportAllocs() @@ -462,7 +462,7 @@ func Test_Ctx_Body_Immutable(t *testing.T) { t.Parallel() app := New() app.config.Immutable = true - c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed + c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck,forcetypeassert // not needed c.Request().SetBody([]byte("john=doe")) require.Equal(t, []byte("john=doe"), c.Body()) @@ -474,7 +474,7 @@ func Benchmark_Ctx_Body_Immutable(b *testing.B) { app := New() app.config.Immutable = true - c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed + c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck,forcetypeassert // not needed c.Request().SetBody([]byte(input)) b.ReportAllocs() @@ -527,7 +527,7 @@ func Test_Ctx_Body_With_Compression(t *testing.T) { t.Run(tCase.name, func(t *testing.T) { t.Parallel() app := New() - c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed + c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck,forcetypeassert // not needed c.Request().Header.Set("Content-Encoding", tCase.contentEncoding) if strings.Contains(tCase.contentEncoding, "gzip") { @@ -720,7 +720,7 @@ func Test_Ctx_Body_With_Compression_Immutable(t *testing.T) { t.Parallel() app := New() app.config.Immutable = true - c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed + c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck,forcetypeassert // not needed c.Request().Header.Set("Content-Encoding", tCase.contentEncoding) if strings.Contains(tCase.contentEncoding, "gzip") { @@ -897,7 +897,7 @@ func Test_Ctx_Context(t *testing.T) { t.Parallel() testKey := struct{}{} testValue := "Test Value" - ctx := context.WithValue(context.Background(), testKey, testValue) //nolint: staticcheck // not needed for tests + ctx := context.WithValue(context.Background(), testKey, testValue) //nolint:staticcheck // not needed for tests require.Equal(t, testValue, ctx.Value(testKey)) }) } @@ -910,7 +910,7 @@ func Test_Ctx_SetContext(t *testing.T) { testKey := struct{}{} testValue := "Test Value" - ctx := context.WithValue(context.Background(), testKey, testValue) //nolint: staticcheck // not needed for tests + ctx := context.WithValue(context.Background(), testKey, testValue) //nolint:staticcheck // not needed for tests c.SetContext(ctx) require.Equal(t, testValue, c.Context().Value(testKey)) } @@ -930,7 +930,7 @@ func Test_Ctx_Context_Multiple_Requests(t *testing.T) { } input := utils.CopyString(Query(c, "input", "NO_VALUE")) - ctx = context.WithValue(ctx, testKey, fmt.Sprintf("%s_%s", testValue, input)) //nolint: staticcheck // not needed for tests + ctx = context.WithValue(ctx, testKey, fmt.Sprintf("%s_%s", testValue, input)) //nolint:staticcheck // not needed for tests c.SetContext(ctx) return c.Status(StatusOK).SendString(fmt.Sprintf("resp_%s_returned", input)) @@ -1013,7 +1013,7 @@ func Test_Ctx_Cookie(t *testing.T) { // go test -v -run=^$ -bench=Benchmark_Ctx_Cookie -benchmem -count=4 func Benchmark_Ctx_Cookie(b *testing.B) { app := New() - c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed + c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck,forcetypeassert // not needed b.ReportAllocs() b.ResetTimer() @@ -1544,12 +1544,12 @@ func Test_Ctx_Binders(t *testing.T) { t.Run("URI", func(t *testing.T) { t.Skip("URI is not ready for v3") //nolint:gocritic // TODO: uncomment - //t.Parallel() - //withValues(t, func(c Ctx, testStruct *TestStruct) error { + // t.Parallel() + // withValues(t, func(c Ctx, testStruct *TestStruct) error { // c.Route().Params = []string{"name", "name2", "class", "class2"} // c.Params().value = [30]string{"foo", "bar", "111", "222"} // return c.Bind().URI(testStruct) - //}) + // }) }) t.Run("ReqHeader", func(t *testing.T) { t.Parallel() @@ -2566,7 +2566,7 @@ func Test_Ctx_Params_Case_Sensitive(t *testing.T) { // go test -v -run=^$ -bench=Benchmark_Ctx_Params -benchmem -count=4 func Benchmark_Ctx_Params(b *testing.B) { app := New() - c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed + c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck,forcetypeassert // not needed c.route = &Route{ Params: []string{ @@ -3746,7 +3746,7 @@ func Benchmark_Ctx_CBOR(b *testing.B) { func Benchmark_Ctx_JSON_Ctype(b *testing.B) { app := New() // TODO: Check extra allocs because of the interface stuff - c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed + c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck,forcetypeassert // not needed type SomeStruct struct { Name string Age uint8 @@ -3813,7 +3813,7 @@ func Test_Ctx_JSONP(t *testing.T) { // go test -v -run=^$ -bench=Benchmark_Ctx_JSONP -benchmem -count=4 func Benchmark_Ctx_JSONP(b *testing.B) { app := New() - c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed + c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck,forcetypeassert // not needed type SomeStruct struct { Name string @@ -3838,7 +3838,7 @@ func Benchmark_Ctx_JSONP(b *testing.B) { func Test_Ctx_XML(t *testing.T) { t.Parallel() app := New() - c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed + c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck,forcetypeassert // not needed require.Error(t, c.JSON(complex(1, 1))) @@ -3897,7 +3897,7 @@ func Test_Ctx_XML(t *testing.T) { // go test -run=^$ -bench=Benchmark_Ctx_XML -benchmem -count=4 func Benchmark_Ctx_XML(b *testing.B) { app := New() - c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed + c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck,forcetypeassert // not needed type SomeStruct struct { Name string `xml:"Name"` Age uint8 `xml:"Age"` @@ -3936,7 +3936,7 @@ func Test_Ctx_Links(t *testing.T) { // go test -v -run=^$ -bench=Benchmark_Ctx_Links -benchmem -count=4 func Benchmark_Ctx_Links(b *testing.B) { app := New() - c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed + c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck,forcetypeassert // not needed b.ReportAllocs() b.ResetTimer() @@ -4363,7 +4363,7 @@ func Benchmark_Ctx_Render_Engine(b *testing.B) { // go test -v -run=^$ -bench=Benchmark_Ctx_Get_Location_From_Route -benchmem -count=4 func Benchmark_Ctx_Get_Location_From_Route(b *testing.B) { app := New() - c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed + c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck,forcetypeassert // not needed app.Get("/user/:name", func(c Ctx) error { return c.SendString(c.Params("name")) @@ -4578,14 +4578,14 @@ func Test_Ctx_SendStreamWriter(t *testing.T) { c := app.AcquireCtx(&fasthttp.RequestCtx{}) err := c.SendStreamWriter(func(w *bufio.Writer) { - w.WriteString("Don't crash please") //nolint:errcheck, revive // It is fine to ignore the error + w.WriteString("Don't crash please") //nolint:errcheck // It is fine to ignore the error }) require.NoError(t, err) require.Equal(t, "Don't crash please", string(c.Response().Body())) err = c.SendStreamWriter(func(w *bufio.Writer) { for lineNum := 1; lineNum <= 5; lineNum++ { - fmt.Fprintf(w, "Line %d\n", lineNum) //nolint:errcheck, revive // It is fine to ignore the error + fmt.Fprintf(w, "Line %d\n", lineNum) if err := w.Flush(); err != nil { t.Errorf("unexpected error: %s", err) return @@ -4607,7 +4607,7 @@ func Test_Ctx_SendStreamWriter_Interrupted(t *testing.T) { app.Get("/", func(c Ctx) error { return c.SendStreamWriter(func(w *bufio.Writer) { for lineNum := 1; lineNum <= 5; lineNum++ { - fmt.Fprintf(w, "Line %d\n", lineNum) //nolint:errcheck // It is fine to ignore the error + fmt.Fprintf(w, "Line %d\n", lineNum) if err := w.Flush(); err != nil { if lineNum < 3 { @@ -4728,7 +4728,7 @@ func Benchmark_Ctx_Type(b *testing.B) { // go test -v -run=^$ -bench=Benchmark_Ctx_Type_Charset -benchmem -count=4 func Benchmark_Ctx_Type_Charset(b *testing.B) { app := New() - c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed + c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck,forcetypeassert // not needed b.ReportAllocs() b.ResetTimer() @@ -4753,7 +4753,7 @@ func Test_Ctx_Vary(t *testing.T) { // go test -v -run=^$ -bench=Benchmark_Ctx_Vary -benchmem -count=4 func Benchmark_Ctx_Vary(b *testing.B) { app := New() - c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed + c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck,forcetypeassert // not needed b.ReportAllocs() b.ResetTimer() @@ -4806,7 +4806,7 @@ func Test_Ctx_Writef(t *testing.T) { // go test -v -run=^$ -bench=Benchmark_Ctx_Writef -benchmem -count=4 func Benchmark_Ctx_Writef(b *testing.B) { app := New() - c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed + c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck,forcetypeassert // not needed world := "World!" b.ReportAllocs() @@ -4951,11 +4951,11 @@ func Test_Ctx_BodyStreamWriter(t *testing.T) { ctx := &fasthttp.RequestCtx{} ctx.SetBodyStreamWriter(func(w *bufio.Writer) { - fmt.Fprintf(w, "body writer line 1\n") //nolint: errcheck // It is fine to ignore the error + fmt.Fprintf(w, "body writer line 1\n") if err := w.Flush(); err != nil { t.Errorf("unexpected error: %s", err) } - fmt.Fprintf(w, "body writer line 2\n") //nolint: errcheck // It is fine to ignore the error + fmt.Fprintf(w, "body writer line 2\n") }) require.True(t, ctx.IsBodyStream()) diff --git a/docs/middleware/helmet.md b/docs/middleware/helmet.md index bc101350..369a4c2c 100644 --- a/docs/middleware/helmet.md +++ b/docs/middleware/helmet.md @@ -54,7 +54,7 @@ curl -I http://localhost:3000 | ContentSecurityPolicy | `string` | ContentSecurityPolicy | "" | | CSPReportOnly | `bool` | CSPReportOnly | false | | HSTSPreloadEnabled | `bool` | HSTSPreloadEnabled | false | -| ReferrerPolicy | `string` | ReferrerPolicy | "ReferrerPolicy" | +| ReferrerPolicy | `string` | ReferrerPolicy | "no-referrer" | | PermissionPolicy | `string` | Permissions-Policy | "" | | CrossOriginEmbedderPolicy | `string` | Cross-Origin-Embedder-Policy | "require-corp" | | CrossOriginOpenerPolicy | `string` | Cross-Origin-Opener-Policy | "same-origin" | diff --git a/docs/middleware/logger.md b/docs/middleware/logger.md index af16f384..c4c60cbc 100644 --- a/docs/middleware/logger.md +++ b/docs/middleware/logger.md @@ -79,7 +79,7 @@ app.Use(logger.New(logger.Config{ TimeZone: "Asia/Shanghai", Done: func(c fiber.Ctx, logString []byte) { if c.Response().StatusCode() != fiber.StatusOK { - reporter.SendToSlack(logString) + reporter.SendToSlack(logString) } }, })) @@ -88,6 +88,23 @@ app.Use(logger.New(logger.Config{ app.Use(logger.New(logger.Config{ DisableColors: true, })) + +// Use predefined formats +app.Use(logger.New(logger.Config{ + Format: logger.FormatCommon, +})) + +app.Use(logger.New(logger.Config{ + Format: logger.FormatCombined, +})) + +app.Use(logger.New(logger.Config{ + Format: logger.FormatJSON, +})) + +app.Use(logger.New(logger.Config{ + Format: logger.FormatECS, +})) ``` ### Use Logger Middleware with Other Loggers @@ -136,37 +153,50 @@ Writing to os.File is goroutine-safe, but if you are using a custom Stream that ### Config -| Property | Type | Description | Default | -|:-----------------|:---------------------------|:---------------------------------------------------------------------------------------------------------------------------------|:----------------------------------------------------------------------| -| Next | `func(fiber.Ctx) bool` | Next defines a function to skip this middleware when returned true. | `nil` | -| Skip | `func(fiber.Ctx) bool` | Skip is a function to determine if logging is skipped or written to Stream. | `nil` | -| Done | `func(fiber.Ctx, []byte)` | Done is a function that is called after the log string for a request is written to Stream, and pass the log string as parameter. | `nil` | -| CustomTags | `map[string]LogFunc` | tagFunctions defines the custom tag action. | `map[string]LogFunc` | -| Format | `string` | Format defines the logging tags. | `[${time}] ${ip} ${status} - ${latency} ${method} ${path} ${error}\n` | -| TimeFormat | `string` | TimeFormat defines the time format for log timestamps. | `15:04:05` | -| TimeZone | `string` | TimeZone can be specified, such as "UTC" and "America/New_York" and "Asia/Chongqing", etc | `"Local"` | -| TimeInterval | `time.Duration` | TimeInterval is the delay before the timestamp is updated. | `500 * time.Millisecond` | -| Stream | `io.Writer` | Stream is a writer where logs are written. | `os.Stdout` | -| LoggerFunc | `func(c fiber.Ctx, data *Data, cfg Config) error` | Custom logger function for integration with logging libraries (Zerolog, Zap, Logrus, etc). Defaults to Fiber's default logger if not defined. | `see default_logger.go defaultLoggerInstance` | -| DisableColors | `bool` | DisableColors defines if the logs output should be colorized. | `false` | +| Property | Type | Description | Default | +| :------------ | :------------------------------------------------ | :-------------------------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------- | +| Next | `func(fiber.Ctx) bool` | Next defines a function to skip this middleware when returned true. | `nil` | +| Skip | `func(fiber.Ctx) bool` | Skip is a function to determine if logging is skipped or written to Stream. | `nil` | +| Done | `func(fiber.Ctx, []byte)` | Done is a function that is called after the log string for a request is written to Stream, and pass the log string as parameter. | `nil` | +| CustomTags | `map[string]LogFunc` | tagFunctions defines the custom tag action. | `map[string]LogFunc` | +| `Format` | `string` | Defines the logging tags. See more in [Predefined Formats](#predefined-formats), or create your own using [Tags](#constants). | `[${time}] ${ip} ${status} - ${latency} ${method} ${path} ${error}\n` (same as `DefaultFormat`) | +| TimeFormat | `string` | TimeFormat defines the time format for log timestamps. | `15:04:05` | +| TimeZone | `string` | TimeZone can be specified, such as "UTC" and "America/New_York" and "Asia/Chongqing", etc | `"Local"` | +| TimeInterval | `time.Duration` | TimeInterval is the delay before the timestamp is updated. | `500 * time.Millisecond` | +| Stream | `io.Writer` | Stream is a writer where logs are written. | `os.Stdout` | +| LoggerFunc | `func(c fiber.Ctx, data *Data, cfg Config) error` | Custom logger function for integration with logging libraries (Zerolog, Zap, Logrus, etc). Defaults to Fiber's default logger if not defined. | `see default_logger.go defaultLoggerInstance` | +| DisableColors | `bool` | DisableColors defines if the logs output should be colorized. | `false` | ## Default Config ```go var ConfigDefault = Config{ - Next: nil, - Skip nil, - Done: nil, - Format: "[${time}] ${ip} ${status} - ${latency} ${method} ${path} ${error}\n", - TimeFormat: "15:04:05", - TimeZone: "Local", - TimeInterval: 500 * time.Millisecond, - Stream: os.Stdout, - DisableColors: false, - LoggerFunc: defaultLoggerInstance, + Next: nil, + Skip: nil, + Done: nil, + Format: DefaultFormat, + TimeFormat: "15:04:05", + TimeZone: "Local", + TimeInterval: 500 * time.Millisecond, + Stream: os.Stdout, + BeforeHandlerFunc: beforeHandlerFunc, + LoggerFunc: defaultLoggerInstance, + enableColors: true, } ``` +## Predefined Formats + +Logger provides predefined formats that you can use by name or directly by specifying the format string. + +| **Format Constant** | **Format String** | **Description** | +|---------------------|--------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------| +| `DefaultFormat` | `"[${time}] ${ip} ${status} - ${latency} ${method} ${path} ${error}\n"` | Fiber's default logger format. | +| `CommonFormat` | `"${ip} - - [${time}] "${method} ${url} ${protocol}" ${status} ${bytesSent}\n"` | Common Log Format (CLF) used in web server logs. | +| `CombinedFormat` | `"${ip} - - [${time}] "${method} ${url} ${protocol}" ${status} ${bytesSent} "${referer}" "${ua}"\n"` | CLF format plus the `referer` and `user agent` fields. | +| `JSONFormat` | `"{time: ${time}, ip: ${ip}, method: ${method}, url: ${url}, status: ${status}, bytesSent: ${bytesSent}}\n"` | JSON format for structured logging. | +| `ECSFormat` | `"{\"@timestamp\":\"${time}\",\"ecs\":{\"version\":\"1.6.0\"},\"client\":{\"ip\":\"${ip}\"},\"http\":{\"request\":{\"method\":\"${method}\",\"url\":\"${url}\",\"protocol\":\"${protocol}\"},\"response\":{\"status_code\":${status},\"body\":{\"bytes\":${bytesSent}}}},\"log\":{\"level\":\"INFO\",\"logger\":\"fiber\"},\"message\":\"${method} ${url} responded with ${status}\"}\n"` | Elastic Common Schema (ECS) format for structured logging. | + ## Constants ```go diff --git a/docs/whats_new.md b/docs/whats_new.md index baebe4c4..4d12e7fa 100644 --- a/docs/whats_new.md +++ b/docs/whats_new.md @@ -937,6 +937,22 @@ app.Use(logger.New(logger.Config{ +#### Predefined Formats + +Logger provides predefined formats that you can use by name or directly by specifying the format string. +
+ +Example Usage + +```go +app.Use(logger.New(logger.Config{ + Format: logger.FormatCombined, +})) +``` + +See more in [Logger](./middleware/logger.md#predefined-formats) +
+ ### Filesystem We've decided to remove filesystem middleware to clear up the confusion between static and filesystem middleware. diff --git a/go.mod b/go.mod index 5367e203..f4cd17c1 100644 --- a/go.mod +++ b/go.mod @@ -23,7 +23,7 @@ require ( github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/x448/float16 v0.8.4 // indirect - golang.org/x/net v0.35.0 // indirect + golang.org/x/net v0.37.0 // indirect golang.org/x/sys v0.31.0 // indirect golang.org/x/text v0.23.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index e586535a..71824581 100644 --- a/go.sum +++ b/go.sum @@ -36,6 +36,8 @@ golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= +golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c= +golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= diff --git a/helpers.go b/helpers.go index a452e13c..584553a7 100644 --- a/helpers.go +++ b/helpers.go @@ -51,16 +51,16 @@ func getTLSConfig(ln net.Listener) *tls.Config { } // Copy value from pointer - if val := reflect.Indirect(pointer); val.Type() != nil { + if val := reflect.Indirect(pointer); val.IsValid() { // Get private field from value - if field := val.FieldByName("config"); field.Type() != nil { + if field := val.FieldByName("config"); field.IsValid() { // Copy value from pointer field (unsafe) newval := reflect.NewAt(field.Type(), unsafe.Pointer(field.UnsafeAddr())) //nolint:gosec // Probably the only way to extract the *tls.Config from a net.Listener. TODO: Verify there really is no easier way without using unsafe. - if newval.Type() == nil { + if !newval.IsValid() { return nil } // Get element from pointer - if elem := newval.Elem(); elem.Type() != nil { + if elem := newval.Elem(); elem.IsValid() { // Cast value to *tls.Config c, ok := elem.Interface().(*tls.Config) if !ok { diff --git a/helpers_test.go b/helpers_test.go index 5e56bade..12d6b60f 100644 --- a/helpers_test.go +++ b/helpers_test.go @@ -566,7 +566,7 @@ func Test_Utils_TestConn_Closed_Write(t *testing.T) { require.NoError(t, err) // Close early, write should fail - conn.Close() //nolint:errcheck, revive // It is fine to ignore the error here + conn.Close() //nolint:errcheck // It is fine to ignore the error here _, err = conn.Write([]byte("Response 2\n")) require.ErrorIs(t, err, errTestConnClosed) diff --git a/internal/storage/memory/memory_test.go b/internal/storage/memory/memory_test.go index 347e9f5f..1952ddcf 100644 --- a/internal/storage/memory/memory_test.go +++ b/internal/storage/memory/memory_test.go @@ -209,7 +209,7 @@ func Benchmark_Memory_Set(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { - _ = testStore.Set("john", []byte("doe"), 0) //nolint: errcheck // error not needed for benchmark + _ = testStore.Set("john", []byte("doe"), 0) //nolint:errcheck // error not needed for benchmark } } @@ -220,7 +220,7 @@ func Benchmark_Memory_Set_Parallel(b *testing.B) { b.RunParallel(func(pb *testing.PB) { for pb.Next() { - _ = testStore.Set("john", []byte("doe"), 0) //nolint: errcheck // error not needed for benchmark + _ = testStore.Set("john", []byte("doe"), 0) //nolint:errcheck // error not needed for benchmark } }) } @@ -259,7 +259,7 @@ func Benchmark_Memory_Get(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { - _, _ = testStore.Get("john") //nolint: errcheck // error not needed for benchmark + _, _ = testStore.Get("john") //nolint:errcheck // error not needed for benchmark } } @@ -273,7 +273,7 @@ func Benchmark_Memory_Get_Parallel(b *testing.B) { b.RunParallel(func(pb *testing.PB) { for pb.Next() { - _, _ = testStore.Get("john") //nolint: errcheck // error not needed for benchmark + _, _ = testStore.Get("john") //nolint:errcheck // error not needed for benchmark } }) } @@ -315,8 +315,8 @@ func Benchmark_Memory_SetAndDelete(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { - _ = testStore.Set("john", []byte("doe"), 0) //nolint: errcheck // error not needed for benchmark - _ = testStore.Delete("john") //nolint: errcheck // error not needed for benchmark + _ = testStore.Set("john", []byte("doe"), 0) //nolint:errcheck // error not needed for benchmark + _ = testStore.Delete("john") //nolint:errcheck // error not needed for benchmark } } @@ -327,8 +327,8 @@ func Benchmark_Memory_SetAndDelete_Parallel(b *testing.B) { b.RunParallel(func(pb *testing.PB) { for pb.Next() { - _ = testStore.Set("john", []byte("doe"), 0) //nolint: errcheck // error not needed for benchmark - _ = testStore.Delete("john") //nolint: errcheck // error not needed for benchmark + _ = testStore.Set("john", []byte("doe"), 0) //nolint:errcheck // error not needed for benchmark + _ = testStore.Delete("john") //nolint:errcheck // error not needed for benchmark } }) } diff --git a/listen.go b/listen.go index f33c9daf..83ed655b 100644 --- a/listen.go +++ b/listen.go @@ -328,7 +328,7 @@ func (*App) prepareListenData(addr string, isTLS bool, cfg ListenConfig) ListenD } // startupMessage prepares the startup message with the handler number, port, address and other information -func (app *App) startupMessage(addr string, isTLS bool, pids string, cfg ListenConfig) { //nolint: revive // Accepting a bool param named isTLS if fine here +func (app *App) startupMessage(addr string, isTLS bool, pids string, cfg ListenConfig) { //nolint:revive // Accepting a bool param named isTLS if fine here // ignore child processes if IsChild() { return @@ -366,38 +366,35 @@ func (app *App) startupMessage(addr string, isTLS bool, pids string, cfg ListenC out = colorable.NewNonColorable(os.Stdout) } - fmt.Fprintf(out, "%s\n", fmt.Sprintf(figletFiberText, colors.Red+"v"+Version+colors.Reset)) //nolint:errcheck,revive // ignore error - fmt.Fprintf(out, strings.Repeat("-", 50)+"\n") //nolint:errcheck,revive,govet // ignore error + fmt.Fprintf(out, "%s\n", fmt.Sprintf(figletFiberText, colors.Red+"v"+Version+colors.Reset)) + fmt.Fprintf(out, strings.Repeat("-", 50)+"\n") if host == "0.0.0.0" { - //nolint:errcheck,revive // ignore error fmt.Fprintf(out, "%sINFO%s Server started on: \t%s%s://127.0.0.1:%s%s (bound on host 0.0.0.0 and port %s)\n", colors.Green, colors.Reset, colors.Blue, scheme, port, colors.Reset, port) } else { - //nolint:errcheck,revive // ignore error fmt.Fprintf(out, "%sINFO%s Server started on: \t%s%s%s\n", colors.Green, colors.Reset, colors.Blue, fmt.Sprintf("%s://%s:%s", scheme, host, port), colors.Reset) } if app.config.AppName != "" { - fmt.Fprintf(out, "%sINFO%s Application name: \t\t%s%s%s\n", colors.Green, colors.Reset, colors.Blue, app.config.AppName, colors.Reset) //nolint:errcheck,revive // ignore error + fmt.Fprintf(out, "%sINFO%s Application name: \t\t%s%s%s\n", colors.Green, colors.Reset, colors.Blue, app.config.AppName, colors.Reset) } - //nolint:errcheck,revive // ignore error fmt.Fprintf(out, "%sINFO%s Total handlers count: \t%s%s%s\n", colors.Green, colors.Reset, colors.Blue, strconv.Itoa(int(app.handlersCount)), colors.Reset) if isPrefork == "Enabled" { - fmt.Fprintf(out, "%sINFO%s Prefork: \t\t\t%s%s%s\n", colors.Green, colors.Reset, colors.Blue, isPrefork, colors.Reset) //nolint:errcheck,revive // ignore error + fmt.Fprintf(out, "%sINFO%s Prefork: \t\t\t%s%s%s\n", colors.Green, colors.Reset, colors.Blue, isPrefork, colors.Reset) } else { - fmt.Fprintf(out, "%sINFO%s Prefork: \t\t\t%s%s%s\n", colors.Green, colors.Reset, colors.Red, isPrefork, colors.Reset) //nolint:errcheck,revive // ignore error + fmt.Fprintf(out, "%sINFO%s Prefork: \t\t\t%s%s%s\n", colors.Green, colors.Reset, colors.Red, isPrefork, colors.Reset) } - fmt.Fprintf(out, "%sINFO%s PID: \t\t\t%s%v%s\n", colors.Green, colors.Reset, colors.Blue, os.Getpid(), colors.Reset) //nolint:errcheck,revive // ignore error - fmt.Fprintf(out, "%sINFO%s Total process count: \t%s%s%s\n", colors.Green, colors.Reset, colors.Blue, procs, colors.Reset) //nolint:errcheck,revive // ignore error + fmt.Fprintf(out, "%sINFO%s PID: \t\t\t%s%v%s\n", colors.Green, colors.Reset, colors.Blue, os.Getpid(), colors.Reset) + fmt.Fprintf(out, "%sINFO%s Total process count: \t%s%s%s\n", colors.Green, colors.Reset, colors.Blue, procs, colors.Reset) if cfg.EnablePrefork { // Turn the `pids` variable (in the form ",a,b,c,d,e,f,etc") into a slice of PIDs @@ -408,7 +405,7 @@ func (app *App) startupMessage(addr string, isTLS bool, pids string, cfg ListenC } } - fmt.Fprintf(out, "%sINFO%s Child PIDs: \t\t%s", colors.Green, colors.Reset, colors.Blue) //nolint:errcheck,revive // ignore error + fmt.Fprintf(out, "%sINFO%s Child PIDs: \t\t%s", colors.Green, colors.Reset, colors.Blue) totalPids := len(pidSlice) rowTotalPidCount := 10 @@ -421,17 +418,17 @@ func (app *App) startupMessage(addr string, isTLS bool, pids string, cfg ListenC } for n, pid := range pidSlice[start:end] { - fmt.Fprintf(out, "%s", pid) //nolint:errcheck,revive // ignore error + fmt.Fprintf(out, "%s", pid) if n+1 != len(pidSlice[start:end]) { - fmt.Fprintf(out, ", ") //nolint:errcheck,revive // ignore error + fmt.Fprintf(out, ", ") } } - fmt.Fprintf(out, "\n%s", colors.Reset) //nolint:errcheck,revive // ignore error + fmt.Fprintf(out, "\n%s", colors.Reset) } } // add new Line as spacer - fmt.Fprintf(out, "\n%s", colors.Reset) //nolint:errcheck,revive // ignore error + fmt.Fprintf(out, "\n%s", colors.Reset) } // printRoutesMessage print all routes with method, path, name and handlers @@ -473,11 +470,10 @@ func (app *App) printRoutesMessage() { return routes[i].path < routes[j].path }) - fmt.Fprintf(w, "%smethod\t%s| %spath\t%s| %sname\t%s| %shandlers\t%s\n", colors.Blue, colors.White, colors.Green, colors.White, colors.Cyan, colors.White, colors.Yellow, colors.Reset) //nolint:errcheck,revive // ignore error - fmt.Fprintf(w, "%s------\t%s| %s----\t%s| %s----\t%s| %s--------\t%s\n", colors.Blue, colors.White, colors.Green, colors.White, colors.Cyan, colors.White, colors.Yellow, colors.Reset) //nolint:errcheck,revive // ignore error + fmt.Fprintf(w, "%smethod\t%s| %spath\t%s| %sname\t%s| %shandlers\t%s\n", colors.Blue, colors.White, colors.Green, colors.White, colors.Cyan, colors.White, colors.Yellow, colors.Reset) + fmt.Fprintf(w, "%s------\t%s| %s----\t%s| %s----\t%s| %s--------\t%s\n", colors.Blue, colors.White, colors.Green, colors.White, colors.Cyan, colors.White, colors.Yellow, colors.Reset) for _, route := range routes { - //nolint:errcheck,revive // ignore error fmt.Fprintf(w, "%s%s\t%s| %s%s\t%s| %s%s\t%s| %s%s%s\n", colors.Blue, route.method, colors.White, colors.Green, route.path, colors.White, colors.Cyan, route.name, colors.White, colors.Yellow, route.handlers, colors.Reset) } diff --git a/log/default.go b/log/default.go index 6de940a4..f376a1a0 100644 --- a/log/default.go +++ b/log/default.go @@ -53,9 +53,9 @@ func (l *defaultLogger) privateLogf(lv Level, format string, fmtArgs []any) { buf.WriteString(level) if len(fmtArgs) > 0 { - _, _ = fmt.Fprintf(buf, format, fmtArgs...) //nolint: errcheck // It is fine to ignore the error + _, _ = fmt.Fprintf(buf, format, fmtArgs...) } else { - _, _ = fmt.Fprint(buf, fmtArgs...) //nolint: errcheck // It is fine to ignore the error + _, _ = fmt.Fprint(buf, fmtArgs...) } _ = l.stdlog.Output(l.depth, buf.String()) //nolint:errcheck // It is fine to ignore the error diff --git a/middleware/adaptor/adaptor_test.go b/middleware/adaptor/adaptor_test.go index 67c306fe..7bede0a8 100644 --- a/middleware/adaptor/adaptor_test.go +++ b/middleware/adaptor/adaptor_test.go @@ -1,4 +1,4 @@ -//nolint:contextcheck, revive // Much easier to just ignore memory leaks in tests +//nolint:contextcheck,revive // Much easier to just ignore memory leaks in tests package adaptor import ( @@ -68,7 +68,7 @@ func Test_HTTPHandler(t *testing.T) { w.Header().Set("Header1", "value1") w.Header().Set("Header2", "value2") w.WriteHeader(http.StatusBadRequest) - fmt.Fprintf(w, "request body is %q", body) //nolint:errcheck // not needed + fmt.Fprintf(w, "request body is %q", body) } fiberH := HTTPHandlerFunc(http.HandlerFunc(nethttpH)) fiberH = setFiberContextValueMiddleware(fiberH, expectedContextKey, expectedContextValue) diff --git a/middleware/csrf/csrf_test.go b/middleware/csrf/csrf_test.go index 090082f4..7f586cd9 100644 --- a/middleware/csrf/csrf_test.go +++ b/middleware/csrf/csrf_test.go @@ -1331,56 +1331,65 @@ func Test_CSRF_Cookie_Injection_Exploit(t *testing.T) { } // TODO: use this test case and make the unsafe header value bug from https://github.com/gofiber/fiber/issues/2045 reproducible and permanently fixed/tested by this testcase -// func Test_CSRF_UnsafeHeaderValue(t *testing.T) { -// t.Parallel() -// app := fiber.New() +func Test_CSRF_UnsafeHeaderValue(t *testing.T) { + t.SkipNow() + t.Parallel() + app := fiber.New() -// app.Use(New()) -// app.Get("/", func(c fiber.Ctx) error { -// return c.SendStatus(fiber.StatusOK) -// }) -// app.Get("/test", func(c fiber.Ctx) error { -// return c.SendStatus(fiber.StatusOK) -// }) -// app.Post("/", func(c fiber.Ctx) error { -// return c.SendStatus(fiber.StatusOK) -// }) + app.Use(New()) + app.Get("/", func(c fiber.Ctx) error { + return c.SendStatus(fiber.StatusOK) + }) + app.Get("/test", func(c fiber.Ctx) error { + return c.SendStatus(fiber.StatusOK) + }) + app.Post("/", func(c fiber.Ctx) error { + return c.SendStatus(fiber.StatusOK) + }) -// resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/", nil)) -// require.NoError(t, err) -// require.Equal(t, fiber.StatusOK, resp.StatusCode) + resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/", nil)) + require.NoError(t, err) + require.Equal(t, fiber.StatusOK, resp.StatusCode) -// var token string -// for _, c := range resp.Cookies() { -// if c.Name != ConfigDefault.CookieName { -// continue -// } -// token = c.Value -// break -// } + var token string + for _, c := range resp.Cookies() { + if c.Name != ConfigDefault.CookieName { + continue + } + token = c.Value + break + } -// fmt.Println("token", token) + t.Log("token", token) -// getReq := httptest.NewRequest(fiber.MethodGet, "/", nil) -// getReq.Header.Set(HeaderName, token) -// resp, err = app.Test(getReq) + getReq := httptest.NewRequest(fiber.MethodGet, "/", nil) + getReq.Header.Set(HeaderName, token) + resp, err = app.Test(getReq) + require.NoError(t, err) + require.Equal(t, fiber.StatusOK, resp.StatusCode) -// getReq = httptest.NewRequest(fiber.MethodGet, "/test", nil) -// getReq.Header.Set("X-Requested-With", "XMLHttpRequest") -// getReq.Header.Set(fiber.HeaderCacheControl, "no") -// getReq.Header.Set(HeaderName, token) + getReq = httptest.NewRequest(fiber.MethodGet, "/test", nil) + getReq.Header.Set("X-Requested-With", "XMLHttpRequest") + getReq.Header.Set(fiber.HeaderCacheControl, "no") + getReq.Header.Set(HeaderName, token) -// resp, err = app.Test(getReq) + resp, err = app.Test(getReq) + require.NoError(t, err) + require.Equal(t, fiber.StatusOK, resp.StatusCode) -// getReq.Header.Set(fiber.HeaderAccept, "*/*") -// getReq.Header.Del(HeaderName) -// resp, err = app.Test(getReq) + getReq.Header.Set(fiber.HeaderAccept, "*/*") + getReq.Header.Del(HeaderName) + resp, err = app.Test(getReq) + require.NoError(t, err) + require.Equal(t, fiber.StatusOK, resp.StatusCode) -// postReq := httptest.NewRequest(fiber.MethodPost, "/", nil) -// postReq.Header.Set("X-Requested-With", "XMLHttpRequest") -// postReq.Header.Set(HeaderName, token) -// resp, err = app.Test(postReq) -// } + postReq := httptest.NewRequest(fiber.MethodPost, "/", nil) + postReq.Header.Set("X-Requested-With", "XMLHttpRequest") + postReq.Header.Set(HeaderName, token) + resp, err = app.Test(postReq) + require.NoError(t, err) + require.Equal(t, fiber.StatusOK, resp.StatusCode) +} // go test -v -run=^$ -bench=Benchmark_Middleware_CSRF_Check -benchmem -count=4 func Benchmark_Middleware_CSRF_Check(b *testing.B) { diff --git a/middleware/helmet/config.go b/middleware/helmet/config.go index c7fa3cab..c9367d81 100644 --- a/middleware/helmet/config.go +++ b/middleware/helmet/config.go @@ -28,7 +28,7 @@ type Config struct { ContentSecurityPolicy string // ReferrerPolicy - // Optional. Default value "ReferrerPolicy". + // Optional. Default value "no-referrer". ReferrerPolicy string // Permissions-Policy diff --git a/middleware/logger/config.go b/middleware/logger/config.go index 2df814eb..d543acfa 100644 --- a/middleware/logger/config.go +++ b/middleware/logger/config.go @@ -50,9 +50,23 @@ type Config struct { timeZoneLocation *time.Location - // Format defines the logging tags + // Format defines the logging format for the middleware. // - // Optional. Default: [${time}] ${ip} ${status} - ${latency} ${method} ${path} ${error} + // You can customize the log output by defining a format string with placeholders + // such as: ${time}, ${ip}, ${status}, ${method}, ${path}, ${latency}, ${error}, etc. + // The full list of available placeholders can be found in 'tags.go' or at + // 'https://docs.gofiber.io/api/middleware/logger/#constants'. + // + // Fiber provides predefined logging formats that can be used directly: + // + // - DefaultFormat → Uses the default log format: "[${time}] ${ip} ${status} - ${latency} ${method} ${path} ${error}" + // - CommonFormat → Uses the Apache Common Log Format (CLF): "${ip} - - [${time}] \"${method} ${url} ${protocol}\" ${status} ${bytesSent}\n" + // - CombinedFormat → Uses the Apache Combined Log Format: "${ip} - - [${time}] \"${method} ${url} ${protocol}\" ${status} ${bytesSent} \"${referer}\" \"${ua}\"\n" + // - JSONFormat → Uses the JSON log format: "{\"time\":\"${time}\",\"ip\":\"${ip}\",\"method\":\"${method}\",\"url\":\"${url}\",\"status\":${status},\"bytesSent\":${bytesSent}}\n" + // - ECSFormat → Uses the Elastic Common Schema (ECS) log format: {\"@timestamp\":\"${time}\",\"ecs\":{\"version\":\"1.6.0\"},\"client\":{\"ip\":\"${ip}\"},\"http\":{\"request\":{\"method\":\"${method}\",\"url\":\"${url}\",\"protocol\":\"${protocol}\"},\"response\":{\"status_code\":${status},\"body\":{\"bytes\":${bytesSent}}}},\"log\":{\"level\":\"INFO\",\"logger\":\"fiber\"},\"message\":\"${method} ${url} responded with ${status}\"}" + // If both `Format` and `CustomFormat` are provided, the `CustomFormat` will be used, and the `Format` field will be ignored. + // If no format is specified, the default format is used: + // "[${time}] ${ip} ${status} - ${latency} ${method} ${path} ${error}" Format string // TimeFormat https://programming.guide/go/format-parse-string-time-date-example.html @@ -105,7 +119,7 @@ var ConfigDefault = Config{ Next: nil, Skip: nil, Done: nil, - Format: defaultFormat, + Format: DefaultFormat, TimeFormat: "15:04:05", TimeZone: "Local", TimeInterval: 500 * time.Millisecond, @@ -115,9 +129,6 @@ var ConfigDefault = Config{ enableColors: true, } -// default logging format for Fiber's default logger -var defaultFormat = "[${time}] ${ip} ${status} - ${latency} ${method} ${path} ${error}\n" - // Helper function to set default values func configDefault(config ...Config) Config { // Return default config if nothing provided diff --git a/middleware/logger/default_logger.go b/middleware/logger/default_logger.go index e4de79bf..a2cbfa1f 100644 --- a/middleware/logger/default_logger.go +++ b/middleware/logger/default_logger.go @@ -28,7 +28,7 @@ func defaultLoggerInstance(c fiber.Ctx, data *Data, cfg Config) error { buf := bytebufferpool.Get() // Default output when no custom Format or io.Writer is given - if cfg.Format == defaultFormat { + if cfg.Format == DefaultFormat { // Format error if exist formatErr := "" if cfg.enableColors { @@ -166,7 +166,7 @@ func writeLog(w io.Writer, msg []byte) { // Write error to output if _, err := w.Write([]byte(err.Error())); err != nil { // There is something wrong with the given io.Writer - _, _ = fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err) //nolint: errcheck // It is fine to ignore the error + _, _ = fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err) } } } diff --git a/middleware/logger/format.go b/middleware/logger/format.go new file mode 100644 index 00000000..901c2409 --- /dev/null +++ b/middleware/logger/format.go @@ -0,0 +1,14 @@ +package logger + +const ( + // Fiber's default logger + DefaultFormat = "[${time}] ${ip} ${status} - ${latency} ${method} ${path} ${error}\n" + // Apache Common Log Format (CLF) + CommonFormat = "${ip} - - [${time}] \"${method} ${url} ${protocol}\" ${status} ${bytesSent}\n" + // Apache Combined Log Format + CombinedFormat = "${ip} - - [${time}] \"${method} ${url} ${protocol}\" ${status} ${bytesSent} \"${referer}\" \"${ua}\"\n" + // JSON log formats + JSONFormat = "{\"time\":\"${time}\",\"ip\":\"${ip}\",\"method\":\"${method}\",\"url\":\"${url}\",\"status\":${status},\"bytesSent\":${bytesSent}}\n" + // Elastic Common Schema (ECS) Log Format + ECSFormat = "{\"@timestamp\":\"${time}\",\"ecs\":{\"version\":\"1.6.0\"},\"client\":{\"ip\":\"${ip}\"},\"http\":{\"request\":{\"method\":\"${method}\",\"url\":\"${url}\",\"protocol\":\"${protocol}\"},\"response\":{\"status_code\":${status},\"body\":{\"bytes\":${bytesSent}}}},\"log\":{\"level\":\"INFO\",\"logger\":\"fiber\"},\"message\":\"${method} ${url} responded with ${status}\"}\n" +) diff --git a/middleware/logger/logger.go b/middleware/logger/logger.go index 793c16c2..7d4befc9 100644 --- a/middleware/logger/logger.go +++ b/middleware/logger/logger.go @@ -40,7 +40,6 @@ func New(config ...Config) fiber.Handler { } }() } - // Set PID once pid := strconv.Itoa(os.Getpid()) diff --git a/middleware/logger/logger_test.go b/middleware/logger/logger_test.go index 011a0ead..edce174c 100644 --- a/middleware/logger/logger_test.go +++ b/middleware/logger/logger_test.go @@ -467,6 +467,124 @@ func Test_Logger_All(t *testing.T) { require.Equal(t, expected, buf.String()) } +func Test_Logger_CLF_Format(t *testing.T) { + t.Parallel() + buf := bytebufferpool.Get() + defer bytebufferpool.Put(buf) + + app := fiber.New() + + app.Use(New(Config{ + Format: CommonFormat, + Stream: buf, + })) + + resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/?foo=bar", nil)) + require.NoError(t, err) + require.Equal(t, fiber.StatusNotFound, resp.StatusCode) + + expected := fmt.Sprintf("0.0.0.0 - - [%s] \"%s %s %s\" %d %d\n", + time.Now().Format("15:04:05"), + fiber.MethodGet, "/?foo=bar", "HTTP/1.1", + fiber.StatusNotFound, + 0) + logResponse := buf.String() + require.Equal(t, expected, logResponse) +} + +func Test_Logger_Combined_CLF_Format(t *testing.T) { + t.Parallel() + buf := bytebufferpool.Get() + defer bytebufferpool.Put(buf) + + app := fiber.New() + + app.Use(New(Config{ + Format: CombinedFormat, + Stream: buf, + })) + const expectedUA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36" + const expectedReferer = "http://example.com" + req := httptest.NewRequest(fiber.MethodGet, "/?foo=bar", nil) + req.Header.Set("Referer", expectedReferer) + req.Header.Set("User-Agent", expectedUA) + resp, err := app.Test(req) + require.NoError(t, err) + require.Equal(t, fiber.StatusNotFound, resp.StatusCode) + + expected := fmt.Sprintf("0.0.0.0 - - [%s] %q %d %d %q %q\n", + time.Now().Format("15:04:05"), + fmt.Sprintf("%s %s %s", fiber.MethodGet, "/?foo=bar", "HTTP/1.1"), + fiber.StatusNotFound, + 0, + expectedReferer, + expectedUA) + logResponse := buf.String() + require.Equal(t, expected, logResponse) +} + +func Test_Logger_Json_Format(t *testing.T) { + t.Parallel() + buf := bytebufferpool.Get() + defer bytebufferpool.Put(buf) + + app := fiber.New() + + app.Use(New(Config{ + Format: JSONFormat, + Stream: buf, + })) + + req := httptest.NewRequest(fiber.MethodGet, "/?foo=bar", nil) + resp, err := app.Test(req) + require.NoError(t, err) + require.Equal(t, fiber.StatusNotFound, resp.StatusCode) + + expected := fmt.Sprintf( + "{\"time\":%q,\"ip\":%q,\"method\":%q,\"url\":%q,\"status\":%d,\"bytesSent\":%d}\n", + time.Now().Format("15:04:05"), + "0.0.0.0", + fiber.MethodGet, + "/?foo=bar", + fiber.StatusNotFound, + 0, + ) + logResponse := buf.String() + require.Equal(t, expected, logResponse) +} + +func Test_Logger_ECS_Format(t *testing.T) { + t.Parallel() + buf := bytebufferpool.Get() + defer bytebufferpool.Put(buf) + + app := fiber.New() + + app.Use(New(Config{ + Format: ECSFormat, + Stream: buf, + })) + + req := httptest.NewRequest(fiber.MethodGet, "/?foo=bar", nil) + resp, err := app.Test(req) + require.NoError(t, err) + require.Equal(t, fiber.StatusNotFound, resp.StatusCode) + + expected := fmt.Sprintf( + "{\"@timestamp\":%q,\"ecs\":{\"version\":\"1.6.0\"},\"client\":{\"ip\":%q},\"http\":{\"request\":{\"method\":%q,\"url\":%q,\"protocol\":%q},\"response\":{\"status_code\":%d,\"body\":{\"bytes\":%d}}},\"log\":{\"level\":\"INFO\",\"logger\":\"fiber\"},\"message\":%q}\n", + time.Now().Format("15:04:05"), + "0.0.0.0", + fiber.MethodGet, + "/?foo=bar", + "HTTP/1.1", + fiber.StatusNotFound, + 0, + fmt.Sprintf("%s %s responded with %d", fiber.MethodGet, "/?foo=bar", fiber.StatusNotFound), + ) + logResponse := buf.String() + require.Equal(t, expected, logResponse) +} + func getLatencyTimeUnits() []struct { unit string div time.Duration @@ -865,7 +983,7 @@ func Test_Logger_ByteSent_Streaming(t *testing.T) { for { i++ msg := fmt.Sprintf("%d - the time is %v", i, time.Now()) - fmt.Fprintf(w, "data: Message: %s\n\n", msg) //nolint:errcheck // ignore error + fmt.Fprintf(w, "data: Message: %s\n\n", msg) err := w.Flush() if err != nil { break @@ -1049,7 +1167,7 @@ func Benchmark_Logger(b *testing.B) { for { i++ msg := fmt.Sprintf("%d - the time is %v", i, time.Now()) - fmt.Fprintf(w, "data: Message: %s\n\n", msg) //nolint:errcheck // ignore error + fmt.Fprintf(w, "data: Message: %s\n\n", msg) err := w.Flush() if err != nil { break @@ -1217,7 +1335,7 @@ func Benchmark_Logger_Parallel(b *testing.B) { for { i++ msg := fmt.Sprintf("%d - the time is %v", i, time.Now()) - fmt.Fprintf(w, "data: Message: %s\n\n", msg) //nolint:errcheck // ignore error + fmt.Fprintf(w, "data: Message: %s\n\n", msg) err := w.Flush() if err != nil { break diff --git a/middleware/proxy/proxy_test.go b/middleware/proxy/proxy_test.go index a8108251..532af09e 100644 --- a/middleware/proxy/proxy_test.go +++ b/middleware/proxy/proxy_test.go @@ -506,7 +506,10 @@ func Test_Proxy_Do_WithRealURL(t *testing.T) { return Do(c, "https://www.google.com") }) - resp, err1 := app.Test(httptest.NewRequest(fiber.MethodGet, "/test", nil)) + resp, err1 := app.Test(httptest.NewRequest(fiber.MethodGet, "/test", nil), fiber.TestConfig{ + Timeout: 2 * time.Second, + FailOnTimeout: true, + }) require.NoError(t, err1) require.Equal(t, fiber.StatusOK, resp.StatusCode) require.Equal(t, "/test", resp.Request.URL.String()) @@ -523,7 +526,10 @@ func Test_Proxy_Do_WithRedirect(t *testing.T) { return Do(c, "https://google.com") }) - resp, err1 := app.Test(httptest.NewRequest(fiber.MethodGet, "/test", nil)) + resp, err1 := app.Test(httptest.NewRequest(fiber.MethodGet, "/test", nil), fiber.TestConfig{ + Timeout: 2 * time.Second, + FailOnTimeout: true, + }) require.NoError(t, err1) body, err := io.ReadAll(resp.Body) require.NoError(t, err) @@ -558,7 +564,10 @@ func Test_Proxy_DoRedirects_TooManyRedirects(t *testing.T) { return DoRedirects(c, "http://google.com", 0) }) - resp, err1 := app.Test(httptest.NewRequest(fiber.MethodGet, "/test", nil)) + resp, err1 := app.Test(httptest.NewRequest(fiber.MethodGet, "/test", nil), fiber.TestConfig{ + Timeout: 2 * time.Second, + FailOnTimeout: true, + }) require.NoError(t, err1) body, err := io.ReadAll(resp.Body) require.NoError(t, err) diff --git a/path.go b/path.go index 3876943d..b188a41c 100644 --- a/path.go +++ b/path.go @@ -487,7 +487,7 @@ func splitNonEscaped(s, sep string) []string { } // getMatch parses the passed url and tries to match it against the route segments and determine the parameter positions -func (parser *routeParser) getMatch(detectionPath, path string, params *[maxParams]string, partialCheck bool) bool { //nolint: revive // Accepting a bool param is fine here +func (parser *routeParser) getMatch(detectionPath, path string, params *[maxParams]string, partialCheck bool) bool { //nolint:revive // Accepting a bool param is fine here var i, paramsIterator, partLen int for _, segment := range parser.segs { partLen = len(detectionPath) diff --git a/redirect_test.go b/redirect_test.go index 1570d05f..82cfb36b 100644 --- a/redirect_test.go +++ b/redirect_test.go @@ -178,7 +178,7 @@ func Test_Redirect_Back_WithFlashMessages(t *testing.T) { return c.SendString("user") }).Name("user") - c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed + c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck,forcetypeassert // not needed err := c.Redirect().With("success", "1").With("message", "test").Back("/") require.NoError(t, err) @@ -225,7 +225,7 @@ func Test_Redirect_Route_WithFlashMessages(t *testing.T) { return c.SendString("user") }).Name("user") - c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed + c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck,forcetypeassert // not needed err := c.Redirect().With("success", "1").With("message", "test").Route("user") @@ -259,7 +259,7 @@ func Test_Redirect_Route_WithOldInput(t *testing.T) { return c.SendString("user") }).Name("user") - c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed + c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck,forcetypeassert // not needed c.Request().URI().SetQueryString("id=1&name=tom") err := c.Redirect().With("success", "1").With("message", "test").WithInput().Route("user") @@ -294,7 +294,7 @@ func Test_Redirect_Route_WithOldInput(t *testing.T) { return c.SendString("user") }).Name("user") - c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed + c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck,forcetypeassert // not needed c.Request().Header.Set(HeaderContentType, MIMEApplicationForm) c.Request().SetBodyString("id=1&name=tom") @@ -330,7 +330,7 @@ func Test_Redirect_Route_WithOldInput(t *testing.T) { return c.SendString("user") }).Name("user") - c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed + c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck,forcetypeassert // not needed body := &bytes.Buffer{} writer := multipart.NewWriter(body) @@ -376,7 +376,7 @@ func Test_Redirect_parseAndClearFlashMessages(t *testing.T) { return c.SendString("user") }).Name("user") - c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed + c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck,forcetypeassert // not needed msgs := redirectionMsgs{ { @@ -464,7 +464,7 @@ func Benchmark_Redirect_Route(b *testing.B) { return c.JSON(c.Params("name")) }).Name("user") - c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed + c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck,forcetypeassert // not needed b.ReportAllocs() b.ResetTimer() @@ -491,7 +491,7 @@ func Benchmark_Redirect_Route_WithQueries(b *testing.B) { return c.JSON(c.Params("name")) }).Name("user") - c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed + c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck,forcetypeassert // not needed b.ReportAllocs() b.ResetTimer() @@ -523,7 +523,7 @@ func Benchmark_Redirect_Route_WithFlashMessages(b *testing.B) { return c.SendString("user") }).Name("user") - c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed + c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck,forcetypeassert // not needed b.ReportAllocs() b.ResetTimer() @@ -576,7 +576,7 @@ func Benchmark_Redirect_parseAndClearFlashMessages(b *testing.B) { return c.SendString("user") }).Name("user") - c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed + c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck,forcetypeassert // not needed val, err := testredirectionMsgs.MarshalMsg(nil) require.NoError(b, err) @@ -618,7 +618,7 @@ func Benchmark_Redirect_processFlashMessages(b *testing.B) { return c.SendString("user") }).Name("user") - c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed + c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck,forcetypeassert // not needed c.Redirect().With("success", "1").With("message", "test") @@ -647,7 +647,7 @@ func Benchmark_Redirect_Messages(b *testing.B) { return c.SendString("user") }).Name("user") - c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed + c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck,forcetypeassert // not needed val, err := testredirectionMsgs.MarshalMsg(nil) require.NoError(b, err) @@ -684,7 +684,7 @@ func Benchmark_Redirect_OldInputs(b *testing.B) { return c.SendString("user") }).Name("user") - c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed + c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck,forcetypeassert // not needed val, err := testredirectionMsgs.MarshalMsg(nil) require.NoError(b, err) @@ -719,7 +719,7 @@ func Benchmark_Redirect_Message(b *testing.B) { return c.SendString("user") }).Name("user") - c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed + c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck,forcetypeassert // not needed val, err := testredirectionMsgs.MarshalMsg(nil) require.NoError(b, err) @@ -750,7 +750,7 @@ func Benchmark_Redirect_OldInput(b *testing.B) { return c.SendString("user") }).Name("user") - c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed + c := app.AcquireCtx(&fasthttp.RequestCtx{}).(*DefaultCtx) //nolint:errcheck,forcetypeassert // not needed val, err := testredirectionMsgs.MarshalMsg(nil) require.NoError(b, err) diff --git a/router.go b/router.go index 28f934f2..c247480e 100644 --- a/router.go +++ b/router.go @@ -108,7 +108,7 @@ func (r *Route) match(detectionPath, path string, params *[maxParams]string) boo return false } -func (app *App) nextCustom(c CustomCtx) (bool, error) { //nolint: unparam // bool param might be useful for testing +func (app *App) nextCustom(c CustomCtx) (bool, error) { //nolint:unparam // bool param might be useful for testing // Get stack length tree, ok := app.treeStack[c.getMethodINT()][c.getTreePath()] if !ok { diff --git a/router_test.go b/router_test.go index d0d378c7..b0175d8c 100644 --- a/router_test.go +++ b/router_test.go @@ -1025,7 +1025,7 @@ func Benchmark_Router_Next(b *testing.B) { var res bool var err error - c := app.AcquireCtx(request).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed + c := app.AcquireCtx(request).(*DefaultCtx) //nolint:errcheck,forcetypeassert // not needed b.ResetTimer() for n := 0; n < b.N; n++ { @@ -1250,7 +1250,7 @@ func Benchmark_Router_Github_API(b *testing.B) { for n := 0; n < b.N; n++ { c.URI().SetPath(routesFixture.TestRoutes[i].Path) - ctx := app.AcquireCtx(c).(*DefaultCtx) //nolint:errcheck, forcetypeassert // not needed + ctx := app.AcquireCtx(c).(*DefaultCtx) //nolint:errcheck,forcetypeassert // not needed match, err = app.next(ctx) app.ReleaseCtx(ctx)