summaryrefslogtreecommitdiff
path: root/crates/chat-server/src/http.rs
diff options
context:
space:
mode:
authorDoan Luu Duc Tai <doan@luuduct.ai>2026-10-31 12:25:30 -0500
committerDoan Luu Duc Tai <doan@luuduct.ai>2026-10-31 12:25:30 -0500
commit9139398d465f5899cc31bc4cdd54daa7392ca550 (patch)
treedebf0b15a969e8c64e3b3597f4eb7953b7f047e1 /crates/chat-server/src/http.rs
parentef61fc5aca6eca613a055c507a060b70bd537a37 (diff)
Migrate browser code and tests to strict TypeScript
Diffstat (limited to 'crates/chat-server/src/http.rs')
-rw-r--r--crates/chat-server/src/http.rs101
1 files changed, 68 insertions, 33 deletions
diff --git a/crates/chat-server/src/http.rs b/crates/chat-server/src/http.rs
index 7394b71..cb21b1f 100644
--- a/crates/chat-server/src/http.rs
+++ b/crates/chat-server/src/http.rs
@@ -93,59 +93,94 @@ async fn api(State(app): State<App>, headers: HeaderMap, Json(request): Json<Val
}
}
-async fn asset(State(app): State<App>, uri: axum::http::Uri) -> Response {
- if uri.path() == "/THIRD-PARTY-LICENSES.html" {
- let Some(origin) = app.public.get("SITE_ORIGIN") else {
- return secured(StatusCode::INTERNAL_SERVER_ERROR.into_response());
- };
- return secured(
- Redirect::permanent(&format!("{origin}/THIRD-PARTY-LICENSES.html")).into_response(),
- );
+fn packaged_asset<'a>(root: &Path, packaged: &'a str, development: &'a str) -> &'a str {
+ if root.join(packaged).is_file() {
+ packaged
+ } else {
+ development
}
- let (path, mime) = match uri.path() {
- "/" => (
+}
+
+fn asset_location(root: &Path, path: &str) -> Option<(&'static str, &'static str)> {
+ let assets = [
+ (
+ "/",
+ "bin/chat/web/index.html",
"crates/chat-server/web/index.html",
"text/html; charset=utf-8",
),
- "/app.js" => (
- "crates/chat-server/web/app.js",
+ (
+ "/app.js",
+ "bin/chat/web/app.js",
+ "var/build/typescript/crates/chat-server/web/app.js",
"text/javascript; charset=utf-8",
),
- "/worker.js" => (
- "crates/chat-server/web/worker.js",
+ (
+ "/worker.js",
+ "bin/chat/web/worker.js",
+ "var/build/typescript/crates/chat-server/web/worker.js",
"text/javascript; charset=utf-8",
),
- "/wasi.mjs" => (
- "crates/chat-crypto/browser/wasi.mjs",
+ (
+ "/wasi.mjs",
+ "bin/chat/wasi.mjs",
+ "var/build/typescript/crates/chat-crypto/browser/wasi.js",
"text/javascript; charset=utf-8",
),
- "/style.css" => (
+ (
+ "/style.css",
+ "bin/chat/web/style.css",
"crates/chat-server/web/style.css",
"text/css; charset=utf-8",
),
- "/crypto.wasm" => (
- if app.root.join("bin/chat/crypto.wasm").is_file() {
- "bin/chat/crypto.wasm"
- } else {
- "target/wasm32-wasip1/release/stack-chat-crypto.wasm"
- },
+ (
+ "/crypto.wasm",
+ "bin/chat/crypto.wasm",
+ "target/wasm32-wasip1/release/stack-chat-crypto.wasm",
"application/wasm",
),
- "/javascript.html" => (
+ (
+ "/javascript.html",
+ "bin/chat/web/javascript.html",
"crates/chat-server/web/javascript.html",
"text/html; charset=utf-8",
),
- "/SOURCE.tar.gz" => (
- if app.root.join("bin/chat/SOURCE.tar.gz").is_file() {
- "bin/chat/SOURCE.tar.gz"
- } else {
- "var/build/chat-source.tar.gz"
- },
+ (
+ "/SOURCE.tar.gz",
+ "bin/chat/SOURCE.tar.gz",
+ "var/build/chat-source.tar.gz",
"application/gzip",
),
- "/LIMITATIONS.txt" => ("docs/CHAT-APPLICATION.txt", "text/plain; charset=utf-8"),
- "/LICENSE" => ("LICENSE", "text/plain; charset=utf-8"),
- _ => return secured(StatusCode::NOT_FOUND.into_response()),
+ (
+ "/LIMITATIONS.txt",
+ "docs/CHAT-APPLICATION.txt",
+ "docs/CHAT-APPLICATION.txt",
+ "text/plain; charset=utf-8",
+ ),
+ (
+ "/LICENSE",
+ "LICENSE",
+ "LICENSE",
+ "text/plain; charset=utf-8",
+ ),
+ ];
+ assets
+ .into_iter()
+ .find(|(route, _, _, _)| *route == path)
+ .map(|(_, packaged, development, mime)| (packaged_asset(root, packaged, development), mime))
+}
+
+async fn asset(State(app): State<App>, uri: axum::http::Uri) -> Response {
+ if uri.path() == "/THIRD-PARTY-LICENSES.html" {
+ let Some(origin) = app.public.get("SITE_ORIGIN") else {
+ return secured(StatusCode::INTERNAL_SERVER_ERROR.into_response());
+ };
+ return secured(
+ Redirect::permanent(&format!("{origin}/THIRD-PARTY-LICENSES.html")).into_response(),
+ );
+ }
+ let Some((path, mime)) = asset_location(&app.root, uri.path()) else {
+ return secured(StatusCode::NOT_FOUND.into_response());
};
if matches!(uri.path(), "/" | "/javascript.html") {
let Ok(bytes) = tokio::fs::read(app.root.join(path)).await else {