1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-01-21 13:00:36 -05:00

perf(ext/http): Migrate op_http_get_request_headers to v8::Array (#19354)

This commit is contained in:
Kamil Ogórek 2023-06-03 00:31:27 +02:00 committed by GitHub
parent ce5bf9fb2a
commit 260d2ec3a1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 50 additions and 10 deletions

1
Cargo.lock generated
View file

@ -1065,6 +1065,7 @@ dependencies = [
"ring", "ring",
"serde", "serde",
"slab", "slab",
"smallvec",
"thiserror", "thiserror",
"tokio", "tokio",
"tokio-util", "tokio-util",

View file

@ -46,6 +46,7 @@ pin-project.workspace = true
ring.workspace = true ring.workspace = true
serde.workspace = true serde.workspace = true
slab.workspace = true slab.workspace = true
smallvec.workspace = true
thiserror.workspace = true thiserror.workspace = true
tokio.workspace = true tokio.workspace = true
tokio-util = { workspace = true, features = ["io"] } tokio-util = { workspace = true, features = ["io"] }

View file

@ -20,8 +20,10 @@ use cache_control::CacheControl;
use deno_core::error::AnyError; use deno_core::error::AnyError;
use deno_core::futures::TryFutureExt; use deno_core::futures::TryFutureExt;
use deno_core::op; use deno_core::op;
use deno_core::serde_v8;
use deno_core::task::spawn; use deno_core::task::spawn;
use deno_core::task::JoinHandle; use deno_core::task::JoinHandle;
use deno_core::v8;
use deno_core::AsyncRefCell; use deno_core::AsyncRefCell;
use deno_core::AsyncResult; use deno_core::AsyncResult;
use deno_core::ByteString; use deno_core::ByteString;
@ -51,11 +53,11 @@ use hyper1::server::conn::http1;
use hyper1::server::conn::http2; use hyper1::server::conn::http2;
use hyper1::service::service_fn; use hyper1::service::service_fn;
use hyper1::service::HttpService; use hyper1::service::HttpService;
use hyper1::StatusCode; use hyper1::StatusCode;
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use pin_project::pin_project; use pin_project::pin_project;
use pin_project::pinned_drop; use pin_project::pinned_drop;
use smallvec::SmallVec;
use std::borrow::Cow; use std::borrow::Cow;
use std::cell::RefCell; use std::cell::RefCell;
use std::future::Future; use std::future::Future;
@ -255,12 +257,17 @@ pub fn op_http_get_request_header(
value.map(|value| value.as_bytes().into()) value.map(|value| value.as_bytes().into())
} }
#[op] #[op(v8)]
pub fn op_http_get_request_headers(slab_id: SlabId) -> Vec<ByteString> { pub fn op_http_get_request_headers<'scope>(
scope: &mut v8::HandleScope<'scope>,
slab_id: SlabId,
) -> serde_v8::Value<'scope> {
let http = slab_get(slab_id); let http = slab_get(slab_id);
let headers = &http.request_parts().headers; let headers = &http.request_parts().headers;
// Two slots for each header key/value pair // Two slots for each header key/value pair
let mut vec = Vec::with_capacity(headers.len() * 2); let mut vec: SmallVec<[v8::Local<v8::Value>; 32]> =
SmallVec::with_capacity(headers.len() * 2);
let mut cookies: Option<Vec<&[u8]>> = None; let mut cookies: Option<Vec<&[u8]>> = None;
for (name, value) in headers { for (name, value) in headers {
if name == COOKIE { if name == COOKIE {
@ -270,9 +277,24 @@ pub fn op_http_get_request_headers(slab_id: SlabId) -> Vec<ByteString> {
cookies = Some(vec![value.as_bytes()]); cookies = Some(vec![value.as_bytes()]);
} }
} else { } else {
let name: &[u8] = name.as_ref(); vec.push(
vec.push(name.into()); v8::String::new_from_one_byte(
vec.push(value.as_bytes().into()); scope,
name.as_ref(),
v8::NewStringType::Normal,
)
.unwrap()
.into(),
);
vec.push(
v8::String::new_from_one_byte(
scope,
value.as_bytes(),
v8::NewStringType::Normal,
)
.unwrap()
.into(),
);
} }
} }
@ -283,11 +305,27 @@ pub fn op_http_get_request_headers(slab_id: SlabId) -> Vec<ByteString> {
// TODO(mmastrac): This should probably happen on the JS side on-demand // TODO(mmastrac): This should probably happen on the JS side on-demand
if let Some(cookies) = cookies { if let Some(cookies) = cookies {
let cookie_sep = "; ".as_bytes(); let cookie_sep = "; ".as_bytes();
vec.push(ByteString::from(COOKIE.as_str()));
vec.push(ByteString::from(cookies.join(cookie_sep))); vec.push(
v8::String::new_external_onebyte_static(scope, COOKIE.as_ref())
.unwrap()
.into(),
);
vec.push(
v8::String::new_from_one_byte(
scope,
cookies.join(cookie_sep).as_ref(),
v8::NewStringType::Normal,
)
.unwrap()
.into(),
);
} }
vec let array = v8::Array::new_with_elements(scope, vec.as_slice());
let array_value: v8::Local<v8::Value> = array.into();
array_value.into()
} }
#[op(fast)] #[op(fast)]