From 6703dea51c3a32d6b30f51ba0d6a7a7deae23e32 Mon Sep 17 00:00:00 2001 From: "Alessandro (Ale) Segala" <43508+ItalyPaleAle@users.noreply.github.com> Date: Thu, 27 May 2021 19:03:59 -0700 Subject: [PATCH] Get client IP when using Cloudflare (#2723) Co-authored-by: thinkerou --- context.go | 7 ++++++- context_test.go | 8 ++++++++ gin.go | 4 ++++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/context.go b/context.go index 12e946d211..0c1fb07f48 100644 --- a/context.go +++ b/context.go @@ -731,10 +731,15 @@ func (c *Context) ShouldBindBodyWith(obj interface{}, bb binding.BindingBody) (e // If the headers are nots syntactically valid OR the remote IP does not correspong to a trusted proxy, // the remote IP (coming form Request.RemoteAddr) is returned. func (c *Context) ClientIP() string { - if c.engine.AppEngine { + switch { + case c.engine.AppEngine: if addr := c.requestHeader("X-Appengine-Remote-Addr"); addr != "" { return addr } + case c.engine.CloudflareProxy: + if addr := c.requestHeader("CF-Connecting-IP"); addr != "" { + return addr + } } remoteIP, trusted := c.RemoteIP() diff --git a/context_test.go b/context_test.go index aaa358e9d0..e0de717ea7 100644 --- a/context_test.go +++ b/context_test.go @@ -1476,6 +1476,13 @@ func TestContextClientIP(t *testing.T) { c.Request.Header.Del("X-Appengine-Remote-Addr") assert.Equal(t, "40.40.40.40", c.ClientIP()) + c.engine.AppEngine = false + c.engine.CloudflareProxy = true + 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()) + // no port c.Request.RemoteAddr = "50.50.50.50" assert.Empty(t, c.ClientIP()) @@ -1485,6 +1492,7 @@ func resetContextForClientIPTests(c *Context) { c.Request.Header.Set("X-Real-IP", " 10.10.10.10 ") c.Request.Header.Set("X-Forwarded-For", " 20.20.20.20, 30.30.30.30") c.Request.Header.Set("X-Appengine-Remote-Addr", "50.50.50.50") + c.Request.Header.Set("CF-Connecting-IP", "60.60.60.60") c.Request.RemoteAddr = " 40.40.40.40:42123 " c.engine.AppEngine = false } diff --git a/gin.go b/gin.go index 56e5c76848..00686e77e1 100644 --- a/gin.go +++ b/gin.go @@ -105,6 +105,10 @@ type Engine struct { // 'X-AppEngine...' for better integration with that PaaS. AppEngine bool + // If enabled, it will trust the CF-Connecting-IP header to determine the + // IP of the client. + CloudflareProxy bool + // If enabled, the url.RawPath will be used to find parameters. UseRawPath bool