diff options
Diffstat (limited to 'cli/js/web/fetch.ts')
-rw-r--r-- | cli/js/web/fetch.ts | 42 |
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")) { |