From 462138a8618dd56d1cec3bd67e05750679244fd5 Mon Sep 17 00:00:00 2001 From: Andreu Botella Date: Mon, 21 Jun 2021 02:33:43 +0200 Subject: [PATCH] fix(extensions/fetch): Encode and decode headers as byte strings. Fixes #10991. --- Cargo.lock | 4 ---- core/Cargo.toml | 6 +++--- core/lib.rs | 1 + extensions/fetch/lib.rs | 38 +++++++++++++++----------------------- tools/wpt/expectation.json | 2 +- 5 files changed, 20 insertions(+), 31 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3b00ff938e0585..3bad35288c63ad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2760,8 +2760,6 @@ dependencies = [ [[package]] name = "rusty_v8" version = "0.22.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa03778bb7866d8320fc3dd5e6be52929dc10f729ae5e61ea2fbce385a4595d2" dependencies = [ "bitflags", "fslock", @@ -2921,8 +2919,6 @@ dependencies = [ [[package]] name = "serde_v8" version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d1c602ced78c18b33338c832d79595e75ac6fd204d20fd4cc462ce5af29a75e" dependencies = [ "rusty_v8", "serde", diff --git a/core/Cargo.toml b/core/Cargo.toml index c9ba4b319fc93d..c2b9b8f54ba6a8 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -20,11 +20,11 @@ lazy_static = "1.4.0" libc = "0.2.93" log = "0.4.14" pin-project = "1.0.6" -rusty_v8 = "0.22.3" +rusty_v8 ={ git = "https://github.com/andreubotella/rusty_v8", branch = "one-and-two-byte-strings" } serde = { version = "1.0.125", features = ["derive"] } serde_json = { version = "1.0.64", features = ["preserve_order"] } -serde_v8 = { version = "0.4.1" } -url = { version = "2.2.1", features = ["serde"] } +serde_v8 = { path = "../../serde_v8" } +url ={ git = "https://github.com/andreubotella/serde_v8", branch = "bytestring" } [[example]] name = "http_bench_json_ops" diff --git a/core/lib.rs b/core/lib.rs index 7d49c142093e24..beb9043b3322c5 100644 --- a/core/lib.rs +++ b/core/lib.rs @@ -22,6 +22,7 @@ pub use rusty_v8 as v8; pub use serde; pub use serde_json; pub use serde_v8::Buffer as ZeroCopyBuf; +pub use serde_v8::ByteString; pub use url; pub use crate::async_cancel::CancelFuture; diff --git a/extensions/fetch/lib.rs b/extensions/fetch/lib.rs index cdac0d64c1f072..13cd9d2df954d8 100644 --- a/extensions/fetch/lib.rs +++ b/extensions/fetch/lib.rs @@ -13,6 +13,7 @@ use deno_core::op_async; use deno_core::op_sync; use deno_core::url::Url; use deno_core::AsyncRefCell; +use deno_core::ByteString; use deno_core::CancelFuture; use deno_core::CancelHandle; use deno_core::CancelTryFuture; @@ -119,9 +120,9 @@ pub fn get_declaration() -> PathBuf { #[derive(Deserialize)] #[serde(rename_all = "camelCase")] pub struct FetchArgs { - method: String, + method: ByteString, url: String, - headers: Vec<(String, String)>, + headers: Vec<(ByteString, ByteString)>, client_rid: Option, has_body: bool, } @@ -153,7 +154,7 @@ where client.clone() }; - let method = Method::from_bytes(args.method.as_bytes())?; + let method = Method::from_bytes(&args.method)?; let url = Url::parse(&args.url)?; // Check scheme before asking for net permission @@ -191,8 +192,8 @@ where }; for (key, value) in args.headers { - let name = HeaderName::from_bytes(key.as_bytes()).unwrap(); - let v = HeaderValue::from_str(&value).unwrap(); + let name = HeaderName::from_bytes(&key).unwrap(); + let v = HeaderValue::from_bytes(&value).unwrap(); request = request.header(name, v); } @@ -274,7 +275,7 @@ where pub struct FetchResponse { status: u16, status_text: String, - headers: Vec<(String, String)>, + headers: Vec<(ByteString, ByteString)>, url: String, response_rid: ResourceId, } @@ -305,20 +306,11 @@ pub async fn op_fetch_send( let url = res.url().to_string(); let mut res_headers = Vec::new(); for (key, val) in res.headers().iter() { - let key_string = key.to_string(); - - if val.as_bytes().is_ascii() { - res_headers.push((key_string, val.to_str().unwrap().to_owned())) - } else { - res_headers.push(( - key_string, - val - .as_bytes() - .iter() - .map(|&c| c as char) - .collect::(), - )); - } + let key_bytes: &[u8] = key.as_ref(); + res_headers.push(( + ByteString(key_bytes.to_owned()), + ByteString(val.as_bytes().to_owned()), + )); } let stream: BytesStream = Box::pin(res.bytes_stream().map(|r| { @@ -460,7 +452,7 @@ impl HttpClientResource { #[serde(default)] pub struct CreateHttpClientOptions { ca_file: Option, - ca_data: Option, + ca_data: Option, } pub fn op_create_http_client( @@ -492,10 +484,10 @@ where fn get_cert_data( ca_file: Option<&str>, - ca_data: Option<&str>, + ca_data: Option<&[u8]>, ) -> Result>, AnyError> { if let Some(ca_data) = ca_data { - Ok(Some(ca_data.as_bytes().to_vec())) + Ok(Some(ca_data.to_vec())) } else if let Some(ca_file) = ca_file { let mut buf = Vec::new(); File::open(ca_file)?.read_to_end(&mut buf)?; diff --git a/tools/wpt/expectation.json b/tools/wpt/expectation.json index 962c12de6d1a20..cdfa5252763398 100644 --- a/tools/wpt/expectation.json +++ b/tools/wpt/expectation.json @@ -718,7 +718,7 @@ "basic": { "request-head.any.html": true, "request-headers-case.any.html": false, - "request-headers-nonascii.any.html": false, + "request-headers-nonascii.any.html": true, "request-headers.any.html": [ "Fetch with PUT without body", "Fetch with PUT with body",