summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarvin Hagemeister <marvin@deno.com>2023-06-06 16:55:37 +0200
committerGitHub <noreply@github.com>2023-06-06 16:55:37 +0200
commit1c3d2132c28f4d47aeebeb5b863bbbda05db7147 (patch)
tree57678d20eebfd819e87256b91fcc2552d850a0dc
parent5aca8b9e5d6420c65ab3ecf516e9d8c8eaaee28f (diff)
perf(http): avoid flattening http headers (#19384)
-rw-r--r--ext/http/00_serve.js3
-rw-r--r--ext/http/http_next.rs33
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);
}
}