summaryrefslogtreecommitdiff
path: root/cli/js/web/fetch.ts
diff options
context:
space:
mode:
authorcrowlKats <crowlkats@gmail.com>2020-03-17 07:32:43 +0100
committerGitHub <noreply@github.com>2020-03-17 02:32:43 -0400
commit9833975ef21afced84c6a16724ce13d026f09298 (patch)
tree1a9d76a9bd12c70d362d6feafc37515c66c446c0 /cli/js/web/fetch.ts
parentf9557a4ff6b73a4af37e713bb6b2294253c7b230 (diff)
feat: fetch should accept a FormData body (#4363)
Diffstat (limited to 'cli/js/web/fetch.ts')
-rw-r--r--cli/js/web/fetch.ts42
1 files changed, 41 insertions, 1 deletions
diff --git a/cli/js/web/fetch.ts b/cli/js/web/fetch.ts
index acf0bad0f..7ab68d2e4 100644
--- a/cli/js/web/fetch.ts
+++ b/cli/js/web/fetch.ts
@@ -13,6 +13,7 @@ import { FormData } from "./form_data.ts";
import { URL } from "./url.ts";
import { URLSearchParams } from "./url_search_params.ts";
import { fetch as opFetch, FetchResponse } from "../ops/fetch.ts";
+import { DomFileImpl } from "./dom_file.ts";
function getHeaderValueParams(value: string): Map<string, string> {
const params = new Map();
@@ -499,8 +500,47 @@ export async function fetch(
} else if (init.body instanceof DenoBlob) {
body = init.body[blobBytesSymbol];
contentType = init.body.type;
+ } else if (init.body instanceof FormData) {
+ let boundary = "";
+ if (headers.has("content-type")) {
+ const params = getHeaderValueParams("content-type");
+ if (params.has("boundary")) {
+ boundary = params.get("boundary")!;
+ }
+ }
+ if (!boundary) {
+ boundary =
+ "----------" +
+ Array.from(Array(32))
+ .map(() => Math.random().toString(36)[2] || 0)
+ .join("");
+ }
+
+ let payload = "";
+ for (const [fieldName, fieldValue] of init.body.entries()) {
+ let part = `\r\n--${boundary}\r\n`;
+ part += `Content-Disposition: form-data; name=\"${fieldName}\"`;
+ if (fieldValue instanceof DomFileImpl) {
+ part += `; filename=\"${fieldValue.name}\"`;
+ }
+ part += "\r\n";
+ if (fieldValue instanceof DomFileImpl) {
+ part += `Content-Type: ${fieldValue.type ||
+ "application/octet-stream"}\r\n`;
+ }
+ part += "\r\n";
+ if (fieldValue instanceof DomFileImpl) {
+ part += new TextDecoder().decode(fieldValue[blobBytesSymbol]);
+ } else {
+ part += fieldValue;
+ }
+ payload += part;
+ }
+ payload += `\r\n--${boundary}--`;
+ body = new TextEncoder().encode(payload);
+ contentType = "multipart/form-data; boundary=" + boundary;
} else {
- // TODO: FormData, ReadableStream
+ // TODO: ReadableStream
notImplemented();
}
if (contentType && !headers.has("content-type")) {