Files
tdkpin/tdkpin-rs/highscore-server/README.md
T
ddidderr 3dff722535 fix(highscores): bound service resource usage
The high-score endpoints previously accepted unbounded request bodies and ran
SQLite work directly in async handlers, allowing oversized input or database
contention to consume server resources. Add a 1 KiB route body limit, admit
only one database operation at a time, shed excess requests with a clear 503,
and run accepted SQLite work on blocking threads while retaining admission
until that work finishes. Extend the Nginx example with matching request,
connection, body, and proxy time limits, and cover the limits, health
availability, contention, and cancellation behavior with tests.

Test Plan:
- `just --justfile tdkpin-rs/justfile test` -- passed (144 tests)
- `just --justfile tdkpin-rs/justfile clippy` -- passed
- `cargo +nightly fmt --manifest-path tdkpin-rs/highscore-server/Cargo.toml -- --check` -- passed
- `rumdl check --flavor commonmark tdkpin-rs/highscore-server/README.md` -- passed
- `git diff --cached --check` -- passed
2026-08-29 19:36:53 +02:00

1.2 KiB

TDK high-score service

This small Axum service stores the shared top-ten table in SQLite. It exposes:

GET  /healthz
GET  /api/highscores
POST /api/highscores

The POST body is JSON with a 21-character maximum name and a u32 score. The response is the canonical top-ten JSON array.

Submissions are anonymous and intentionally trust the browser's score. Add rate limiting, moderation, or server-side run verification if the table needs to resist forged scores.

Run it from tdkpin-rs with:

TDKPIN_HIGHSCORE_BIND=127.0.0.1:3000 \
TDKPIN_HIGHSCORE_DB=/var/lib/tdkpin/highscores.sqlite3 \
cargo run --manifest-path highscore-server/Cargo.toml

Copy the rate and connection zone declarations from nginx.conf.example into the existing http block, then place its two location blocks inside the public site's server block. The example bounds per-client and aggregate API traffic, request bodies, and proxy waits. The browser client expects the API at /api/highscores on the same origin as the game.

The crate inherits the parent rustfmt.toml; run just fmt-highscore-server when formatting it directly.