Fix S3 filename header escaping
Use an ASCII-only fallback for Content-Disposition filename and RFC 5987 path escaping for filename* so presigned S3 responses keep spaces and Unicode filenames interoperable. Signed-off-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Ludovic <ludovic@probo.com>
This commit is contained in:
@@ -20,6 +20,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3"
|
||||
@@ -118,11 +119,10 @@ func (s *Service) GeneratePresignedURL(
|
||||
) (string, error) {
|
||||
presignClient := s3.NewPresignClient(s.s3Client)
|
||||
|
||||
encodedFilename := url.QueryEscape(file.FileName)
|
||||
contentDisposition := fmt.Sprintf(
|
||||
"attachment; filename=%q; filename*=UTF-8''%s",
|
||||
encodedFilename,
|
||||
encodedFilename,
|
||||
asciiFilename(file.FileName),
|
||||
url.PathEscape(file.FileName),
|
||||
)
|
||||
|
||||
presignedReq, err := presignClient.PresignGetObject(
|
||||
@@ -145,6 +145,22 @@ func (s *Service) GeneratePresignedURL(
|
||||
return presignedReq.URL, nil
|
||||
}
|
||||
|
||||
func asciiFilename(filename string) string {
|
||||
var b strings.Builder
|
||||
b.Grow(len(filename))
|
||||
|
||||
for _, r := range filename {
|
||||
if r < 0x20 || r > 0x7e {
|
||||
b.WriteByte('_')
|
||||
continue
|
||||
}
|
||||
|
||||
b.WriteRune(r)
|
||||
}
|
||||
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// GetFileSize determines the byte size of a seekable io.Reader by seeking to
|
||||
// the end and back. Returns an error if content is not seekable.
|
||||
func GetFileSize(content io.Reader) (int64, error) {
|
||||
|
||||
Reference in New Issue
Block a user