From f8c514cb25c5a5e0a8417ed4cdb284f25022c563 Mon Sep 17 00:00:00 2001 From: Juan Calderon-Perez <835733+gaby@users.noreply.github.com> Date: Mon, 23 Sep 2024 09:16:52 -0400 Subject: [PATCH] v3: Optimize IsFromLocal() performance (#3140) Optimize IsFromLocal() --- ctx.go | 14 +---------- ctx_interface_gen.go | 2 -- ctx_test.go | 58 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 15 deletions(-) diff --git a/ctx.go b/ctx.go index 4d7417ee2a..2a4341b268 100644 --- a/ctx.go +++ b/ctx.go @@ -1841,21 +1841,9 @@ func (c *DefaultCtx) IsProxyTrusted() bool { return false } -var localHosts = [...]string{"127.0.0.1", "::1"} - -// IsLocalHost will return true if address is a localhost address. -func (*DefaultCtx) isLocalHost(address string) bool { - for _, h := range localHosts { - if address == h { - return true - } - } - return false -} - // IsFromLocal will return true if request came from local. func (c *DefaultCtx) IsFromLocal() bool { - return c.isLocalHost(c.fasthttp.RemoteIP().String()) + return c.fasthttp.RemoteIP().IsLoopback() } // Bind You can bind body, cookie, headers etc. into the map, map slice, struct easily by using Binding method. diff --git a/ctx_interface_gen.go b/ctx_interface_gen.go index 7709f7c929..62f2d368ad 100644 --- a/ctx_interface_gen.go +++ b/ctx_interface_gen.go @@ -318,8 +318,6 @@ type Ctx interface { // If EnableTrustedProxyCheck false, it returns true // IsProxyTrusted can check remote ip by proxy ranges and ip map. IsProxyTrusted() bool - // IsLocalHost will return true if address is a localhost address. - isLocalHost(address string) bool // IsFromLocal will return true if request came from local. IsFromLocal() bool // Bind You can bind body, cookie, headers etc. into the map, map slice, struct easily by using Binding method. diff --git a/ctx_test.go b/ctx_test.go index 6dcd74109e..2060e2a942 100644 --- a/ctx_test.go +++ b/ctx_test.go @@ -6352,3 +6352,61 @@ func Benchmark_Ctx_IsProxyTrusted(b *testing.B) { }) }) } + +func Benchmark_Ctx_IsFromLocalhost(b *testing.B) { + // Scenario without localhost check + b.Run("Non_Localhost", func(b *testing.B) { + app := New() + c := app.AcquireCtx(&fasthttp.RequestCtx{}) + c.Request().SetRequestURI("http://google.com:8080/test") + b.ReportAllocs() + b.ResetTimer() + for n := 0; n < b.N; n++ { + c.IsFromLocal() + } + app.ReleaseCtx(c) + }) + + // Scenario without localhost check in parallel + b.Run("Non_Localhost_Parallel", func(b *testing.B) { + app := New() + b.ReportAllocs() + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + c := app.AcquireCtx(&fasthttp.RequestCtx{}) + c.Request().SetRequestURI("http://google.com:8080/test") + for pb.Next() { + c.IsFromLocal() + } + app.ReleaseCtx(c) + }) + }) + + // Scenario with localhost check + b.Run("Localhost", func(b *testing.B) { + app := New() + c := app.AcquireCtx(&fasthttp.RequestCtx{}) + c.Request().SetRequestURI("http://localhost:8080/test") + b.ReportAllocs() + b.ResetTimer() + for n := 0; n < b.N; n++ { + c.IsFromLocal() + } + app.ReleaseCtx(c) + }) + + // Scenario with localhost check in parallel + b.Run("Localhost_Parallel", func(b *testing.B) { + app := New() + b.ReportAllocs() + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + c := app.AcquireCtx(&fasthttp.RequestCtx{}) + c.Request().SetRequestURI("http://localhost:8080/test") + for pb.Next() { + c.IsFromLocal() + } + app.ReleaseCtx(c) + }) + }) +}