github.com/ulule/limiter/v3@v3.11.3-0.20230613131926-4cb9c1da4633/network_test.go (about) 1 package limiter_test 2 3 import ( 4 "fmt" 5 "net" 6 "net/http" 7 "net/url" 8 "testing" 9 10 "github.com/stretchr/testify/require" 11 12 "github.com/ulule/limiter/v3" 13 ) 14 15 func TestGetIP(t *testing.T) { 16 is := require.New(t) 17 18 limiter1 := New(limiter.WithTrustForwardHeader(false)) 19 limiter2 := New(limiter.WithTrustForwardHeader(true)) 20 limiter3 := New(limiter.WithIPv4Mask(net.CIDRMask(24, 32))) 21 limiter4 := New(limiter.WithIPv6Mask(net.CIDRMask(48, 128))) 22 23 request1 := &http.Request{ 24 URL: &url.URL{Path: "/"}, 25 Header: http.Header{}, 26 RemoteAddr: "8.8.8.8:8888", 27 } 28 29 request2 := &http.Request{ 30 URL: &url.URL{Path: "/foo"}, 31 Header: http.Header{}, 32 RemoteAddr: "8.8.8.8:8888", 33 } 34 request2.Header.Add("X-Forwarded-For", "9.9.9.9, 7.7.7.7, 6.6.6.6") 35 36 request3 := &http.Request{ 37 URL: &url.URL{Path: "/bar"}, 38 Header: http.Header{}, 39 RemoteAddr: "8.8.8.8:8888", 40 } 41 request3.Header.Add("X-Real-IP", "6.6.6.6") 42 43 request4 := &http.Request{ 44 URL: &url.URL{Path: "/"}, 45 Header: http.Header{}, 46 RemoteAddr: "[2001:db8:cafe:1234:beef::fafa]:8888", 47 } 48 49 scenarios := []struct { 50 request *http.Request 51 limiter *limiter.Limiter 52 expected net.IP 53 }{ 54 { 55 // 56 // Scenario #1 : RemoteAddr without proxy. 57 // 58 request: request1, 59 limiter: limiter1, 60 expected: net.ParseIP("8.8.8.8").To4(), 61 }, 62 { 63 // 64 // Scenario #2 : X-Forwarded-For without proxy. 65 // 66 request: request2, 67 limiter: limiter1, 68 expected: net.ParseIP("8.8.8.8").To4(), 69 }, 70 { 71 // 72 // Scenario #3 : X-Real-IP without proxy. 73 // 74 request: request3, 75 limiter: limiter1, 76 expected: net.ParseIP("8.8.8.8").To4(), 77 }, 78 { 79 // 80 // Scenario #4 : RemoteAddr with proxy. 81 // 82 request: request1, 83 limiter: limiter2, 84 expected: net.ParseIP("8.8.8.8").To4(), 85 }, 86 { 87 // 88 // Scenario #5 : X-Forwarded-For with proxy. 89 // 90 request: request2, 91 limiter: limiter2, 92 expected: net.ParseIP("9.9.9.9").To4(), 93 }, 94 { 95 // 96 // Scenario #6 : X-Real-IP with proxy. 97 // 98 request: request3, 99 limiter: limiter2, 100 expected: net.ParseIP("6.6.6.6").To4(), 101 }, 102 { 103 // 104 // Scenario #7 : IPv4 with mask. 105 // 106 request: request1, 107 limiter: limiter3, 108 expected: net.ParseIP("8.8.8.0").To4(), 109 }, 110 { 111 // 112 // Scenario #8 : IPv6 with mask. 113 // 114 request: request4, 115 limiter: limiter4, 116 expected: net.ParseIP("2001:db8:cafe::").To16(), 117 }, 118 } 119 120 for i, scenario := range scenarios { 121 message := fmt.Sprintf("Scenario #%d", (i + 1)) 122 ip := scenario.limiter.GetIPWithMask(scenario.request) 123 is.Equal(scenario.expected, ip, message) 124 } 125 } 126 127 func TestGetIPKey(t *testing.T) { 128 is := require.New(t) 129 130 limiter1 := New(limiter.WithTrustForwardHeader(false)) 131 limiter2 := New(limiter.WithTrustForwardHeader(true)) 132 limiter3 := New(limiter.WithIPv4Mask(net.CIDRMask(24, 32))) 133 limiter4 := New(limiter.WithIPv6Mask(net.CIDRMask(48, 128))) 134 135 request1 := &http.Request{ 136 URL: &url.URL{Path: "/"}, 137 Header: http.Header{}, 138 RemoteAddr: "8.8.8.8:8888", 139 } 140 141 request2 := &http.Request{ 142 URL: &url.URL{Path: "/foo"}, 143 Header: http.Header{}, 144 RemoteAddr: "8.8.8.8:8888", 145 } 146 request2.Header.Add("X-Forwarded-For", "9.9.9.9, 7.7.7.7, 6.6.6.6") 147 148 request3 := &http.Request{ 149 URL: &url.URL{Path: "/bar"}, 150 Header: http.Header{}, 151 RemoteAddr: "8.8.8.8:8888", 152 } 153 request3.Header.Add("X-Real-IP", "6.6.6.6") 154 155 request4 := &http.Request{ 156 URL: &url.URL{Path: "/"}, 157 Header: http.Header{}, 158 RemoteAddr: "[2001:db8:cafe:1234:beef::fafa]:8888", 159 } 160 161 scenarios := []struct { 162 request *http.Request 163 limiter *limiter.Limiter 164 expected string 165 }{ 166 { 167 // 168 // Scenario #1 : RemoteAddr without proxy. 169 // 170 request: request1, 171 limiter: limiter1, 172 expected: "8.8.8.8", 173 }, 174 { 175 // 176 // Scenario #2 : X-Forwarded-For without proxy. 177 // 178 request: request2, 179 limiter: limiter1, 180 expected: "8.8.8.8", 181 }, 182 { 183 // 184 // Scenario #3 : X-Real-IP without proxy. 185 // 186 request: request3, 187 limiter: limiter1, 188 expected: "8.8.8.8", 189 }, 190 { 191 // 192 // Scenario #4 : RemoteAddr without proxy. 193 // 194 request: request1, 195 limiter: limiter2, 196 expected: "8.8.8.8", 197 }, 198 { 199 // 200 // Scenario #5 : X-Forwarded-For without proxy. 201 // 202 request: request2, 203 limiter: limiter2, 204 expected: "9.9.9.9", 205 }, 206 { 207 // 208 // Scenario #6 : X-Real-IP without proxy. 209 // 210 request: request3, 211 limiter: limiter2, 212 expected: "6.6.6.6", 213 }, 214 { 215 // 216 // Scenario #7 : IPv4 with mask. 217 // 218 request: request1, 219 limiter: limiter3, 220 expected: "8.8.8.0", 221 }, 222 { 223 // 224 // Scenario #8 : IPv6 with mask. 225 // 226 request: request4, 227 limiter: limiter4, 228 expected: "2001:db8:cafe::", 229 }, 230 } 231 232 for i, scenario := range scenarios { 233 message := fmt.Sprintf("Scenario #%d", (i + 1)) 234 key := scenario.limiter.GetIPKey(scenario.request) 235 is.Equal(scenario.expected, key, message) 236 } 237 }