vertigo_cli/serve/
vertigo_handler.rs1use actix_web::{HttpRequest, http::StatusCode, web};
2use std::time::Instant;
3
4use crate::serve::MountConfig;
5
6use super::server_state::ServerState;
7
8pub fn vertigo_handler(mount_config: &MountConfig) -> actix_web::Route {
33 let mount_point = mount_config.mount_point().to_string();
34
35 web::route().to(move |req: HttpRequest| {
36 let mount_point = mount_point.clone();
37 async move {
38 let state = ServerState::global(&mount_point);
39 let now = Instant::now();
40 let url = req.uri();
41
42 let uri = {
43 let path = url.path();
44 let local_url = if state.mount_config.mount_point() != "/" {
46 path.trim_start_matches(state.mount_config.mount_point())
47 } else {
48 path
49 };
50
51 match url.query() {
52 Some(query) => format!("{local_url}?{query}"),
53 None => local_url.to_string(),
54 }
55 };
56
57 log::debug!("Incoming request: {uri}");
58 let mut response_state = state.request(&uri).await;
59
60 let time = now.elapsed().as_millis();
61 let log_level = if time > 1000 {
62 log::Level::Warn
63 } else {
64 log::Level::Info
65 };
66 log::log!(
67 log_level,
68 "Response for request: {} {time}ms {uri}",
69 response_state.status,
70 );
71
72 if let Some(port_watch) = state.port_watch {
73 response_state.add_watch_script(port_watch);
74 }
75
76 if StatusCode::from_u16(response_state.status)
78 .unwrap_or(StatusCode::INTERNAL_SERVER_ERROR)
79 .is_server_error()
80 {
81 log::error!("WASM status: {}", response_state.status);
82
83 match String::from_utf8(response_state.body.clone()) {
84 Ok(messagee) => {
85 log::error!("WASM response: text={}", messagee);
86 }
87 Err(_) => {
88 log::error!("WASM response: bytes={:#?}", response_state.body);
89 }
90 }
91 }
92
93 actix_web::HttpResponse::from(response_state)
94 }
95 })
96}