From 7ce2391203c47f8fc72a893c84efcd6fc682c2e7 Mon Sep 17 00:00:00 2001 From: Andrey Torsunov Date: Tue, 16 Oct 2018 13:23:15 +0300 Subject: [PATCH 1/2] Add support of RFC5987 for Content-Disposition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For example, `attachement; filename*=UTF-8'ru'%D1%81%D0%B2%D0%B5%D0%B4%D0%B5%D0%BD%D0%B8%D1%8F.xlsx` in result will be `сведения.xlsx`. --- src/core/utils.js | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/core/utils.js b/src/core/utils.js index 3323a87dda5..7d10279fa04 100644 --- a/src/core/utils.js +++ b/src/core/utils.js @@ -343,13 +343,27 @@ export function mapToList(map, keyNames="key", collectedKeys=Im.Map()) { } export function extractFileNameFromContentDispositionHeader(value){ - let responseFilename = /filename="([^;]*);?"/i.exec(value) - if (responseFilename === null) { - responseFilename = /filename=([^;]*);?/i.exec(value) - } + let patterns = [ + /filename\*=[^']+'\w*'"([^"]+)";?/i, + /filename\*=[^']+'\w*'([^;]+);?/i, + /filename="([^;]*);?"/i, + /filename=([^;]*);?/i + ] + + let responseFilename + patterns.some(regex => { + responseFilename = regex.exec(value) + return responseFilename !== null + }) + if (responseFilename !== null && responseFilename.length > 1) { - return responseFilename[1] + try { + return decodeURIComponent(responseFilename[1]) + } catch(e) { + console.error(e) + } } + return null } @@ -788,4 +802,4 @@ export function numberToString(thing) { } return thing -} \ No newline at end of file +} From cfdc732d5e8164b39b88f1ba8f34edbd33a008b6 Mon Sep 17 00:00:00 2001 From: Andrey Torsunov Date: Tue, 16 Oct 2018 15:12:28 +0300 Subject: [PATCH 2/2] Test of support of RFC5987 in Content-Disposition --- test/core/utils.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/core/utils.js b/test/core/utils.js index 8383c0fe235..06b8b9e0b30 100644 --- a/test/core/utils.js +++ b/test/core/utils.js @@ -109,6 +109,18 @@ describe("utils", function() { let expectedResult = "filename.jpg" expect(extractFileNameFromContentDispositionHeader(cdHeader)).toEqual(expectedResult) }) + + it("should extract quoted filename in utf-8", function(){ + let cdHeader = "attachment; filename*=UTF-8''\"%D1%84%D0%B0%D0%B9%D0%BB.txt\"" + let expectedResult = "файл.txt" + expect(extractFileNameFromContentDispositionHeader(cdHeader)).toEqual(expectedResult) + }) + + it("should extract filename in utf-8", function(){ + let cdHeader = "attachment; filename*=utf-8'ru'%D1%84%D0%B0%D0%B9%D0%BB.txt" + let expectedResult = "файл.txt" + expect(extractFileNameFromContentDispositionHeader(cdHeader)).toEqual(expectedResult) + }) it("should not extract filename and return null", function(){ let cdHeader = "attachment; no file name provided"