Skip to content

Commit 64f9935

Browse files
Lukasr29shockey
authored andcommitted
improve(tio): extract file name from Content-Disposition (#4035)
* Added extraction of quoted file name from content disposition header * Added extraction of quoted file name from content disposition header - PR Fixes * Added extraction of quoted file name from content disposition header - PR Fixes * Added extraction of quoted file name from content disposition header - PR Fixes
1 parent b3e80cc commit 64f9935

File tree

3 files changed

+39
-5
lines changed

3 files changed

+39
-5
lines changed

src/core/components/response-body.jsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React from "react"
22
import PropTypes from "prop-types"
33
import formatXml from "xml-but-prettier"
44
import lowerCase from "lodash/lowerCase"
5+
import { extractFileNameFromContentDispositionHeader } from "core/utils"
56

67
export default class ResponseBody extends React.Component {
78

@@ -70,12 +71,13 @@ export default class ResponseBody extends React.Component {
7071
let fileName = url.substr(url.lastIndexOf("/") + 1)
7172
let download = [type, fileName, href].join(":")
7273

73-
// Use filename from response header
74+
// Use filename from response header,
75+
// First check if filename is quoted (e.g. contains space), if no, fallback to not quoted check
7476
let disposition = headers["content-disposition"] || headers["Content-Disposition"]
7577
if (typeof disposition !== "undefined") {
76-
let responseFilename = /filename=([^;]*);?/i.exec(disposition)
77-
if (responseFilename !== null && responseFilename.length > 1) {
78-
download = responseFilename[1]
78+
let responseFilename = extractFileNameFromContentDispositionHeader(disposition)
79+
if (responseFilename !== null) {
80+
download = responseFilename
7981
}
8082
}
8183

src/core/utils.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,17 @@ export function mapToList(map, keyNames="key", collectedKeys=Im.Map()) {
342342
return list
343343
}
344344

345+
export function extractFileNameFromContentDispositionHeader(value){
346+
let responseFilename = /filename="([^;]*);?"/i.exec(value)
347+
if (responseFilename === null) {
348+
responseFilename = /filename=([^;]*);?/i.exec(value)
349+
}
350+
if (responseFilename !== null && responseFilename.length > 1) {
351+
return responseFilename[1]
352+
}
353+
return null
354+
}
355+
345356
// PascalCase, aka UpperCamelCase
346357
export function pascalCase(str) {
347358
return upperFirst(camelCase(str))

test/core/utils.js

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ import {
1818
getAcceptControllingResponse,
1919
createDeepLinkPath,
2020
escapeDeepLinkPath,
21-
sanitizeUrl
21+
sanitizeUrl,
22+
extractFileNameFromContentDispositionHeader
2223
} from "core/utils"
2324
import win from "core/window"
2425

@@ -90,6 +91,26 @@ describe("utils", function() {
9091

9192
})
9293

94+
describe("extractFileNameFromContentDispositionHeader", function(){
95+
it("should extract quoted filename", function(){
96+
let cdHeader = "attachment; filename=\"file name.jpg\""
97+
let expectedResult = "file name.jpg"
98+
expect(extractFileNameFromContentDispositionHeader(cdHeader)).toEqual(expectedResult)
99+
})
100+
101+
it("should extract filename", function(){
102+
let cdHeader = "attachment; filename=filename.jpg"
103+
let expectedResult = "filename.jpg"
104+
expect(extractFileNameFromContentDispositionHeader(cdHeader)).toEqual(expectedResult)
105+
})
106+
107+
it("should not extract filename and return null", function(){
108+
let cdHeader = "attachment; no file name provided"
109+
let expectedResult = null
110+
expect(extractFileNameFromContentDispositionHeader(cdHeader)).toEqual(expectedResult)
111+
})
112+
})
113+
93114
describe("validateMaximum", function() {
94115
let errorMessage = "Value must be less than Maximum"
95116

0 commit comments

Comments
 (0)