diff options
Diffstat (limited to 'ext')
-rw-r--r-- | ext/fetch/lib.rs | 43 | ||||
-rw-r--r-- | ext/net/ops_tls.rs | 2 | ||||
-rw-r--r-- | ext/tls/lib.rs | 69 | ||||
-rw-r--r-- | ext/websocket/lib.rs | 1 |
4 files changed, 58 insertions, 57 deletions
diff --git a/ext/fetch/lib.rs b/ext/fetch/lib.rs index ec2bc5e4e..56e9ef1af 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<RootCertStore>, + ca_certs: Vec<Vec<u8>>, + proxy: Option<Proxy>, + unsafely_ignore_certificate_errors: Option<Vec<String>>, + client_cert_chain_and_key: Option<(String, String)>, +) -> Result<Client, AnyError> { + 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 fd2308ef1..67e6dfc16 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 b29a142b9..91eb4c54b 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<RootCertStore>, ca_certs: Vec<Vec<u8>>, unsafely_ignore_certificate_errors: Option<Vec<String>>, + client_cert_chain_and_key: Option<(String, String)>, ) -> Result<ClientConfig, AnyError> { 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<Vec<PrivateKey>, 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<RootCertStore>, - ca_certs: Vec<Vec<u8>>, - proxy: Option<Proxy>, - unsafely_ignore_certificate_errors: Option<Vec<String>>, - client_cert_chain_and_key: Option<(String, String)>, -) -> Result<Client, AnyError> { - 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 f3d44cac7..cf2ab6cac 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) |