diff --git a/context.go b/context.go index 01c7cb4..d19e1ee 100644 --- a/context.go +++ b/context.go @@ -349,13 +349,10 @@ func (c *Context) BindWith(obj interface{}, b binding.Binding) error { // ClientIP implements a best effort algorithm to return the real client IP, it parses // X-Real-IP and X-Forwarded-For in order to work properly with reverse-proxies such us: nginx or haproxy. +// Use X-Forwarded-For before X-Real-Ip as nginx uses X-Real-Ip with the proxy's IP. func (c *Context) ClientIP() string { if c.engine.ForwardedByClientIP { - clientIP := strings.TrimSpace(c.requestHeader("X-Real-Ip")) - if len(clientIP) > 0 { - return clientIP - } - clientIP = c.requestHeader("X-Forwarded-For") + clientIP := c.requestHeader("X-Forwarded-For") if index := strings.IndexByte(clientIP, ','); index >= 0 { clientIP = clientIP[0:index] } @@ -363,6 +360,10 @@ func (c *Context) ClientIP() string { if len(clientIP) > 0 { return clientIP } + clientIP = strings.TrimSpace(c.requestHeader("X-Real-Ip")) + if len(clientIP) > 0 { + return clientIP + } } if c.engine.AppEngine { diff --git a/context_test.go b/context_test.go index fe22c49..7dc3085 100644 --- a/context_test.go +++ b/context_test.go @@ -718,24 +718,25 @@ func TestContextClientIP(t *testing.T) { c.Request.Header.Set("X-Appengine-Remote-Addr", "50.50.50.50") c.Request.RemoteAddr = " 40.40.40.40:42123 " - assert.Equal(t, c.ClientIP(), "10.10.10.10") - - c.Request.Header.Del("X-Real-IP") - assert.Equal(t, c.ClientIP(), "20.20.20.20") - - c.Request.Header.Set("X-Forwarded-For", "30.30.30.30 ") - assert.Equal(t, c.ClientIP(), "30.30.30.30") + 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.AppEngine = true - assert.Equal(t, c.ClientIP(), "50.50.50.50") + assert.Equal(t, "50.50.50.50", c.ClientIP()) c.Request.Header.Del("X-Appengine-Remote-Addr") - assert.Equal(t, c.ClientIP(), "40.40.40.40") + assert.Equal(t, "40.40.40.40", c.ClientIP()) // no port c.Request.RemoteAddr = "50.50.50.50" - assert.Equal(t, c.ClientIP(), "") + assert.Equal(t, "", c.ClientIP()) } func TestContextContentType(t *testing.T) {