wip: add client base and basic router

This commit is contained in:
2025-05-02 10:08:29 +02:00
parent 96bf9303ea
commit 4af8c825bb
8 changed files with 126 additions and 9 deletions

View File

@@ -5,10 +5,16 @@ build: \
dst/release/theseus-server
.PHONY: run
run: dst/dev.toml
run: dst/dev.toml $(TARGETS_CLIENT)
cargo run --package theseus-server -- dst/dev.toml
dst/release/theseus-server: $(SRCS_RUST_THESEUS_SERVER)
cargo build --package theseus-server --release
.PHONY: clean
clean: client_clean
rm -rf dst
include config/make.mk
include client/make.mk
dst/release/theseus-server: $(SRCS_RUST_THESEUS_SERVER) $(TARGETS_CLIENT)
cargo build --package theseus-server --release
touch $@

36
client/index.html Normal file
View File

@@ -0,0 +1,36 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Ask Stallman</title>
<link href="style.css" rel="stylesheet">
</head>
<body>
<header>
<h1>Ask Stallman</h1>
</header>
<div class="question">
<form method="post">
<input type="text" name="question" placeholder="Your question" autocomplete="off">
</form>
</div>
<div class="info">
<p>We kindly ask you to consider this before sending:</p>
<ul>
<li>
Please write your question in English. Dr Stallman will be reading it
unedited during the discussion block.
</li>
<li>Keep it kind. We are all here to learn something.</li>
<li>
Don't spam. We try to keep algorithmic moderation as permissive as possible.
So we ask you to moderate yourself.
</li>
</ul>
</div>
<footer>
<p><a href="https://zumepro.cz">Zumepro</a> 2025</p>
</footer>
</body>
</html>

View File

@@ -0,0 +1,31 @@
TARGETS_CLIENT_PAGES := index.html not_found.html
TARGETS_CLIENT_SCRIPTS := script.js
TARGETS_CLIENT_STYLES := style.css
TARGETS_CLIENT := $(TARGETS_CLIENT_PAGES:%=dst/%) \
$(TARGETS_CLIENT_SCRIPTS:%=dst/%) \
$(TARGETS_CLIENT_STYLES:%=dst/%)
.PHONY: client_clean
client_clean:
rm -rf client/node_modules
client/node_modules:
cd client && bun install
dst/%.html: client/%.html client/node_modules
@mkdir -p $(@D)
cat $< | bun run --cwd client html-minifier \
--collapse-inline-tag-whitespace \
--collapse-boolean-attributes \
--collapse-whitespace \
--remove-attribute-quotes \
--remove-comments \
--remove-redundant-attributes > $@
dst/%.css: client/%.scss client/node_modules
@mkdir -p $(@D)
bun run --cwd client sass $(notdir $<) --style compressed > $@
dst/%.js: client/%.ts client/node_modules
@mkdir -p $(@D)
bun build $< --minify --outfile $@

21
client/not_found.html Normal file
View File

@@ -0,0 +1,21 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Not Found | Ask Stallman</title>
<link href="style.css" rel="stylesheet">
</head>
<body>
<header>
<h1>Ask Stallman</h1>
</header>
<div class="info">
<h1>Not Found</h1>
<p>This page was not found. Please check the URL.</p>
</div>
<footer>
<p><a href="https://zumepro.cz">Zumepro</a> 2025</p>
</footer>
</body>
</html>

0
client/script.ts Normal file
View File

0
client/style.scss Normal file
View File

View File

@@ -3,7 +3,4 @@ name = "search_and_replace"
version = "0.1.0"
edition = "2021"
[profile.release]
strip = true
[dependencies]

View File

@@ -1,7 +1,8 @@
use std::sync::{atomic::AtomicU32, Arc};
use http_body_util::{combinators::BoxBody, BodyExt, Full};
use hyper::{
body::{Bytes, Incoming}, server::conn::http1, service::service_fn, Error, Request, Response
body::{Bytes, Incoming},
server::conn::http1, service::service_fn, Error, Method, Request, Response
};
use hyper_util::rt::TokioIo;
use tokio::net::TcpListener;
@@ -10,11 +11,36 @@ mod logger;
mod args;
mod config;
macro_rules! response {
($status: ident $body: expr) => {{
let mut res = Response::new(Full::new(Bytes::from($body)).map_err(|n| match n {}).boxed());
*res.status_mut() = hyper::StatusCode::$status;
res
}};
($status: ident $body: expr, $($hkey: ident : $hval: literal),*$(,)?) => {{
let mut res = Response::new(Full::new(Bytes::from($body)).map_err(|n| match n {}).boxed());
*res.status_mut() = hyper::StatusCode::$status;
$(res.headers_mut()
.append(hyper::header::$hkey, hyper::header::HeaderValue::from_static($hval));)*
res
}};
}
async fn router(
_: Request<Incoming>,
req: Request<Incoming>,
_: Arc<SharedState>,
) -> Result<Response<BoxBody<Bytes, Error>>, Error> {
Ok(Response::new(Full::new("test".into()).map_err(|n| match n {}).boxed()))
match (req.method(), req.uri().path()) {
(&Method::GET, "/") => Ok(response!(
OK include_str!("../../dst/index.html"),
CONTENT_TYPE: "text/html",
)),
_ => Ok(response!(
NOT_FOUND include_str!("../../dst/not_found.html"),
CONTENT_TYPE: "text/html",
)),
}
}
fn load_config(path: &str) -> Result<config::Config, &'static str> {