diff options
Diffstat (limited to 'vendor/github.com/tomasen')
-rw-r--r-- | vendor/github.com/tomasen/realip/.travis.yml | 21 | ||||
-rw-r--r-- | vendor/github.com/tomasen/realip/README.md | 18 | ||||
-rw-r--r-- | vendor/github.com/tomasen/realip/realip.go | 71 | ||||
-rw-r--r-- | vendor/github.com/tomasen/realip/realip_test.go | 86 |
4 files changed, 196 insertions, 0 deletions
diff --git a/vendor/github.com/tomasen/realip/.travis.yml b/vendor/github.com/tomasen/realip/.travis.yml new file mode 100644 index 0000000..9c90009 --- /dev/null +++ b/vendor/github.com/tomasen/realip/.travis.yml @@ -0,0 +1,21 @@ +language: go + +go: + - 1.4 + - 1.5 + - tip + +before_install: + # lint + - go get github.com/golang/lint/golint + + # code complexity + - go get github.com/on99/gocyclo + + # test + - go get github.com/smartystreets/goconvey/convey + +script: + - golint ./... + - go vet ./... + - gocyclo -skip-godeps=true -top 10 -over 10 . # over 10 is bad code diff --git a/vendor/github.com/tomasen/realip/README.md b/vendor/github.com/tomasen/realip/README.md new file mode 100644 index 0000000..3eea89a --- /dev/null +++ b/vendor/github.com/tomasen/realip/README.md @@ -0,0 +1,18 @@ +a golang library that can get client's real public ip address from http request headers + +[![Build Status](https://travis-ci.org/tomasen/realip.svg?branch=master)](https://travis-ci.org/Tomasen/realip) +[![GoDoc](https://godoc.org/github.com/Tomasen/realip?status.svg)](http://godoc.org/github.com/Tomasen/realip) + + +* follow the rule of X-FORWARDED-FOR/rfc7239 +* follow the rule of X-Real-Ip +* lan/intranet IP address filtered + +## Developing + +Commited code must pass: + +* [golint](https://github.com/golang/lint) +* [go vet](https://godoc.org/golang.org/x/tools/cmd/vet) +* [gofmt](https://golang.org/cmd/gofmt) +* [go test](https://golang.org/cmd/go/#hdr-Test_packages): diff --git a/vendor/github.com/tomasen/realip/realip.go b/vendor/github.com/tomasen/realip/realip.go new file mode 100644 index 0000000..09ed74d --- /dev/null +++ b/vendor/github.com/tomasen/realip/realip.go @@ -0,0 +1,71 @@ +package realip + +import ( + "log" + "net" + "net/http" + "strings" +) + +var cidrs []*net.IPNet + +func init() { + lancidrs := []string{ + "127.0.0.1/8", "10.0.0.0/8", "169.254.0.0/16", "172.16.0.0/12", "192.168.0.0/16", "::1/128", "fc00::/7", + } + + cidrs = make([]*net.IPNet, len(lancidrs)) + + for i, it := range lancidrs { + _, cidrnet, err := net.ParseCIDR(it) + if err != nil { + log.Fatalf("ParseCIDR error: %v", err) // assuming I did it right above + } + + cidrs[i] = cidrnet + } +} + +func isLocalAddress(addr string) bool { + for i := range cidrs { + myaddr := net.ParseIP(addr) + if cidrs[i].Contains(myaddr) { + return true + } + } + + return false +} + +// Request.RemoteAddress contains port, which we want to remove i.e.: +// "[::1]:58292" => "[::1]" +func ipAddrFromRemoteAddr(s string) string { + idx := strings.LastIndex(s, ":") + if idx == -1 { + return s + } + return s[:idx] +} + +// RealIP return client's real public IP address +// from http request headers. +func RealIP(r *http.Request) string { + hdr := r.Header + hdrRealIP := hdr.Get("X-Real-Ip") + hdrForwardedFor := hdr.Get("X-Forwarded-For") + + if len(hdrForwardedFor) == 0 && len(hdrRealIP) == 0 { + return ipAddrFromRemoteAddr(r.RemoteAddr) + } + + // X-Forwarded-For is potentially a list of addresses separated with "," + for _, addr := range strings.Split(hdrForwardedFor, ",") { + // return first non-local address + addr = strings.TrimSpace(addr) + if len(addr) > 0 && !isLocalAddress(addr) { + return addr + } + } + + return hdrRealIP +} diff --git a/vendor/github.com/tomasen/realip/realip_test.go b/vendor/github.com/tomasen/realip/realip_test.go new file mode 100644 index 0000000..e301ee8 --- /dev/null +++ b/vendor/github.com/tomasen/realip/realip_test.go @@ -0,0 +1,86 @@ +package realip + +import ( + "net/http" + "strings" + "testing" +) + +func TestIsLocalAddr(t *testing.T) { + testData := map[string]bool{ + "127.0.0.0": true, + "10.0.0.0": true, + "169.254.0.0": true, + "192.168.0.0": true, + "::1": true, + "fc00::": true, + + "172.15.0.0": false, + "172.16.0.0": true, + "172.31.0.0": true, + "172.32.0.0": false, + + "147.12.56.11": false, + } + + for addr, isLocal := range testData { + if isLocalAddress(addr) != isLocal { + format := "%s should " + if !isLocal { + format += "not " + } + format += "be local address" + + t.Errorf(format, addr) + } + } +} + +func TestIpAddrFromRemoteAddr(t *testing.T) { + testData := map[string]string{ + "127.0.0.1:8888": "127.0.0.1", + "ip:port": "ip", + "ip": "ip", + "12:34::0": "12:34:", + } + + for remoteAddr, expectedAddr := range testData { + if actualAddr := ipAddrFromRemoteAddr(remoteAddr); actualAddr != expectedAddr { + t.Errorf("ipAddrFromRemoteAddr of %s should be %s but get %s", remoteAddr, expectedAddr, actualAddr) + } + } +} + +func TestRealIP(t *testing.T) { + newRequest := func(remoteAddr, hdrRealIP, hdrForwardedFor string) *http.Request { + h := http.Header{} + h["X-Real-Ip"] = []string{hdrRealIP} + h["X-Forwarded-For"] = []string{hdrForwardedFor} + return &http.Request{ + RemoteAddr: remoteAddr, + Header: h, + } + } + + remoteAddr := "144.12.54.87" + anotherRemoteAddr := "119.14.55.11" + localAddr := "127.0.0.0" + + testData := []struct { + expected string + request *http.Request + }{ + {remoteAddr, newRequest(remoteAddr, "", "")}, // no header + {remoteAddr, newRequest("", "", remoteAddr)}, // X-Forwarded-For: remoteAddr + {remoteAddr, newRequest("", remoteAddr, "")}, // X-RealIP: remoteAddr + + // X-Forwarded-For: localAddr, remoteAddr, anotherRemoteAddr + {remoteAddr, newRequest("", "", strings.Join([]string{localAddr, remoteAddr, anotherRemoteAddr}, ", "))}, + } + + for _, v := range testData { + if actual := RealIP(v.request); v.expected != actual { + t.Errorf("expected %s but get %s", v.expected, actual) + } + } +} |