Skip to content

Commit dbbe0a2

Browse files
append crlf to formdata body (#3625) (#4210)
* append crlf to formdata body * fixup! v18 (cherry picked from commit fdeccc2) Co-authored-by: Khafra <[email protected]>
1 parent b63d939 commit dbbe0a2

File tree

2 files changed

+33
-1
lines changed

2 files changed

+33
-1
lines changed

lib/web/fetch/body.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,10 @@ function extractBody (object, keepalive = false) {
162162
}
163163
}
164164

165-
const chunk = textEncoder.encode(`--${boundary}--`)
165+
// CRLF is appended to the body to function with legacy servers and match other implementations.
166+
// https://github.com/curl/curl/blob/3434c6b46e682452973972e8313613dfa58cd690/lib/mime.c#L1029-L1030
167+
// https://github.com/form-data/form-data/issues/63
168+
const chunk = textEncoder.encode(`--${boundary}--\r\n`)
166169
blobParts.push(chunk)
167170
length += chunk.byteLength
168171
if (hasUnknownSizeValue) {

test/fetch/issue-3624.js

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
'use strict'
2+
3+
const assert = require('node:assert')
4+
const { File } = require('node:buffer')
5+
const { test } = require('node:test')
6+
const { once } = require('node:events')
7+
const { createServer } = require('node:http')
8+
const { fetch, FormData } = require('../..')
9+
10+
// https://github.com/nodejs/undici/issues/3624
11+
test('crlf is appended to formdata body (issue #3624)', async (t) => {
12+
const server = createServer((req, res) => {
13+
req.pipe(res)
14+
}).listen(0)
15+
16+
t.after(server.close.bind(server))
17+
await once(server, 'listening')
18+
19+
const fd = new FormData()
20+
fd.set('a', 'b')
21+
fd.set('c', new File(['d'], 'd.txt.exe'), 'd.txt.exe')
22+
23+
const response = await fetch(`http://localhost:${server.address().port}`, {
24+
body: fd,
25+
method: 'POST'
26+
})
27+
28+
assert((await response.text()).endsWith('\r\n'))
29+
})

0 commit comments

Comments
 (0)