From 399f9325a5384d24853d340c6131ed1c1d6b5757 Mon Sep 17 00:00:00 2001 From: saltbo Date: Wed, 27 May 2026 14:12:15 -0400 Subject: [PATCH] fix(s3): conform to RFC 6266 for ResponseContentDisposition filename encoding --- server/services/s3.test.ts | 2 +- server/services/s3.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/server/services/s3.test.ts b/server/services/s3.test.ts index 85f98066..79b3368c 100644 --- a/server/services/s3.test.ts +++ b/server/services/s3.test.ts @@ -185,7 +185,7 @@ describe('S3Service', () => { expect.anything(), expect.objectContaining({ input: expect.objectContaining({ - ResponseContentDisposition: 'attachment; filename="my%20photo.jpg"', + ResponseContentDisposition: 'attachment; filename="my photo.jpg"; filename*=UTF-8\'\'my%20photo.jpg', }), }), expect.anything(), diff --git a/server/services/s3.ts b/server/services/s3.ts index 743f7226..06612a5a 100644 --- a/server/services/s3.ts +++ b/server/services/s3.ts @@ -57,7 +57,7 @@ export class S3Service { const command = new GetObjectCommand({ Bucket: storage.bucket, Key: key, - ResponseContentDisposition: `attachment; filename="${encodeURIComponent(filename)}"`, + ResponseContentDisposition: `attachment; filename="${filename.replace(/"/g, '\\"')}"; filename*=UTF-8''${encodeURIComponent(filename)}`, }) const url = await getSignedUrl(client, command, { expiresIn }) return this.applyCustomHost(storage, url)