Initial commit

This commit is contained in:
2026-09-12 23:26:07 +02:00
commit a180fe4b52
35 changed files with 4921 additions and 0 deletions
+84
View File
@@ -0,0 +1,84 @@
package server
import (
"mime"
"strings"
"testing"
)
// Content-Disposition is the header that keeps an uploaded file from being
// rendered, so it has to survive whatever a filename throws at it.
func TestContentDisposition(t *testing.T) {
cases := []struct {
name string
wantASCII string
wantExt bool // expect an RFC 5987 filename* parameter too
}{
{"MyGame.zip", "MyGame.zip", false},
{"notes (draft).txt", "notes (draft).txt", false},
{`quo"te.txt`, "quo_te.txt", true},
{`back\slash.txt`, "back_slash.txt", true},
{"naïve.txt", "na_ve.txt", true},
{"日本語.bin", "___.bin", true},
{"🙂.png", "_.png", true},
}
for _, c := range cases {
got := contentDisposition(c.name)
// It must always parse, and always be an attachment.
disp, params, err := mime.ParseMediaType(got)
if err != nil {
t.Errorf("contentDisposition(%q) = %q: does not parse: %v", c.name, got, err)
continue
}
if disp != "attachment" {
t.Errorf("contentDisposition(%q): disposition = %q", c.name, disp)
}
// Whatever the encoding, the decoded filename must be the real one when
// an extended parameter is present.
if c.wantExt {
if !strings.Contains(got, "filename*=UTF-8''") {
t.Errorf("contentDisposition(%q) = %q: no RFC 5987 parameter", c.name, got)
}
if params["filename"] != c.name {
t.Errorf("contentDisposition(%q): decoded filename = %q", c.name, params["filename"])
}
} else if params["filename"] != c.wantASCII {
t.Errorf("contentDisposition(%q): filename = %q, want %q", c.name, params["filename"], c.wantASCII)
}
// Nothing may break out of the header, in any spelling.
if strings.ContainsAny(got, "\r\n") {
t.Errorf("contentDisposition(%q) = %q: contains a line break", c.name, got)
}
if i := strings.Index(got, `filename="`); i >= 0 {
quoted := got[i+len(`filename="`):]
quoted = quoted[:strings.Index(quoted, `"`)]
if strings.ContainsAny(quoted, `"\`) {
t.Errorf("contentDisposition(%q): unescaped quoting in %q", c.name, quoted)
}
}
}
}
func TestASCIIFilenameNeverEmpty(t *testing.T) {
for _, in := range []string{"", "...", "___", " ", "🙂"} {
if got := asciiFilename(in); strings.Trim(got, "_. ") == "" {
t.Errorf("asciiFilename(%q) = %q, which names nothing", in, got)
}
}
}
func TestEncodeRFC5987(t *testing.T) {
cases := map[string]string{
"plain.txt": "plain.txt",
"a b.txt": "a%20b.txt",
"naïve": "na%C3%AFve",
`q"x`: "q%22x",
}
for in, want := range cases {
if got := encodeRFC5987(in); got != want {
t.Errorf("encodeRFC5987(%q) = %q, want %q", in, got, want)
}
}
}