use actix_web::{HttpRequest, http::StatusCode, web};
use std::time::Instant;
use crate::serve::{MountConfig, response_state::ResponseState};
use super::server_state::ServerState;
pub fn vertigo_handler(mount_config: &MountConfig) -> actix_web::Route {
let mount_point = mount_config.mount_point().to_string();
web::route().to(move |req: HttpRequest| {
let mount_point = mount_point.clone();
async move {
let state = ServerState::global(&mount_point);
let now = Instant::now();
let url = req.uri();
let uri = {
let path = url.path();
let local_url = if state.mount_config.mount_point() != "/" {
path.trim_start_matches(state.mount_config.mount_point())
} else {
path
};
match url.query() {
Some(query) => format!("{local_url}?{query}"),
None => local_url.to_string(),
}
};
log::debug!("Incoming request: {uri}");
let mut response_state = state.request(&uri).await;
let time = now.elapsed().as_millis();
let log_level = if time > 1000 {
log::Level::Warn
} else {
log::Level::Info
};
log::log!(
log_level,
"Response for request: {} {time}ms {uri}",
response_state.status,
);
if let Some(port_watch) = state.port_watch
&& response_state.headers.get("content-type")
== Some(&ResponseState::HTML.to_string())
{
response_state.add_watch_script(port_watch);
}
if StatusCode::from_u16(response_state.status)
.unwrap_or(StatusCode::INTERNAL_SERVER_ERROR)
.is_server_error()
{
log::error!("WASM status: {}", response_state.status);
match String::from_utf8(response_state.body.clone()) {
Ok(messagee) => {
log::error!("WASM response: text={}", messagee);
}
Err(_) => {
log::error!("WASM response: bytes={:#?}", response_state.body);
}
}
}
actix_web::HttpResponse::from(response_state)
}
})
}