use super::preview_request;
use crate::commands::dev;
use crate::commands::dev::gcs::headers::destructure_response;
use crate::commands::dev::server_config::ServerConfig;
use crate::commands::dev::utils::{get_path_as_str, rewrite_redirect};
use crate::terminal::emoji;
use std::sync::{Arc, Mutex};
use anyhow::Result;
use chrono::prelude::*;
use hyper::service::{make_service_fn, service_fn};
use hyper::{Response, Server};
pub async fn http(server_config: ServerConfig, preview_id: Arc<Mutex<String>>) -> Result<()> {
let client = dev::client();
let listening_address = server_config.listening_address;
let make_service = make_service_fn(move |_| {
let client = client.to_owned();
let server_config = server_config.to_owned();
let preview_id = preview_id.to_owned();
async move {
Ok::<_, anyhow::Error>(service_fn(move |req| {
let client = client.to_owned();
let server_config = server_config.to_owned();
let preview_id = preview_id.lock().unwrap().to_owned();
let version = req.version();
let now: DateTime<Local> = Local::now();
let (parts, body) = req.into_parts();
let local_host = format!(
"{}:{}",
server_config.listening_address.ip().to_string(),
server_config.listening_address.port().to_string()
);
let req_method = parts.method.to_string();
let path = get_path_as_str(&parts.uri);
async move {
let resp = client
.request(preview_request(parts, body, preview_id.to_owned()))
.await?;
let (mut parts, body) = resp.into_parts();
destructure_response(&mut parts)?;
let mut resp = Response::from_parts(parts, body);
rewrite_redirect(
&mut resp,
&server_config.host.to_string(),
&local_host,
false,
);
println!(
"[{}] {} {}{} {:?} {}",
now.format("%Y-%m-%d %H:%M:%S"),
req_method,
server_config.host,
path,
version,
resp.status()
);
Ok::<_, anyhow::Error>(resp)
}
}))
}
});
let server = Server::bind(&listening_address).serve(make_service);
println!(
"{} Listening on http://{}",
emoji::EAR,
listening_address.to_string()
);
if let Err(e) = server.await {
eprintln!("server error: {}", e);
}
Ok(())
}