Skip to content

Commit

Permalink
req level ipv6 support
Browse files Browse the repository at this point in the history
  • Loading branch information
talhahwahla committed Jan 8, 2024
1 parent d97f769 commit 255d830
Showing 1 changed file with 25 additions and 23 deletions.
48 changes: 25 additions & 23 deletions src/ipinfo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ use tokio::time::timeout;

const COUNTRY_FLAG_URL: &str =
"https://cdn.ipinfo.io/static/images/countries-flags/";

const BASE_URL: &str = "https://ipinfo.io";

const BASE_URL_V6: &str = "https://v6.ipinfo.io";

/// IpInfo structure configuration.
pub struct IpInfoConfig {
/// IPinfo access token.
Expand Down Expand Up @@ -75,7 +80,6 @@ impl Default for IpInfoConfig {

/// IPinfo requests context structure.
pub struct IpInfo {
url: String,
token: Option<String>,
client: reqwest::Client,
cache: LruCache<String, IpDetails>,
Expand Down Expand Up @@ -103,7 +107,7 @@ impl Default for BatchReqOpts {
}

impl IpInfo {
/// Construct a new IpInfo structure with the default URL "https://ipinfo.io".
/// Construct a new IpInfo structure.
///
/// # Examples
///
Expand All @@ -113,28 +117,10 @@ impl IpInfo {
/// let ipinfo = IpInfo::new(Default::default()).expect("should construct");
/// ```
pub fn new(config: IpInfoConfig) -> Result<Self, IpError> {
Self::base_request(config, "https://ipinfo.io")
}

/// Construct a new IpInfo structure with the URL "https://v6.ipinfo.io/".
///
/// # Examples
///
/// ```
/// use ipinfo::IpInfo;
///
/// let ipinfo = IpInfo::new_v6(Default::default()).expect("should construct");
/// ```
pub fn new_v6(config: IpInfoConfig) -> Result<Self, IpError> {
Self::base_request(config, "https://v6.ipinfo.io/")
}

fn base_request(config: IpInfoConfig, url: &str) -> Result<Self, IpError> {
let client =
reqwest::Client::builder().timeout(config.timeout).build()?;

let mut ipinfo_obj = Self {
url: url.to_owned(),
client,
token: config.token,
cache: LruCache::new(
Expand Down Expand Up @@ -275,7 +261,7 @@ impl IpInfo {
) -> Result<HashMap<String, IpDetails>, IpError> {
// Lookup cache misses which are not bogon
let response = client
.post(&format!("{}/batch", self.url))
.post(&format!("{}/batch", BASE_URL))
.headers(Self::construct_headers())
.bearer_auth(self.token.as_deref().unwrap_or_default())
.json(&json!(ips))
Expand Down Expand Up @@ -318,6 +304,14 @@ impl IpInfo {
/// }
/// ```
pub async fn lookup(&mut self, ip: &str) -> Result<IpDetails, IpError> {
self.lookup_internal(ip, BASE_URL).await
}

pub async fn lookup_v6(&mut self, ip: &str) -> Result<IpDetails, IpError> {
self.lookup_internal(ip, BASE_URL_V6).await
}

async fn lookup_internal(&mut self, ip: &str, base_url: &str) -> Result<IpDetails, IpError> {
if is_bogon(ip) {
return Ok(IpDetails {
ip: ip.to_string(),
Expand All @@ -336,7 +330,7 @@ impl IpInfo {
// lookup in case of a cache miss
let response = self
.client
.get(&format!("{}/{}", self.url, ip))
.get(&format!("{}/{}", base_url, ip))
.headers(Self::construct_headers())
.bearer_auth(self.token.as_deref().unwrap_or_default())
.send()
Expand Down Expand Up @@ -381,11 +375,19 @@ impl IpInfo {
/// }
/// ```
pub async fn get_map(&self, ips: &[&str]) -> Result<String, IpError> {
self.get_map_internal(ips, BASE_URL).await
}

pub async fn get_map_v6(&self, ips: &[&str]) -> Result<String, IpError> {
self.get_map_internal(ips, BASE_URL_V6).await
}

async fn get_map_internal(&self, ips: &[&str], base_url: &str) -> Result<String, IpError> {
if ips.len() > 500_000 {
return Err(err!(MapLimitError));
}

let map_url = &format!("{}/tools/map?cli=1", self.url);
let map_url = &format!("{}/tools/map?cli=1", base_url);
let client = self.client.clone();
let json_ips = serde_json::json!(ips);

Expand Down

0 comments on commit 255d830

Please sign in to comment.