mirror of
https://github.com/zebrajr/node.git
synced 2025-12-06 12:20:27 +01:00
PR-URL: https://github.com/nodejs/node/pull/55063 Reviewed-By: Filip Skokan <panva.ip@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
100 lines
3.4 KiB
JavaScript
100 lines
3.4 KiB
JavaScript
"use strict";
|
|
|
|
const kTestChars = "ABC~‾¥≈¤・・•∙·☼★星🌟星★☼·∙•・・¤≈¥‾~XYZ";
|
|
|
|
// formDataPostFileUploadTest - verifies multipart upload structure and
|
|
// numeric character reference replacement for filenames, field names,
|
|
// and field values using FormData and fetch().
|
|
//
|
|
// Uses /fetch/api/resources/echo-content.py to echo the upload
|
|
// POST (unlike in send-file-form-helper.js, here we expect all
|
|
// multipart/form-data request bodies to be UTF-8, so we don't need to
|
|
// escape controls and non-ASCII bytes).
|
|
//
|
|
// Fields in the parameter object:
|
|
//
|
|
// - fileNameSource: purely explanatory and gives a clue about which
|
|
// character encoding is the source for the non-7-bit-ASCII parts of
|
|
// the fileBaseName, or Unicode if no smaller-than-Unicode source
|
|
// contains all the characters. Used in the test name.
|
|
// - fileBaseName: the not-necessarily-just-7-bit-ASCII file basename
|
|
// used for the constructed test file. Used in the test name.
|
|
const formDataPostFileUploadTest = ({
|
|
fileNameSource,
|
|
fileBaseName,
|
|
}) => {
|
|
promise_test(async (testCase) => {
|
|
const formData = new FormData();
|
|
let file = new Blob([kTestChars], { type: "text/plain" });
|
|
try {
|
|
// Switch to File in browsers that allow this
|
|
file = new File([file], fileBaseName, { type: file.type });
|
|
} catch (ignoredException) {
|
|
}
|
|
|
|
// Used to verify that the browser agrees with the test about
|
|
// field value replacement and encoding independently of file system
|
|
// idiosyncrasies.
|
|
formData.append("filename", fileBaseName);
|
|
|
|
// Same, but with name and value reversed to ensure field names
|
|
// get the same treatment.
|
|
formData.append(fileBaseName, "filename");
|
|
|
|
formData.append("file", file, fileBaseName);
|
|
|
|
const formDataText = await (await fetch(
|
|
`/fetch/api/resources/echo-content.py`,
|
|
{
|
|
method: "POST",
|
|
body: formData,
|
|
},
|
|
)).text();
|
|
const formDataLines = formDataText.split("\r\n");
|
|
if (formDataLines.length && !formDataLines[formDataLines.length - 1]) {
|
|
--formDataLines.length;
|
|
}
|
|
assert_greater_than(
|
|
formDataLines.length,
|
|
2,
|
|
`${fileBaseName}: multipart form data must have at least 3 lines: ${
|
|
JSON.stringify(formDataText)
|
|
}`,
|
|
);
|
|
const boundary = formDataLines[0];
|
|
assert_equals(
|
|
formDataLines[formDataLines.length - 1],
|
|
boundary + "--",
|
|
`${fileBaseName}: multipart form data must end with ${boundary}--: ${
|
|
JSON.stringify(formDataText)
|
|
}`,
|
|
);
|
|
|
|
const asValue = fileBaseName.replace(/\r\n?|\n/g, "\r\n");
|
|
const asName = asValue.replace(/[\r\n"]/g, encodeURIComponent);
|
|
const asFilename = fileBaseName.replace(/[\r\n"]/g, encodeURIComponent);
|
|
const expectedText = [
|
|
boundary,
|
|
'Content-Disposition: form-data; name="filename"',
|
|
"",
|
|
asValue,
|
|
boundary,
|
|
`Content-Disposition: form-data; name="${asName}"`,
|
|
"",
|
|
"filename",
|
|
boundary,
|
|
`Content-Disposition: form-data; name="file"; ` +
|
|
`filename="${asFilename}"`,
|
|
"Content-Type: text/plain",
|
|
"",
|
|
kTestChars,
|
|
boundary + "--",
|
|
].join("\r\n");
|
|
|
|
assert_true(
|
|
formDataText.startsWith(expectedText),
|
|
`Unexpected multipart-shaped form data received:\n${formDataText}\nExpected:\n${expectedText}`,
|
|
);
|
|
}, `Upload ${fileBaseName} (${fileNameSource}) in fetch with FormData`);
|
|
};
|