fileserver: Fix tests on Windows

This commit is contained in:
Matthew Holt 2026-02-20 11:46:45 -07:00
parent a1081194bf
commit cb436f0a0e
No known key found for this signature in database
2 changed files with 69 additions and 44 deletions

View File

@ -20,7 +20,9 @@ import (
"net/http/httptest"
"net/url"
"os"
"path/filepath"
"runtime"
"strings"
"testing"
"github.com/caddyserver/caddy/v2"
@ -28,6 +30,13 @@ import (
"github.com/caddyserver/caddy/v2/modules/caddyhttp"
)
type testCase struct {
path string
expectedPath string
expectedType string
matched bool
}
func TestFileMatcher(t *testing.T) {
// Windows doesn't like colons in files names
isWindows := runtime.GOOS == "windows"
@ -45,12 +54,7 @@ func TestFileMatcher(t *testing.T) {
f.Close()
}
for i, tc := range []struct {
path string
expectedPath string
expectedType string
matched bool
}{
for i, tc := range []testCase{
{
path: "/foo.txt",
expectedPath: "/foo.txt",
@ -115,51 +119,72 @@ func TestFileMatcher(t *testing.T) {
expectedType: "file",
matched: !isWindows,
},
{
path: "/foodir/secr%5Cet.txt",
expectedPath: "/foodir/secr\\et.txt",
expectedType: "file",
matched: true,
},
} {
m := &MatchFile{
fsmap: &filesystems.FileSystemMap{},
Root: "./testdata",
TryFiles: []string{"{http.request.uri.path}", "{http.request.uri.path}/"},
}
fileMatcherTest(t, i, tc)
}
}
u, err := url.Parse(tc.path)
if err != nil {
t.Errorf("Test %d: parsing path: %v", i, err)
}
func TestFileMatcherNonWindows(t *testing.T) {
if runtime.GOOS == "windows" {
return
}
req := &http.Request{URL: u}
repl := caddyhttp.NewTestReplacer(req)
// this is impossible to test on Windows, but tests a security patch for other platforms
tc := testCase{
path: "/foodir/secr%5Cet.txt",
expectedPath: "/foodir/secr\\et.txt",
expectedType: "file",
matched: true,
}
result, err := m.MatchWithError(req)
if err != nil {
t.Errorf("Test %d: unexpected error: %v", i, err)
}
if result != tc.matched {
t.Errorf("Test %d: expected match=%t, got %t", i, tc.matched, result)
}
f, err := os.Create(filepath.Join("testdata", strings.TrimPrefix(tc.expectedPath, "/")))
if err != nil {
t.Fatalf("could not create test file: %v", err)
}
defer f.Close()
defer os.Remove(f.Name())
rel, ok := repl.Get("http.matchers.file.relative")
if !ok && result {
t.Errorf("Test %d: expected replacer value", i)
}
if !result {
continue
}
fileMatcherTest(t, 0, tc)
}
if rel != tc.expectedPath {
t.Errorf("Test %d: actual path: %v, expected: %v", i, rel, tc.expectedPath)
}
func fileMatcherTest(t *testing.T, i int, tc testCase) {
m := &MatchFile{
fsmap: &filesystems.FileSystemMap{},
Root: "./testdata",
TryFiles: []string{"{http.request.uri.path}", "{http.request.uri.path}/"},
}
fileType, _ := repl.Get("http.matchers.file.type")
if fileType != tc.expectedType {
t.Errorf("Test %d: actual file type: %v, expected: %v", i, fileType, tc.expectedType)
}
u, err := url.Parse(tc.path)
if err != nil {
t.Errorf("Test %d: parsing path: %v", i, err)
}
req := &http.Request{URL: u}
repl := caddyhttp.NewTestReplacer(req)
result, err := m.MatchWithError(req)
if err != nil {
t.Errorf("Test %d: unexpected error: %v", i, err)
}
if result != tc.matched {
t.Errorf("Test %d: expected match=%t, got %t", i, tc.matched, result)
}
rel, ok := repl.Get("http.matchers.file.relative")
if !ok && result {
t.Errorf("Test %d: expected replacer value", i)
}
if !result {
return
}
if rel != tc.expectedPath {
t.Errorf("Test %d: actual path: %v, expected: %v", i, rel, tc.expectedPath)
}
fileType, _ := repl.Get("http.matchers.file.type")
if fileType != tc.expectedType {
t.Errorf("Test %d: actual file type: %v, expected: %v", i, fileType, tc.expectedType)
}
}