From 03e5e05ae089bc989f1ca41841f05504d29e3fd9 Mon Sep 17 00:00:00 2001 From: Xudong Cai Date: Fri, 9 Apr 2021 00:27:34 +0800 Subject: [PATCH] fix: data race with trustedCIDRs (#2674) (#2675) Co-authored-by: Bo-Yi Wu --- context.go | 2 -- context_test.go | 16 +++++++++++++++- logger_test.go | 2 ++ 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/context.go b/context.go index 1ba0fa2..dc03c35 100644 --- a/context.go +++ b/context.go @@ -767,8 +767,6 @@ func (c *Context) RemoteIP() (net.IP, bool) { return nil, false } - trustedCIDRs, _ := c.engine.prepareTrustedCIDRs() - c.engine.trustedCIDRs = trustedCIDRs if c.engine.trustedCIDRs != nil { for _, cidr := range c.engine.trustedCIDRs { if cidr.Contains(remoteIP) { diff --git a/context_test.go b/context_test.go index 8fe4761..cf3f0be 100644 --- a/context_test.go +++ b/context_test.go @@ -1388,10 +1388,14 @@ func TestContextAbortWithError(t *testing.T) { assert.True(t, c.IsAborted()) } +func resetTrustedCIDRs(c *Context) { + c.engine.trustedCIDRs, _ = c.engine.prepareTrustedCIDRs() +} + func TestContextClientIP(t *testing.T) { c, _ := CreateTestContext(httptest.NewRecorder()) c.Request, _ = http.NewRequest("POST", "/", nil) - + resetTrustedCIDRs(c) resetContextForClientIPTests(c) // Legacy tests (validating that the defaults don't break the @@ -1421,35 +1425,43 @@ func TestContextClientIP(t *testing.T) { // No trusted proxies c.engine.TrustedProxies = []string{} + resetTrustedCIDRs(c) c.engine.RemoteIPHeaders = []string{"X-Forwarded-For"} assert.Equal(t, "40.40.40.40", c.ClientIP()) // Last proxy is trusted, but the RemoteAddr is not c.engine.TrustedProxies = []string{"30.30.30.30"} + resetTrustedCIDRs(c) assert.Equal(t, "40.40.40.40", c.ClientIP()) // Only trust RemoteAddr c.engine.TrustedProxies = []string{"40.40.40.40"} + resetTrustedCIDRs(c) assert.Equal(t, "20.20.20.20", c.ClientIP()) // All steps are trusted c.engine.TrustedProxies = []string{"40.40.40.40", "30.30.30.30", "20.20.20.20"} + resetTrustedCIDRs(c) assert.Equal(t, "20.20.20.20", c.ClientIP()) // Use CIDR c.engine.TrustedProxies = []string{"40.40.25.25/16", "30.30.30.30"} + resetTrustedCIDRs(c) assert.Equal(t, "20.20.20.20", c.ClientIP()) // Use hostname that resolves to all the proxies c.engine.TrustedProxies = []string{"foo"} + resetTrustedCIDRs(c) assert.Equal(t, "40.40.40.40", c.ClientIP()) // Use hostname that returns an error c.engine.TrustedProxies = []string{"bar"} + resetTrustedCIDRs(c) assert.Equal(t, "40.40.40.40", c.ClientIP()) // X-Forwarded-For has a non-IP element c.engine.TrustedProxies = []string{"40.40.40.40"} + resetTrustedCIDRs(c) c.Request.Header.Set("X-Forwarded-For", " blah ") assert.Equal(t, "40.40.40.40", c.ClientIP()) @@ -1457,10 +1469,12 @@ func TestContextClientIP(t *testing.T) { // happen, but we should test it to make sure we handle it // gracefully. c.engine.TrustedProxies = []string{"baz"} + resetTrustedCIDRs(c) c.Request.Header.Set("X-Forwarded-For", " 30.30.30.30 ") assert.Equal(t, "40.40.40.40", c.ClientIP()) c.engine.TrustedProxies = []string{"40.40.40.40"} + resetTrustedCIDRs(c) c.Request.Header.Del("X-Forwarded-For") c.engine.RemoteIPHeaders = []string{"X-Forwarded-For", "X-Real-IP"} assert.Equal(t, "10.10.10.10", c.ClientIP()) diff --git a/logger_test.go b/logger_test.go index 0d40666..80961ce 100644 --- a/logger_test.go +++ b/logger_test.go @@ -185,6 +185,8 @@ func TestLoggerWithConfigFormatting(t *testing.T) { buffer := new(bytes.Buffer) router := New() + router.engine.trustedCIDRs, _ = router.engine.prepareTrustedCIDRs() + router.Use(LoggerWithConfig(LoggerConfig{ Output: buffer, Formatter: func(param LogFormatterParams) string {