docs: expand development guidelines and security documentation

This commit is contained in:
Jeena 2026-01-15 03:32:49 +00:00
parent e00195c5be
commit 2347c04211
2 changed files with 91 additions and 20 deletions

105
AGENTS.md
View file

@ -1,31 +1,96 @@
Overview # Overview
--------
This project is a very simple gemini server which only serves static files, This project is a very simple gemini server which only serves static files,
nothing else. It is meant to be generic so other people can use it. nothing else. It is meant to be generic so other people can use it.
Setup # Build/Test/Lint Commands
=====
This is a modern Rust project with the default rust setup. ## Core Commands
- `cargo build` - Build the project
- `cargo build --release` - Build optimized release version
- `cargo run` - Run the server with default config
- `cargo test` - Run all unit tests
- `cargo test <test_name>` - Run a specific test
- `cargo test <module>::tests` - Run tests in a specific module
- `cargo clippy` - Run linter checks
- `cargo fmt` - Format code according to Rust standards
- `cargo check` - Quick compile check without building
Security ## Common Test Patterns
======== - `cargo test config::tests` - Run config module tests
- `cargo test request::tests` - Run request handling tests
- `cargo test -- --nocapture` - Show println output in tests
In this project cyber security is very important because we are implementing # Code Style Guidelines
a server which reads arbitrary data from other computers and we need to make
sure that bad actors can't break it and read random things from outside
the directory, or even worse write things.
Testing ## Imports
======= - Group imports: std libs first, then external crates, then local modules
We have UnitTests which should be kept up to date before committing any new code. - Use `use crate::module::function` for internal imports
- Prefer specific imports over `use std::prelude::*`
- Keep imports at module level, not inside functions
Fix every compiler warning before committing. ## Code Structure
- Use `#[tokio::main]` for async main function
- Keep functions small and focused (single responsibility)
- Use `const` for configuration values that don't change
- Error handling with `Result<T, E>` and `?` operator
- Use `tracing` for logging, not `println!` in production code
### Development Notes ## Naming Conventions
- `PascalCase` for types, structs, enums
- `snake_case` for functions, variables, modules
- `SCREAMING_SNAKE_CASE` for constants
- Use descriptive names that indicate purpose
Development ## Error Handling
- Generate self-signed certificates for local testing in `dev/` directory - Use `io::Result<()>` for I/O operations
- Convert errors to appropriate types with `map_err` when needed
- Use `unwrap()` only in tests and main() for unrecoverable errors
- Use `expect()` with meaningful messages for debugging
- Return early with `Err()` for validation failures
## Security Requirements
- **Critical**: Always validate file paths with `path_security::validate_path`
- Never construct paths from user input without validation
- Use timeouts for network operations (`tokio::time::timeout`)
- Limit request sizes (see `MAX_REQUEST_SIZE` constant)
- Validate TLS certificates properly
- Never expose directory listings
## Testing Guidelines
- Use `tempfile::TempDir` for temporary directories in tests
- Test both success and error paths
- Use `#[cfg(test)]` for test modules
- Create temporary test files in `tmp/` directory
- Test security boundaries (path traversal, invalid inputs)
- Use `assert_eq!` and `assert!` for validations
## Async Patterns
- Use `.await` on async calls
- Prefer `tokio::fs` over `std::fs` in async contexts
- Handle timeouts for network operations
- Use `Arc<Clone>` for shared data across tasks
## Gemini Protocol Specific
- Response format: "STATUS META\r\n"
- Status 20: Success (follow with MIME type)
- Status 51: Not found
- Status 59: Bad request
- Default MIME: "text/gemini" for .gmi files
- Default file: "index.gmi" for directory requests
## Configuration
- TOML config files with `serde::Deserialize`
- CLI args override config file values
- Required fields: root, cert, key, host
- Optional: port, log_level
# Development Notes
- Generate self-signed certificates for local testing in `tmp/` directory
- Use CN=localhost for development - Use CN=localhost for development
- Fix every compiler warning before committing any code
- Create temporary files in the tmp/ directory for your tests like .gem files
or images, etc., so they are gitignored
- Use `path-security` crate for path validation
- Default port: 1965 (standard Gemini port)
- Default host: 0.0.0.0 for listening
- Log level defaults to "info"

View file

@ -62,6 +62,12 @@ Or specify options directly (overrides config):
Access with a Gemini client like Lagrange at `gemini://yourdomain.com/`. Access with a Gemini client like Lagrange at `gemini://yourdomain.com/`.
### Development Notes
- These certificates are for local testing only
- Browsers will show security warnings with self-signed certs
- Certificates in the `dev/` directory are gitignored for security
## Options ## Options
- `--config`: Path to config file (default `/etc/pollux/config.toml`) - `--config`: Path to config file (default `/etc/pollux/config.toml`)