diff options
author | Tomofumi Chiba <tomofumi.chiba@gmail.com> | 2021-06-22 12:21:57 +0900 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-06-22 05:21:57 +0200 |
commit | 4f1b1903cfadeeba24e1b0448879fe12682effb9 (patch) | |
tree | 5adf8bd7af8b86052ef555ca7f6ae221515baec0 /extensions/fetch/lib.rs | |
parent | 580c9f9ef02f8e8226437137867d3edeb9241b5e (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.rs | 39 |
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))) |