-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathfcors_test.go
130 lines (114 loc) · 3.69 KB
/
fcors_test.go
1
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package fcors_test
import (
"net/http"
"net/http/httptest"
"slices"
"strconv"
"testing"
"github.com/jub0bs/fcors/internal/util"
)
const (
dummyInvalidOrigin = "https://jub0bs.com/"
abnormallyLongOrigin = "https://foobarbaz.foobarbaz.foobarbaz." +
"foobarbaz.foobarbaz.foobarbaz.foobarbaz.foobarbaz.foobarbaz." +
"foobarbaz.foobarbaz.foobarbaz.foobarbaz.foobarbaz.foobarbaz." +
"foobarbaz.foobarbaz.foobarbaz.foobarbaz.foobarbaz.foobarbaz." +
"foobarbaz.foobarbaz.foobarbaz.foobarbaz.foobarbaz.foobarbaz." +
"foobarbaz.foobarbaz.foobarbaz.foobarbaz.foobarbaz.foobarbaz." +
"foobarbaz.foobarbaz.foobarbaz.foobarbaz.foobarbaz.foobarbaz." +
"foobarbaz.foobarbaz.foobarbaz.foobarbaz.foobarbaz.foobarbaz.com"
headerOrigin = "Origin"
headerACRM = "Access-Control-Request-Method"
headerACRH = "Access-Control-Request-Headers"
headerACRPN = "Access-Control-Request-Private-Network"
headerACAO = "Access-Control-Allow-Origin"
headerACAC = "Access-Control-Allow-Credentials"
headerACMA = "Access-Control-Max-Age"
headerACAM = "Access-Control-Allow-Methods"
headerACAH = "Access-Control-Allow-Headers"
headerACAPN = "Access-Control-Allow-Private-Network"
headerACEH = "Access-Control-Expose-Headers"
headerVary = "Vary"
varyPreflightValue = headerACRH + ", " + headerACRM + ", " +
headerACRPN + ", " + headerOrigin
wildcard = "*"
wildcardAndAuth = wildcard + ",authorization"
headerValueTrue = "true"
defaultPreflightSuccessStatus = http.StatusNoContent
)
type TestCase struct {
name string
reqMethod string
reqHeaders http.Header
expectedStatus int
expectedRespHeaders http.Header
}
var dummyHandler = http.HandlerFunc(func(_ http.ResponseWriter, _ *http.Request) {})
var headerVaryBefore = []string{"before"}
var varyMiddleware = func(next http.Handler) http.Handler {
f := func(w http.ResponseWriter, r *http.Request) {
w.Header()[headerVary] = headerVaryBefore
next.ServeHTTP(w, r)
}
return http.HandlerFunc(f)
}
func process(t *testing.T, handler http.Handler, cases []TestCase) {
t.Helper()
for _, c := range cases {
f := func(t *testing.T) {
req := newRequest(c.reqMethod, c.reqHeaders)
rec := httptest.NewRecorder()
handler.ServeHTTP(rec, req)
res := rec.Result()
if res.StatusCode != c.expectedStatus {
t.Errorf("want status %d; got %d", c.expectedStatus, res.StatusCode)
}
checkResponseHeaders(t, res.Header, c.expectedRespHeaders)
}
t.Run("versus "+c.name, f)
}
}
func checkResponseHeaders(
t *testing.T,
actualHeaders http.Header,
expectedHeaders http.Header,
) {
t.Helper()
unexpectedNames := util.NewSet(
headerACAO,
headerACAC,
headerACAM,
headerACAH,
headerACMA,
headerACAPN,
headerACEH,
headerVary,
)
for expectedName, expectedValue := range expectedHeaders {
delete(unexpectedNames, expectedName)
actualValue, found := actualHeaders[expectedName]
if !found {
t.Errorf("absence of expected header %q", expectedName)
return
}
if !slices.Equal(expectedValue, actualValue) {
const tmpl = "unexpected header value for header %q:\n\tgot %q;\n\twant %q"
t.Errorf(tmpl, expectedName, actualValue, expectedValue)
}
}
for unwantedName := range unexpectedNames {
if value, found := actualHeaders[unwantedName]; found {
const tmpl = "presence of unexpected response header %q: %q"
t.Errorf(tmpl, unwantedName, value[0])
}
}
}
func newRequest(method string, headers http.Header) *http.Request {
const dummyEndpoint = "https://example.com/whatever"
req := httptest.NewRequest(method, dummyEndpoint, nil)
req.Header = headers
return req
}
func stringFromUint(u uint) string {
return strconv.FormatUint(uint64(u), 10)
}