mirror of
https://github.com/denoland/deno.git
synced 2025-10-03 15:44:36 +00:00
Fix MultipartReader for big files (#4865)
This commit is contained in:
parent
d308e8d0c0
commit
78e0ae643c
2 changed files with 34 additions and 21 deletions
|
@ -308,7 +308,7 @@ export class MultipartReader {
|
||||||
}
|
}
|
||||||
// file
|
// file
|
||||||
let formFile: FormFile | undefined;
|
let formFile: FormFile | undefined;
|
||||||
const n = await copy(p, buf);
|
const n = await copyN(p, buf, maxValueBytes);
|
||||||
const contentType = p.headers.get("content-type");
|
const contentType = p.headers.get("content-type");
|
||||||
assert(contentType != null, "content-type must be set");
|
assert(contentType != null, "content-type must be set");
|
||||||
if (n > maxMemory) {
|
if (n > maxMemory) {
|
||||||
|
@ -319,11 +319,8 @@ export class MultipartReader {
|
||||||
postfix: ext,
|
postfix: ext,
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
const size = await copyN(
|
const size = await copy(new MultiReader(buf, p), file);
|
||||||
new MultiReader(buf, p),
|
|
||||||
file,
|
|
||||||
maxValueBytes
|
|
||||||
);
|
|
||||||
file.close();
|
file.close();
|
||||||
formFile = {
|
formFile = {
|
||||||
filename: p.fileName,
|
filename: p.fileName,
|
||||||
|
@ -333,6 +330,7 @@ export class MultipartReader {
|
||||||
};
|
};
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
await remove(filepath);
|
await remove(filepath);
|
||||||
|
throw e;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
formFile = {
|
formFile = {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
const { Buffer, copy, open, test } = Deno;
|
const { Buffer, open, test } = Deno;
|
||||||
import {
|
import {
|
||||||
assert,
|
assert,
|
||||||
assertEquals,
|
assertEquals,
|
||||||
|
@ -21,6 +21,7 @@ const e = new TextEncoder();
|
||||||
const boundary = "--abcde";
|
const boundary = "--abcde";
|
||||||
const dashBoundary = e.encode("--" + boundary);
|
const dashBoundary = e.encode("--" + boundary);
|
||||||
const nlDashBoundary = e.encode("\r\n--" + boundary);
|
const nlDashBoundary = e.encode("\r\n--" + boundary);
|
||||||
|
const testdataDir = path.resolve("mime", "testdata");
|
||||||
|
|
||||||
test("multipartScanUntilBoundary1", function (): void {
|
test("multipartScanUntilBoundary1", function (): void {
|
||||||
const data = `--${boundary}`;
|
const data = `--${boundary}`;
|
||||||
|
@ -192,29 +193,43 @@ test({
|
||||||
});
|
});
|
||||||
|
|
||||||
test({
|
test({
|
||||||
name: "[mime/multipart] readForm() should store big file in temp file",
|
name:
|
||||||
|
"[mime/multipart] readForm() should store big file completely in temp file",
|
||||||
async fn() {
|
async fn() {
|
||||||
const o = await open(path.resolve("./mime/testdata/sample.txt"));
|
const multipartFile = path.join(testdataDir, "form-data.dat");
|
||||||
const mr = new MultipartReader(
|
const sampleFile = await Deno.makeTempFile();
|
||||||
o,
|
const writer = await open(multipartFile, { write: true, create: true });
|
||||||
"--------------------------434049563556637648550474"
|
|
||||||
);
|
const size = 1 << 24; // 16mb
|
||||||
|
|
||||||
|
await Deno.truncate(sampleFile, size);
|
||||||
|
const bigFile = await open(sampleFile, { read: true });
|
||||||
|
|
||||||
|
const mw = new MultipartWriter(writer);
|
||||||
|
await mw.writeField("deno", "land");
|
||||||
|
await mw.writeField("bar", "bar");
|
||||||
|
await mw.writeFile("file", "sample.bin", bigFile);
|
||||||
|
|
||||||
|
await mw.close();
|
||||||
|
writer.close();
|
||||||
|
bigFile.close();
|
||||||
|
|
||||||
|
const o = await Deno.open(multipartFile);
|
||||||
|
const mr = new MultipartReader(o, mw.boundary);
|
||||||
// use low-memory to write "file" into temp file.
|
// use low-memory to write "file" into temp file.
|
||||||
const form = await mr.readForm(20);
|
const form = await mr.readForm(20);
|
||||||
try {
|
try {
|
||||||
assertEquals(form.value("foo"), "foo");
|
assertEquals(form.value("deno"), "land");
|
||||||
assertEquals(form.value("bar"), "bar");
|
assertEquals(form.value("bar"), "bar");
|
||||||
const file = form.file("file");
|
const file = form.file("file");
|
||||||
assert(file != null);
|
assert(file != null);
|
||||||
assertEquals(file.type, "application/octet-stream");
|
|
||||||
assert(file.tempfile != null);
|
assert(file.tempfile != null);
|
||||||
const f = await open(file.tempfile);
|
assertEquals(file.size, size);
|
||||||
const w = new StringWriter();
|
assertEquals(file.type, "application/octet-stream");
|
||||||
await copy(f, w);
|
// TODO checksum of tmp & sampleFile
|
||||||
const json = JSON.parse(w.toString());
|
|
||||||
assertEquals(json["compilerOptions"]["target"], "es2018");
|
|
||||||
f.close();
|
|
||||||
} finally {
|
} finally {
|
||||||
|
await Deno.remove(multipartFile);
|
||||||
|
await Deno.remove(sampleFile);
|
||||||
await form.removeAll();
|
await form.removeAll();
|
||||||
o.close();
|
o.close();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue