summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKamil Ogórek <kamil.ogorek@gmail.com>2023-06-02 17:59:16 +0200
committerGitHub <noreply@github.com>2023-06-02 09:59:16 -0600
commit98320ff1f88e6b6ee1d85d64e99519986f6a7239 (patch)
tree21adde93dba24a7279bc57fe13049b59cace0372
parentf5c1ff08e6c67c38043b4c76b5472ad71c93d697 (diff)
perf(ext/http): Use flat list of headers for multiple set/get methods (#19336)
This PR attempts to resolve the first item on the list from https://github.com/denoland/deno/issues/19330 which is about using a flat list of interleaved key/value pairs, instead of a nested array of tuples. I can tackle some more if you can provide a quick example of using raw v8 arrays, cc @mmastrac
-rw-r--r--ext/http/00_serve.js9
-rw-r--r--ext/http/http_next.rs28
2 files changed, 19 insertions, 18 deletions
diff --git a/ext/http/00_serve.js b/ext/http/00_serve.js
index d84244ee4..dbdc22705 100644
--- a/ext/http/00_serve.js
+++ b/ext/http/00_serve.js
@@ -334,7 +334,12 @@ class InnerRequest {
if (this.#slabId === undefined) {
throw new TypeError("request closed");
}
- return op_http_get_request_headers(this.#slabId);
+ const headers = [];
+ const reqHeaders = op_http_get_request_headers(this.#slabId);
+ for (let i = 0; i < reqHeaders.length; i += 2) {
+ headers.push([reqHeaders[i], reqHeaders[i + 1]]);
+ }
+ return headers;
}
get slabId() {
@@ -570,7 +575,7 @@ function mapToCallback(context, callback, onError) {
if (headers.length == 1) {
op_http_set_response_header(req, headers[0][0], headers[0][1]);
} else {
- op_http_set_response_headers(req, headers);
+ op_http_set_response_headers(req, headers.flat());
}
}
diff --git a/ext/http/http_next.rs b/ext/http/http_next.rs
index 7a02757c0..9ec9e12c9 100644
--- a/ext/http/http_next.rs
+++ b/ext/http/http_next.rs
@@ -256,12 +256,11 @@ pub fn op_http_get_request_header(
}
#[op]
-pub fn op_http_get_request_headers(
- slab_id: SlabId,
-) -> Vec<(ByteString, ByteString)> {
+pub fn op_http_get_request_headers(slab_id: SlabId) -> Vec<ByteString> {
let http = slab_get(slab_id);
let headers = &http.request_parts().headers;
- let mut vec = Vec::with_capacity(headers.len());
+ // Two slots for each header key/value pair
+ let mut vec = Vec::with_capacity(headers.len() * 2);
let mut cookies: Option<Vec<&[u8]>> = None;
for (name, value) in headers {
if name == COOKIE {
@@ -272,7 +271,8 @@ pub fn op_http_get_request_headers(
}
} else {
let name: &[u8] = name.as_ref();
- vec.push((name.into(), value.as_bytes().into()))
+ vec.push(name.into());
+ vec.push(value.as_bytes().into());
}
}
@@ -283,11 +283,10 @@ pub fn op_http_get_request_headers(
// TODO(mmastrac): This should probably happen on the JS side on-demand
if let Some(cookies) = cookies {
let cookie_sep = "; ".as_bytes();
- vec.push((
- ByteString::from(COOKIE.as_str()),
- ByteString::from(cookies.join(cookie_sep)),
- ));
+ vec.push(ByteString::from(COOKIE.as_str()));
+ vec.push(ByteString::from(cookies.join(cookie_sep)));
}
+
vec
}
@@ -313,18 +312,15 @@ pub fn op_http_set_response_header(slab_id: SlabId, name: &str, value: &str) {
}
#[op]
-pub fn op_http_set_response_headers(
- slab_id: SlabId,
- headers: Vec<(ByteString, ByteString)>,
-) {
+pub fn op_http_set_response_headers(slab_id: SlabId, headers: Vec<ByteString>) {
let mut http = slab_get(slab_id);
// TODO(mmastrac): Invalid headers should be handled?
let resp_headers = http.response().headers_mut();
resp_headers.reserve(headers.len());
- for (name, value) in headers {
+ for header in headers.chunks_exact(2) {
// These are valid latin-1 strings
- let name = HeaderName::from_bytes(&name).unwrap();
- let value = HeaderValue::from_bytes(&value).unwrap();
+ let name = HeaderName::from_bytes(&header[0]).unwrap();
+ let value = HeaderValue::from_bytes(&header[1]).unwrap();
resp_headers.append(name, value);
}
}