diff --git a/README.md b/README.md index b20d37a..4d69a39 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ go-realip [license]: https://github.com/natureglobal/go-realip/blob/master/LICENSE [godoc]: https://godoc.org/github.com/natureglobal/go-realip -The go-realip detects RealIP in Go's http middleware layer. +The go-realip detects client real ip in Go's HTTP middleware layer. ## Synopsis @@ -30,7 +30,7 @@ handler = middleware(handler) ## Description -The go-realip package implements detect clietn real IP from request headers in Go's http middleware layer. +The go-realip package implements detecting client real IP mechanisms from request headers in Go's HTTP middleware layer. This have a similar behavior as Nginx's ngx\_http\_go-realip\_module ## Installation diff --git a/realip.go b/realip.go index b93533c..85dbc26 100644 --- a/realip.go +++ b/realip.go @@ -57,7 +57,7 @@ func (c *Config) handler(next http.Handler) http.Handler { switch c.realIPHeader() { case HeaderXForwardedFor: return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { - if len(c.RealIPFrom) > 0 && !trustedIP(net.ParseIP(remoteIP(req.RemoteAddr)), c.RealIPFrom) { + if !trustedIP(net.ParseIP(remoteIP(req.RemoteAddr)), c.RealIPFrom) { req.Header.Set(c.setHeader(), remoteIP(req.RemoteAddr)) } else { realIP := realIPFromXFF( @@ -73,7 +73,7 @@ func (c *Config) handler(next http.Handler) http.Handler { }) default: return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { - if len(c.RealIPFrom) > 0 && !trustedIP(net.ParseIP(remoteIP(req.RemoteAddr)), c.RealIPFrom) { + if !trustedIP(net.ParseIP(remoteIP(req.RemoteAddr)), c.RealIPFrom) { req.Header.Set(c.setHeader(), remoteIP(req.RemoteAddr)) } else { realIP := req.Header.Get(c.realIPHeader()) @@ -88,6 +88,9 @@ func (c *Config) handler(next http.Handler) http.Handler { } func trustedIP(ip net.IP, realIPFrom []*net.IPNet) bool { + if len(realIPFrom) == 0 { + return true + } for _, fromIP := range realIPFrom { if fromIP.Contains(ip) { return true @@ -124,5 +127,5 @@ func realIPFromXFF(xff string, realIPFrom []*net.IPNet, recursive bool) string { return ipStr } } - return "" + return strings.TrimSpace(ips[0]) } diff --git a/realip_test.go b/realip_test.go index 597b279..46613d4 100644 --- a/realip_test.go +++ b/realip_test.go @@ -92,9 +92,31 @@ func TestMiddleware(t *testing.T) { "X-Forwarded-For": "1.2.3.4, 1.1.1.1, 192.168.0.1", }, expect: "127.0.0.1", + }, { + name: "x-forwarded-for: all entries in xff is trusted ip", + config: &realip.Config{ + RealIPFrom: []*net.IPNet{ + mustParseCIDR("127.0.0.1/32"), + mustParseCIDR("192.168.0.0/16"), + }, + RealIPHeader: realip.HeaderXForwardedFor, + RealIPRecursive: true, + }, + headers: map[string]string{ + "X-Forwarded-For": "192.168.0.2, 192.168.0.1", + }, + expect: "192.168.0.2", + }, { + name: "x-forwarded-for: no RealIPFrom config and true RealIPRecursive return left entry in xff", + config: &realip.Config{ + RealIPHeader: realip.HeaderXForwardedFor, + RealIPRecursive: true, + }, + headers: map[string]string{ + "X-Forwarded-For": "192.168.0.2, 192.168.0.1", + }, + expect: "192.168.0.2", }} - // XXX: When RealIPFrom is empty and RealIPRecursive is true, I don't know what it - // should do, so I don't test it. for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) {