use rand::seq::SliceRandom;
use std::time::Duration;
pub fn get_public_ip_addr() -> Option<String> {
let sources = vec![
("https://icanhazip.com/", false), ("https://api.ip.sb/ip", false), ("https://api.ipsimple.org/ipv4?format=json", true), ("https://api.ipify.org/?format=json", true), ];
let client = reqwest::blocking::Client::builder()
.timeout(Duration::from_secs(3))
.build()
.unwrap();
let mut rng = rand::thread_rng();
let mut shuffled = sources.clone();
shuffled.shuffle(&mut rng);
for (url, is_json) in shuffled {
if let Ok(resp) = client.get(url).send() {
if is_json {
if let Ok(json) = resp.json::<serde_json::Value>() {
if let Some(ip) = json.get("ip").and_then(|v| v.as_str()) {
return Some(ip.to_string());
}
}
} else if let Ok(text) = resp.text() {
let ip = text.trim().to_string();
if !ip.is_empty() {
return Some(ip);
}
}
}
}
None
}