fix: decode URL-encoded filename from contentDisposition header (#1099)

This commit is contained in:
Krau authored and GitHub committed 2025-09-04 18:22:30 +08:00
1 parent 55e6bdc4f7
commit cfdcb586ee
3 files changed
+34 -2

No files matched your search

+3 -2
View File
@@ -23,6 +23,7 @@ import (
"github.com/GopeedLab/gopeed/internal/fetcher"
"github.com/GopeedLab/gopeed/pkg/base"
fhttp "github.com/GopeedLab/gopeed/pkg/protocol/http"
"github.com/GopeedLab/gopeed/pkg/util"
"github.com/xiaoqidun/setft"
"golang.org/x/sync/errgroup"
)
@@ -172,13 +173,13 @@ func (f *Fetcher) Resolve(req *base.Request) error {
filename = strings.Replace(filename, "UTF8", "UTF-8", 1)
file.Name, _ = decoder.Decode(filename)
} else {
file.Name = filename
file.Name = util.TryUrlQueryUnescape(filename)
}
} else {
substr := "attachment; filename="
index := strings.Index(contentDisposition, substr)
if index != -1 {
file.Name = contentDisposition[index+len(substr):]
file.Name = util.TryUrlQueryUnescape(contentDisposition[index+len(substr):])
}
}
}
+10
View File
@@ -56,3 +56,13 @@ func ProxyUrlToHandler(proxyUrl *url.URL) func(*http.Request) (*url.URL, error)
}
return http.ProxyURL(proxyUrl)
}
// TryUrlQueryUnescape tries to unescape a URL-encoded string.
//
// If unescaping fails, it returns the original string.
func TryUrlQueryUnescape(s string) string {
if decoded, err := url.QueryUnescape(s); err == nil {
return decoded
}
return s
}
+21
View File
@@ -128,3 +128,24 @@ func TestParseDataUri(t *testing.T) {
})
}
}
func TestTryURLDecode(t *testing.T) {
tests := []struct {
input string
expected string
}{
{"normal.txt", "normal.txt"},
{"%E7%8F%80%E5%B0%94%E8%AF%BA.zip", "珀尔诺.zip"},
{"hello%20world.txt", "hello world.txt"},
{"bad%2-text", "bad%2-text"},
}
for _, tt := range tests {
t.Run(tt.input, func(t *testing.T) {
got := TryUrlQueryUnescape(tt.input)
if got != tt.expected {
t.Errorf("TryUrlQueryUnescape(%q) = %q, want %q", tt.input, got, tt.expected)
}
})
}
}