Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS
Mirrored from https://github.com/Slazee/caddy.git
Synced Nov 11, 14:45 UTC
fileserver: Fix tests on Windows
Matthew Holt committed
Feb 20, 2026 at 11:46 UTC
cb436f0a0ed62e0a5d4af158486bba39fc575fe1
2 files changed
+69
-44
modules/caddyhttp/fileserver/matcher_test.go
+69
-44
@@ -20,7 +20,9 @@ import (
20
"net/http/httptest"
21
"net/url"
22
"os"
23
+ "path/filepath"
24
"runtime"
25
+ "strings"
26
"testing"
27
28
"github.com/caddyserver/caddy/v2"
@@ -28,6 +30,13 @@ import (
30
"github.com/caddyserver/caddy/v2/modules/caddyhttp"
31
)
32
33
+type testCase struct {
34
+ path string
35
+ expectedPath string
36
+ expectedType string
37
+ matched bool
38
+}
39
+
40
func TestFileMatcher(t *testing.T) {
41
// Windows doesn't like colons in files names
42
isWindows := runtime.GOOS == "windows"
@@ -45,12 +54,7 @@ func TestFileMatcher(t *testing.T) {
54
f.Close()
55
}
56
48
- for i, tc := range []struct {
49
- path string
50
- expectedPath string
51
- expectedType string
52
- matched bool
53
- }{
57
+ for i, tc := range []testCase{
58
{
59
path: "/foo.txt",
60
expectedPath: "/foo.txt",
@@ -115,51 +119,72 @@ func TestFileMatcher(t *testing.T) {
119
expectedType: "file",
120
matched: !isWindows,
121
},
118
- {
119
- path: "/foodir/secr%5Cet.txt",
120
- expectedPath: "/foodir/secr\\et.txt",
121
- expectedType: "file",
122
- matched: true,
123
- },
122
} {
125
- m := &MatchFile{
126
- fsmap: &filesystems.FileSystemMap{},
127
- Root: "./testdata",
128
- TryFiles: []string{"{http.request.uri.path}", "{http.request.uri.path}/"},
129
- }
123
+ fileMatcherTest(t, i, tc)
124
+ }
125
+}
126
131
- u, err := url.Parse(tc.path)
132
- if err != nil {
133
- t.Errorf("Test %d: parsing path: %v", i, err)
134
- }
127
+func TestFileMatcherNonWindows(t *testing.T) {
128
+ if runtime.GOOS == "windows" {
129
+ return
130
+ }
131
136
- req := &http.Request{URL: u}
137
- repl := caddyhttp.NewTestReplacer(req)
132
+ // this is impossible to test on Windows, but tests a security patch for other platforms
133
+ tc := testCase{
134
+ path: "/foodir/secr%5Cet.txt",
135
+ expectedPath: "/foodir/secr\\et.txt",
136
+ expectedType: "file",
137
+ matched: true,
138
+ }
139
139
- result, err := m.MatchWithError(req)
140
- if err != nil {
141
- t.Errorf("Test %d: unexpected error: %v", i, err)
142
- }
143
- if result != tc.matched {
144
- t.Errorf("Test %d: expected match=%t, got %t", i, tc.matched, result)
145
- }
140
+ f, err := os.Create(filepath.Join("testdata", strings.TrimPrefix(tc.expectedPath, "/")))
141
+ if err != nil {
142
+ t.Fatalf("could not create test file: %v", err)
143
+ }
144
+ defer f.Close()
145
+ defer os.Remove(f.Name())
146
147
- rel, ok := repl.Get("http.matchers.file.relative")
148
- if !ok && result {
149
- t.Errorf("Test %d: expected replacer value", i)
150
- }
151
- if !result {
152
- continue
153
- }
147
+ fileMatcherTest(t, 0, tc)
148
+}
149
155
- if rel != tc.expectedPath {
156
- t.Errorf("Test %d: actual path: %v, expected: %v", i, rel, tc.expectedPath)
157
- }
150
+func fileMatcherTest(t *testing.T, i int, tc testCase) {
151
+ m := &MatchFile{
152
+ fsmap: &filesystems.FileSystemMap{},
153
+ Root: "./testdata",
154
+ TryFiles: []string{"{http.request.uri.path}", "{http.request.uri.path}/"},
155
+ }
156
159
- fileType, _ := repl.Get("http.matchers.file.type")
160
- if fileType != tc.expectedType {
161
- t.Errorf("Test %d: actual file type: %v, expected: %v", i, fileType, tc.expectedType)
162
- }
157
+ u, err := url.Parse(tc.path)
158
+ if err != nil {
159
+ t.Errorf("Test %d: parsing path: %v", i, err)
160
+ }
161
+
162
+ req := &http.Request{URL: u}
163
+ repl := caddyhttp.NewTestReplacer(req)
164
+
165
+ result, err := m.MatchWithError(req)
166
+ if err != nil {
167
+ t.Errorf("Test %d: unexpected error: %v", i, err)
168
+ }
169
+ if result != tc.matched {
170
+ t.Errorf("Test %d: expected match=%t, got %t", i, tc.matched, result)
171
+ }
172
+
173
+ rel, ok := repl.Get("http.matchers.file.relative")
174
+ if !ok && result {
175
+ t.Errorf("Test %d: expected replacer value", i)
176
+ }
177
+ if !result {
178
+ return
179
+ }
180
+
181
+ if rel != tc.expectedPath {
182
+ t.Errorf("Test %d: actual path: %v, expected: %v", i, rel, tc.expectedPath)
183
+ }
184
+
185
+ fileType, _ := repl.Get("http.matchers.file.type")
186
+ if fileType != tc.expectedType {
187
+ t.Errorf("Test %d: actual file type: %v, expected: %v", i, fileType, tc.expectedType)
188
}
189
}
190