- main
- manifest
- deps
- main
- Install
- Run
use fastly::http::{header, StatusCode};
use fastly::{geo, ConfigStore, Error, Request, Response};
use log::LevelFilter::Info;
use regex::Regex;
const BACKEND_NAME: &str = "origin_0";
#[fastly::main]
fn main(mut req: Request) -> Result<Response, Error> {
log_fastly::init_simple("mylogs", Info);
let mut latitude = 0.0f64;
let mut longtitude = 0.0f64;
if let Some(geo) = req.get_client_ip_addr().and_then(geo::geo_lookup) {
let country_code = geo.country_code();
let dict = ConfigStore::open("region_defs");
let region = if let Some(region) = dict.get(country_code) {
region
} else if let Some(region) = dict.get("_default") {
region
} else {
"blocked".to_owned()
};
log::info!("Country: {}, Region: {}", country_code, region);
if region == "blocked" {
return Ok(
Response::from_status(StatusCode::FORBIDDEN).with_body_text_plain(
"Sorry, our service is currently not available in your region\n",
),
);
}
let continent = geo.continent().as_code();
req.set_header("client-geo-country", country_code);
req.set_header("client-geo-region", region);
req.set_header("client-geo-continent", continent);
log::info!("Continent: {}", continent);
latitude = geo.latitude();
longtitude = geo.longitude();
}
if let Some((lat, lng)) = get_cookie_geo(&req) {
latitude = lat;
longtitude = lng;
}
req.set_header(
"client-geo-latlng",
format!("{:.1}, {:.1}", latitude, longtitude),
);
log::info!("Lat:{}, Lng: {}", latitude, longtitude);
Ok(req.send(BACKEND_NAME)?)
}
fn get_cookie_geo(req: &Request) -> Option<(f64, f64)> {
let cookie_val: &str = req.get_header(header::COOKIE)?.to_str().ok()?;
let geo_string = cookie_val.split(';').find_map(|kv| {
let index = kv.find('=')?;
let (key, value) = kv.split_at(index);
if key.trim() != "client-geo-latlng" {
return None;
}
let value = value[1..].to_string();
Some(value)
})?;
let geo = urlencoding::decode(&geo_string).ok()?;
let geo_cap = Regex::new(r"^([0-9\.]+),\s*([0-9\.]+)$")
.ok()?
.captures(&geo)?;
let lat: f64 = geo_cap.get(1)?.as_str().parse().ok()?;
let long: f64 = geo_cap.get(2)?.as_str().parse().ok()?;
Some((lat, long))
}