From 084caffc08ceb33c4d20c4b6d744ce15c19c4baf Mon Sep 17 00:00:00 2001 From: Ryan Dahl Date: Wed, 1 Dec 2021 11:13:11 -0500 Subject: [PATCH] refactor: cli doesn't need to depend on deno_tls (#12952) also move create_http_client to deno_fetch --- Cargo.lock | 1 - cli/Cargo.toml | 1 - cli/file_fetcher.rs | 4 +-- cli/http_util.rs | 5 ++-- cli/proc_state.rs | 6 ++-- cli/standalone.rs | 2 +- ext/fetch/lib.rs | 43 ++++++++++++++++++++++++++- ext/net/ops_tls.rs | 2 ++ ext/tls/lib.rs | 69 +++++++++----------------------------------- ext/websocket/lib.rs | 1 + 10 files changed, 67 insertions(+), 67 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f9b235790b..2fe742071e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -642,7 +642,6 @@ dependencies = [ "deno_lint", "deno_net", "deno_runtime", - "deno_tls", "deno_url", "deno_web", "deno_webgpu", diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 7f2ee1bbe8..b5767788fb 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -45,7 +45,6 @@ deno_doc = "0.21.0" deno_graph = "0.12.0" deno_lint = { version = "0.19.0", features = ["docs"] } deno_runtime = { version = "0.35.0", path = "../runtime" } -deno_tls = { version = "0.14.0", path = "../ext/tls" } atty = "0.2.14" base64 = "0.13.0" diff --git a/cli/file_fetcher.rs b/cli/file_fetcher.rs index 246491394a..924076872c 100644 --- a/cli/file_fetcher.rs +++ b/cli/file_fetcher.rs @@ -18,11 +18,11 @@ use deno_core::futures; use deno_core::futures::future::FutureExt; use deno_core::parking_lot::Mutex; use deno_core::ModuleSpecifier; +use deno_runtime::deno_fetch::create_http_client; use deno_runtime::deno_fetch::reqwest; +use deno_runtime::deno_tls::rustls::RootCertStore; use deno_runtime::deno_web::BlobStore; use deno_runtime::permissions::Permissions; -use deno_tls::create_http_client; -use deno_tls::rustls::RootCertStore; use log::debug; use log::info; use std::borrow::Borrow; diff --git a/cli/http_util.rs b/cli/http_util.rs index 1a2aaf0d50..c66fa32d35 100644 --- a/cli/http_util.rs +++ b/cli/http_util.rs @@ -148,7 +148,8 @@ pub async fn fetch_once( mod tests { use super::*; use crate::version; - use deno_tls::create_http_client; + use deno_runtime::deno_fetch::create_http_client; + use deno_runtime::deno_tls::rustls::RootCertStore; use std::fs::read; fn create_test_client() -> Client { @@ -413,7 +414,7 @@ mod tests { let url = Url::parse("https://deno.land").unwrap(); let client = create_http_client( version::get_user_agent(), - Some(deno_tls::rustls::RootCertStore::empty()), // no certs loaded at all + Some(RootCertStore::empty()), // no certs loaded at all vec![], None, None, diff --git a/cli/proc_state.rs b/cli/proc_state.rs index b62cdc464a..be3213a62d 100644 --- a/cli/proc_state.rs +++ b/cli/proc_state.rs @@ -38,12 +38,12 @@ use deno_graph::MediaType; use deno_graph::ModuleGraphError; use deno_graph::Range; use deno_runtime::deno_broadcast_channel::InMemoryBroadcastChannel; +use deno_runtime::deno_tls::rustls::RootCertStore; +use deno_runtime::deno_tls::rustls_native_certs::load_native_certs; +use deno_runtime::deno_tls::webpki_roots::TLS_SERVER_ROOTS; use deno_runtime::deno_web::BlobStore; use deno_runtime::inspector_server::InspectorServer; use deno_runtime::permissions::Permissions; -use deno_tls::rustls::RootCertStore; -use deno_tls::rustls_native_certs::load_native_certs; -use deno_tls::webpki_roots::TLS_SERVER_ROOTS; use import_map::ImportMap; use std::collections::BTreeMap; use std::collections::HashMap; diff --git a/cli/standalone.rs b/cli/standalone.rs index 92e7dfbae0..464ff2c2d2 100644 --- a/cli/standalone.rs +++ b/cli/standalone.rs @@ -21,13 +21,13 @@ use deno_core::v8_set_flags; use deno_core::ModuleLoader; use deno_core::ModuleSpecifier; use deno_runtime::deno_broadcast_channel::InMemoryBroadcastChannel; +use deno_runtime::deno_tls::create_default_root_cert_store; use deno_runtime::deno_web::BlobStore; use deno_runtime::permissions::Permissions; use deno_runtime::permissions::PermissionsOptions; use deno_runtime::worker::MainWorker; use deno_runtime::worker::WorkerOptions; use deno_runtime::BootstrapOptions; -use deno_tls::create_default_root_cert_store; use log::Level; use std::env::current_exe; use std::fs::File; diff --git a/ext/fetch/lib.rs b/ext/fetch/lib.rs index ec2bc5e4e1..56e9ef1afa 100644 --- a/ext/fetch/lib.rs +++ b/ext/fetch/lib.rs @@ -25,13 +25,15 @@ use deno_core::RcRef; use deno_core::Resource; use deno_core::ResourceId; use deno_core::ZeroCopyBuf; -use deno_tls::create_http_client; use deno_tls::rustls::RootCertStore; use deno_tls::Proxy; use http::header::CONTENT_LENGTH; +use reqwest::header::HeaderMap; use reqwest::header::HeaderName; use reqwest::header::HeaderValue; use reqwest::header::HOST; +use reqwest::header::USER_AGENT; +use reqwest::redirect::Policy; use reqwest::Body; use reqwest::Client; use reqwest::Method; @@ -573,3 +575,42 @@ where let rid = state.resource_table.add(HttpClientResource::new(client)); Ok(rid) } + +/// Create new instance of async reqwest::Client. This client supports +/// proxies and doesn't follow redirects. +pub fn create_http_client( + user_agent: String, + root_cert_store: Option, + ca_certs: Vec>, + proxy: Option, + unsafely_ignore_certificate_errors: Option>, + client_cert_chain_and_key: Option<(String, String)>, +) -> Result { + let mut tls_config = deno_tls::create_client_config( + root_cert_store, + ca_certs, + unsafely_ignore_certificate_errors, + client_cert_chain_and_key, + )?; + + tls_config.alpn_protocols = vec!["h2".into(), "http/1.1".into()]; + + let mut headers = HeaderMap::new(); + headers.insert(USER_AGENT, user_agent.parse().unwrap()); + let mut builder = Client::builder() + .redirect(Policy::none()) + .default_headers(headers) + .use_preconfigured_tls(tls_config); + + if let Some(proxy) = proxy { + let mut reqwest_proxy = reqwest::Proxy::all(&proxy.url)?; + if let Some(basic_auth) = &proxy.basic_auth { + reqwest_proxy = + reqwest_proxy.basic_auth(&basic_auth.username, &basic_auth.password); + } + builder = builder.proxy(reqwest_proxy); + } + + // unwrap here because it can only fail when native TLS is used. + Ok(builder.build().unwrap()) +} diff --git a/ext/net/ops_tls.rs b/ext/net/ops_tls.rs index fd2308ef18..67e6dfc167 100644 --- a/ext/net/ops_tls.rs +++ b/ext/net/ops_tls.rs @@ -883,6 +883,7 @@ where root_cert_store, ca_certs, unsafely_ignore_certificate_errors, + None, )?; if let Some(alpn_protocols) = args.alpn_protocols { @@ -983,6 +984,7 @@ where root_cert_store, ca_certs, unsafely_ignore_certificate_errors, + None, )?; if let Some(alpn_protocols) = args.alpn_protocols { diff --git a/ext/tls/lib.rs b/ext/tls/lib.rs index b29a142b9a..91eb4c54b1 100644 --- a/ext/tls/lib.rs +++ b/ext/tls/lib.rs @@ -8,15 +8,10 @@ pub use webpki_roots; use deno_core::anyhow::anyhow; use deno_core::error::custom_error; -use deno_core::error::generic_error; use deno_core::error::AnyError; use deno_core::parking_lot::Mutex; use deno_core::Extension; -use reqwest::header::HeaderMap; -use reqwest::header::USER_AGENT; -use reqwest::redirect::Policy; -use reqwest::Client; use rustls::internal::msgs::handshake::DigitallySignedStruct; use rustls::internal::pemfile::certs; use rustls::internal::pemfile::pkcs8_private_keys; @@ -138,6 +133,7 @@ pub fn create_client_config( root_cert_store: Option, ca_certs: Vec>, unsafely_ignore_certificate_errors: Option>, + client_cert_chain_and_key: Option<(String, String)>, ) -> Result { let mut tls_config = ClientConfig::new(); tls_config.set_persistence(CLIENT_SESSION_MEMORY_CACHE.clone()); @@ -159,6 +155,18 @@ pub fn create_client_config( )); } + if let Some((cert_chain, private_key)) = client_cert_chain_and_key { + // The `remove` is safe because load_private_keys checks that there is at least one key. + let private_key = load_private_keys(private_key.as_bytes())?.remove(0); + + tls_config + .set_single_client_cert( + load_certs(&mut cert_chain.as_bytes())?, + private_key, + ) + .expect("invalid client key or certificate"); + } + Ok(tls_config) } @@ -209,54 +217,3 @@ pub fn load_private_keys(bytes: &[u8]) -> Result, AnyError> { Ok(keys) } - -/// Create new instance of async reqwest::Client. This client supports -/// proxies and doesn't follow redirects. -pub fn create_http_client( - user_agent: String, - root_cert_store: Option, - ca_certs: Vec>, - proxy: Option, - unsafely_ignore_certificate_errors: Option>, - client_cert_chain_and_key: Option<(String, String)>, -) -> Result { - let mut tls_config = create_client_config( - root_cert_store, - ca_certs, - unsafely_ignore_certificate_errors, - )?; - - if let Some((cert_chain, private_key)) = client_cert_chain_and_key { - // The `remove` is safe because load_private_keys checks that there is at least one key. - let private_key = load_private_keys(private_key.as_bytes())?.remove(0); - - tls_config - .set_single_client_cert( - load_certs(&mut cert_chain.as_bytes())?, - private_key, - ) - .expect("invalid client key or certificate"); - } - - tls_config.alpn_protocols = vec!["h2".into(), "http/1.1".into()]; - - let mut headers = HeaderMap::new(); - headers.insert(USER_AGENT, user_agent.parse().unwrap()); - let mut builder = Client::builder() - .redirect(Policy::none()) - .default_headers(headers) - .use_preconfigured_tls(tls_config); - - if let Some(proxy) = proxy { - let mut reqwest_proxy = reqwest::Proxy::all(&proxy.url)?; - if let Some(basic_auth) = &proxy.basic_auth { - reqwest_proxy = - reqwest_proxy.basic_auth(&basic_auth.username, &basic_auth.password); - } - builder = builder.proxy(reqwest_proxy); - } - - builder - .build() - .map_err(|e| generic_error(format!("Unable to build http client: {}", e))) -} diff --git a/ext/websocket/lib.rs b/ext/websocket/lib.rs index f3d44cac71..cf2ab6cacf 100644 --- a/ext/websocket/lib.rs +++ b/ext/websocket/lib.rs @@ -281,6 +281,7 @@ where root_cert_store, vec![], unsafely_ignore_certificate_errors, + None, )?; let tls_connector = TlsConnector::from(Arc::new(tls_config)); let dnsname = DNSNameRef::try_from_ascii_str(domain)