2019-02-10 18:49:48 -05:00
|
|
|
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
|
|
|
|
2019-02-26 00:35:50 -05:00
|
|
|
const { Buffer, copy, open, remove } = Deno;
|
2019-03-06 16:39:50 -05:00
|
|
|
import {
|
|
|
|
assert,
|
2019-03-06 19:42:24 -05:00
|
|
|
assertEquals,
|
2019-03-06 16:39:50 -05:00
|
|
|
assertThrows,
|
|
|
|
assertThrowsAsync
|
|
|
|
} from "../testing/asserts.ts";
|
|
|
|
import { test } from "../testing/mod.ts";
|
2019-02-10 18:49:48 -05:00
|
|
|
import {
|
|
|
|
matchAfterPrefix,
|
|
|
|
MultipartReader,
|
|
|
|
MultipartWriter,
|
|
|
|
scanUntilBoundary
|
|
|
|
} from "./multipart.ts";
|
|
|
|
import * as path from "../fs/path.ts";
|
|
|
|
import { FormFile, isFormFile } from "./formfile.ts";
|
|
|
|
import { StringWriter } from "../io/writers.ts";
|
|
|
|
|
|
|
|
const e = new TextEncoder();
|
|
|
|
const boundary = "--abcde";
|
|
|
|
const dashBoundary = e.encode("--" + boundary);
|
|
|
|
const nlDashBoundary = e.encode("\r\n--" + boundary);
|
|
|
|
|
|
|
|
test(function multipartScanUntilBoundary1() {
|
|
|
|
const data = `--${boundary}`;
|
|
|
|
const [n, err] = scanUntilBoundary(
|
|
|
|
e.encode(data),
|
|
|
|
dashBoundary,
|
|
|
|
nlDashBoundary,
|
|
|
|
0,
|
|
|
|
"EOF"
|
|
|
|
);
|
2019-03-06 19:42:24 -05:00
|
|
|
assertEquals(n, 0);
|
|
|
|
assertEquals(err, "EOF");
|
2019-02-10 18:49:48 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
test(function multipartScanUntilBoundary2() {
|
|
|
|
const data = `foo\r\n--${boundary}`;
|
|
|
|
const [n, err] = scanUntilBoundary(
|
|
|
|
e.encode(data),
|
|
|
|
dashBoundary,
|
|
|
|
nlDashBoundary,
|
|
|
|
0,
|
|
|
|
"EOF"
|
|
|
|
);
|
2019-03-06 19:42:24 -05:00
|
|
|
assertEquals(n, 3);
|
|
|
|
assertEquals(err, "EOF");
|
2019-02-10 18:49:48 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
test(function multipartScanUntilBoundary4() {
|
|
|
|
const data = `foo\r\n--`;
|
|
|
|
const [n, err] = scanUntilBoundary(
|
|
|
|
e.encode(data),
|
|
|
|
dashBoundary,
|
|
|
|
nlDashBoundary,
|
|
|
|
0,
|
|
|
|
null
|
|
|
|
);
|
2019-03-06 19:42:24 -05:00
|
|
|
assertEquals(n, 3);
|
|
|
|
assertEquals(err, null);
|
2019-02-10 18:49:48 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
test(function multipartScanUntilBoundary3() {
|
|
|
|
const data = `foobar`;
|
|
|
|
const [n, err] = scanUntilBoundary(
|
|
|
|
e.encode(data),
|
|
|
|
dashBoundary,
|
|
|
|
nlDashBoundary,
|
|
|
|
0,
|
|
|
|
null
|
|
|
|
);
|
2019-03-06 19:42:24 -05:00
|
|
|
assertEquals(n, data.length);
|
|
|
|
assertEquals(err, null);
|
2019-02-10 18:49:48 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
test(function multipartMatchAfterPrefix1() {
|
|
|
|
const data = `${boundary}\r`;
|
|
|
|
const v = matchAfterPrefix(e.encode(data), e.encode(boundary), null);
|
2019-03-06 19:42:24 -05:00
|
|
|
assertEquals(v, 1);
|
2019-02-10 18:49:48 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
test(function multipartMatchAfterPrefix2() {
|
|
|
|
const data = `${boundary}hoge`;
|
|
|
|
const v = matchAfterPrefix(e.encode(data), e.encode(boundary), null);
|
2019-03-06 19:42:24 -05:00
|
|
|
assertEquals(v, -1);
|
2019-02-10 18:49:48 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
test(function multipartMatchAfterPrefix3() {
|
|
|
|
const data = `${boundary}`;
|
|
|
|
const v = matchAfterPrefix(e.encode(data), e.encode(boundary), null);
|
2019-03-06 19:42:24 -05:00
|
|
|
assertEquals(v, 0);
|
2019-02-10 18:49:48 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
test(async function multipartMultipartWriter() {
|
|
|
|
const buf = new Buffer();
|
|
|
|
const mw = new MultipartWriter(buf);
|
|
|
|
await mw.writeField("foo", "foo");
|
|
|
|
await mw.writeField("bar", "bar");
|
|
|
|
const f = await open(path.resolve("./multipart/fixtures/sample.txt"), "r");
|
|
|
|
await mw.writeFile("file", "sample.txt", f);
|
|
|
|
await mw.close();
|
|
|
|
});
|
|
|
|
|
|
|
|
test(function multipartMultipartWriter2() {
|
|
|
|
const w = new StringWriter();
|
2019-03-06 16:39:50 -05:00
|
|
|
assertThrows(
|
2019-02-10 18:49:48 -05:00
|
|
|
() => new MultipartWriter(w, ""),
|
|
|
|
Error,
|
|
|
|
"invalid boundary length"
|
|
|
|
);
|
2019-03-06 16:39:50 -05:00
|
|
|
assertThrows(
|
2019-02-10 18:49:48 -05:00
|
|
|
() =>
|
|
|
|
new MultipartWriter(
|
|
|
|
w,
|
|
|
|
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
|
|
|
|
),
|
|
|
|
Error,
|
|
|
|
"invalid boundary length"
|
|
|
|
);
|
2019-03-06 16:39:50 -05:00
|
|
|
assertThrows(
|
2019-02-10 18:49:48 -05:00
|
|
|
() => new MultipartWriter(w, "aaa aaa"),
|
|
|
|
Error,
|
|
|
|
"invalid boundary character"
|
|
|
|
);
|
2019-03-06 16:39:50 -05:00
|
|
|
assertThrows(
|
2019-02-10 18:49:48 -05:00
|
|
|
() => new MultipartWriter(w, "boundary¥¥"),
|
|
|
|
Error,
|
|
|
|
"invalid boundary character"
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
test(async function multipartMultipartWriter3() {
|
|
|
|
const w = new StringWriter();
|
|
|
|
const mw = new MultipartWriter(w);
|
|
|
|
await mw.writeField("foo", "foo");
|
|
|
|
await mw.close();
|
2019-03-06 16:39:50 -05:00
|
|
|
await assertThrowsAsync(
|
2019-02-10 18:49:48 -05:00
|
|
|
async () => {
|
|
|
|
await mw.close();
|
|
|
|
},
|
|
|
|
Error,
|
|
|
|
"closed"
|
|
|
|
);
|
2019-03-06 16:39:50 -05:00
|
|
|
await assertThrowsAsync(
|
2019-02-10 18:49:48 -05:00
|
|
|
async () => {
|
|
|
|
await mw.writeFile("bar", "file", null);
|
|
|
|
},
|
|
|
|
Error,
|
|
|
|
"closed"
|
|
|
|
);
|
2019-03-06 16:39:50 -05:00
|
|
|
await assertThrowsAsync(
|
2019-02-10 18:49:48 -05:00
|
|
|
async () => {
|
|
|
|
await mw.writeField("bar", "bar");
|
|
|
|
},
|
|
|
|
Error,
|
|
|
|
"closed"
|
|
|
|
);
|
2019-03-06 16:39:50 -05:00
|
|
|
assertThrows(
|
2019-02-10 18:49:48 -05:00
|
|
|
() => {
|
|
|
|
mw.createFormField("bar");
|
|
|
|
},
|
|
|
|
Error,
|
|
|
|
"closed"
|
|
|
|
);
|
2019-03-06 16:39:50 -05:00
|
|
|
assertThrows(
|
2019-02-10 18:49:48 -05:00
|
|
|
() => {
|
|
|
|
mw.createFormFile("bar", "file");
|
|
|
|
},
|
|
|
|
Error,
|
|
|
|
"closed"
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
test(async function multipartMultipartReader() {
|
|
|
|
// FIXME: path resolution
|
|
|
|
const o = await open(path.resolve("./multipart/fixtures/sample.txt"));
|
|
|
|
const mr = new MultipartReader(
|
|
|
|
o,
|
|
|
|
"--------------------------434049563556637648550474"
|
|
|
|
);
|
|
|
|
const form = await mr.readForm(10 << 20);
|
2019-03-06 19:42:24 -05:00
|
|
|
assertEquals(form["foo"], "foo");
|
|
|
|
assertEquals(form["bar"], "bar");
|
2019-02-10 18:49:48 -05:00
|
|
|
const file = form["file"] as FormFile;
|
2019-03-06 19:42:24 -05:00
|
|
|
assertEquals(isFormFile(file), true);
|
2019-03-06 16:39:50 -05:00
|
|
|
assert(file.content !== void 0);
|
2019-02-10 18:49:48 -05:00
|
|
|
});
|
|
|
|
|
|
|
|
test(async function multipartMultipartReader2() {
|
|
|
|
const o = await open(path.resolve("./multipart/fixtures/sample.txt"));
|
|
|
|
const mr = new MultipartReader(
|
|
|
|
o,
|
|
|
|
"--------------------------434049563556637648550474"
|
|
|
|
);
|
|
|
|
const form = await mr.readForm(20); //
|
|
|
|
try {
|
2019-03-06 19:42:24 -05:00
|
|
|
assertEquals(form["foo"], "foo");
|
|
|
|
assertEquals(form["bar"], "bar");
|
2019-02-10 18:49:48 -05:00
|
|
|
const file = form["file"] as FormFile;
|
2019-03-06 19:42:24 -05:00
|
|
|
assertEquals(file.type, "application/octet-stream");
|
2019-02-10 18:49:48 -05:00
|
|
|
const f = await open(file.tempfile);
|
|
|
|
const w = new StringWriter();
|
|
|
|
await copy(w, f);
|
|
|
|
const json = JSON.parse(w.toString());
|
2019-03-06 19:42:24 -05:00
|
|
|
assertEquals(json["compilerOptions"]["target"], "es2018");
|
2019-02-10 18:49:48 -05:00
|
|
|
f.close();
|
|
|
|
} finally {
|
|
|
|
const file = form["file"] as FormFile;
|
|
|
|
await remove(file.tempfile);
|
|
|
|
}
|
|
|
|
});
|