summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cli/tests/unit/fetch_test.ts21
-rw-r--r--op_crates/fetch/lib.rs53
-rw-r--r--runtime/http_util.rs42
-rw-r--r--runtime/lib.rs1
-rw-r--r--runtime/ops/fetch.rs9
5 files changed, 69 insertions, 57 deletions
diff --git a/cli/tests/unit/fetch_test.ts b/cli/tests/unit/fetch_test.ts
index 71307cd69..fa013f0c5 100644
--- a/cli/tests/unit/fetch_test.ts
+++ b/cli/tests/unit/fetch_test.ts
@@ -1064,6 +1064,27 @@ MNf4EgWfK+tZMnuqfpfO9740KzfcVoMNo4QJD4yn5YxroUOO/Azi
);
unitTest(
+ { perms: { net: true } },
+ async function fetchCustomClientUserAgent(): Promise<
+ void
+ > {
+ const data = "Hello World";
+ const client = Deno.createHttpClient({});
+ const response = await fetch("http://localhost:4545/echo_server", {
+ client,
+ method: "POST",
+ body: new TextEncoder().encode(data),
+ });
+ assertEquals(
+ response.headers.get("user-agent"),
+ `Deno/${Deno.version.deno}`,
+ );
+ await response.text();
+ client.close();
+ },
+);
+
+unitTest(
{
perms: { net: true },
},
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)))
diff --git a/runtime/http_util.rs b/runtime/http_util.rs
deleted file mode 100644
index 72d41d6e3..000000000
--- a/runtime/http_util.rs
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
-
-use deno_core::error::generic_error;
-use deno_core::error::AnyError;
-use deno_fetch::reqwest;
-use deno_fetch::reqwest::header::HeaderMap;
-use deno_fetch::reqwest::header::USER_AGENT;
-use deno_fetch::reqwest::redirect::Policy;
-use deno_fetch::reqwest::Client;
-
-/// 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)))
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
-
- #[test]
- fn create_test_client() {
- create_http_client("test_client".to_string(), None).unwrap();
- }
-}
diff --git a/runtime/lib.rs b/runtime/lib.rs
index f4cf559d2..b30f10bd1 100644
--- a/runtime/lib.rs
+++ b/runtime/lib.rs
@@ -19,7 +19,6 @@ pub use deno_websocket;
pub mod colors;
pub mod errors;
pub mod fs_util;
-pub mod http_util;
pub mod inspector;
pub mod js;
pub mod metrics;
diff --git a/runtime/ops/fetch.rs b/runtime/ops/fetch.rs
index e1b43c910..9ab86858d 100644
--- a/runtime/ops/fetch.rs
+++ b/runtime/ops/fetch.rs
@@ -1,7 +1,7 @@
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
-use crate::http_util;
use crate::permissions::Permissions;
use deno_fetch::reqwest;
+use deno_fetch::HttpClientDefaults;
pub fn init(
rt: &mut deno_core::JsRuntime,
@@ -12,7 +12,12 @@ pub fn init(
let op_state = rt.op_state();
let mut state = op_state.borrow_mut();
state.put::<reqwest::Client>({
- http_util::create_http_client(user_agent, ca_data).unwrap()
+ deno_fetch::create_http_client(user_agent.clone(), ca_data.clone())
+ .unwrap()
+ });
+ state.put::<HttpClientDefaults>(HttpClientDefaults {
+ ca_data,
+ user_agent,
});
}
super::reg_json_sync(rt, "op_fetch", deno_fetch::op_fetch::<Permissions>);