diff options
author | Aaron O'Mullan <aaron.omullan@gmail.com> | 2021-03-18 23:54:26 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-18 23:54:26 +0100 |
commit | 7d12dd18992cc58ce9866c2e42d914c8c8cf6d7a (patch) | |
tree | d4cc0871a744b72b9a4f7b7c8e926741d9108a90 /op_crates/fetch/lib.rs | |
parent | fb5a2786ec9854ceca840daeb9ae154dcf804d12 (diff) |
fix: fallback to default UA and CA data for Deno.createHttpClient() (#9830)
Diffstat (limited to 'op_crates/fetch/lib.rs')
-rw-r--r-- | op_crates/fetch/lib.rs | 53 |
1 files changed, 41 insertions, 12 deletions
diff --git a/op_crates/fetch/lib.rs b/op_crates/fetch/lib.rs index c37670852..f6f3e9607 100644 --- a/op_crates/fetch/lib.rs +++ b/op_crates/fetch/lib.rs @@ -23,8 +23,10 @@ use deno_core::RcRef; use deno_core::Resource; use deno_core::ZeroCopyBuf; +use reqwest::header::HeaderMap; use reqwest::header::HeaderName; use reqwest::header::HeaderValue; +use reqwest::header::USER_AGENT; use reqwest::redirect::Policy; use reqwest::Body; use reqwest::Client; @@ -80,6 +82,11 @@ pub fn init(isolate: &mut JsRuntime) { } } +pub struct HttpClientDefaults { + pub user_agent: String, + pub ca_data: Option<Vec<u8>>, +} + pub trait FetchPermissions { fn check_net_url(&self, _url: &Url) -> Result<(), AnyError>; fn check_read(&self, _p: &Path) -> Result<(), AnyError>; @@ -399,31 +406,53 @@ where permissions.check_read(&PathBuf::from(ca_file))?; } - let client = - create_http_client(args.ca_file.as_deref(), args.ca_data.as_deref()) - .unwrap(); + let defaults = state.borrow::<HttpClientDefaults>(); + + let cert_data = + get_cert_data(args.ca_file.as_deref(), args.ca_data.as_deref())?; + let client = create_http_client( + defaults.user_agent.clone(), + cert_data.or_else(|| defaults.ca_data.clone()), + ) + .unwrap(); let rid = state.resource_table.add(HttpClientResource::new(client)); Ok(json!(rid)) } -/// Create new instance of async reqwest::Client. This client supports -/// proxies and doesn't follow redirects. -fn create_http_client( +fn get_cert_data( ca_file: Option<&str>, ca_data: Option<&str>, -) -> Result<Client, AnyError> { - let mut builder = Client::builder().redirect(Policy::none()).use_rustls_tls(); +) -> Result<Option<Vec<u8>>, AnyError> { if let Some(ca_data) = ca_data { - let ca_data_vec = ca_data.as_bytes().to_vec(); - let cert = reqwest::Certificate::from_pem(&ca_data_vec)?; - builder = builder.add_root_certificate(cert); + Ok(Some(ca_data.as_bytes().to_vec())) } else if let Some(ca_file) = ca_file { let mut buf = Vec::new(); File::open(ca_file)?.read_to_end(&mut buf)?; - let cert = reqwest::Certificate::from_pem(&buf)?; + Ok(Some(buf)) + } else { + Ok(None) + } +} + +/// Create new instance of async reqwest::Client. This client supports +/// proxies and doesn't follow redirects. +pub fn create_http_client( + user_agent: String, + ca_data: Option<Vec<u8>>, +) -> Result<Client, AnyError> { + 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_rustls_tls(); + + if let Some(ca_data) = ca_data { + let cert = reqwest::Certificate::from_pem(&ca_data)?; builder = builder.add_root_certificate(cert); } + builder .build() .map_err(|e| generic_error(format!("Unable to build http client: {}", e))) |