diff options
author | Marvin Hagemeister <marvin@deno.com> | 2023-06-06 16:55:37 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-06-06 16:55:37 +0200 |
commit | 1c3d2132c28f4d47aeebeb5b863bbbda05db7147 (patch) | |
tree | 57678d20eebfd819e87256b91fcc2552d850a0dc | |
parent | 5aca8b9e5d6420c65ab3ecf516e9d8c8eaaee28f (diff) |
perf(http): avoid flattening http headers (#19384)
-rw-r--r-- | ext/http/00_serve.js | 3 | ||||
-rw-r--r-- | ext/http/http_next.rs | 33 |
2 files changed, 26 insertions, 10 deletions
diff --git a/ext/http/00_serve.js b/ext/http/00_serve.js index c5a5c0e18..7c9b29069 100644 --- a/ext/http/00_serve.js +++ b/ext/http/00_serve.js @@ -37,7 +37,6 @@ import { import { listen, TcpConn } from "ext:deno_net/01_net.js"; import { listenTls } from "ext:deno_net/02_tls.js"; const { - ArrayPrototypeFlat, ArrayPrototypePush, ObjectPrototypeIsPrototypeOf, PromisePrototypeCatch, @@ -559,7 +558,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, ArrayPrototypeFlat(headers)); + op_http_set_response_headers(req, headers); } } diff --git a/ext/http/http_next.rs b/ext/http/http_next.rs index 14b5457e5..900a956f4 100644 --- a/ext/http/http_next.rs +++ b/ext/http/http_next.rs @@ -21,6 +21,7 @@ use deno_core::error::AnyError; use deno_core::futures::TryFutureExt; use deno_core::op; use deno_core::serde_v8; +use deno_core::serde_v8::from_v8; use deno_core::task::spawn; use deno_core::task::JoinHandle; use deno_core::v8; @@ -384,17 +385,33 @@ pub fn op_http_set_response_header(slab_id: SlabId, name: &str, value: &str) { resp_headers.append(name, value); } -#[op] -pub fn op_http_set_response_headers(slab_id: SlabId, headers: Vec<ByteString>) { +#[op(v8)] +fn op_http_set_response_headers( + scope: &mut v8::HandleScope, + slab_id: SlabId, + headers: serde_v8::Value, +) { 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 header in headers.chunks_exact(2) { - // These are valid latin-1 strings - let name = HeaderName::from_bytes(&header[0]).unwrap(); - let value = HeaderValue::from_bytes(&header[1]).unwrap(); - resp_headers.append(name, value); + + let arr = v8::Local::<v8::Array>::try_from(headers.v8_value).unwrap(); + + let len = arr.length(); + let header_len = len * 2; + resp_headers.reserve(header_len.try_into().unwrap()); + + for i in 0..len { + let item = arr.get_index(scope, i).unwrap(); + let pair = v8::Local::<v8::Array>::try_from(item).unwrap(); + let name = pair.get_index(scope, 0).unwrap(); + let value = pair.get_index(scope, 1).unwrap(); + + let v8_name: ByteString = from_v8(scope, name).unwrap(); + let v8_value: ByteString = from_v8(scope, value).unwrap(); + let header_name = HeaderName::from_bytes(&v8_name).unwrap(); + let header_value = HeaderValue::from_bytes(&v8_value).unwrap(); + resp_headers.append(header_name, header_value); } } |