- main
- manifest
- deps
- main
- Install
- Run
use fastly::http::header;
use fastly::{Error, Request, Response};
use lazy_static::lazy_static;
use regex::Regex;
const BACKEND_NAME: &str = "origin_0";
const MAX_REDIRECT_COUNT: u32 = 2;
lazy_static! {
static ref LOCATION_CAP: Regex = Regex::new(r"^(?:https?://([^/]+))?(/.*)?$").unwrap();
}
#[fastly::main]
fn main(mut req: Request) -> Result<Response, Error> {
log_fastly::init_simple("my_log", log::LevelFilter::Info);
fastly::log::set_panic_endpoint("my_log").unwrap();
let request_host = req
.get_header(header::HOST)
.expect("host will be present")
.clone();
let mut req_redirect = req.clone_with_body();
let mut resp = req.send(BACKEND_NAME)?;
let mut redirect_count = 0;
while resp.get_status().is_redirection() && redirect_count < MAX_REDIRECT_COUNT {
if let Some((redirect_host, redirect_path_query)) = get_location_from_resp(&resp) {
log::info!(
"Redirect to {}{}, redirect count {}",
redirect_host,
redirect_path_query,
redirect_count
);
if redirect_host.is_empty() || redirect_host == request_host {
let redirect_url = format!("http://dummy-host{}", redirect_path_query);
req_redirect.set_url(redirect_url);
let req_clone = req_redirect.clone_with_body();
resp = req_redirect.send(BACKEND_NAME)?;
req_redirect = req_clone;
redirect_count += 1;
continue;
}
}
break;
}
Ok(resp)
}
fn get_location_from_resp(resp: &Response) -> Option<(&str, &str)> {
let location = resp.get_header_str(header::LOCATION)?;
let location_cap = LOCATION_CAP.captures(location)?;
let host = match location_cap.get(1) {
Some(host_match) => host_match.as_str(),
None => "",
};
let path_query = match location_cap.get(2) {
Some(path_query_match) => path_query_match.as_str(),
None => "/",
};
Some((host, path_query))
}