# 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 Frontends**: Two HTML frontends are embedded as string constants: - `SIMPLE_FRONTEND`: Minimalist main page with just "No" centered on screen - `PLAYGROUND_FRONTEND`: Interactive API testing playground with buttons and examples 2. **Request Router**: The `route_request()` function handles all routing logic: - `/` - Serves the minimalist "No" page - `/playground` - Serves the interactive API testing interface - `/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 - When creating a release, we normally just increment the patch level. We always update all relevant version fields, and we always want to include an up to date debian package in the forgejo release.