Skip to content

Commit

Permalink
Content disposition parsing (nodejs#2051)
Browse files Browse the repository at this point in the history
  • Loading branch information
KhafraDev authored and crysmags committed Feb 27, 2024
1 parent 89dbed1 commit 1a7d604
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 13 deletions.
37 changes: 25 additions & 12 deletions lib/core/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -222,40 +222,53 @@ function parseHeaders (headers, obj = {}) {
const key = headers[i].toString().toLowerCase()
let val = obj[key]

const encoding = key.length === 19 && key === 'content-disposition'
? 'latin1'
: 'utf8'

if (!val) {
if (Array.isArray(headers[i + 1])) {
obj[key] = headers[i + 1]
} else {
obj[key] = headers[i + 1].toString(encoding)
obj[key] = headers[i + 1].toString('utf8')
}
} else {
if (!Array.isArray(val)) {
val = [val]
obj[key] = val
}
val.push(headers[i + 1].toString(encoding))
val.push(headers[i + 1].toString('utf8'))
}
}

// See https://github.com/nodejs/node/pull/46528
if ('content-length' in obj && 'content-disposition' in obj) {
obj['content-disposition'] = Buffer.from(obj['content-disposition']).toString('latin1')
}

return obj
}

function parseRawHeaders (headers) {
const ret = []
let hasContentLength = false
let contentDispositionIdx = -1

for (let n = 0; n < headers.length; n += 2) {
const key = headers[n + 0].toString()
const val = headers[n + 1].toString('utf8')

const encoding = key.length === 19 && key.toLowerCase() === 'content-disposition'
? 'latin1'
: 'utf8'

const val = headers[n + 1].toString(encoding)
if (key.length === 14 && (key === 'content-length' || key.toLowerCase() === 'content-length')) {
ret.push(key, val)
hasContentLength = true
} else if (key.length === 19 && (key === 'content-disposition' || key.toLowerCase() === 'content-disposition')) {
contentDispositionIdx = ret.push(key, val) - 1
} else {
ret.push(key, val)
}
}

ret.push(key, val)
// See https://github.com/nodejs/node/pull/46528
if (hasContentLength && contentDispositionIdx !== -1) {
ret[contentDispositionIdx] = Buffer.from(ret[contentDispositionIdx]).toString('latin1')
}

return ret
}

Expand Down
3 changes: 2 additions & 1 deletion test/issue-1903.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
const { createServer } = require('http')
const { test } = require('tap')
const { request } = require('..')
const { nodeMajor } = require('../lib/core/util')

function createPromise () {
const result = {}
Expand All @@ -12,7 +13,7 @@ function createPromise () {
return result
}

test('should parse content-disposition consistencely', async (t) => {
test('should parse content-disposition consistently', { skip: nodeMajor >= 19 }, async (t) => {
t.plan(5)

// create promise to allow server spinup in parallel
Expand Down

0 comments on commit 1a7d604

Please sign in to comment.