mirror of
https://github.com/denoland/deno.git
synced 2025-03-03 17:34:47 -05:00
fix(ext/formdata): support multiple headers in FormData (#20801)
Fixes https://github.com/denoland/deno/issues/20793
This commit is contained in:
parent
1619932a65
commit
176bf9ba5f
2 changed files with 47 additions and 16 deletions
|
@ -155,3 +155,35 @@ Deno.test(async function bodyArrayBufferMultipleParts() {
|
|||
const body = buildBody(stream);
|
||||
assertEquals((await body.arrayBuffer()).byteLength, size);
|
||||
});
|
||||
|
||||
// https://github.com/denoland/deno/issues/20793
|
||||
Deno.test(
|
||||
{ permissions: { net: true } },
|
||||
async function bodyMultipartFormDataMultipleHeaders() {
|
||||
const boundary = "----formdata-polyfill-0.970665446687947";
|
||||
const payload = [
|
||||
"------formdata-polyfill-0.970665446687947",
|
||||
'Content-Disposition: form-data; name="x"; filename="blob"',
|
||||
"Content-Length: 1",
|
||||
"Content-Type: application/octet-stream",
|
||||
"last-modified: Wed, 04 Oct 2023 20:28:45 GMT",
|
||||
"",
|
||||
"y",
|
||||
"------formdata-polyfill-0.970665446687947--",
|
||||
].join("\r\n");
|
||||
|
||||
const body = buildBody(
|
||||
new TextEncoder().encode(payload),
|
||||
new Headers({
|
||||
"Content-Type": `multipart/form-data; boundary=${boundary}`,
|
||||
}),
|
||||
);
|
||||
|
||||
const formData = await body.formData();
|
||||
const file = formData.get("x");
|
||||
assert(file instanceof File);
|
||||
const text = await file.text();
|
||||
assertEquals(text, "y");
|
||||
assertEquals(file.size, 1);
|
||||
},
|
||||
);
|
||||
|
|
|
@ -448,25 +448,24 @@ class MultipartParser {
|
|||
const prevByte = this.body[i - 1];
|
||||
const isNewLine = byte === LF && prevByte === CR;
|
||||
|
||||
if (state === 1 || state === 2 || state == 3) {
|
||||
if (state === 1) {
|
||||
headerText += StringFromCharCode(byte);
|
||||
}
|
||||
|
||||
if (state === 0 && isNewLine) {
|
||||
state = 1;
|
||||
} else if (state === 1 && isNewLine) {
|
||||
state = 2;
|
||||
const headersDone = this.body[i + 1] === CR &&
|
||||
this.body[i + 2] === LF;
|
||||
|
||||
if (headersDone) {
|
||||
state = 3;
|
||||
} else if (
|
||||
state === 1
|
||||
) {
|
||||
if (
|
||||
isNewLine && this.body[i + 1] === CR &&
|
||||
this.body[i + 2] === LF
|
||||
) {
|
||||
// end of the headers section
|
||||
state = 2;
|
||||
fileStart = i + 3; // After \r\n
|
||||
}
|
||||
} else if (state === 2 && isNewLine) {
|
||||
state = 3;
|
||||
} else if (state === 3 && isNewLine) {
|
||||
state = 4;
|
||||
fileStart = i + 1;
|
||||
} else if (state === 4) {
|
||||
} else if (state === 2) {
|
||||
if (this.boundaryChars[boundaryIndex] !== byte) {
|
||||
boundaryIndex = 0;
|
||||
} else {
|
||||
|
@ -487,7 +486,7 @@ class MultipartParser {
|
|||
const latin1Filename = MapPrototypeGet(disposition, "filename");
|
||||
const latin1Name = MapPrototypeGet(disposition, "name");
|
||||
|
||||
state = 5;
|
||||
state = 3;
|
||||
// Reset
|
||||
boundaryIndex = 0;
|
||||
headerText = "";
|
||||
|
@ -510,7 +509,7 @@ class MultipartParser {
|
|||
formData.append(name, core.decode(content));
|
||||
}
|
||||
}
|
||||
} else if (state === 5 && isNewLine) {
|
||||
} else if (state === 3 && isNewLine) {
|
||||
state = 1;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue