feat: default service handler, lets all love lain

This commit is contained in:
2026-03-21 17:41:36 +01:00
parent 4fdd2b7134
commit 36dd65c144
11 changed files with 237 additions and 14 deletions

View File

@@ -36,6 +36,13 @@ pub const USER_PFP_PATHS: &[&str] = &[
".face",
];
pub const ERROR_ASCII_ARTS: &[&str] = &[
include_str!("../assets/lain/lain-dancing.txt"),
include_str!("../assets/lain/lain-head.txt"),
include_str!("../assets/lain/lain-teddy-head.txt"),
include_str!("../assets/lain/lain-teddy.txt"),
];
pub mod web_scopes {
pub const IMAGES: &str = "/image";
}

View File

@@ -1,4 +1,10 @@
#![feature(seek_stream_len, once_cell_try, decl_macro, duration_constructors)]
#![feature(
decl_macro,
duration_constructors,
never_type,
once_cell_try,
seek_stream_len,
)]
#![allow(clippy::future_not_send)] // will get to fix these later
//! # About, Licensing and More

View File

@@ -38,6 +38,7 @@ pub async fn start_app(args: crate::args::Args, config: crate::conf::Config) ->
App::new()
.app_data(web::Data::new(app))
.service(services::images::make_scope(ws::IMAGES))
.default_service(web::to(services::not_found::not_found))
})
.bind(&app.config.server.listen)?
.run()

View File

@@ -1 +1,2 @@
pub mod images;
pub mod not_found;

View File

@@ -0,0 +1,47 @@
use actix_web::{
HttpRequest, HttpResponse,
web::{self, Bytes},
};
use futures_util::stream;
use crate::consts;
fn mix_u32s(seed: impl Iterator<Item = u32>) -> u32 {
// from wyhash32, according to GPT, should just have a nice bit distribution anyways
const U32_BIT_MIXING_CONSTANT: u32 = 0x7feb_352d;
const U32_SELF_BIT_MIXING: u32 = 0x846c_a68b;
let mut random = seed.fold(0_u32, |acc, e| {
// mix bits
acc.wrapping_add(e.wrapping_mul(U32_BIT_MIXING_CONSTANT))
});
// GPT's suggestion for a nicer distribution, like 8 cpu instructions so whatever
random ^= random >> 16;
random = random.wrapping_mul(U32_SELF_BIT_MIXING);
random ^= random >> 15;
random
}
pub async fn not_found(req: HttpRequest) -> HttpResponse {
let seed = req.path().as_bytes();
let random = mix_u32s(seed.iter().copied().map(u32::from));
let res = consts::ERROR_ASCII_ARTS[random as usize % consts::ERROR_ASCII_ARTS.len()];
let method = req.method().as_str();
let url = req.path();
HttpResponse::NotFound()
.content_type("text/plain; charset=utf-8")
.streaming(stream::iter([
Ok::<_, !>(web::Bytes::from(format!(
"> {method} '{url}'\n404 NOT FOUND\nLet's all love lain\n\n"
))),
Ok(Bytes::from_static(res.as_bytes())),
]))
// .body(format!(
// "> {method} '{url}'\n404 NOT FOUND\nLet's all love lain\n\n{res}"
// ))
}