CDN Edge redirection
Base on GeoIp information and accept language header, redirect to the right path.
Compute
Use this solution in your CDB Edge Compute service:
use proxy_wasm::traits::*;
use proxy_wasm::types::*;
proxy_wasm::main! {{
proxy_wasm::set_log_level(LogLevel::Trace);
proxy_wasm::set_root_context(|_| -> Box<dyn RootContext> { Box::new(HttpHeadersRoot) });
}}
struct HttpHeadersRoot;
impl Context for HttpHeadersRoot {}
impl RootContext for HttpHeadersRoot {
fn create_http_context(&self, _context_id: u32) -> Option<Box<dyn HttpContext>> {
Some(Box::new(HttpHeaders {}))
}
fn get_type(&self) -> Option<ContextType> {
Some(ContextType::HttpContext)
}
}
struct HttpHeaders {}
impl Context for HttpHeaders {}
const INTERNAL_SERVER_ERROR: u32 = 500;
const FOUND: u32 = 302;
impl HttpContext for HttpHeaders {
fn on_http_request_headers(&mut self, _: usize, _: bool) -> Action {
let Some(country_code) = self.get_property(vec!["request.country"]) else {
self.send_http_response(
INTERNAL_SERVER_ERROR,
vec![],
Some(b"Malformed request - no country field"),
);
println!("Malformed request - no country field");
return Action::Pause;
};
let Ok(country_code) = std::str::from_utf8(&country_code) else {
self.send_http_response(
INTERNAL_SERVER_ERROR,
vec![],
Some(b"Malformed request - country not utf8 string"),
);
println!("Malformed request - country not utf8 string");
return Action::Pause;
};
println!("country: {}|", country_code);
let Some(fowarded_host) = self.get_http_request_header("X-Forwarded-Host") else {
println!("no fowarded_host field");
self.send_http_response(INTERNAL_SERVER_ERROR, vec![], Some(b"Malformed request - no fowarded_host field"));
return Action::Pause;
};
println!("fowarded_host: {}|", fowarded_host.as_str());
let Some(fowarded_proto) = self.get_http_request_header("X-Forwarded-Proto") else {
println!("no fowarded_proto field");
self.send_http_response(INTERNAL_SERVER_ERROR, vec![], Some(b"Malformed request - no fowarded_proto field"));
return Action::Pause;
};
println!("fowarded_proto: {}|", fowarded_proto.as_str());
let Some(accept_language) = self.get_http_request_header("accept-language") else {
println!("no accept_language field");
self.send_http_response(INTERNAL_SERVER_ERROR, vec![], Some(b"Malformed request - no accept_language field"));
return Action::Pause;
};
println!("accept_language: {}|", accept_language.as_str());
// Détermination du chemin selon les règles`
let location_path = if accept_language.contains("pt-br") {
"/br"
} else if accept_language.contains("es") {
"/es"
} else {
match country_code {
"FR" => "/fr",
"BE" => "/be-en",
"LU" => "/lu-en",
_ => "/en",
}
};
let redirection_location = format!("{}://{}{}", fowarded_proto, fowarded_host, location_path);
println!("redirection_location: {}|", redirection_location);
self.add_http_response_header("Location", redirection_location.as_str());
self.send_http_response(FOUND, vec![], Some(b"redirection"));
return Action::Pause;
}
}