diff --git a/Cargo.toml b/Cargo.toml
index 2b4163d..b1d6d63 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -39,7 +39,10 @@ rate_limit = ["dep:rate_limit"]
websocket = ["dep:websocket"]
[workspace.dependencies]
-aws-sdk-s3 = "1.21.0"
+aws-sdk-s3 = { version = "1.137", default-features = false, features = [
+ "rt-tokio",
+ "default-https-client",
+] }
axum = "0.8.7"
[dependencies]
diff --git a/crates/analytics/Cargo.toml b/crates/analytics/Cargo.toml
index 7e323d7..d420264 100644
--- a/crates/analytics/Cargo.toml
+++ b/crates/analytics/Cargo.toml
@@ -18,7 +18,7 @@ tap = "1.0"
chrono = { version = "0.4" }
aws-sdk-s3.workspace = true
bytes = "1.5"
-parquet = { version = "57.1", default-features = false, features = ["flate2-rust_backened"] }
+parquet = { version = "59", default-features = false, features = ["flate2-rust_backened"] }
[dev-dependencies]
-parquet_derive = "57.1"
+parquet_derive = "59"
diff --git a/crates/geoip/Cargo.toml b/crates/geoip/Cargo.toml
index 77347c0..0c6abba 100644
--- a/crates/geoip/Cargo.toml
+++ b/crates/geoip/Cargo.toml
@@ -20,7 +20,7 @@ thiserror = "1.0"
futures = "0.3"
bytes = "1.5"
aws-sdk-s3.workspace = true
-maxminddb = "0.23"
+maxminddb = "0.27"
[dev-dependencies]
tokio = { version = "1", features = ["full"] }
diff --git a/crates/geoip/src/block.rs b/crates/geoip/src/block.rs
index 362d1e4..df18aaf 100644
--- a/crates/geoip/src/block.rs
+++ b/crates/geoip/src/block.rs
@@ -72,10 +72,7 @@ impl ZoneFilter {
.lookup_geo_data_raw(addr)
.map_err(|_| Error::UnableToExtractGeoData)?;
- let country = geo_data
- .country
- .and_then(|country| country.iso_code)
- .ok_or(Error::CountryNotFound)?;
+ let country = geo_data.country.iso_code.ok_or(Error::CountryNotFound)?;
let zone_blocked = self.blocked_zones.iter().any(|blocked_zone| {
if blocked_zone.country == country {
@@ -84,17 +81,13 @@ impl ZoneFilter {
} else {
geo_data
.subdivisions
- .as_deref()
- .is_some_and(|subdivisions| {
- subdivisions
+ .iter()
+ .filter_map(|sub| sub.iso_code)
+ .any(|sub| {
+ blocked_zone
+ .subdivisions
.iter()
- .filter_map(|sub| sub.iso_code)
- .any(|sub| {
- blocked_zone
- .subdivisions
- .iter()
- .any(|blocked_sub| sub.eq_ignore_ascii_case(blocked_sub))
- })
+ .any(|blocked_sub| sub.eq_ignore_ascii_case(blocked_sub))
})
}
} else {
diff --git a/crates/geoip/src/block/middleware/tests.rs b/crates/geoip/src/block/middleware/tests.rs
index 1632488..93831e6 100644
--- a/crates/geoip/src/block/middleware/tests.rs
+++ b/crates/geoip/src/block/middleware/tests.rs
@@ -16,50 +16,31 @@ async fn handle(_request: Request
) -> Result, Infallible> {
fn resolve_ip_no_subs(_addr: IpAddr) -> City<'static> {
City {
- city: None,
- continent: None,
- country: Some(geoip2::city::Country {
- geoname_id: None,
- is_in_european_union: None,
+ country: geoip2::city::Country {
iso_code: Some("CU"),
- names: None,
- }),
- location: None,
- postal: None,
- registered_country: None,
- represented_country: None,
- subdivisions: None,
- traits: None,
+ ..Default::default()
+ },
+ ..Default::default()
}
}
fn resolve_ip(_addr: IpAddr) -> City<'static> {
City {
- city: None,
- continent: None,
- country: Some(geoip2::city::Country {
- geoname_id: None,
- is_in_european_union: None,
+ country: geoip2::city::Country {
iso_code: Some("CU"),
- names: None,
- }),
- location: None,
- postal: None,
- registered_country: None,
- represented_country: None,
- subdivisions: Some(vec![
+ ..Default::default()
+ },
+ subdivisions: vec![
geoip2::city::Subdivision {
- geoname_id: None,
iso_code: Some("12"),
- names: None,
+ ..Default::default()
},
geoip2::city::Subdivision {
- geoname_id: None,
iso_code: Some("34"),
- names: None,
+ ..Default::default()
},
- ]),
- traits: None,
+ ],
+ ..Default::default()
}
}
diff --git a/crates/geoip/src/lib.rs b/crates/geoip/src/lib.rs
index 9407b38..408ba2d 100644
--- a/crates/geoip/src/lib.rs
+++ b/crates/geoip/src/lib.rs
@@ -116,7 +116,10 @@ pub enum MaxMindResolverError {
ByteStream(Box),
#[error("MaxMind DB lookup error: {0}")]
- MaxMindDB(#[from] maxminddb::MaxMindDBError),
+ MaxMindDB(#[from] maxminddb::MaxMindDbError),
+
+ #[error("Address not found in MaxMind DB")]
+ AddressNotFound,
}
impl From> for MaxMindResolverError {
@@ -165,29 +168,27 @@ impl Resolver for MaxMindResolver {
type Error = MaxMindResolverError;
fn lookup_geo_data_raw(&self, addr: IpAddr) -> Result, Self::Error> {
- self.reader.lookup::(addr).map_err(Into::into)
+ self.reader
+ .lookup(addr)?
+ .decode::()?
+ .ok_or(MaxMindResolverError::AddressNotFound)
}
fn lookup_geo_data(&self, addr: IpAddr) -> Result {
let lookup_data = self.lookup_geo_data_raw(addr)?;
+ let region: Vec = lookup_data
+ .subdivisions
+ .into_iter()
+ .filter_map(|div| div.iso_code)
+ .map(Into::into)
+ .collect();
+
Ok(Data {
- continent: lookup_data
- .continent
- .and_then(|continent| continent.code.map(Into::into)),
- country: lookup_data
- .country
- .and_then(|country| country.iso_code.map(Into::into)),
- region: lookup_data.subdivisions.map(|divs| {
- divs.into_iter()
- .filter_map(|div| div.iso_code)
- .map(Into::into)
- .collect()
- }),
- city: lookup_data
- .city
- .and_then(|city| city.names)
- .and_then(|city_names| city_names.get("en").copied().map(Into::into)),
+ continent: lookup_data.continent.code.map(Into::into),
+ country: lookup_data.country.iso_code.map(Into::into),
+ region: (!region.is_empty()).then_some(region),
+ city: lookup_data.city.names.english.map(Into::into),
})
}
}
diff --git a/examples/geoblock.rs b/examples/geoblock.rs
index f54b006..5592153 100644
--- a/examples/geoblock.rs
+++ b/examples/geoblock.rs
@@ -16,20 +16,11 @@ async fn handle(_request: Request) -> Result, Infallible> {
fn resolve_ip(_addr: IpAddr) -> geoip2::City<'static> {
geoip2::City {
- city: None,
- continent: None,
- country: Some(geoip2::city::Country {
- geoname_id: None,
- is_in_european_union: None,
+ country: geoip2::city::Country {
iso_code: Some("IR"),
- names: None,
- }),
- location: None,
- postal: None,
- registered_country: None,
- represented_country: None,
- subdivisions: None,
- traits: None,
+ ..Default::default()
+ },
+ ..Default::default()
}
}