diff --git a/Gopkg.lock b/Gopkg.lock new file mode 100644 index 0000000..bef2d00 --- /dev/null +++ b/Gopkg.lock @@ -0,0 +1,9 @@ +# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. + + +[solve-meta] + analyzer-name = "dep" + analyzer-version = 1 + inputs-digest = "ab4fef131ee828e96ba67d31a7d690bd5f2f42040c6766b1b12fe856f87e0ff7" + solver-name = "gps-cdcl" + solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml new file mode 100644 index 0000000..24f0f17 --- /dev/null +++ b/Gopkg.toml @@ -0,0 +1,30 @@ +# Gopkg.toml example +# +# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md +# for detailed Gopkg.toml documentation. +# +# required = ["github.com/user/thing/cmd/thing"] +# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] +# +# [[constraint]] +# name = "github.com/user/project" +# version = "1.0.0" +# +# [[constraint]] +# name = "github.com/user/project2" +# branch = "dev" +# source = "github.com/myfork/project2" +# +# [[override]] +# name = "github.com/x/y" +# version = "2.4.0" +# +# [prune] +# non-go = false +# go-tests = true +# unused-packages = true + + +[prune] + go-tests = true + unused-packages = true diff --git a/realip.go b/realip.go index e2803a2..cd32af1 100644 --- a/realip.go +++ b/realip.go @@ -7,6 +7,16 @@ import ( "strings" ) +// Should use canonical format of the header key s +// https://golang.org/pkg/net/http/#CanonicalHeaderKey +var xForwardedFor = http.CanonicalHeaderKey("X-Forwarded-For") +var xRealIP = http.CanonicalHeaderKey("X-Real-IP") + +// RFC7239 defines a new "Forwarded: " header designed to replace the +// existing use of X-Forwarded-* headers. +// e.g. Forwarded: for=192.0.2.60;proto=https;by=203.0.113.43 +var forwarded = http.CanonicalHeaderKey("Forwarded") + var cidrs []*net.IPNet func init() { @@ -49,11 +59,12 @@ func isPrivateAddress(address string) (bool, error) { return false, nil } -// FromRequest return client's real public IP address from http request headers. +// FromRequest returns client's real public IP address from http request headers. func FromRequest(r *http.Request) string { // Fetch header value - xRealIP := r.Header.Get("X-Real-Ip") - xForwardedFor := r.Header.Get("X-Forwarded-For") + xRealIP := r.Header.Get(xRealIP) + xForwardedFor := r.Header.Get(xForwardedFor) + // forwarded := r.Header.Get(forwarded) // If both empty, return IP from remote address if xRealIP == "" && xForwardedFor == "" { diff --git a/realip_test.go b/realip_test.go index e80efe0..fce22c7 100644 --- a/realip_test.go +++ b/realip_test.go @@ -1,6 +1,7 @@ package realip import ( + "fmt" "net/http" "testing" ) @@ -50,11 +51,12 @@ func TestRealIP(t *testing.T) { newRequest := func(remoteAddr, xRealIP string, xForwardedFor ...string) *http.Request { h := http.Header{} - h.Set("X-Real-IP", xRealIP) + if xRealIP != "" { + h.Set("X-Real-IP", xRealIP) + } for _, address := range xForwardedFor { h.Set("X-Forwarded-For", address) } - return &http.Request{ RemoteAddr: remoteAddr, Header: h, @@ -79,6 +81,10 @@ func TestRealIP(t *testing.T) { name: "Has multiple X-Forwarded-For", request: newRequest("", "", localAddr, publicAddr1, publicAddr2), expected: publicAddr2, + }, { + name: "Has multiple address for X-Forwarded-For", + request: newRequest("", "", localAddr, fmt.Sprintf("%s,%s", publicAddr1, publicAddr2)), + expected: publicAddr1, }, { name: "Has X-Real-IP", request: newRequest("", publicAddr1),