1use reqwest::redirect::Policy;
2use reqwest::StatusCode;
3use serde::Deserialize;
4use serde_json::Value;
5pub async fn geo_ip<T: Deserialize<'static>>(ipv4: Option<String>) -> anyhow::Result<T> {
21 let client = reqwest::Client::builder()
22 .timeout(std::time::Duration::from_secs(10))
23 .redirect(Policy::none())
24 .build()?;
25 let api = if let Some(addr) = ipv4 {
26 format!("https://qifu-api.baidubce.com/ip/geo/v1/district?ip={addr}")
27 } else {
28 "https://qifu-api.baidubce.com/ip/local/geo/v1/district".to_owned()
29 };
30 let res = client
31 .get(api)
32 .header(
33 "User-Agent",
34 "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/116.0",
35 )
36 .send()
37 .await?;
38 if res.status() == StatusCode::OK {
39 let body = res.json::<Value>().await?;
40 return Ok(T::deserialize(body)?);
41 } else {
42 return Err(anyhow::anyhow!("http response is not ok"));
43 }
44}