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:
Cursor Agent
2026-06-11 14:12:01 +00:00
parent 732493d054
commit 6794f14a24
2 changed files with 56 additions and 3 deletions

View File

@@ -15,9 +15,16 @@
package filemanager_test
import (
"context"
"net/url"
"testing"
"time"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/credentials"
awss3 "github.com/aws/aws-sdk-go-v2/service/s3"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.probo.inc/probo/pkg/baseurl"
"go.probo.inc/probo/pkg/coredata"
"go.probo.inc/probo/pkg/filemanager"
@@ -65,3 +72,33 @@ func TestGenerateFileURL_PrivateFile(t *testing.T) {
svc.GenerateFileURL(file),
)
}
func TestGeneratePresignedFileURL_EscapesContentDispositionFilename(t *testing.T) {
t.Parallel()
s3Client := awss3.NewFromConfig(
aws.Config{
Region: "us-east-1",
Credentials: credentials.NewStaticCredentialsProvider("access-key", "secret-key", ""),
},
)
svc := filemanager.NewService(nil, nil, s3Client)
file := &coredata.File{
BucketName: "uploads",
FileKey: "tenant/file",
FileName: `report "Q2"/résumé 100%.pdf`,
MimeType: "application/pdf",
}
rawURL, err := svc.GeneratePresignedFileURL(context.Background(), file, time.Hour)
require.NoError(t, err)
parsedURL, err := url.Parse(rawURL)
require.NoError(t, err)
assert.Equal(
t,
`attachment; filename="report \"Q2\"/r_sum_ 100%.pdf"; filename*=UTF-8''report%20%22Q2%22%2Fr%C3%A9sum%C3%A9%20100%25.pdf`,
parsedURL.Query().Get("response-content-disposition"),
)
}