Migrate to actix-web #8
13
Cargo.lock
generated
13
Cargo.lock
generated
|
@ -44,9 +44,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "actix-http"
|
||||
version = "3.2.1"
|
||||
version = "3.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f9ffb6db08c1c3a1f4aef540f1a63193adc73c4fbd40b75a95fc8c5258f6e51"
|
||||
checksum = "0c83abf9903e1f0ad9973cc4f7b9767fd5a03a583f51a5b7a339e07987cd2724"
|
||||
dependencies = [
|
||||
"actix-codec",
|
||||
"actix-rt",
|
||||
|
@ -154,9 +154,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "actix-web"
|
||||
version = "4.1.0"
|
||||
version = "4.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a27e8fe9ba4ae613c21f677c2cfaf0696c3744030c6f485b34634e502d6bb379"
|
||||
checksum = "d48f7b6534e06c7bfc72ee91db7917d4af6afe23e7d223b51e68fffbb21e96b9"
|
||||
dependencies = [
|
||||
"actix-codec",
|
||||
"actix-http",
|
||||
|
@ -176,6 +176,7 @@ dependencies = [
|
|||
"encoding_rs",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"http",
|
||||
"itoa",
|
||||
"language-tags",
|
||||
"log",
|
||||
|
@ -194,9 +195,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "actix-web-codegen"
|
||||
version = "4.0.1"
|
||||
version = "4.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f270541caec49c15673b0af0e9a00143421ad4f118d2df7edcb68b627632f56"
|
||||
checksum = "1fa9362663c8643d67b2d5eafba49e4cb2c8a053a29ed00a0bea121f17c76b13"
|
||||
dependencies = [
|
||||
"actix-router",
|
||||
"proc-macro2",
|
||||
|
|
|
@ -5,7 +5,7 @@ edition = "2021"
|
|||
|
||||
[dependencies]
|
||||
actix-files = "0.6.2"
|
||||
actix-web = "4.1.0"
|
||||
actix-web = { version = "4.2.1", features = ["macros"] }
|
||||
clap = { version = "3.2.17", features = ["derive"] }
|
||||
derive_more = "0.99.17"
|
||||
env_logger = "0.9.0"
|
||||
|
|
|
@ -7,7 +7,7 @@ use actix_web::{web, HttpResponse, ResponseError};
|
|||
use derive_more::{Display, Error};
|
||||
|
||||
use super::SharedData;
|
||||
use crate::template_utils::{ErrorMessage, TemplateArgs};
|
||||
use crate::template_utils::{render_template, ErrorMessage, TemplateArgs};
|
||||
|
||||
#[derive(Debug, Display, Error)]
|
||||
pub enum UserError {
|
||||
|
@ -56,8 +56,7 @@ pub fn generic_error<B>(
|
|||
.error_page(ErrorMessage::new(message, status_code.as_u16()))
|
||||
.build();
|
||||
|
||||
let body = handlebars
|
||||
.render("error", &args)
|
||||
let body = render_template(handlebars, "error", &args)
|
||||
.map_err(|_| UserError::InternalError)?;
|
||||
|
||||
HttpResponse::build(res.status())
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
use std::net::SocketAddr;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use actix_files::Files;
|
||||
use actix_web::{
|
||||
http::{Method, StatusCode},
|
||||
middleware::{self, ErrorHandlers},
|
||||
|
@ -15,7 +16,7 @@ mod main_pages;
|
|||
mod template_utils;
|
||||
|
||||
use errors::generic_error;
|
||||
use main_pages::{mail_post, static_file, template, template_index};
|
||||
use main_pages::{mail_post, template};
|
||||
|
||||
#[derive(Parser, Debug, Clone)]
|
||||
struct Config {
|
||||
|
@ -66,9 +67,8 @@ async fn main() -> std::io::Result<()> {
|
|||
)
|
||||
.app_data(shared_data.clone())
|
||||
.service(template)
|
||||
.service(static_file)
|
||||
.service(template_index)
|
||||
.service(mail_post)
|
||||
.service(Files::new("/", &config.template_directory))
|
||||
.default_service(web::route().method(Method::GET))
|
||||
})
|
||||
.bind(config.address)?
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
use actix_files::NamedFile;
|
||||
use actix_web::{get, post, web, HttpRequest, HttpResponse, Responder};
|
||||
use actix_web::{post, routes, web, HttpRequest, HttpResponse, Responder};
|
||||
use log::info;
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::errors::UserError;
|
||||
use crate::template_utils::TemplateArgs;
|
||||
use crate::template_utils::{Flash, FlashType};
|
||||
use crate::template_utils::{render_template, Flash, FlashType, TemplateArgs};
|
||||
use crate::SharedData;
|
||||
|
||||
#[derive(Clone, Debug, Deserialize)]
|
||||
|
@ -15,69 +12,22 @@ pub(crate) struct Mail {
|
|||
message: String,
|
||||
}
|
||||
|
||||
#[routes]
|
||||
#[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");
|
||||
let path = match req.match_info().query("filename") {
|
||||
"" => "index",
|
||||
other => other
|
||||
.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)?,
|
||||
}
|
||||
render_template(&shared.handlebars, path, &TemplateArgs::default())
|
||||
.map(|body| HttpResponse::Ok().body(body))
|
||||
}
|
||||
|
||||
#[post("/mail.html")]
|
||||
|
@ -91,13 +41,5 @@ pub(crate) async fn mail_post(
|
|||
.flash(Flash::new("Mail successfully sent!", FlashType::Success))
|
||||
.build();
|
||||
|
||||
if shared.handlebars.has_template("mail") {
|
||||
let body = shared
|
||||
.handlebars
|
||||
.render("mail", &args)
|
||||
.map_err(|_| UserError::InternalError)?;
|
||||
Ok(HttpResponse::Ok().body(body))
|
||||
} else {
|
||||
Err(UserError::InternalError)?
|
||||
}
|
||||
render_template(&shared.handlebars, "mail", &args).map(|body| HttpResponse::Ok().body(body))
|
||||
}
|
||||
|
|
|
@ -1,7 +1,23 @@
|
|||
use serde::Serialize;
|
||||
|
||||
use crate::errors::UserError;
|
||||
|
||||
pub fn render_template(
|
||||
handlebars: &handlebars::Handlebars,
|
||||
name: &str,
|
||||
args: &TemplateArgs,
|
||||
) -> actix_web::Result<String> {
|
||||
if handlebars.has_template(name) {
|
||||
Ok(handlebars
|
||||
.render(name, args)
|
||||
.map_err(|_| UserError::InternalError)?)
|
||||
} else {
|
||||
Err(UserError::NotFound)?
|
||||
}
|
||||
}
|
||||
|
||||
/** All arguments that can be given to a template. */
|
||||
#[derive(Serialize)]
|
||||
#[derive(Default, Serialize)]
|
||||
pub struct TemplateArgs {
|
||||
flash: Option<Flash>,
|
||||
error: Option<ErrorMessage>,
|
||||
|
|
Loading…
Reference in a new issue