use proxy_watch::{EnvPrecedence, ProxyConfigSource, ProxyEnv, ProxyStep, Url, read, resolve};
const DEFAULT_URLS: &[&str] = &[
"http://example.com/",
"https://example.com/",
"http://localhost:8080/",
"http://intranet/",
];
fn main() -> Result<(), Box<dyn std::error::Error>> {
let args: Vec<String> = std::env::args().skip(1).collect();
let os_first = args.iter().any(|a| a == "--os-first");
let urls: Vec<&str> = {
let rest: Vec<&str> = args
.iter()
.map(String::as_str)
.filter(|a| *a != "--os-first")
.collect();
if rest.is_empty() {
DEFAULT_URLS.to_vec()
} else {
rest
}
};
let precedence = if os_first {
EnvPrecedence::AfterSystem
} else {
EnvPrecedence::BeforeSystem
};
let config = read()?.with_env(&ProxyEnv::from_env()?, precedence);
println!(
"policy: {}",
if os_first {
"OS first, then env (if set)"
} else {
"env first (if set), then OS"
}
);
println!("effective: {:?}", config.effective);
println!("sources:");
for (source, mode) in &config.sources {
println!(" {source:?} -> {mode:?}");
}
if !config.fallbacks.is_empty() {
println!("fallbacks: {:?}", config.fallbacks);
}
if config.source(ProxyConfigSource::Env).is_none() {
println!("(the process environment contributed nothing to this snapshot)\n");
} else {
println!();
}
for input in urls {
let url = Url::parse(input)?;
match resolve(&config, &url) {
Ok(steps) => {
let decision: Vec<String> = steps
.iter()
.map(|step| match step.endpoint() {
None => "DIRECT".to_owned(),
Some(endpoint) => match endpoint.scheme_hint {
Some(_) => endpoint.to_string(),
None => format!("{}://{endpoint}", step.scheme().unwrap_or("?")),
},
})
.collect();
println!("{input} -> {}", decision.join(", "));
if let Some(ProxyStep::Socks5(endpoint)) = steps.first() {
println!(" (a SOCKS5 proxy: {endpoint})");
}
}
Err(error) => println!("{input} -> error: {error}"),
}
}
Ok(())
}