diff options
author | Divy Srivastava <dj.srivastava23@gmail.com> | 2022-08-18 17:35:02 +0530 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-08-18 17:35:02 +0530 |
commit | cd21cff29942f24ba7d38287186cce64d0e84e56 (patch) | |
tree | e663eff884526ee762ae9141a3cf5a0f6967a84e /ext/fetch | |
parent | 0b0843e4a54d7c1ddf293ac1ccee2479b69a5ba9 (diff) |
feat(ext/flash): An optimized http/1.1 server (#15405)
Co-authored-by: Bartek IwaĆczuk <biwanczuk@gmail.com>
Co-authored-by: Ben Noordhuis <info@bnoordhuis.nl>
Co-authored-by: crowlkats <crowlkats@toaxl.com>
Co-authored-by: Ryan Dahl <ry@tinyclouds.org>
Diffstat (limited to 'ext/fetch')
-rw-r--r-- | ext/fetch/22_body.js | 16 | ||||
-rw-r--r-- | ext/fetch/23_request.js | 77 | ||||
-rw-r--r-- | ext/fetch/23_response.js | 20 |
3 files changed, 97 insertions, 16 deletions
diff --git a/ext/fetch/22_body.js b/ext/fetch/22_body.js index 10ddb7603..a51cdc184 100644 --- a/ext/fetch/22_body.js +++ b/ext/fetch/22_body.js @@ -388,7 +388,10 @@ let source = null; let length = null; let contentType = null; - if (ObjectPrototypeIsPrototypeOf(BlobPrototype, object)) { + if (typeof object === "string") { + source = object; + contentType = "text/plain;charset=UTF-8"; + } else if (ObjectPrototypeIsPrototypeOf(BlobPrototype, object)) { stream = object.stream(); source = object; length = object.size; @@ -424,24 +427,21 @@ // TODO(@satyarohith): not sure what primordial here. source = object.toString(); contentType = "application/x-www-form-urlencoded;charset=UTF-8"; - } else if (typeof object === "string") { - source = object; - contentType = "text/plain;charset=UTF-8"; } else if (ObjectPrototypeIsPrototypeOf(ReadableStreamPrototype, object)) { stream = object; if (object.locked || isReadableStreamDisturbed(object)) { throw new TypeError("ReadableStream is locked or disturbed"); } } - if (ObjectPrototypeIsPrototypeOf(Uint8ArrayPrototype, source)) { - stream = { body: source, consumed: false }; - length = source.byteLength; - } else if (typeof source === "string") { + if (typeof source === "string") { // WARNING: this deviates from spec (expects length to be set) // https://fetch.spec.whatwg.org/#bodyinit > 7. // no observable side-effect for users so far, but could change stream = { body: source, consumed: false }; length = null; // NOTE: string length != byte length + } else if (ObjectPrototypeIsPrototypeOf(Uint8ArrayPrototype, source)) { + stream = { body: source, consumed: false }; + length = source.byteLength; } const body = new InnerBody(stream); body.source = source; diff --git a/ext/fetch/23_request.js b/ext/fetch/23_request.js index 63fc6a26e..5221d5ca9 100644 --- a/ext/fetch/23_request.js +++ b/ext/fetch/23_request.js @@ -16,7 +16,7 @@ const { HTTP_TOKEN_CODE_POINT_RE, byteUpperCase } = window.__bootstrap.infra; const { URL } = window.__bootstrap.url; const { guardFromHeaders } = window.__bootstrap.headers; - const { mixinBody, extractBody } = window.__bootstrap.fetchBody; + const { mixinBody, extractBody, InnerBody } = window.__bootstrap.fetchBody; const { getLocationHref } = window.__bootstrap.location; const { extractMimeType } = window.__bootstrap.mimesniff; const { blobFromObjectUrl } = window.__bootstrap.file; @@ -48,6 +48,9 @@ const _signal = Symbol("signal"); const _mimeType = Symbol("mime type"); const _body = Symbol("body"); + const _flash = Symbol("flash"); + const _url = Symbol("url"); + const _method = Symbol("method"); /** * @param {(() => string)[]} urlList @@ -266,7 +269,11 @@ return extractMimeType(values); } get [_body]() { - return this[_request].body; + if (this[_flash]) { + return this[_flash].body; + } else { + return this[_request].body; + } } /** @@ -427,12 +434,31 @@ get method() { webidl.assertBranded(this, RequestPrototype); - return this[_request].method; + if (this[_method]) { + return this[_method]; + } + if (this[_flash]) { + this[_method] = this[_flash].methodCb(); + return this[_method]; + } else { + this[_method] = this[_request].method; + return this[_method]; + } } get url() { webidl.assertBranded(this, RequestPrototype); - return this[_request].url(); + if (this[_url]) { + return this[_url]; + } + + if (this[_flash]) { + this[_url] = this[_flash].urlCb(); + return this[_url]; + } else { + this[_url] = this[_request].url(); + return this[_url]; + } } get headers() { @@ -442,6 +468,9 @@ get redirect() { webidl.assertBranded(this, RequestPrototype); + if (this[_flash]) { + return this[_flash].redirectMode; + } return this[_request].redirectMode; } @@ -455,7 +484,12 @@ if (this[_body] && this[_body].unusable()) { throw new TypeError("Body is unusable."); } - const newReq = cloneInnerRequest(this[_request]); + let newReq; + if (this[_flash]) { + newReq = cloneInnerRequest(this[_flash]); + } else { + newReq = cloneInnerRequest(this[_request]); + } const newSignal = abortSignal.newSignal(); abortSignal.follow(newSignal, this[_signal]); return fromInnerRequest( @@ -549,10 +583,43 @@ return request; } + /** + * @param {number} serverId + * @param {number} streamRid + * @param {ReadableStream} body + * @param {() => string} methodCb + * @param {() => string} urlCb + * @param {() => [string, string][]} headersCb + * @returns {Request} + */ + function fromFlashRequest( + serverId, + streamRid, + body, + methodCb, + urlCb, + headersCb, + ) { + const request = webidl.createBranded(Request); + request[_flash] = { + body: body !== null ? new InnerBody(body) : null, + methodCb, + urlCb, + streamRid, + serverId, + redirectMode: "follow", + redirectCount: 0, + }; + request[_getHeaders] = () => headersFromHeaderList(headersCb(), "request"); + return request; + } + window.__bootstrap.fetch ??= {}; window.__bootstrap.fetch.Request = Request; window.__bootstrap.fetch.toInnerRequest = toInnerRequest; + window.__bootstrap.fetch.fromFlashRequest = fromFlashRequest; window.__bootstrap.fetch.fromInnerRequest = fromInnerRequest; window.__bootstrap.fetch.newInnerRequest = newInnerRequest; window.__bootstrap.fetch.processUrlList = processUrlList; + window.__bootstrap.fetch._flash = _flash; })(globalThis); diff --git a/ext/fetch/23_response.js b/ext/fetch/23_response.js index 226a751bd..3c19f963a 100644 --- a/ext/fetch/23_response.js +++ b/ext/fetch/23_response.js @@ -15,6 +15,9 @@ const { isProxy } = Deno.core; const webidl = window.__bootstrap.webidl; const consoleInternal = window.__bootstrap.console; + const { + byteLowerCase, + } = window.__bootstrap.infra; const { HTTP_TAB_OR_SPACE, regexMatcher, serializeJSValueToJSONString } = window.__bootstrap.infra; const { extractBody, mixinBody } = window.__bootstrap.fetchBody; @@ -185,7 +188,6 @@ // 4. response[_response].statusMessage = init.statusText; - // 5. /** @type {__bootstrap.headers.Headers} */ const headers = response[_headers]; @@ -200,10 +202,22 @@ "Response with null body status cannot have body", ); } + const { body, contentType } = bodyWithType; response[_response].body = body; - if (contentType !== null && !headers.has("content-type")) { - headers.append("Content-Type", contentType); + + if (contentType !== null) { + let hasContentType = false; + const list = headerListFromHeaders(headers); + for (let i = 0; i < list.length; i++) { + if (byteLowerCase(list[i][0]) === "content-type") { + hasContentType = true; + break; + } + } + if (!hasContentType) { + ArrayPrototypePush(list, ["Content-Type", contentType]); + } } } } |