From 1d9802530d4b2255a05c7c348a6c2d212e53a672 Mon Sep 17 00:00:00 2001 From: emilis Date: Sun, 11 Sep 2022 17:30:19 +0100 Subject: [PATCH] added static file hosting & changed error handling again --- Cargo.lock | 92 ++++++++++++++++++++++++++++++++++++- Cargo.toml | 3 ++ src/helpers.rs | 20 -------- src/main.rs | 1 - src/servek/html.rs | 28 ++++++++++- src/servek/servek.rs | 39 +++++++++------- static/style/main.css | 4 ++ templates/html/index.html | 8 +--- templates/html/profile.html | 10 +--- 9 files changed, 149 insertions(+), 56 deletions(-) delete mode 100644 src/helpers.rs diff --git a/Cargo.lock b/Cargo.lock index 979643b..c7707de 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -214,12 +214,15 @@ dependencies = [ "anyhow", "base-62", "handlebars", + "mime_guess", "rand", + "rust-embed", "serde", "serde_json", "tokio", "tokio-postgres", "warp", + "warp-embed", ] [[package]] @@ -786,7 +789,7 @@ dependencies = [ "md-5", "memchr", "rand", - "sha2", + "sha2 0.10.5", "stringprep", ] @@ -881,6 +884,40 @@ dependencies = [ "winapi", ] +[[package]] +name = "rust-embed" +version = "6.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a17e5ac65b318f397182ae94e532da0ba56b88dd1200b774715d36c4943b1c3" +dependencies = [ + "rust-embed-impl", + "rust-embed-utils", + "walkdir", +] + +[[package]] +name = "rust-embed-impl" +version = "6.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94e763e24ba2bf0c72bc6be883f967f794a019fafd1b86ba1daff9c91a7edd30" +dependencies = [ + "proc-macro2", + "quote", + "rust-embed-utils", + "syn", + "walkdir", +] + +[[package]] +name = "rust-embed-utils" +version = "7.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "756feca3afcbb1487a1d01f4ecd94cf8ec98ea074c55a69e7136d29fb6166029" +dependencies = [ + "sha2 0.9.9", + "walkdir", +] + [[package]] name = "rustc-demangle" version = "0.1.21" @@ -899,6 +936,15 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "scoped-tls" version = "1.0.0" @@ -989,6 +1035,19 @@ dependencies = [ "digest 0.10.3", ] +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + [[package]] name = "sha2" version = "0.10.5" @@ -1368,6 +1427,17 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "walkdir" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +dependencies = [ + "same-file", + "winapi", + "winapi-util", +] + [[package]] name = "want" version = "0.3.0" @@ -1408,6 +1478,17 @@ dependencies = [ "tracing", ] +[[package]] +name = "warp-embed" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b958139e25f097e0ebde85342a3a2dbb728983ca893ba96b7fb8f448337110af" +dependencies = [ + "mime_guess", + "rust-embed", + "warp", +] + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -1430,6 +1511,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" diff --git a/Cargo.toml b/Cargo.toml index 3c0c0ae..d844a43 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,9 +9,12 @@ edition = "2021" anyhow = "1.0.64" base-62 = "0.1.1" handlebars = "4.3.3" +mime_guess = "2.0.4" rand = "0.8.5" +rust-embed = "6.4.0" serde = { version = "1.0.144", features = ["derive", "std", "serde_derive"]} serde_json = "1.0.85" tokio = { version = "1", features = ["full"] } tokio-postgres = { version = "0.7.7", features = ["with-serde_json-1"] } warp = { version = "0.3.2" } +warp-embed = "0.4.0" diff --git a/src/helpers.rs b/src/helpers.rs deleted file mode 100644 index d964050..0000000 --- a/src/helpers.rs +++ /dev/null @@ -1,20 +0,0 @@ -use warp::hyper::StatusCode; - -pub(crate) fn html_with_status(body: String, status: StatusCode) -> warp::http::Response { - warp::http::Response::builder() - .header("Content-Type", "text/html; charset=utf-8") - .status(status) - .body(body) - .expect("failed marshalling html response") -} - -pub(crate) fn html(body: String) -> warp::http::Response { - html_with_status(body, StatusCode::OK) -} - -// pub(crate) fn html(body: String) -> Result, warp::http::Error> { -// warp::http::Response::builder() -// .header("Content-Type", "text/html; charset=utf-8") -// .status(StatusCode::OK) -// .body(body) -// } diff --git a/src/main.rs b/src/main.rs index 12d2166..a4a5012 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,4 @@ mod database; -mod helpers; mod model; mod servek; mod svc; diff --git a/src/servek/html.rs b/src/servek/html.rs index 55b4c0d..ac1b4d4 100644 --- a/src/servek/html.rs +++ b/src/servek/html.rs @@ -1,8 +1,13 @@ use std::str::FromStr; -use warp::{hyper::Uri, Filter, Rejection, Reply}; +use warp::{http::HeaderValue, hyper::Uri, path::Tail, reply::Response, Filter, Rejection, Reply}; use super::servek::{Server, ServerError}; +use rust_embed::RustEmbed; + +#[derive(RustEmbed)] +#[folder = "static"] +struct StaticData; impl Server { pub(super) async fn html( @@ -10,7 +15,7 @@ impl Server { ) -> impl Filter + Clone { Self::index() .or(self.profile().await) - .or(self.create_profile().await) + .or(self.create_profile().await.or(Server::static_files())) } fn index() -> impl Filter + Clone { @@ -64,4 +69,23 @@ impl Server { }), ) } + + fn static_files() -> impl Filter + Clone { + warp::get().and(warp::path("static").and(warp::path::tail()).and_then( + |path: Tail| async move { + let asset = match StaticData::get(path.as_str()) { + Some(a) => a, + None => return Err(ServerError::NotFound.reject_self()), + }; + let mime = mime_guess::from_path(path.as_str()).first_or_octet_stream(); + + let mut res = Response::new(asset.data.into()); + res.headers_mut().insert( + "Content-Type", + HeaderValue::from_str(mime.as_ref()).unwrap(), + ); + Ok(res) + }, + )) + } } diff --git a/src/servek/servek.rs b/src/servek/servek.rs index 0197635..7953e0a 100644 --- a/src/servek/servek.rs +++ b/src/servek/servek.rs @@ -2,9 +2,14 @@ use core::panic; use std::{convert::Infallible, fmt::Display}; use handlebars::{Handlebars, RenderError}; -use warp::{hyper::StatusCode, reject::Reject, Filter, Rejection, Reply}; +use warp::{ + hyper::StatusCode, + reject::{MethodNotAllowed, Reject}, + Filter, Rejection, Reply, +}; use crate::{ + database::users::User, model, svc::profiles::{Profiler, UserError}, }; @@ -46,20 +51,19 @@ impl Server { code = StatusCode::INTERNAL_SERVER_ERROR; message = "internal server error"; } - ServerError::User(u) => match u { - UserError::Duplicate => { - code = StatusCode::BAD_REQUEST; - message = "duplicate entry"; - } - UserError::Other(_) => { - panic!("FIXME: other case should already be handled in conversions") - } - UserError::NotFound => { - code = StatusCode::NOT_FOUND; - message = "not found"; - } - }, + ServerError::NotFound => { + code = StatusCode::NOT_FOUND; + message = "not found"; + } + ServerError::Duplicate => { + code = StatusCode::BAD_REQUEST; + message = "duplicate entry exists"; + } } + } else if let Some(err) = err.find::() { + println!("MethodNotAllowed: {:#?}", err); + code = StatusCode::NOT_FOUND; + message = "not found"; } else { // We should have expected this... Just log and say its a 500 println!("FIXME: unhandled rejection: {:?}", err); @@ -77,7 +81,8 @@ impl Server { #[derive(Clone, Debug)] pub(super) enum ServerError { Internal(String), - User(UserError), + NotFound, + Duplicate, } impl ServerError { @@ -97,8 +102,8 @@ impl From for ServerError { impl From for ServerError { fn from(u: UserError) -> Self { match u { - UserError::Duplicate => Self::User(u), - UserError::NotFound => Self::User(u), + UserError::Duplicate => Self::Duplicate, + UserError::NotFound => Self::NotFound, UserError::Other(o) => Self::Internal(format!("UserError: {}", o)), } } diff --git a/static/style/main.css b/static/style/main.css index 4fb35ab..606cd46 100644 --- a/static/style/main.css +++ b/static/style/main.css @@ -2,3 +2,7 @@ body { background-color: black; color: rebeccapurple; } + +h1 { + text-align: center; +} diff --git a/templates/html/index.html b/templates/html/index.html index ee62876..6ed51de 100644 --- a/templates/html/index.html +++ b/templates/html/index.html @@ -3,13 +3,7 @@ flabk - + diff --git a/templates/html/profile.html b/templates/html/profile.html index 7f96f4f..86730a3 100644 --- a/templates/html/profile.html +++ b/templates/html/profile.html @@ -3,17 +3,11 @@ @{{username}} - + -

hi {{username}}

+

hi {{username}}, your id is {{id}}