diff --git a/realip.go b/realip.go index e2803a2..f07fd35 100644 --- a/realip.go +++ b/realip.go @@ -53,10 +53,10 @@ func isPrivateAddress(address string) (bool, error) { func FromRequest(r *http.Request) string { // Fetch header value xRealIP := r.Header.Get("X-Real-Ip") - xForwardedFor := r.Header.Get("X-Forwarded-For") + xForwardedFor, _ := r.Header["X-Forwarded-For"] // If both empty, return IP from remote address - if xRealIP == "" && xForwardedFor == "" { + if xRealIP == "" && len(xForwardedFor) == 0 { var remoteIP string // If there are colon in remote address, remove the port number @@ -71,11 +71,13 @@ func FromRequest(r *http.Request) string { } // Check list of IP in X-Forwarded-For and return the first global address - for _, address := range strings.Split(xForwardedFor, ",") { - address = strings.TrimSpace(address) - isPrivate, err := isPrivateAddress(address) - if !isPrivate && err == nil { - return address + for _, a := range xForwardedFor { + for _, b := range strings.Split(a, ",") { + address := strings.TrimSpace(b) + isPrivate, err := isPrivateAddress(address) + if !isPrivate && err == nil { + return address + } } } diff --git a/realip_test.go b/realip_test.go index e80efe0..4da3488 100644 --- a/realip_test.go +++ b/realip_test.go @@ -1,6 +1,7 @@ package realip import ( + "fmt" "net/http" "testing" ) @@ -52,7 +53,7 @@ func TestRealIP(t *testing.T) { h := http.Header{} h.Set("X-Real-IP", xRealIP) for _, address := range xForwardedFor { - h.Set("X-Forwarded-For", address) + h.Add("X-Forwarded-For", address) } return &http.Request{ @@ -75,10 +76,18 @@ func TestRealIP(t *testing.T) { name: "Has X-Forwarded-For", request: newRequest("", "", publicAddr1), expected: publicAddr1, + }, { + name: "Has X-Forwarded-For multiple IPs (comma separated)(", + request: newRequest("", "", fmt.Sprintf("%s,%s", localAddr, publicAddr1)), + expected: publicAddr1, + }, { + name: "Has X-Forwarded-For multiple IPs (comma and then space)", + request: newRequest("", "", fmt.Sprintf("%s, %s", localAddr, publicAddr1)), + expected: publicAddr1, }, { name: "Has multiple X-Forwarded-For", request: newRequest("", "", localAddr, publicAddr1, publicAddr2), - expected: publicAddr2, + expected: publicAddr1, }, { name: "Has X-Real-IP", request: newRequest("", publicAddr1),