Skip to content

Commit 2263858

Browse files
Dutchy-PascalMinder
authored andcommitted
Trim spaces in forwarded header addresses
1 parent 2fd4fe2 commit 2263858

File tree

2 files changed

+83
-2
lines changed

2 files changed

+83
-2
lines changed

geoblock.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,7 @@ func ipInSlice(a net.IP, list []net.IP) bool {
456456
}
457457

458458
func parseIP(addr string) (net.IP, error) {
459-
ipAddress := net.ParseIP(addr)
459+
ipAddress := net.ParseIP(strings.TrimSpace(addr))
460460

461461
if ipAddress == nil {
462462
return nil, fmt.Errorf("unable parse IP address from address [%s]", addr)

geoblock_test.go

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,14 @@ const (
1919
CountryHeader = "X-IPCountry"
2020
caExampleIP = "99.220.109.148"
2121
chExampleIP = "82.220.110.18"
22+
multiForwardedIP = "82.220.110.18,192.168.1.1,10.0.0.1"
23+
multiForwardedIPwithSpaces = "82.220.110.18, 192.168.1.1, 10.0.0.1"
2224
privateRangeIP = "192.168.1.1"
2325
invalidIP = "192.168.1.X"
2426
unknownCountry = "1.1.1.1"
2527
apiURI = "https://get.geojs.io/v1/ip/country/{ip}"
2628
ipGeolocationHTTPHeaderField = "cf-ipcountry"
29+
allowedRequest = "Allowed request"
2730
)
2831

2932
func TestEmptyApi(t *testing.T) {
@@ -134,7 +137,7 @@ func TestAllowedCountry(t *testing.T) {
134137
t.Fatal(err)
135138
}
136139

137-
expectedBody := "Allowed request"
140+
expectedBody := allowedRequest
138141
if string(body) != expectedBody {
139142
t.Fatalf("expected body %q, got %q", expectedBody, string(body))
140143
}
@@ -166,6 +169,84 @@ func TestMultipleAllowedCountry(t *testing.T) {
166169
assertStatusCode(t, recorder.Result(), http.StatusOK)
167170
}
168171

172+
func TestMultipleForwardedForIP(t *testing.T) {
173+
cfg := createTesterConfig()
174+
cfg.Countries = append(cfg.Countries, "CH")
175+
cfg.AllowLocalRequests = true
176+
177+
ctx := context.Background()
178+
next := http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { _, _ = w.Write([]byte("Allowed request")) })
179+
180+
handler, err := geoblock.New(ctx, next, cfg, "GeoBlock")
181+
if err != nil {
182+
t.Fatal(err)
183+
}
184+
185+
recorder := httptest.NewRecorder()
186+
187+
req, err := http.NewRequestWithContext(ctx, http.MethodGet, "http://localhost", nil)
188+
if err != nil {
189+
t.Fatal(err)
190+
}
191+
192+
req.Header.Add(xForwardedFor, multiForwardedIP)
193+
194+
handler.ServeHTTP(recorder, req)
195+
196+
recorderResult := recorder.Result()
197+
198+
assertStatusCode(t, recorderResult, http.StatusOK)
199+
200+
body, err := io.ReadAll(recorderResult.Body)
201+
if err != nil {
202+
t.Fatal(err)
203+
}
204+
205+
expectedBody := allowedRequest
206+
if string(body) != expectedBody {
207+
t.Fatalf("expected body %q, got %q", expectedBody, string(body))
208+
}
209+
}
210+
211+
func TestMultipleForwardedForIPwithSpaces(t *testing.T) {
212+
cfg := createTesterConfig()
213+
cfg.Countries = append(cfg.Countries, "CH")
214+
cfg.AllowLocalRequests = true
215+
216+
ctx := context.Background()
217+
next := http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { _, _ = w.Write([]byte("Allowed request")) })
218+
219+
handler, err := geoblock.New(ctx, next, cfg, "GeoBlock")
220+
if err != nil {
221+
t.Fatal(err)
222+
}
223+
224+
recorder := httptest.NewRecorder()
225+
226+
req, err := http.NewRequestWithContext(ctx, http.MethodGet, "http://localhost", nil)
227+
if err != nil {
228+
t.Fatal(err)
229+
}
230+
231+
req.Header.Add(xForwardedFor, multiForwardedIPwithSpaces)
232+
233+
handler.ServeHTTP(recorder, req)
234+
235+
recorderResult := recorder.Result()
236+
237+
assertStatusCode(t, recorderResult, http.StatusOK)
238+
239+
body, err := io.ReadAll(recorderResult.Body)
240+
if err != nil {
241+
t.Fatal(err)
242+
}
243+
244+
expectedBody := allowedRequest
245+
if string(body) != expectedBody {
246+
t.Fatalf("expected body %q, got %q", expectedBody, string(body))
247+
}
248+
}
249+
169250
func createMockAPIServer(t *testing.T, ipResponseMap map[string][]byte) *httptest.Server {
170251
return httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
171252
t.Logf("Intercepted request: %s %s", req.Method, req.URL.String())

0 commit comments

Comments
 (0)