#[cfg(feature = "portal")]
async fn do_request() -> Result<(), Box<dyn std::error::Error>> {
let portal_resolver = system_proxy::unix::FreedesktopPortalProxyResolver::connect().await?;
let env_proxies = system_proxy::env::from_curl_env();
let proxy = reqwest::Proxy::custom(move |url| {
let proxy = env_proxies.lookup(url).map(Clone::clone);
println!("Environment provided proxy {proxy:?}");
proxy.or_else(|| {
let (tx, rx) = tokio::sync::oneshot::channel();
let url = url.clone();
let portal_resolver = portal_resolver.clone();
tokio::task::spawn(async move {
let result = portal_resolver.lookup(&url).await;
tx.send(result).unwrap();
});
let proxy = tokio::task::block_in_place(|| rx.blocking_recv())
.unwrap()
.unwrap_or_else(|err| {
eprintln!("Proxy lookup on portal failed: {}", err);
None
});
println!("Portal provided proxy {proxy:?}");
proxy
})
});
let client = reqwest::Client::builder()
.user_agent(concat!(
env!("CARGO_PKG_NAME"),
"/",
env!("CARGO_PKG_VERSION")
))
.proxy(proxy)
.build()?;
let response = client.get("https://httpbin.org/status/200").send().await?;
println!("Status code: {}", response.status());
Ok(())
}
#[cfg(feature = "portal")]
fn main() {
let runtime = tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()
.unwrap();
runtime.block_on(do_request()).unwrap();
}
#[cfg(not(feature = "portal"))]
fn main() {
panic!("--features portal required for this example");
}