summaryrefslogtreecommitdiff
path: root/op_crates/fetch
diff options
context:
space:
mode:
authorAaron O'Mullan <aaron.omullan@gmail.com>2021-03-18 23:54:26 +0100
committerGitHub <noreply@github.com>2021-03-18 23:54:26 +0100
commit7d12dd18992cc58ce9866c2e42d914c8c8cf6d7a (patch)
treed4cc0871a744b72b9a4f7b7c8e926741d9108a90 /op_crates/fetch
parentfb5a2786ec9854ceca840daeb9ae154dcf804d12 (diff)
fix: fallback to default UA and CA data for Deno.createHttpClient() (#9830)
Diffstat (limited to 'op_crates/fetch')
-rw-r--r--op_crates/fetch/lib.rs53
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)))