223 lines
6.2 KiB
Markdown
223 lines
6.2 KiB
Markdown
# AGENTS.md - Rust HTTP Server Project Guide
|
|
|
|
This file provides essential information for agentic coding agents working on the rhttpd project.
|
|
|
|
## Project Overview
|
|
|
|
rhttpd is a high-performance, configurable HTTP server written in Rust that supports:
|
|
- Multi-site hosting on a single port
|
|
- Multiple proxy types (reverse, forward, TCP)
|
|
- JavaScript dynamic configuration
|
|
- Static file serving with MIME type detection
|
|
|
|
## Build, Test, and Development Commands
|
|
|
|
### Core Commands
|
|
```bash
|
|
# Build the project
|
|
cargo build
|
|
|
|
# Build with optimizations
|
|
cargo build --release
|
|
|
|
# Run the server
|
|
cargo run
|
|
|
|
# Run tests
|
|
cargo test
|
|
|
|
# Run a single test (replace test_name with actual test)
|
|
cargo test test_name
|
|
|
|
# Run tests with output
|
|
cargo test -- --nocapture
|
|
|
|
# Check code without building
|
|
cargo check
|
|
|
|
# Format code
|
|
cargo fmt
|
|
|
|
# Run clippy lints
|
|
cargo clippy
|
|
|
|
# Run clippy with all targets and features
|
|
cargo clippy --all-targets --all-features
|
|
|
|
# Generate documentation
|
|
cargo doc --open
|
|
|
|
# Clean build artifacts
|
|
cargo clean
|
|
```
|
|
|
|
## Code Style Guidelines
|
|
|
|
### General Rust Conventions
|
|
- Use `rustfmt` for formatting (run `cargo fmt` before commits)
|
|
- Follow Rust 2024 edition standards
|
|
- Use `cargo clippy` to catch common issues and improve code
|
|
|
|
### Imports and Dependencies
|
|
- Group imports in the following order:
|
|
1. Standard library imports (`std::*`)
|
|
2. Third-party crate imports
|
|
3. Local module imports (`crate::*`)
|
|
- Use explicit imports rather than glob imports where possible
|
|
- Prefer `use crate::module::Item;` over `use super::module::Item;`
|
|
|
|
### Naming Conventions
|
|
- **Functions and variables**: `snake_case`
|
|
- **Types and structs**: `PascalCase`
|
|
- **Constants**: `SCREAMING_SNAKE_CASE`
|
|
- **Modules**: `snake_case`
|
|
- **File names**: `snake_case.rs`
|
|
|
|
### Error Handling
|
|
- Use `Result<T, E>` for functions that can fail
|
|
- Create custom error types using `thiserror` or `anyhow` when needed
|
|
- Use `?` operator for error propagation
|
|
- Handle errors gracefully with proper logging
|
|
- Avoid using `unwrap()` or `expect()` in production code
|
|
|
|
### Async/Await Patterns
|
|
- Use `async`/`await` for asynchronous operations
|
|
- Prefer `tokio` runtime for async operations
|
|
- Use `.await` instead of blocking calls in async contexts
|
|
- Handle async errors with `Result` types
|
|
|
|
### Struct and Enum Design
|
|
- Use `#[derive(Debug, Clone, PartialEq, Eq)]` where appropriate
|
|
- Implement `Default` for structs with sensible defaults
|
|
- Use `serde` derives for configuration structs:
|
|
```rust
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
```
|
|
- Use builder pattern for complex configuration
|
|
|
|
### Memory Management
|
|
- Use `Arc<RwLock<T>>` for shared configuration that needs concurrent access
|
|
- Use `Arc<Mutex<T>>` when exclusive access is needed
|
|
- Prefer borrowing over cloning when possible
|
|
- Use `Cow<str>` for string data that might be borrowed or owned
|
|
|
|
### Module Organization
|
|
- Keep modules focused and cohesive
|
|
- Use `mod.rs` for directory modules
|
|
- Declare public APIs with `pub` keyword
|
|
- Use `pub(crate)` for internal APIs shared across modules
|
|
|
|
### Testing Guidelines
|
|
- Write unit tests for all public functions
|
|
- Use `#[cfg(test)]` for test modules
|
|
- Use integration tests in `tests/` directory for end-to-end testing
|
|
- Mock external dependencies in tests
|
|
- Use `tokio::test` for async tests
|
|
|
|
### Documentation
|
|
- Document all public APIs with `///` doc comments
|
|
- Use `#[doc]` attributes for module-level documentation
|
|
- Include examples in doc comments where helpful
|
|
- Use `cargo doc` to verify documentation builds correctly
|
|
|
|
### Performance Considerations
|
|
- Use `Vec<T>` for collections when size is known
|
|
- Use `String` for owned string data
|
|
- Avoid unnecessary allocations
|
|
- Use `&str` for string references when possible
|
|
- Profile with `cargo flamegraph` for performance optimization
|
|
|
|
### Security Best Practices
|
|
- Validate all external inputs
|
|
- Use type-safe configurations
|
|
- Avoid unsafe code unless absolutely necessary
|
|
- Sanitize file paths to prevent directory traversal
|
|
- Implement rate limiting for proxy endpoints
|
|
|
|
## Project Structure
|
|
|
|
```
|
|
rhttpd/
|
|
├── src/
|
|
│ ├── main.rs # Application entry point
|
|
│ ├── lib.rs # Library root (if applicable)
|
|
│ ├── server/ # Server implementation
|
|
│ ├── config/ # Configuration management
|
|
│ ├── proxy/ # Proxy implementations
|
|
│ └── js_engine/ # JavaScript integration
|
|
├── tests/ # Integration tests
|
|
├── doc/ # Documentation and requirements
|
|
├── Cargo.toml # Project configuration
|
|
└── AGENTS.md # This file
|
|
```
|
|
|
|
## Key Dependencies (as specified in requirements)
|
|
|
|
### Core Runtime
|
|
- `tokio` - Async runtime
|
|
- `hyper` or `axum` - HTTP server framework
|
|
- `tower` - Middleware and service abstractions
|
|
|
|
### Configuration
|
|
- `serde` - Serialization/deserialization
|
|
- `serde_json` - JSON support
|
|
- `toml` - TOML configuration support
|
|
|
|
### Static Files
|
|
- `tower-http` - HTTP service utilities
|
|
- `mime_guess` - MIME type detection
|
|
|
|
### Proxy Support
|
|
- `reqwest` - HTTP client for reverse proxy
|
|
- `tokio-util` - Utilities for async I/O
|
|
- `tokio-native-tls` - TLS support
|
|
|
|
### JavaScript Engine
|
|
- Choose one: `deno_core`, `rquickjs`, or `boa_engine`
|
|
|
|
## Development Workflow
|
|
|
|
1. Run `cargo check` to verify code compiles
|
|
2. Run `cargo clippy` to catch issues
|
|
3. Run `cargo fmt` to format code
|
|
4. Run `cargo test` to verify tests pass
|
|
5. Commit changes with descriptive messages
|
|
|
|
## Testing Strategy
|
|
|
|
- Unit tests for individual components
|
|
- Integration tests for end-to-end functionality
|
|
- Performance tests for proxy operations
|
|
- Configuration validation tests
|
|
|
|
## Common Patterns
|
|
|
|
### Configuration Loading
|
|
```rust
|
|
#[derive(Debug, Deserialize)]
|
|
struct ServerConfig {
|
|
port: u16,
|
|
sites: HashMap<String, SiteConfig>,
|
|
}
|
|
```
|
|
|
|
### Error Types
|
|
```rust
|
|
#[derive(Debug, thiserror::Error)]
|
|
enum ServerError {
|
|
#[error("Configuration error: {0}")]
|
|
Config(#[from] ConfigError),
|
|
#[error("IO error: {0}")]
|
|
Io(#[from] std::io::Error),
|
|
}
|
|
```
|
|
|
|
### Async Service Pattern
|
|
```rust
|
|
#[async_trait]
|
|
trait ProxyService {
|
|
async fn handle_request(&self, req: Request<Body>) -> Result<Response<Body>, ServerError>;
|
|
}
|
|
```
|
|
|
|
Remember to run `cargo fmt` and `cargo clippy` before committing changes! |