From fdeccc23b510bda706f5b62921a72ecdc593bda4 Mon Sep 17 00:00:00 2001 From: Khafra Date: Thu, 19 Sep 2024 21:27:17 -0400 Subject: [PATCH] append crlf to formdata body (#3625) * append crlf to formdata body * fixup! v18 --- lib/web/fetch/body.js | 5 ++++- test/fetch/issue-3624.js | 29 +++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 test/fetch/issue-3624.js diff --git a/lib/web/fetch/body.js b/lib/web/fetch/body.js index 683a67400c8..9de2a7e41b9 100644 --- a/lib/web/fetch/body.js +++ b/lib/web/fetch/body.js @@ -152,7 +152,10 @@ function extractBody (object, keepalive = false) { } } - const chunk = textEncoder.encode(`--${boundary}--`) + // CRLF is appended to the body to function with legacy servers and match other implementations. + // https://github.com/curl/curl/blob/3434c6b46e682452973972e8313613dfa58cd690/lib/mime.c#L1029-L1030 + // https://github.com/form-data/form-data/issues/63 + const chunk = textEncoder.encode(`--${boundary}--\r\n`) blobParts.push(chunk) length += chunk.byteLength if (hasUnknownSizeValue) { diff --git a/test/fetch/issue-3624.js b/test/fetch/issue-3624.js new file mode 100644 index 00000000000..37e722d7e4e --- /dev/null +++ b/test/fetch/issue-3624.js @@ -0,0 +1,29 @@ +'use strict' + +const assert = require('node:assert') +const { File } = require('node:buffer') +const { test } = require('node:test') +const { once } = require('node:events') +const { createServer } = require('node:http') +const { fetch, FormData } = require('../..') + +// https://github.com/nodejs/undici/issues/3624 +test('crlf is appended to formdata body (issue #3624)', async (t) => { + const server = createServer((req, res) => { + req.pipe(res) + }).listen(0) + + t.after(server.close.bind(server)) + await once(server, 'listening') + + const fd = new FormData() + fd.set('a', 'b') + fd.set('c', new File(['d'], 'd.txt.exe'), 'd.txt.exe') + + const response = await fetch(`http://localhost:${server.address().port}`, { + body: fd, + method: 'POST' + }) + + assert((await response.text()).endsWith('\r\n')) +})