@marcel91200 / caddy Mirror · read-only / commits / cb436f0a
Fork 0

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