98 lines
2.6 KiB
Rust
98 lines
2.6 KiB
Rust
use actix_files::NamedFile;
|
|
use actix_web::{get, post, web, HttpRequest, HttpResponse, Responder};
|
|
use log::info;
|
|
use serde::Deserialize;
|
|
|
|
use crate::errors::UserError;
|
|
use crate::SharedData;
|
|
|
|
#[derive(Clone, Debug, Deserialize)]
|
|
pub(crate) struct Mail {
|
|
mail: String,
|
|
subject: String,
|
|
message: String,
|
|
}
|
|
|
|
#[get(r"/")]
|
|
pub(crate) async fn template_index(
|
|
shared: web::Data<SharedData<'_>>,
|
|
) -> actix_web::Result<impl Responder> {
|
|
if shared.handlebars.has_template("index") {
|
|
let body = shared
|
|
.handlebars
|
|
.render("index", &())
|
|
.map_err(|_| UserError::InternalError)?;
|
|
Ok(HttpResponse::Ok().body(body))
|
|
} else {
|
|
Err(UserError::NotFound)?
|
|
}
|
|
}
|
|
|
|
#[get(r"/{filename:.*\.html}")]
|
|
pub(crate) async fn template(
|
|
shared: web::Data<SharedData<'_>>,
|
|
req: HttpRequest,
|
|
) -> actix_web::Result<impl Responder> {
|
|
let path = req
|
|
.match_info()
|
|
.query("filename")
|
|
.strip_suffix(".html")
|
|
.expect("only paths with this suffix should get here");
|
|
|
|
if shared.handlebars.has_template(path) {
|
|
let body = shared
|
|
.handlebars
|
|
.render(path, &())
|
|
.map_err(|_| UserError::InternalError)?;
|
|
Ok(HttpResponse::Ok().body(body))
|
|
} else {
|
|
Err(UserError::NotFound)?
|
|
}
|
|
}
|
|
|
|
#[get("/{filename:.*[^/]+}")]
|
|
pub(crate) async fn static_file(
|
|
shared: web::Data<SharedData<'_>>,
|
|
req: HttpRequest,
|
|
) -> actix_web::Result<impl Responder> {
|
|
let requested = req.match_info().query("filename");
|
|
|
|
match shared
|
|
.config
|
|
.template_directory
|
|
.join(requested)
|
|
.canonicalize()
|
|
{
|
|
// We only want to serve paths that are both valid *and* in
|
|
// the template directory.
|
|
//
|
|
// i.e., don't serve up /etc/passwd
|
|
Ok(path) if path.starts_with(&shared.config.template_directory) => {
|
|
let file = NamedFile::open_async(path)
|
|
.await
|
|
.map_err(|_| UserError::NotFound)?;
|
|
Ok(file.use_last_modified(false).respond_to(&req))
|
|
}
|
|
// Any other cases should 404
|
|
_ => Err(UserError::NotFound)?,
|
|
}
|
|
}
|
|
|
|
#[post("/mail.html")]
|
|
pub(crate) async fn mail_post(
|
|
shared: web::Data<SharedData<'_>>,
|
|
form: web::Form<Mail>,
|
|
) -> actix_web::Result<impl Responder> {
|
|
info!("{:?}", form);
|
|
|
|
if shared.handlebars.has_template("mail") {
|
|
let body = shared
|
|
.handlebars
|
|
.render("mail", &())
|
|
.map_err(|_| UserError::InternalError)?;
|
|
Ok(HttpResponse::Ok().body(body))
|
|
} else {
|
|
Err(UserError::InternalError)?
|
|
}
|
|
}
|