Hook up the range data to the API
parent
9656d070b6
commit
300b827915
|
@ -154,6 +154,8 @@ name = "geoip-api"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"itertools",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tokio",
|
||||
"warp",
|
||||
]
|
||||
|
@ -646,6 +648,20 @@ name = "serde"
|
|||
version = "1.0.132"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b9875c23cf305cd1fd7eb77234cbb705f21ea6a72c637a5c6db5fe4b8e7f008"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.132"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ecc0db5cb2556c0e558887d9bbdcf6ac4471e83ff66cf696e5419024d1606276"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
|
|
|
@ -6,5 +6,7 @@ authors = ["charlotte ✨ <charlotte@lavender.software>"]
|
|||
|
||||
[dependencies]
|
||||
itertools = "0.10.3"
|
||||
serde = { version = "1.0.132", features = ["derive"] }
|
||||
serde_json = "1.0.73"
|
||||
tokio = { version = "1.15.0", features = ["full"] }
|
||||
warp = "0.3.2"
|
||||
|
|
45
src/main.rs
45
src/main.rs
|
@ -1,13 +1,18 @@
|
|||
use itertools::Itertools;
|
||||
use serde::Serialize;
|
||||
use std::{net::Ipv4Addr, sync::Arc};
|
||||
|
||||
use warp::Filter;
|
||||
use warp::{http::StatusCode, reply, Filter};
|
||||
|
||||
use serde_json::json;
|
||||
|
||||
const IP2ASN_DATA: &str = include_str!("../data/ip2asn-v4.tsv");
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Serialize)]
|
||||
struct RangeRecord {
|
||||
#[serde(skip)]
|
||||
ip_start: Ipv4Addr,
|
||||
#[serde(skip)]
|
||||
ip_end: Ipv4Addr,
|
||||
asn: u64,
|
||||
country_code: &'static str,
|
||||
|
@ -38,13 +43,43 @@ fn parse_ranges() -> Vec<RangeRecord> {
|
|||
ranges
|
||||
}
|
||||
|
||||
type RangeData = Arc<Vec<RangeRecord>>;
|
||||
fn with_ranges(
|
||||
ranges: RangeData,
|
||||
) -> impl Filter<Extract = (RangeData,), Error = std::convert::Infallible> + Clone {
|
||||
warp::any().map(move || ranges.clone())
|
||||
}
|
||||
|
||||
fn get_range_data(ip: String, ranges: RangeData) -> impl warp::Reply {
|
||||
if let Ok(ipv4) = ip.parse::<Ipv4Addr>() {
|
||||
for range in ranges.iter() {
|
||||
if (range.ip_start..=range.ip_end).contains(&ipv4) {
|
||||
return reply::with_status(reply::json(&range), StatusCode::OK);
|
||||
}
|
||||
}
|
||||
|
||||
reply::with_status(
|
||||
reply::json(&json!({ "error": "range not found" })),
|
||||
StatusCode::NOT_FOUND,
|
||||
)
|
||||
} else {
|
||||
reply::with_status(
|
||||
reply::json(&json!({ "error": "invalid ipv4 address" })),
|
||||
StatusCode::BAD_REQUEST,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
eprintln!("[i] Parsing IP ASN data...");
|
||||
let _ranges = Arc::new(parse_ranges());
|
||||
let ranges: RangeData = Arc::new(parse_ranges());
|
||||
eprintln!("[i] Done!");
|
||||
|
||||
let hello = warp::any().map(|| "Hello!".to_string());
|
||||
let get_ip_data = warp::path!(String)
|
||||
.and(with_ranges(ranges.clone()))
|
||||
.map(get_range_data);
|
||||
|
||||
println!("\nListening on http://127.0.0.1:8000 ...");
|
||||
warp::serve(hello).bind(([127, 0, 0, 1], 8000)).await;
|
||||
warp::serve(get_ip_data).bind(([127, 0, 0, 1], 8000)).await;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue