//! A small blocking HTTP client for the few requests the app makes itself: //! version checks and usage hubs. Call it from a background task. use std::time::Duration; /// GETs `url` and returns the body, or a short description of what failed. pub fn get(url: &str, headers: &[(&str, &str)], timeout: Duration) -> Result { let agent = ureq::AgentBuilder::new().timeout(timeout).build(); let mut request = agent.get(url).set("User-Agent", concat!("vectrum-code/", env!("CARGO_PKG_VERSION"))); for (name, value) in headers { request = request.set(name, value); } match request.call() { Ok(response) => response.into_string().map_err(|err| err.to_string()), Err(ureq::Error::Status(code, response)) => { let body = response.into_string().unwrap_or_default(); let detail = serde_json::from_str::(&body) .ok() .and_then(|value| value.get("error").and_then(|error| error.as_str()).map(str::to_string)) .unwrap_or_else(|| body.trim().chars().take(120).collect()); Err(if detail.is_empty() { format!("HTTP {code}") } else { format!("HTTP {code}: {detail}") }) } Err(err) => Err(err.to_string()), } }