0
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-02-12 16:59:32 -05:00

perf(ext/http): lazy load headers (#15055)

This commit is contained in:
Divy Srivastava 2022-07-04 07:41:52 +05:30 committed by David Sherret
parent 78d4dedcdb
commit 6130cb70a3
3 changed files with 50 additions and 12 deletions

View file

@ -43,6 +43,8 @@
const _request = Symbol("request"); const _request = Symbol("request");
const _headers = Symbol("headers"); const _headers = Symbol("headers");
const _getHeaders = Symbol("get headers");
const _headersCache = Symbol("headers cache");
const _signal = Symbol("signal"); const _signal = Symbol("signal");
const _mimeType = Symbol("mime type"); const _mimeType = Symbol("mime type");
const _body = Symbol("body"); const _body = Symbol("body");
@ -52,7 +54,7 @@
* @property {string} method * @property {string} method
* @property {() => string} url * @property {() => string} url
* @property {() => string} currentUrl * @property {() => string} currentUrl
* @property {[string, string][]} headerList * @property {() => [string, string][]} headerList
* @property {null | typeof __window.bootstrap.fetchBody.InnerBody} body * @property {null | typeof __window.bootstrap.fetchBody.InnerBody} body
* @property {"follow" | "error" | "manual"} redirectMode * @property {"follow" | "error" | "manual"} redirectMode
* @property {number} redirectCount * @property {number} redirectCount
@ -64,7 +66,7 @@
/** /**
* @param {string} method * @param {string} method
* @param {string} url * @param {string} url
* @param {[string, string][]} headerList * @param {() => [string, string][]} headerList
* @param {typeof __window.bootstrap.fetchBody.InnerBody} body * @param {typeof __window.bootstrap.fetchBody.InnerBody} body
* @param {boolean} maybeBlob * @param {boolean} maybeBlob
* @returns * @returns
@ -76,7 +78,16 @@
} }
return { return {
method, method,
headerList, headerListInner: null,
get headerList() {
if (this.headerListInner === null) {
this.headerListInner = headerList();
}
return this.headerListInner;
},
set headerList(value) {
this.headerListInner = value;
},
body, body,
redirectMode: "follow", redirectMode: "follow",
redirectCount: 0, redirectCount: 0,
@ -167,7 +178,21 @@
/** @type {InnerRequest} */ /** @type {InnerRequest} */
[_request]; [_request];
/** @type {Headers} */ /** @type {Headers} */
[_headers]; [_headersCache];
[_getHeaders];
/** @type {Headers} */
get [_headers]() {
if (this[_headersCache] === undefined) {
this[_headersCache] = this[_getHeaders]();
}
return this[_headersCache];
}
set [_headers](value) {
this[_headersCache] = value;
}
/** @type {AbortSignal} */ /** @type {AbortSignal} */
[_signal]; [_signal];
get [_mimeType]() { get [_mimeType]() {
@ -210,7 +235,7 @@
// 5. // 5.
if (typeof input === "string") { if (typeof input === "string") {
const parsedURL = new URL(input, baseURL); const parsedURL = new URL(input, baseURL);
request = newInnerRequest("GET", parsedURL.href, [], null, true); request = newInnerRequest("GET", parsedURL.href, () => [], null, true);
} else { // 6. } else { // 6.
if (!ObjectPrototypeIsPrototypeOf(RequestPrototype, input)) { if (!ObjectPrototypeIsPrototypeOf(RequestPrototype, input)) {
throw new TypeError("Unreachable"); throw new TypeError("Unreachable");
@ -451,7 +476,7 @@
const request = webidl.createBranded(Request); const request = webidl.createBranded(Request);
request[_request] = inner; request[_request] = inner;
request[_signal] = signal; request[_signal] = signal;
request[_headers] = headersFromHeaderList(inner.headerList, guard); request[_getHeaders] = () => headersFromHeaderList(inner.headerList, guard);
return request; return request;
} }

View file

@ -111,7 +111,7 @@
return null; return null;
} }
const [streamRid, method, headersList, url] = nextRequest; const [streamRid, method, url] = nextRequest;
SetPrototypeAdd(this.managedResources, streamRid); SetPrototypeAdd(this.managedResources, streamRid);
/** @type {ReadableStream<Uint8Array> | undefined} */ /** @type {ReadableStream<Uint8Array> | undefined} */
@ -126,7 +126,7 @@
const innerRequest = newInnerRequest( const innerRequest = newInnerRequest(
method, method,
url, url,
headersList, () => core.opSync("op_http_headers", streamRid),
body !== null ? new InnerBody(body) : null, body !== null ? new InnerBody(body) : null,
false, false,
); );

View file

@ -79,6 +79,7 @@ pub fn init() -> Extension {
op_http_accept::decl(), op_http_accept::decl(),
op_http_read::decl(), op_http_read::decl(),
op_http_write_headers::decl(), op_http_write_headers::decl(),
op_http_headers::decl(),
op_http_write::decl(), op_http_write::decl(),
op_http_write_resource::decl(), op_http_write_resource::decl(),
op_http_shutdown::decl(), op_http_shutdown::decl(),
@ -365,8 +366,6 @@ struct NextRequestResponse(
// This is a String rather than a ByteString because reqwest will only return // This is a String rather than a ByteString because reqwest will only return
// the method as a str which is guaranteed to be ASCII-only. // the method as a str which is guaranteed to be ASCII-only.
String, String,
// headers:
Vec<(ByteString, ByteString)>,
// url: // url:
String, String,
); );
@ -403,12 +402,11 @@ async fn op_http_accept(
}); });
let method = request.method().to_string(); let method = request.method().to_string();
let headers = req_headers(request);
let url = req_url(request, conn.scheme(), conn.addr()); let url = req_url(request, conn.scheme(), conn.addr());
let stream_rid = state.borrow_mut().resource_table.add_rc(stream); let stream_rid = state.borrow_mut().resource_table.add_rc(stream);
let r = NextRequestResponse(stream_rid, method, headers, url); let r = NextRequestResponse(stream_rid, method, url);
Ok(Some(r)) Ok(Some(r))
} }
@ -561,6 +559,21 @@ async fn op_http_write_headers(
} }
} }
#[op]
fn op_http_headers(
state: &mut OpState,
rid: u32,
) -> Result<Vec<(ByteString, ByteString)>, AnyError> {
let stream = state.resource_table.get::<HttpStreamResource>(rid)?;
let rd = RcRef::map(&stream, |r| &r.rd)
.try_borrow()
.ok_or_else(|| http_error("already in use"))?;
match &*rd {
HttpRequestReader::Headers(request) => Ok(req_headers(request)),
_ => unreachable!(),
}
}
fn http_response( fn http_response(
data: Option<StringOrBuffer>, data: Option<StringOrBuffer>,
compressing: bool, compressing: bool,