2020-01-02 15:13:47 -05:00
|
|
|
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
2019-02-10 18:49:48 -05:00
|
|
|
|
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,
|
2020-03-28 13:03:49 -04:00
|
|
|
assertThrowsAsync,
|
2019-03-06 16:39:50 -05:00
|
|
|
} from "../testing/asserts.ts";
|
2020-02-11 11:24:27 -05:00
|
|
|
const { test } = Deno;
|
2019-10-16 14:39:33 -04:00
|
|
|
import * as path from "../path/mod.ts";
|
2019-02-10 18:49:48 -05:00
|
|
|
import {
|
2020-01-10 14:29:09 -05:00
|
|
|
FormFile,
|
2019-02-10 18:49:48 -05:00
|
|
|
MultipartReader,
|
|
|
|
MultipartWriter,
|
2020-01-10 14:29:09 -05:00
|
|
|
isFormFile,
|
|
|
|
matchAfterPrefix,
|
2020-03-28 13:03:49 -04:00
|
|
|
scanUntilBoundary,
|
2019-02-10 18:49:48 -05:00
|
|
|
} from "./multipart.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);
|
|
|
|
|
2019-04-24 07:41:23 -04:00
|
|
|
test(function multipartScanUntilBoundary1(): void {
|
2019-02-10 18:49:48 -05:00
|
|
|
const data = `--${boundary}`;
|
2019-05-23 22:04:06 -04:00
|
|
|
const n = scanUntilBoundary(
|
2019-02-10 18:49:48 -05:00
|
|
|
e.encode(data),
|
|
|
|
dashBoundary,
|
|
|
|
nlDashBoundary,
|
|
|
|
0,
|
2019-05-23 22:04:06 -04:00
|
|
|
true
|
2019-02-10 18:49:48 -05:00
|
|
|
);
|
2019-07-07 15:20:41 -04:00
|
|
|
assertEquals(n, Deno.EOF);
|
2019-02-10 18:49:48 -05:00
|
|
|
});
|
|
|
|
|
2019-04-24 07:41:23 -04:00
|
|
|
test(function multipartScanUntilBoundary2(): void {
|
2019-02-10 18:49:48 -05:00
|
|
|
const data = `foo\r\n--${boundary}`;
|
2019-05-23 22:04:06 -04:00
|
|
|
const n = scanUntilBoundary(
|
2019-02-10 18:49:48 -05:00
|
|
|
e.encode(data),
|
|
|
|
dashBoundary,
|
|
|
|
nlDashBoundary,
|
|
|
|
0,
|
2019-05-23 22:04:06 -04:00
|
|
|
true
|
2019-02-10 18:49:48 -05:00
|
|
|
);
|
2019-03-06 19:42:24 -05:00
|
|
|
assertEquals(n, 3);
|
2019-02-10 18:49:48 -05:00
|
|
|
});
|
|
|
|
|
2019-05-23 22:04:06 -04:00
|
|
|
test(function multipartScanUntilBoundary3(): void {
|
|
|
|
const data = `foobar`;
|
|
|
|
const n = scanUntilBoundary(
|
2019-02-10 18:49:48 -05:00
|
|
|
e.encode(data),
|
|
|
|
dashBoundary,
|
|
|
|
nlDashBoundary,
|
|
|
|
0,
|
2019-05-23 22:04:06 -04:00
|
|
|
false
|
2019-02-10 18:49:48 -05:00
|
|
|
);
|
2019-05-23 22:04:06 -04:00
|
|
|
assertEquals(n, data.length);
|
2019-02-10 18:49:48 -05:00
|
|
|
});
|
|
|
|
|
2019-05-23 22:04:06 -04:00
|
|
|
test(function multipartScanUntilBoundary4(): void {
|
|
|
|
const data = `foo\r\n--`;
|
|
|
|
const n = scanUntilBoundary(
|
2019-02-10 18:49:48 -05:00
|
|
|
e.encode(data),
|
|
|
|
dashBoundary,
|
|
|
|
nlDashBoundary,
|
|
|
|
0,
|
2019-05-23 22:04:06 -04:00
|
|
|
false
|
2019-02-10 18:49:48 -05:00
|
|
|
);
|
2019-05-23 22:04:06 -04:00
|
|
|
assertEquals(n, 3);
|
2019-02-10 18:49:48 -05:00
|
|
|
});
|
|
|
|
|
2019-04-24 07:41:23 -04:00
|
|
|
test(function multipartMatchAfterPrefix1(): void {
|
2019-02-10 18:49:48 -05:00
|
|
|
const data = `${boundary}\r`;
|
2019-05-23 22:04:06 -04:00
|
|
|
const v = matchAfterPrefix(e.encode(data), e.encode(boundary), false);
|
2019-03-06 19:42:24 -05:00
|
|
|
assertEquals(v, 1);
|
2019-02-10 18:49:48 -05:00
|
|
|
});
|
|
|
|
|
2019-04-24 07:41:23 -04:00
|
|
|
test(function multipartMatchAfterPrefix2(): void {
|
2019-02-10 18:49:48 -05:00
|
|
|
const data = `${boundary}hoge`;
|
2019-05-23 22:04:06 -04:00
|
|
|
const v = matchAfterPrefix(e.encode(data), e.encode(boundary), false);
|
2019-03-06 19:42:24 -05:00
|
|
|
assertEquals(v, -1);
|
2019-02-10 18:49:48 -05:00
|
|
|
});
|
|
|
|
|
2019-04-24 07:41:23 -04:00
|
|
|
test(function multipartMatchAfterPrefix3(): void {
|
2019-02-10 18:49:48 -05:00
|
|
|
const data = `${boundary}`;
|
2019-05-23 22:04:06 -04:00
|
|
|
const v = matchAfterPrefix(e.encode(data), e.encode(boundary), false);
|
2019-03-06 19:42:24 -05:00
|
|
|
assertEquals(v, 0);
|
2019-02-10 18:49:48 -05:00
|
|
|
});
|
|
|
|
|
2019-04-24 07:41:23 -04:00
|
|
|
test(async function multipartMultipartWriter(): Promise<void> {
|
2019-02-10 18:49:48 -05:00
|
|
|
const buf = new Buffer();
|
|
|
|
const mw = new MultipartWriter(buf);
|
|
|
|
await mw.writeField("foo", "foo");
|
|
|
|
await mw.writeField("bar", "bar");
|
2020-01-10 14:29:09 -05:00
|
|
|
const f = await open(path.resolve("./mime/testdata/sample.txt"), "r");
|
2019-02-10 18:49:48 -05:00
|
|
|
await mw.writeFile("file", "sample.txt", f);
|
|
|
|
await mw.close();
|
2020-03-18 19:25:55 -04:00
|
|
|
f.close();
|
2019-02-10 18:49:48 -05:00
|
|
|
});
|
|
|
|
|
2019-04-24 07:41:23 -04:00
|
|
|
test(function multipartMultipartWriter2(): void {
|
2019-02-10 18:49:48 -05:00
|
|
|
const w = new StringWriter();
|
2019-03-06 16:39:50 -05:00
|
|
|
assertThrows(
|
2019-04-24 07:41:23 -04:00
|
|
|
(): MultipartWriter => new MultipartWriter(w, ""),
|
2019-02-10 18:49:48 -05:00
|
|
|
Error,
|
|
|
|
"invalid boundary length"
|
|
|
|
);
|
2019-03-06 16:39:50 -05:00
|
|
|
assertThrows(
|
2019-04-24 07:41:23 -04:00
|
|
|
(): MultipartWriter =>
|
2019-02-10 18:49:48 -05:00
|
|
|
new MultipartWriter(
|
|
|
|
w,
|
2019-06-19 00:22:01 -04:00
|
|
|
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" +
|
|
|
|
"aaaaaaaa"
|
2019-02-10 18:49:48 -05:00
|
|
|
),
|
|
|
|
Error,
|
|
|
|
"invalid boundary length"
|
|
|
|
);
|
2019-03-06 16:39:50 -05:00
|
|
|
assertThrows(
|
2019-04-24 07:41:23 -04:00
|
|
|
(): MultipartWriter => new MultipartWriter(w, "aaa aaa"),
|
2019-02-10 18:49:48 -05:00
|
|
|
Error,
|
|
|
|
"invalid boundary character"
|
|
|
|
);
|
2019-03-06 16:39:50 -05:00
|
|
|
assertThrows(
|
2019-04-24 07:41:23 -04:00
|
|
|
(): MultipartWriter => new MultipartWriter(w, "boundary¥¥"),
|
2019-02-10 18:49:48 -05:00
|
|
|
Error,
|
|
|
|
"invalid boundary character"
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
2019-04-24 07:41:23 -04:00
|
|
|
test(async function multipartMultipartWriter3(): Promise<void> {
|
2019-02-10 18:49:48 -05:00
|
|
|
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-04-24 07:41:23 -04:00
|
|
|
async (): Promise<void> => {
|
2019-02-10 18:49:48 -05:00
|
|
|
await mw.close();
|
|
|
|
},
|
|
|
|
Error,
|
|
|
|
"closed"
|
|
|
|
);
|
2019-03-06 16:39:50 -05:00
|
|
|
await assertThrowsAsync(
|
2019-04-24 07:41:23 -04:00
|
|
|
async (): Promise<void> => {
|
2019-05-30 08:59:30 -04:00
|
|
|
// @ts-ignore
|
2019-02-10 18:49:48 -05:00
|
|
|
await mw.writeFile("bar", "file", null);
|
|
|
|
},
|
|
|
|
Error,
|
|
|
|
"closed"
|
|
|
|
);
|
2019-03-06 16:39:50 -05:00
|
|
|
await assertThrowsAsync(
|
2019-04-24 07:41:23 -04:00
|
|
|
async (): Promise<void> => {
|
2019-02-10 18:49:48 -05:00
|
|
|
await mw.writeField("bar", "bar");
|
|
|
|
},
|
|
|
|
Error,
|
|
|
|
"closed"
|
|
|
|
);
|
2019-03-06 16:39:50 -05:00
|
|
|
assertThrows(
|
2019-04-24 07:41:23 -04:00
|
|
|
(): void => {
|
2019-02-10 18:49:48 -05:00
|
|
|
mw.createFormField("bar");
|
|
|
|
},
|
|
|
|
Error,
|
|
|
|
"closed"
|
|
|
|
);
|
2019-03-06 16:39:50 -05:00
|
|
|
assertThrows(
|
2019-04-24 07:41:23 -04:00
|
|
|
(): void => {
|
2019-02-10 18:49:48 -05:00
|
|
|
mw.createFormFile("bar", "file");
|
|
|
|
},
|
|
|
|
Error,
|
|
|
|
"closed"
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
2019-04-24 07:41:23 -04:00
|
|
|
test(async function multipartMultipartReader(): Promise<void> {
|
2019-02-10 18:49:48 -05:00
|
|
|
// FIXME: path resolution
|
2020-01-10 14:29:09 -05:00
|
|
|
const o = await open(path.resolve("./mime/testdata/sample.txt"));
|
2019-02-10 18:49:48 -05:00
|
|
|
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);
|
2020-03-18 19:25:55 -04:00
|
|
|
o.close();
|
2019-02-10 18:49:48 -05:00
|
|
|
});
|
|
|
|
|
2019-04-24 07:41:23 -04:00
|
|
|
test(async function multipartMultipartReader2(): Promise<void> {
|
2020-01-10 14:29:09 -05:00
|
|
|
const o = await open(path.resolve("./mime/testdata/sample.txt"));
|
2019-02-10 18:49:48 -05:00
|
|
|
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");
|
2020-02-07 02:23:38 -05:00
|
|
|
assert(file.tempfile != null);
|
|
|
|
const f = await open(file.tempfile);
|
2019-02-10 18:49:48 -05:00
|
|
|
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;
|
2020-02-07 02:23:38 -05:00
|
|
|
if (file.tempfile) {
|
|
|
|
await remove(file.tempfile);
|
|
|
|
}
|
2020-03-18 19:25:55 -04:00
|
|
|
o.close();
|
2019-02-10 18:49:48 -05:00
|
|
|
}
|
|
|
|
});
|