@@ -1392,11 +1392,10 @@ func TestContextClientIP(t *testing.T) {
13921392 c , _ := CreateTestContext (httptest .NewRecorder ())
13931393 c .Request , _ = http .NewRequest ("POST" , "/" , nil )
13941394
1395- c .Request .Header .Set ("X-Real-IP" , " 10.10.10.10 " )
1396- c .Request .Header .Set ("X-Forwarded-For" , " 20.20.20.20, 30.30.30.30" )
1397- c .Request .Header .Set ("X-Appengine-Remote-Addr" , "50.50.50.50" )
1398- c .Request .RemoteAddr = " 40.40.40.40:42123 "
1395+ resetContextForClientIPTests (c )
13991396
1397+ // Legacy tests (validating that the defaults don't break the
1398+ // (insecure!) old behaviour)
14001399 assert .Equal (t , "20.20.20.20" , c .ClientIP ())
14011400
14021401 c .Request .Header .Del ("X-Forwarded-For" )
@@ -1416,6 +1415,74 @@ func TestContextClientIP(t *testing.T) {
14161415 // no port
14171416 c .Request .RemoteAddr = "50.50.50.50"
14181417 assert .Empty (t , c .ClientIP ())
1418+
1419+ // Tests exercising the TrustedProxies functionality
1420+ resetContextForClientIPTests (c )
1421+
1422+ // No trusted proxies
1423+ c .engine .TrustedProxies = []string {}
1424+ c .engine .RemoteIPHeaders = []string {"X-Forwarded-For" }
1425+ assert .Equal (t , "40.40.40.40" , c .ClientIP ())
1426+
1427+ // Last proxy is trusted, but the RemoteAddr is not
1428+ c .engine .TrustedProxies = []string {"30.30.30.30" }
1429+ assert .Equal (t , "40.40.40.40" , c .ClientIP ())
1430+
1431+ // Only trust RemoteAddr
1432+ c .engine .TrustedProxies = []string {"40.40.40.40" }
1433+ assert .Equal (t , "20.20.20.20" , c .ClientIP ())
1434+
1435+ // All steps are trusted
1436+ c .engine .TrustedProxies = []string {"40.40.40.40" , "30.30.30.30" , "20.20.20.20" }
1437+ assert .Equal (t , "20.20.20.20" , c .ClientIP ())
1438+
1439+ // Use CIDR
1440+ c .engine .TrustedProxies = []string {"40.40.25.25/16" , "30.30.30.30" }
1441+ assert .Equal (t , "20.20.20.20" , c .ClientIP ())
1442+
1443+ // Use hostname that resolves to all the proxies
1444+ c .engine .TrustedProxies = []string {"foo" }
1445+ assert .Equal (t , "40.40.40.40" , c .ClientIP ())
1446+
1447+ // Use hostname that returns an error
1448+ c .engine .TrustedProxies = []string {"bar" }
1449+ assert .Equal (t , "40.40.40.40" , c .ClientIP ())
1450+
1451+ // X-Forwarded-For has a non-IP element
1452+ c .engine .TrustedProxies = []string {"40.40.40.40" }
1453+ c .Request .Header .Set ("X-Forwarded-For" , " blah " )
1454+ assert .Equal (t , "40.40.40.40" , c .ClientIP ())
1455+
1456+ // Result from LookupHost has non-IP element. This should never
1457+ // happen, but we should test it to make sure we handle it
1458+ // gracefully.
1459+ c .engine .TrustedProxies = []string {"baz" }
1460+ c .Request .Header .Set ("X-Forwarded-For" , " 30.30.30.30 " )
1461+ assert .Equal (t , "40.40.40.40" , c .ClientIP ())
1462+
1463+ c .engine .TrustedProxies = []string {"40.40.40.40" }
1464+ c .Request .Header .Del ("X-Forwarded-For" )
1465+ c .engine .RemoteIPHeaders = []string {"X-Forwarded-For" , "X-Real-IP" }
1466+ assert .Equal (t , "10.10.10.10" , c .ClientIP ())
1467+
1468+ c .engine .RemoteIPHeaders = []string {}
1469+ c .engine .AppEngine = true
1470+ assert .Equal (t , "50.50.50.50" , c .ClientIP ())
1471+
1472+ c .Request .Header .Del ("X-Appengine-Remote-Addr" )
1473+ assert .Equal (t , "40.40.40.40" , c .ClientIP ())
1474+
1475+ // no port
1476+ c .Request .RemoteAddr = "50.50.50.50"
1477+ assert .Empty (t , c .ClientIP ())
1478+ }
1479+
1480+ func resetContextForClientIPTests (c * Context ) {
1481+ c .Request .Header .Set ("X-Real-IP" , " 10.10.10.10 " )
1482+ c .Request .Header .Set ("X-Forwarded-For" , " 20.20.20.20, 30.30.30.30" )
1483+ c .Request .Header .Set ("X-Appengine-Remote-Addr" , "50.50.50.50" )
1484+ c .Request .RemoteAddr = " 40.40.40.40:42123 "
1485+ c .engine .AppEngine = false
14191486}
14201487
14211488func TestContextContentType (t * testing.T ) {
@@ -1960,3 +2027,12 @@ func TestContextWithKeysMutex(t *testing.T) {
19602027 assert .Nil (t , value )
19612028 assert .False (t , err )
19622029}
2030+
2031+ func TestRemoteIPFail (t * testing.T ) {
2032+ c , _ := CreateTestContext (httptest .NewRecorder ())
2033+ c .Request , _ = http .NewRequest ("POST" , "/" , nil )
2034+ c .Request .RemoteAddr = "[:::]:80"
2035+ ip , trust := c .RemoteIP ()
2036+ assert .Nil (t , ip )
2037+ assert .False (t , trust )
2038+ }
0 commit comments