commit d87afd154828e0c2cf1270785e0e8e4845e51d06 Author: Ole-Morten Duesund Date: Sat Sep 27 16:35:55 2025 +0200 Add CLAUDE.md for Claude Code guidance Document project architecture, commands, and deployment configuration to help future Claude Code instances work effectively with this codebase. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..2593432 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,112 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +NaaS (No as a Service) is a lightweight HTTP service written in pure Rust that always responds with "no" in various formats. It uses only the Rust standard library with zero external dependencies, making it extremely lightweight and fast. + +## Development Commands + +### Build and Run + +```bash +# Debug build +cargo build + +# Release build (optimized for size) +cargo build --release + +# Run locally +PORT=8080 cargo run + +# Run release binary +PORT=8080 ./target/release/naas +``` + +### Testing + +```bash +# Run tests (currently no test files exist) +cargo test + +# Test endpoints manually +curl http://localhost:8080/api/no +curl http://localhost:8080/api/no?format=json +curl http://localhost:8080/health +``` + +### Container Operations + +```bash +# Build container with Podman (preferred over Docker) +BUILDAH_FORMAT=docker podman build -t naas:latest -f Containerfile . + +# Run container +podman run -d --name naas -p 8080:8080 --restart=always naas:latest + +# Check container health +podman healthcheck run naas +``` + +## Architecture + +### Single-File Design +The entire application is contained in `src/main.rs` with ~372 lines of code. This monolithic approach is intentional for simplicity and minimal binary size. + +### Key Components + +1. **Embedded HTML Frontend**: The HTML/CSS/JavaScript frontend is embedded as a string constant (`HTML_FRONTEND`) directly in the source code, eliminating the need for static file serving. + +2. **Request Router**: The `route_request()` function handles all routing logic: + - `/` - Serves the embedded HTML frontend + - `/api/no` - API endpoint with format parameter support + - `/health` - Health check endpoint + - CORS headers are added to all responses + +3. **Thread-per-Connection Model**: Each incoming TCP connection spawns a new thread via `thread::spawn()`, providing simple concurrency without async complexity. + +4. **Manual HTTP Parsing**: The application manually parses HTTP requests and constructs responses, avoiding HTTP library dependencies. + +## API Response Formats + +The `/api/no` endpoint supports these formats via the `format` query parameter: +- **text** (default): Plain text "no" +- **json**: `{"answer":"no"}` +- **bool**: `false` +- **xml**: `no` +- **yaml**: `answer: no` + +## Deployment Configuration + +### Container Security +- Runs as non-root user (UID 1000) +- Read-only filesystem +- All capabilities dropped except `NET_BIND_SERVICE` +- Health checks configured in Containerfile + +### Systemd Service +The `naas.service` file configures: +- Automatic container build and run via Podman +- Resource limits (256MB memory, 50% CPU) +- Security hardening (PrivateTmp, ProtectSystem, NoNewPrivileges) + +### Binary Optimization +The `Cargo.toml` release profile optimizes for minimal size: +- `opt-level = "z"` - Size optimization +- `lto = true` - Link-time optimization +- `codegen-units = 1` - Single codegen unit +- `strip = true` - Strip debug symbols +- `panic = "abort"` - Smaller panic handler + +## Port Configuration + +The application reads the `PORT` environment variable (defaults to 8080) and binds to `0.0.0.0:$PORT` for all network interfaces. + +## Error Handling + +The application uses simple error handling: +- TCP connection errors are logged to stderr +- Stream read/write errors are logged but don't crash the server +- Invalid HTTP requests return 400 Bad Request +- Non-GET methods return 405 Method Not Allowed \ No newline at end of file