1
Fork 0
mirror of https://github.com/RGBCube/Site synced 2025-08-01 13:37:49 +00:00

Start rewriting for axum

This commit is contained in:
RGBCube 2024-01-07 23:59:07 +03:00
parent a5ffcce3c8
commit 52783348df
No known key found for this signature in database
10 changed files with 417 additions and 824 deletions

1022
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -9,8 +9,9 @@ repositoty = "https://github.com/RGBCube/rgbcube.github.io"
edition = "2021" edition = "2021"
[dependencies] [dependencies]
actix-web = { version = "4.4.1", features = [ "openssl" ] }
anyhow = "1.0.77" anyhow = "1.0.77"
axum = "0.7.3"
axum-server = { version = "0.6.0", features = [ "tls-rustls" ] }
bytes = "1.5.0" bytes = "1.5.0"
cargo_toml = "0.17.2" cargo_toml = "0.17.2"
chrono = "0.4.31" chrono = "0.4.31"
@ -18,11 +19,13 @@ clap = { version = "4.4.12", features = [ "derive" ] }
embed = { git = "https://github.com/RGBCube/embed-rs" } embed = { git = "https://github.com/RGBCube/embed-rs" }
env_logger = "0.10.1" env_logger = "0.10.1"
log = { version = "0.4.20", features = [ "serde" ] } log = { version = "0.4.20", features = [ "serde" ] }
maud = { version = "0.25.0", features = [ "actix-web" ] } maud = { git = "https://github.com/lambda-fairy/maud", features = [ "axum" ] }
mime_guess = "2.0.4" mime_guess = "2.0.4"
minify-js = "0.6.0" minify-js = "0.6.0"
openssl = "0.10.62"
pulldown-cmark = "0.9.3" pulldown-cmark = "0.9.3"
tokio = { version = "1.35.1", features = [ "full" ] }
tower = "0.4.13"
tower-http = { version = "0.5.0", features = [ "trace" ] }
[patch.crates-io] [patch.crates-io]
proc-macro2 = { git = "https://github.com/RGBCube/proc-macro2" } proc-macro2 = { git = "https://github.com/RGBCube/proc-macro2" }

View file

@ -72,12 +72,7 @@
inherit cargoArtifacts; inherit cargoArtifacts;
}); });
in { in {
devShells.${system}.default = crane.devShell { devShells.${system}.default = crane.devShell {};
packages = with nixpkgs.legacyPackages.${system}; [
openssl
pkg-config
];
};
checks.${system} = { checks.${system} = {
inherit site; inherit site;

View file

@ -1,16 +1,11 @@
use axum::Router;
mod internal_server_error; mod internal_server_error;
mod not_found; mod not_found;
use actix_web::{
http::StatusCode,
middleware::ErrorHandlers,
};
pub fn handler<B: 'static>() -> ErrorHandlers<B> { pub fn handler<B: 'static>() -> ErrorHandlers<B> {
ErrorHandlers::new() Router::new().fallback(not_found::handler).handler(
.handler(StatusCode::NOT_FOUND, not_found::handler) StatusCode::INTERNAL_SERVER_ERROR,
.handler( internal_server_error::handler,
StatusCode::INTERNAL_SERVER_ERROR, )
internal_server_error::handler,
)
} }

View file

@ -1,44 +1,29 @@
use std::array; use std::array;
use actix_web::{ use maud::{
dev::ServiceResponse, html,
middleware::ErrorHandlerResponse, Markup,
}; };
use maud::html;
use crate::{ use crate::{
asset, asset,
page::cube, page::cube,
}; };
pub fn handler<B: 'static>( pub fn handler() -> Markup {
response: ServiceResponse<B>, cube::create(
) -> actix_web::Result<ErrorHandlerResponse<B>> { Some("404"),
let (request, response) = response.into_parts(); asset::Css::Shared("cube-grid.css"),
array::from_fn(|_| {
let response = response.set_body( html! {
cube::create( .frame {
Some("404"), a href="/" { "404" }
asset::Css::Shared("cube-grid.css"), }
array::from_fn(|_| { .square .black {}
(html! { .square .magenta {}
.frame { .square .magenta {}
a href="/" { "404" } .square .black {}
} }
.square .black {} }),
.square .magenta {} )
.square .magenta {}
.square .black {}
})
.clone()
}),
)
.into_string(),
);
Ok(ErrorHandlerResponse::Response(
ServiceResponse::new(request, response)
.map_into_boxed_body()
.map_into_right_body(),
))
} }

View file

@ -1,4 +1,4 @@
#![feature(iterator_try_collect, lazy_cell, let_chains)] #![feature(lazy_cell, let_chains)]
mod asset; mod asset;
mod errors; mod errors;
@ -7,21 +7,16 @@ mod minify;
mod page; mod page;
mod routes; mod routes;
use std::path::PathBuf; use std::{
net::SocketAddr,
path::PathBuf,
};
use actix_web::{
main as async_main,
middleware,
App,
HttpServer,
};
use anyhow::Context; use anyhow::Context;
use axum::Router;
use axum_server::tls_rustls::RustlsConfig;
use clap::Parser; use clap::Parser;
use openssl::ssl::{ use tower_http::trace::TraceLayer;
SslAcceptor,
SslFiletype,
SslMethod,
};
#[derive(Parser)] #[derive(Parser)]
#[command(author, version, about)] #[command(author, version, about)]
@ -41,7 +36,7 @@ struct Cli {
key: Option<PathBuf>, key: Option<PathBuf>,
} }
#[async_main] #[tokio::main]
async fn main() -> anyhow::Result<()> { async fn main() -> anyhow::Result<()> {
let args = Cli::parse(); let args = Cli::parse();
@ -51,35 +46,26 @@ async fn main() -> anyhow::Result<()> {
.format_timestamp(None) .format_timestamp(None)
.init(); .init();
let server = HttpServer::new(|| { let app = Router::new()
App::new() .merge(routes::router())
.wrap(middleware::Logger::default()) .merge(errors::router())
.wrap(errors::handler()) .layer(TraceLayer::new_for_http())
.service(routes::handler()) .into_make_service();
});
let server = if let Some(certificate_path) = args.certificate let address = SocketAddr::from(([0, 0, 0, 0], args.port));
if let Some(certificate_path) = args.certificate
&& let Some(key_path) = args.key && let Some(key_path) = args.key
{ {
let mut builder = SslAcceptor::mozilla_intermediate_v5(SslMethod::tls()).unwrap(); let config = RustlsConfig::from_pem_file(certificate_path, key_path)
.await
.with_context(|| "Failed to create TLS configuration from PEM files")?;
builder axum_server::bind_rustls(address, config).serve(app).await
.set_private_key_file(key_path, SslFiletype::PEM)
.unwrap();
builder
.set_certificate_chain_file(certificate_path)
.unwrap();
server.bind_openssl(("0.0.0.0", args.port), builder)
} else { } else {
server.bind(("0.0.0.0", args.port)) axum_server::bind(address).serve(app).await
}; }
.with_context(|| "Failed to run server")?;
server
.with_context(|| format!("Failed to bind to 0.0.0.0:{}", args.port))?
.run()
.await
.with_context(|| "Failed to run HttpServer")?;
Ok(()) Ok(())
} }

View file

@ -1,4 +1,3 @@
use actix_web::get;
use maud::Markup; use maud::Markup;
use crate::{ use crate::{
@ -9,11 +8,10 @@ use crate::{
}, },
}; };
#[get("/about")] pub async fn handler() -> Markup {
pub async fn handler() -> actix_web::Result<Markup> { text::create(
Ok(text::create(
Some("About"), Some("About"),
Page::About, Page::About,
markdown::parse(embed::string!("about.md").as_ref()), markdown::parse(embed::string!("about.md").as_ref()),
)) )
} }

