[tor-commits] [meek/master] Add tests for originalClientIP.
dcf at torproject.org
dcf at torproject.org
Sun Dec 20 20:09:35 UTC 2015
commit 2e585a73bc6718e80069e6f05a0574e65c547cc2
Author: David Fifield <david at bamsoftware.com>
Date: Sun Dec 13 23:57:53 2015 -0800
Add tests for originalClientIP.
Includes failing tests for X-Forwarded-For.
---
meek-server/useraddr_test.go | 131 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 131 insertions(+)
diff --git a/meek-server/useraddr_test.go b/meek-server/useraddr_test.go
new file mode 100644
index 0000000..d603031
--- /dev/null
+++ b/meek-server/useraddr_test.go
@@ -0,0 +1,131 @@
+package main
+
+import (
+ "net"
+ "net/http"
+ "testing"
+)
+
+func checkExpected(t *testing.T, req *http.Request, expected net.IP) {
+ ip, err := originalClientIP(req)
+ // If ip is nil, then err must not be nil; and if ip is not nil, then
+ // err must be nil.
+ if (ip == nil && err == nil) || (ip != nil && err != nil) {
+ t.Errorf("%v returned ip=%v and err=%v", req, ip, expected)
+ return
+ }
+ // Either both are nil or ip is equal to expected.
+ if (ip == nil && expected != nil) ||
+ (ip != nil && !ip.Equal(expected)) {
+ t.Errorf("%v got %v, expected %v", req, ip, expected)
+ }
+}
+
+// Test that in the absence of headers indicating the original client IP
+// address, originalClientIP returns an answer based on RemoteAddr.
+func TestOriginalClientIPRemoteAddr(t *testing.T) {
+ tests := []struct {
+ RemoteAddr string
+ Expected net.IP
+ }{
+ {"", nil},
+ {"1.2.3.4:1234", net.IPv4(1, 2, 3, 4)},
+ {"[1:2::3:4]:1234", net.IP{0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 4}},
+ // Bad syntax.
+ {"1.2.3.4", nil},
+ {"1:2::3:4:1234", nil},
+ {"xyz", nil},
+ }
+
+ for _, test := range tests {
+ req := &http.Request{
+ RemoteAddr: test.RemoteAddr,
+ }
+ checkExpected(t, req, test.Expected)
+ }
+}
+
+// Test that originalClientIP reads the X-Forwarded-For header if present.
+func TestOriginalClientXForwardedFor(t *testing.T) {
+ tests := []struct {
+ XForwardedFor string
+ Expected net.IP
+ }{
+ {"", nil},
+ {"1.2.3.4", net.IPv4(1, 2, 3, 4)},
+ {"1:2::3:4", net.IP{0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 4}},
+ {"1.2.3.4,1:2::3:4", net.IPv4(1, 2, 3, 4)},
+ {"1.2.3.4, 1:2::3:4", net.IPv4(1, 2, 3, 4)},
+ {"1:2::3:4, 1.2.3.4", net.IP{0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 4}},
+ // Bad syntax.
+ {"xyz", nil},
+ {"1.2.3.4:1234", nil},
+ // Only try to parse the first element
+ {"1.2.3.4, xyz", net.IPv4(1, 2, 3, 4)},
+ {"1.2.3.4,,,", net.IPv4(1, 2, 3, 4)},
+ {"xyz, 1.2.3.4", nil},
+ // X-Forwarded-For doesn't use square brackets on IPv6.
+ {"[1:2::3:4]", nil},
+ {"[1:2::3:4]:1234", nil},
+ }
+
+ for _, test := range tests {
+ req := &http.Request{
+ Header: make(http.Header),
+ }
+ req.Header.Set("X-Forwarded-For", test.XForwardedFor)
+ checkExpected(t, req, test.Expected)
+ }
+}
+
+// Test that headers prevent reading RemoteAddr, even if the headers cannot be
+// parsed.
+func TestOriginalClientPrecedence(t *testing.T) {
+ tests := []struct {
+ Req http.Request
+ Expected net.IP
+ }{
+ {
+ http.Request{},
+ nil,
+ },
+ {
+ http.Request{
+ RemoteAddr: "5.6.7.8:5678",
+ },
+ net.IPv4(5, 6, 7, 8),
+ },
+ {
+ http.Request{
+ RemoteAddr: "5.6.7.8:5678",
+ Header: http.Header{
+ http.CanonicalHeaderKey("X-Forwarded-For"): []string{"1.2.3.4"},
+ },
+ },
+ net.IPv4(1, 2, 3, 4),
+ },
+ {
+ http.Request{
+ RemoteAddr: "5.6.7.8:5678",
+ Header: http.Header{
+ http.CanonicalHeaderKey("X-Forwarded-For"): []string{"1:2::3:4"},
+ },
+ },
+ net.IP{0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 4},
+ },
+ // X-Forwarded-For shadows RemoteAddr, even if bad syntax.
+ {
+ http.Request{
+ RemoteAddr: "5.6.7.8:5678",
+ Header: http.Header{
+ http.CanonicalHeaderKey("X-Forwarded-For"): []string{"xyz"},
+ },
+ },
+ nil,
+ },
+ }
+
+ for _, test := range tests {
+ checkExpected(t, &test.Req, test.Expected)
+ }
+}
More information about the tor-commits
mailing list