From 57d31ccfb7cca336fd43466992197665f0f1ef86 Mon Sep 17 00:00:00 2001 From: Juan Calderon-Perez Date: Wed, 24 Jul 2024 23:46:59 -0400 Subject: [PATCH 1/2] Improve performance of Body() --- ctx.go | 14 +++++++++----- ctx_test.go | 27 +++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/ctx.go b/ctx.go index b10a5e837a..b961508b52 100644 --- a/ctx.go +++ b/ctx.go @@ -339,12 +339,16 @@ func (c *DefaultCtx) Body() []byte { encodingOrder = []string{"", "", ""} ) - // faster than peek - c.Request().Header.VisitAll(func(key, value []byte) { - if c.app.getString(key) == HeaderContentEncoding { - headerEncoding = c.app.getString(value) + // Get Content-Encoding header + headerEncoding = utils.UnsafeString(c.Request().Header.ContentEncoding()) + + // If no encoding is provided, return the original body + if len(headerEncoding) == 0 { + if c.app.config.Immutable { + return utils.CopyBytes(c.fasthttp.Request.Body()) } - }) + return c.fasthttp.Request.Body() + } // Split and get the encodings list, in order to attend the // rule defined at: https://www.rfc-editor.org/rfc/rfc9110#section-8.4-5 diff --git a/ctx_test.go b/ctx_test.go index c7a7ae9ee6..090a9b5b0d 100644 --- a/ctx_test.go +++ b/ctx_test.go @@ -356,6 +356,16 @@ func Test_Ctx_Body(t *testing.T) { require.Equal(t, []byte("john=doe"), c.Body()) } +// go test -run Test_Ctx_BodyRaw +func Test_Ctx_BodyRaw(t *testing.T) { + t.Parallel() + app := New() + 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()) +} + // go test -v -run=^$ -bench=Benchmark_Ctx_Body -benchmem -count=4 func Benchmark_Ctx_Body(b *testing.B) { const input = "john=doe" @@ -373,6 +383,23 @@ func Benchmark_Ctx_Body(b *testing.B) { require.Equal(b, []byte(input), c.Body()) } +// go test -v -run=^$ -bench=Benchmark_Ctx_BodyRaw -benchmem -count=4 +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.Request().SetBodyRaw([]byte(input)) + b.ReportAllocs() + b.ResetTimer() + for i := 0; i < b.N; i++ { + _ = c.BodyRaw() + } + + require.Equal(b, []byte(input), c.BodyRaw()) +} + // go test -run Test_Ctx_Body_Immutable func Test_Ctx_Body_Immutable(t *testing.T) { t.Parallel() From 70b808f5aa8e53fa47139ae900bd73bd42a37380 Mon Sep 17 00:00:00 2001 From: Juan Calderon-Perez Date: Thu, 25 Jul 2024 00:22:33 -0400 Subject: [PATCH 2/2] Add unit-test and benchmark for BodyRaw() with Immutable --- ctx_test.go | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/ctx_test.go b/ctx_test.go index 090a9b5b0d..d56eaee4d2 100644 --- a/ctx_test.go +++ b/ctx_test.go @@ -366,6 +366,16 @@ func Test_Ctx_BodyRaw(t *testing.T) { require.Equal(t, []byte("john=doe"), c.BodyRaw()) } +// go test -run Test_Ctx_BodyRaw_Immutable +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.Request().SetBodyRaw([]byte("john=doe")) + require.Equal(t, []byte("john=doe"), c.BodyRaw()) +} + // go test -v -run=^$ -bench=Benchmark_Ctx_Body -benchmem -count=4 func Benchmark_Ctx_Body(b *testing.B) { const input = "john=doe" @@ -400,6 +410,23 @@ func Benchmark_Ctx_BodyRaw(b *testing.B) { require.Equal(b, []byte(input), c.BodyRaw()) } +// go test -v -run=^$ -bench=Benchmark_Ctx_BodyRaw_Immutable -benchmem -count=4 +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.Request().SetBodyRaw([]byte(input)) + b.ReportAllocs() + b.ResetTimer() + for i := 0; i < b.N; i++ { + _ = c.BodyRaw() + } + + require.Equal(b, []byte(input), c.BodyRaw()) +} + // go test -run Test_Ctx_Body_Immutable func Test_Ctx_Body_Immutable(t *testing.T) { t.Parallel()