View file

@ -1,13 +1,18 @@
use std::{ use std::{
collections::HashMap, collections::HashMap,
path::Path, path,
sync::LazyLock, sync::LazyLock,
}; };
use actix_web::{ use axum::{
get, body::Body,
web, extract::Path,
HttpResponse, http::{
header::CONTENT_TYPE,
Response,
StatusCode,
},
response::IntoResponse,
}; };
use bytes::Bytes; use bytes::Bytes;
@ -19,7 +24,7 @@ static ASSETS: LazyLock<HashMap<String, Bytes>> = LazyLock::new(|| {
let mut assets = HashMap::new(); let mut assets = HashMap::new();
for file in embed::dir!("..").flatten() { for file in embed::dir!("..").flatten() {
let path = Path::new(file.path().as_ref()) let path = path::Path::new(file.path().as_ref())
.file_name() .file_name()
.unwrap() .unwrap()
.to_str() .to_str()
@ -46,19 +51,19 @@ static ASSETS: LazyLock<HashMap<String, Bytes>> = LazyLock::new(|| {
assets assets
}); });
#[get("/assets/{path}")] pub async fn handler(Path(path): Path<String>) -> Response<Body> {
pub async fn handler(path: web::Path<String>) -> HttpResponse {
let path = path.into_inner();
if let Some(body) = ASSETS.get(&path) { if let Some(body) = ASSETS.get(&path) {
HttpResponse::Ok() (
.content_type( [(
CONTENT_TYPE,
mime_guess::from_path(&path) mime_guess::from_path(&path)
.first_or_octet_stream() .first_or_octet_stream()
.essence_str(), .essence_str(),
) )],
.body(Bytes::clone(body)) Bytes::clone(body),
)
.into_response()
} else { } else {
HttpResponse::NotFound().into() StatusCode::NOT_FOUND.into_response()
} }
} }

View file

@ -1,4 +1,3 @@
use actix_web::get;
use maud::{ use maud::{
html, html,
Markup, Markup,
@ -9,9 +8,8 @@ use crate::{
page::cube, page::cube,
}; };
#[get("/")] pub async fn handler() -> Markup {
pub async fn handler() -> actix_web::Result<Markup> { cube::create(
Ok(cube::create(
None, None,
asset::css::owned!("index.css"), asset::css::owned!("index.css"),
[ [
@ -46,5 +44,5 @@ pub async fn handler() -> actix_web::Result<Markup> {
} }
}, },
], ],
)) )
} }

View file

@ -1,15 +1,15 @@
use axum::{
routing::get,
Router,
};
mod about; mod about;
mod assets; mod assets;
mod index; mod index;
use actix_web::{ pub fn router() -> Router {
web, Router::new()
Scope, .route("/", get(index::handler))
}; .route("/about", get(about::handler))
.route("/assets/*path", get(assets::handler))
pub fn handler() -> Scope {
web::scope("")
.service(index::handler)
.service(about::handler)
.service(assets::handler)
} }