access_test.go
63 lines1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package router
import (
"net/http"
"net/http/httptest"
"testing"
)
func serveWith(h Handler, remoteAddr, xff string) int {
ok := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
})
req := httptest.NewRequest("GET", "http://example.com/", nil)
req.RemoteAddr = remoteAddr
if xff != "" {
req.Header.Set("X-Forwarded-For", xff)
}
rec := httptest.NewRecorder()
h(ok).ServeHTTP(rec, req)
return rec.Code
}
func TestIpBlockList(t *testing.T) {
block := IpBlockList("203.0.113.0/24", "198.51.100.7")
if code := serveWith(block, "203.0.113.5:1234", ""); code != http.StatusForbidden {
t.Errorf("CIDR match should be blocked, got %d", code)
}
if code := serveWith(block, "198.51.100.7:1234", ""); code != http.StatusForbidden {
t.Errorf("bare IP match should be blocked, got %d", code)
}
if code := serveWith(block, "10.0.0.1:1234", ""); code != http.StatusOK {
t.Errorf("non-match should pass, got %d", code)
}
// XFF is honored: RemoteAddr is a proxy, real client is blocked.
if code := serveWith(block, "10.0.0.1:1234", "203.0.113.9"); code != http.StatusForbidden {
t.Errorf("XFF client should be blocked, got %d", code)
}
}
func TestIpAllowList(t *testing.T) {
allow := IpAllowList("10.0.0.0/8")
if code := serveWith(allow, "10.9.9.9:1234", ""); code != http.StatusOK {
t.Errorf("in-range should pass, got %d", code)
}
if code := serveWith(allow, "203.0.113.1:1234", ""); code != http.StatusForbidden {
t.Errorf("out-of-range should be blocked, got %d", code)
}
// Unparseable client IP is not on the allow list.
if code := serveWith(allow, "garbage", ""); code != http.StatusForbidden {
t.Errorf("unparseable IP should be blocked, got %d", code)
}
}
func TestParsePrefixesPanicsOnGarbage(t *testing.T) {
defer func() {
if recover() == nil {
t.Error("expected panic on invalid CIDR")
}
}()
IpBlockList("not-an-ip")
}