Home / Function/ TestContextClientIP() — gin Function Reference

TestContextClientIP() — gin Function Reference

Architecture documentation for the TestContextClientIP() function in context_test.go from the gin codebase.

Entity Profile

Dependency Diagram

graph TD
  d556b132_c03b_ea5b_79f4_5fd5b8cd84c4["TestContextClientIP()"]
  1faea5f9_bd4b_0fb0_66fd_35057b965aad["resetContextForClientIPTests()"]
  d556b132_c03b_ea5b_79f4_5fd5b8cd84c4 -->|calls| 1faea5f9_bd4b_0fb0_66fd_35057b965aad
  style d556b132_c03b_ea5b_79f4_5fd5b8cd84c4 fill:#6366f1,stroke:#818cf8,color:#fff

Relationship Graph

Source Code

context_test.go lines 1946–2085

func TestContextClientIP(t *testing.T) {
	c, _ := CreateTestContext(httptest.NewRecorder())
	c.Request, _ = http.NewRequest(http.MethodPost, "/", nil)
	c.engine.trustedCIDRs, _ = c.engine.prepareTrustedCIDRs()
	resetContextForClientIPTests(c)

	// unix address
	addr := &net.UnixAddr{Net: "unix", Name: "@"}
	c.Request = c.Request.WithContext(context.WithValue(c.Request.Context(), http.LocalAddrContextKey, addr))
	c.Request.RemoteAddr = addr.String()
	assert.Equal(t, "20.20.20.20", c.ClientIP())

	// reset
	c.Request = c.Request.WithContext(context.Background())
	resetContextForClientIPTests(c)

	// Legacy tests (validating that the defaults don't break the
	// (insecure!) old behaviour)
	assert.Equal(t, "20.20.20.20", c.ClientIP())

	c.Request.Header.Del("X-Forwarded-For")
	assert.Equal(t, "10.10.10.10", c.ClientIP())

	c.Request.Header.Set("X-Forwarded-For", "30.30.30.30  ")
	assert.Equal(t, "30.30.30.30", c.ClientIP())

	c.Request.Header.Del("X-Forwarded-For")
	c.Request.Header.Del("X-Real-IP")
	c.engine.TrustedPlatform = PlatformGoogleAppEngine
	assert.Equal(t, "50.50.50.50", c.ClientIP())

	c.Request.Header.Del("X-Appengine-Remote-Addr")
	assert.Equal(t, "40.40.40.40", c.ClientIP())

	// no port
	c.Request.RemoteAddr = "50.50.50.50"
	assert.Empty(t, c.ClientIP())

	// Tests exercising the TrustedProxies functionality
	resetContextForClientIPTests(c)

	// IPv6 support
	c.Request.RemoteAddr = fmt.Sprintf("[%s]:12345", localhostIPv6)
	assert.Equal(t, "20.20.20.20", c.ClientIP())

	resetContextForClientIPTests(c)
	// No trusted proxies
	_ = c.engine.SetTrustedProxies([]string{})
	c.engine.RemoteIPHeaders = []string{"X-Forwarded-For"}
	assert.Equal(t, "40.40.40.40", c.ClientIP())

	// Disabled TrustedProxies feature
	_ = c.engine.SetTrustedProxies(nil)
	assert.Equal(t, "40.40.40.40", c.ClientIP())

	// Last proxy is trusted, but the RemoteAddr is not
	_ = c.engine.SetTrustedProxies([]string{"30.30.30.30"})
	assert.Equal(t, "40.40.40.40", c.ClientIP())

	// Only trust RemoteAddr
	_ = c.engine.SetTrustedProxies([]string{"40.40.40.40"})
	assert.Equal(t, "30.30.30.30", c.ClientIP())

	// All steps are trusted
	_ = c.engine.SetTrustedProxies([]string{"40.40.40.40", "30.30.30.30", "20.20.20.20"})
	assert.Equal(t, "20.20.20.20", c.ClientIP())

	// Use CIDR
	_ = c.engine.SetTrustedProxies([]string{"40.40.25.25/16", "30.30.30.30"})
	assert.Equal(t, "20.20.20.20", c.ClientIP())

	// Use hostname that resolves to all the proxies
	_ = c.engine.SetTrustedProxies([]string{"foo"})
	assert.Equal(t, "40.40.40.40", c.ClientIP())

	// Use hostname that returns an error
	_ = c.engine.SetTrustedProxies([]string{"bar"})
	assert.Equal(t, "40.40.40.40", c.ClientIP())

	// X-Forwarded-For has a non-IP element
	_ = c.engine.SetTrustedProxies([]string{"40.40.40.40"})
	c.Request.Header.Set("X-Forwarded-For", " blah ")
	assert.Equal(t, "40.40.40.40", c.ClientIP())

	// Result from LookupHost has non-IP element. This should never
	// happen, but we should test it to make sure we handle it
	// gracefully.
	_ = c.engine.SetTrustedProxies([]string{"baz"})
	c.Request.Header.Set("X-Forwarded-For", " 30.30.30.30 ")
	assert.Equal(t, "40.40.40.40", c.ClientIP())

	_ = c.engine.SetTrustedProxies([]string{"40.40.40.40"})
	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())

	c.engine.RemoteIPHeaders = []string{}
	c.engine.TrustedPlatform = PlatformGoogleAppEngine
	assert.Equal(t, "50.50.50.50", c.ClientIP())

	// Use custom TrustedPlatform header
	c.engine.TrustedPlatform = "X-CDN-IP"
	c.Request.Header.Set("X-CDN-IP", "80.80.80.80")
	assert.Equal(t, "80.80.80.80", c.ClientIP())
	// wrong header
	c.engine.TrustedPlatform = "X-Wrong-Header"
	assert.Equal(t, "40.40.40.40", c.ClientIP())

	c.Request.Header.Del("X-CDN-IP")
	// TrustedPlatform is empty
	c.engine.TrustedPlatform = ""
	assert.Equal(t, "40.40.40.40", c.ClientIP())

	// Test the legacy flag
	c.engine.AppEngine = true
	assert.Equal(t, "50.50.50.50", c.ClientIP())
	c.engine.AppEngine = false
	c.engine.TrustedPlatform = PlatformGoogleAppEngine

	c.Request.Header.Del("X-Appengine-Remote-Addr")
	assert.Equal(t, "40.40.40.40", c.ClientIP())

	c.engine.TrustedPlatform = PlatformCloudflare
	assert.Equal(t, "60.60.60.60", c.ClientIP())

	c.Request.Header.Del("CF-Connecting-IP")
	assert.Equal(t, "40.40.40.40", c.ClientIP())

	c.engine.TrustedPlatform = PlatformFlyIO
	assert.Equal(t, "70.70.70.70", c.ClientIP())

	c.Request.Header.Del("Fly-Client-IP")
	assert.Equal(t, "40.40.40.40", c.ClientIP())

	c.engine.TrustedPlatform = ""

	// no port
	c.Request.RemoteAddr = "50.50.50.50"
	assert.Empty(t, c.ClientIP())
}

Domain

Subdomains

Frequently Asked Questions

What does TestContextClientIP() do?
TestContextClientIP() is a function in the gin codebase.
What does TestContextClientIP() call?
TestContextClientIP() calls 1 function(s): resetContextForClientIPTests.

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free