mirror of
https://github.com/GopeedLab/gopeed.git
synced 2026-11-04 15:49:49 +00:00
188 lines
4.3 KiB
Go
188 lines
4.3 KiB
Go
package http
|
|
|
|
import (
|
|
"testing"
|
|
)
|
|
|
|
// TestParseFilenameWithAmpersand tests the fix for filenames containing & character
|
|
// Issue: filenames with & are HTML-encoded as & and then truncated at the semicolon
|
|
func TestParseFilenameWithAmpersand(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
disposition string
|
|
want string
|
|
}{
|
|
{
|
|
name: "quoted filename with &",
|
|
disposition: `attachment; filename="查询处理&优化.pptx"`,
|
|
want: "查询处理&优化.pptx",
|
|
},
|
|
{
|
|
name: "unquoted filename with &",
|
|
disposition: `attachment; filename=test&file.txt`,
|
|
want: "test&file.txt",
|
|
},
|
|
{
|
|
name: "quoted filename with & and extra params",
|
|
disposition: `attachment; filename="test&file.txt"; charset=utf-8`,
|
|
want: "test&file.txt",
|
|
},
|
|
{
|
|
name: "filename with multiple HTML entities",
|
|
disposition: `attachment; filename="test&<>.txt"`,
|
|
want: "test&<>.txt",
|
|
},
|
|
{
|
|
name: "normal filename without entities",
|
|
disposition: `attachment; filename="normal.txt"`,
|
|
want: "normal.txt",
|
|
},
|
|
{
|
|
name: "filename with actual ampersand (no encoding)",
|
|
disposition: `attachment; filename="test&file.txt"`,
|
|
want: "test&file.txt",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got := parseFilename(tt.disposition)
|
|
if got != tt.want {
|
|
t.Errorf("parseFilename() = %q, want %q", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestFindParamValueEnd tests the helper function for finding parameter value boundaries
|
|
func TestFindParamValueEnd(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
value string
|
|
want int
|
|
}{
|
|
{
|
|
name: "quoted value with semicolon inside",
|
|
value: `"test&file.txt"; charset=utf-8`,
|
|
want: 19, // Position of semicolon after closing quote
|
|
},
|
|
{
|
|
name: "quoted value without semicolon after",
|
|
value: `"test.txt"`,
|
|
want: -1,
|
|
},
|
|
{
|
|
name: "unquoted value with semicolon",
|
|
value: `test.txt; charset=utf-8`,
|
|
want: 8,
|
|
},
|
|
{
|
|
name: "unquoted value without semicolon",
|
|
value: `test.txt`,
|
|
want: -1,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got := findParamValueEnd(tt.value)
|
|
if got != tt.want {
|
|
t.Errorf("findParamValueEnd() = %d, want %d", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestUnescapeHTMLEntities tests HTML entity unescaping
|
|
func TestUnescapeHTMLEntities(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
in string
|
|
want string
|
|
}{
|
|
{
|
|
name: "ampersand",
|
|
in: "test&file.txt",
|
|
want: "test&file.txt",
|
|
},
|
|
{
|
|
name: "less than and greater than",
|
|
in: "<test>.txt",
|
|
want: "<test>.txt",
|
|
},
|
|
{
|
|
name: "quote",
|
|
in: "test"file.txt",
|
|
want: "test\"file.txt",
|
|
},
|
|
{
|
|
name: "multiple entities",
|
|
in: "a&b<c>d"e",
|
|
want: "a&b<c>d\"e",
|
|
},
|
|
{
|
|
name: "no entities",
|
|
in: "normal.txt",
|
|
want: "normal.txt",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got := unescapeHTMLEntities(tt.in)
|
|
if got != tt.want {
|
|
t.Errorf("unescapeHTMLEntities() = %q, want %q", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestAppendFilenameExtension(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
filename string
|
|
contentType string
|
|
want string
|
|
}{
|
|
{
|
|
name: "adds extension from content type",
|
|
filename: "download",
|
|
contentType: "image/png",
|
|
want: "download.png",
|
|
},
|
|
{
|
|
name: "parses MIME parameters",
|
|
filename: "download",
|
|
contentType: "image/png; charset=binary",
|
|
want: "download.png",
|
|
},
|
|
{
|
|
name: "preserves existing extension",
|
|
filename: "download.zip",
|
|
contentType: "application/zip",
|
|
want: "download.zip",
|
|
},
|
|
{
|
|
name: "ignores invalid content type",
|
|
filename: "download",
|
|
contentType: "not a content type",
|
|
want: "download",
|
|
},
|
|
{
|
|
name: "ignores unknown content type",
|
|
filename: "download",
|
|
contentType: "application/x-gopeed-unknown",
|
|
want: "download",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got := appendFilenameExtension(tt.filename, tt.contentType)
|
|
if got != tt.want {
|
|
t.Errorf("appendFilenameExtension() = %q, want %q", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|