diff options
author | Bartek Iwańczuk <biwanczuk@gmail.com> | 2020-03-05 13:05:41 +0100 |
---|---|---|
committer | Bartek Iwańczuk <biwanczuk@gmail.com> | 2020-03-05 18:48:55 +0100 |
commit | 2e590072148c85bbc479ab49aa9556b0a2cfaff2 (patch) | |
tree | 89747e7b6762158e35f9120ca0ef0fa14991ae34 /cli/js/web/request.ts | |
parent | 9b59ed7c7907c5f365e72b5c5a74114eb8ff1488 (diff) |
move Web APIs to cli/js/web/
Diffstat (limited to 'cli/js/web/request.ts')
-rw-r--r-- | cli/js/web/request.ts | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/cli/js/web/request.ts b/cli/js/web/request.ts new file mode 100644 index 000000000..1416a95d6 --- /dev/null +++ b/cli/js/web/request.ts @@ -0,0 +1,159 @@ +// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. +import * as headers from "./headers.ts"; +import * as body from "./body.ts"; +import * as domTypes from "./dom_types.ts"; +import * as streams from "./streams/mod.ts"; + +const { Headers } = headers; +const { ReadableStream } = streams; + +function byteUpperCase(s: string): string { + return String(s).replace(/[a-z]/g, function byteUpperCaseReplace(c): string { + return c.toUpperCase(); + }); +} + +function normalizeMethod(m: string): string { + const u = byteUpperCase(m); + if ( + u === "DELETE" || + u === "GET" || + u === "HEAD" || + u === "OPTIONS" || + u === "POST" || + u === "PUT" + ) { + return u; + } + return m; +} + +/** + * An HTTP request + * @param {Blob|String} [body] + * @param {Object} [init] + */ +export class Request extends body.Body implements domTypes.Request { + public method: string; + public url: string; + public credentials?: "omit" | "same-origin" | "include"; + public headers: domTypes.Headers; + + constructor(input: domTypes.RequestInfo, init?: domTypes.RequestInit) { + if (arguments.length < 1) { + throw TypeError("Not enough arguments"); + } + + if (!init) { + init = {}; + } + + let b: body.BodySource; + + // prefer body from init + if (init.body) { + b = init.body; + } else if (input instanceof Request && input._bodySource) { + if (input.bodyUsed) { + throw TypeError(body.BodyUsedError); + } + b = input._bodySource; + } else if (typeof input === "object" && "body" in input && input.body) { + if (input.bodyUsed) { + throw TypeError(body.BodyUsedError); + } + b = input.body; + } else { + b = ""; + } + + let headers: domTypes.Headers; + + // prefer headers from init + if (init.headers) { + headers = new Headers(init.headers); + } else if (input instanceof Request) { + headers = input.headers; + } else { + headers = new Headers(); + } + + const contentType = headers.get("content-type") || ""; + super(b, contentType); + this.headers = headers; + + // readonly attribute ByteString method; + /** + * The HTTP request method + * @readonly + * @default GET + * @type {string} + */ + this.method = "GET"; + + // readonly attribute USVString url; + /** + * The request URL + * @readonly + * @type {string} + */ + this.url = ""; + + // readonly attribute RequestCredentials credentials; + this.credentials = "omit"; + + if (input instanceof Request) { + if (input.bodyUsed) { + throw TypeError(body.BodyUsedError); + } + this.method = input.method; + this.url = input.url; + this.headers = new Headers(input.headers); + this.credentials = input.credentials; + this._stream = input._stream; + } else if (typeof input === "string") { + this.url = input; + } + + if (init && "method" in init) { + this.method = normalizeMethod(init.method as string); + } + + if ( + init && + "credentials" in init && + init.credentials && + ["omit", "same-origin", "include"].indexOf(init.credentials) !== -1 + ) { + this.credentials = init.credentials; + } + } + + public clone(): domTypes.Request { + if (this.bodyUsed) { + throw TypeError(body.BodyUsedError); + } + + const iterators = this.headers.entries(); + const headersList: Array<[string, string]> = []; + for (const header of iterators) { + headersList.push(header); + } + + let body2 = this._bodySource; + + if (this._bodySource instanceof ReadableStream) { + const tees = (this._bodySource as domTypes.ReadableStream).tee(); + this._stream = this._bodySource = tees[0]; + body2 = tees[1]; + } + + const cloned = new Request(this.url, { + body: body2, + method: this.method, + headers: new Headers(headersList), + credentials: this.credentials + }); + return cloned; + } +} |