summaryrefslogtreecommitdiff
path: root/extensions/fetch/lib.rs
diff options
context:
space:
mode:
authorTomofumi Chiba <tomofumi.chiba@gmail.com>2021-06-22 12:21:57 +0900
committerGitHub <noreply@github.com>2021-06-22 05:21:57 +0200
commit4f1b1903cfadeeba24e1b0448879fe12682effb9 (patch)
tree5adf8bd7af8b86052ef555ca7f6ae221515baec0 /extensions/fetch/lib.rs
parent580c9f9ef02f8e8226437137867d3edeb9241b5e (diff)
feat(fetch): add programmatic proxy (#10907)
This commit adds new options to unstable "Deno.createHttpClient" API. "proxy" and "basicAuth" options were added that allow to use custom proxy when client instance is passed to "fetch" API.
Diffstat (limited to 'extensions/fetch/lib.rs')
-rw-r--r--extensions/fetch/lib.rs39
1 files changed, 38 insertions, 1 deletions
diff --git a/extensions/fetch/lib.rs b/extensions/fetch/lib.rs
index cdac0d64c..3652c8724 100644
--- a/extensions/fetch/lib.rs
+++ b/extensions/fetch/lib.rs
@@ -56,6 +56,7 @@ pub use reqwest; // Re-export reqwest
pub fn init<P: FetchPermissions + 'static>(
user_agent: String,
ca_data: Option<Vec<u8>>,
+ proxy: Option<Proxy>,
) -> Extension {
Extension::builder()
.js(include_js_files!(
@@ -78,11 +79,13 @@ pub fn init<P: FetchPermissions + 'static>(
])
.state(move |state| {
state.put::<reqwest::Client>({
- create_http_client(user_agent.clone(), ca_data.clone()).unwrap()
+ create_http_client(user_agent.clone(), ca_data.clone(), proxy.clone())
+ .unwrap()
});
state.put::<HttpClientDefaults>(HttpClientDefaults {
ca_data: ca_data.clone(),
user_agent: user_agent.clone(),
+ proxy: proxy.clone(),
});
Ok(())
})
@@ -92,6 +95,7 @@ pub fn init<P: FetchPermissions + 'static>(
pub struct HttpClientDefaults {
pub user_agent: String,
pub ca_data: Option<Vec<u8>>,
+ pub proxy: Option<Proxy>,
}
pub trait FetchPermissions {
@@ -461,6 +465,22 @@ impl HttpClientResource {
pub struct CreateHttpClientOptions {
ca_file: Option<String>,
ca_data: Option<String>,
+ proxy: Option<Proxy>,
+}
+
+#[derive(Deserialize, Default, Debug, Clone)]
+#[serde(rename_all = "camelCase")]
+#[serde(default)]
+pub struct Proxy {
+ pub url: String,
+ pub basic_auth: Option<BasicAuth>,
+}
+
+#[derive(Deserialize, Default, Debug, Clone)]
+#[serde(default)]
+pub struct BasicAuth {
+ pub username: String,
+ pub password: String,
}
pub fn op_create_http_client<FP>(
@@ -476,6 +496,12 @@ where
permissions.check_read(&PathBuf::from(ca_file))?;
}
+ if let Some(proxy) = args.proxy.clone() {
+ let permissions = state.borrow_mut::<FP>();
+ let url = Url::parse(&proxy.url)?;
+ permissions.check_net_url(&url)?;
+ }
+
let defaults = state.borrow::<HttpClientDefaults>();
let cert_data =
@@ -483,6 +509,7 @@ where
let client = create_http_client(
defaults.user_agent.clone(),
cert_data.or_else(|| defaults.ca_data.clone()),
+ args.proxy,
)
.unwrap();
@@ -510,6 +537,7 @@ fn get_cert_data(
pub fn create_http_client(
user_agent: String,
ca_data: Option<Vec<u8>>,
+ proxy: Option<Proxy>,
) -> Result<Client, AnyError> {
let mut headers = HeaderMap::new();
headers.insert(USER_AGENT, user_agent.parse().unwrap());
@@ -523,6 +551,15 @@ pub fn create_http_client(
builder = builder.add_root_certificate(cert);
}
+ 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)))