1use crate::SyncError;
10use sioul_core::pgp::{self, KeySummary};
11use std::time::Duration;
12
13pub fn lookup(address: &str) -> Result<Vec<KeySummary>, SyncError> {
15 let address = address.trim();
16 let agent: ureq::Agent = ureq::Agent::config_builder().timeout_global(Some(Duration::from_secs(15))).https_only(true).build().into();
18 let mut urls: Vec<String> = pgp::wkd_urls(address).map(Vec::from).unwrap_or_default();
19 let encoded: String = address.bytes().map(|b| if b.is_ascii_alphanumeric() || b"-._~".contains(&b) { (b as char).to_string() } else { format!("%{b:02X}") }).collect();
20 urls.push(format!("https://keys.openpgp.org/vks/v1/by-email/{encoded}"));
21 let mut last_error = None;
22 for url in urls {
23 match agent.get(&url).call() {
24 Ok(mut response) => {
25 let bytes = response.body_mut().read_to_vec().unwrap_or_default();
26 let found = pgp::learn(&bytes, address);
27 if !found.is_empty() {
28 return Ok(found);
29 }
30 }
31 Err(ureq::Error::StatusCode(_)) => {}
32 Err(e) => last_error = Some(e.to_string()),
33 }
34 }
35 match last_error {
36 Some(e) => Err(SyncError::Network(e)),
37 None => Ok(Vec::new()),
38 }
39}