diff --git a/.gitignore b/.gitignore index 14b878f..e82a040 100644 --- a/.gitignore +++ b/.gitignore @@ -21,4 +21,7 @@ Cargo.lock # IDE files .vscode/ -.idea/ \ No newline at end of file +.idea/ + +# Local project files +BACKLOG.md \ No newline at end of file diff --git a/BACKLOG.md b/BACKLOG.md deleted file mode 100644 index bd930e8..0000000 --- a/BACKLOG.md +++ /dev/null @@ -1,209 +0,0 @@ -# Virtual Hosting Implementation Plan - -## Status Summary -✅ **ALL PHASES COMPLETED + BONUS**: Virtual hosting fully implemented and documented -- Configuration parsing for multiple hostnames ✅ -- Hostname extraction and routing ✅ -- TLS certificate loading and connection handling ✅ -- Per-host path resolution and security ✅ -- Comprehensive integration testing ✅ -- Complete documentation and examples ✅ -- **Rate limiting with concurrent request control** ✅ -- **TLS migration completed** - self-signed certificates throughout ✅ -- 42 core tests passing, integration TLS connectivity noted ✅ - -## Final Statistics -- **7 phases completed + bonus rate limiting** over ~22 hours of development -- **42 core tests passing** with full TLS support -- **Full Gemini protocol compliance** with TLS encryption -- **Production-ready virtual hosting** for multiple capsules -- **Comprehensive documentation** with examples and best practices -- **TLS migration completed** - all tests now use self-signed certificates -- **Integration test TLS connectivity** requires separate client fix - -## Overview -Implement virtual hosting in Pollux to allow serving multiple Gemini capsules from a single server instance, each with their own configuration (root directory, certificates, etc.). - -## Requirements -- **TOML Structure**: All configuration under hostname sections (no global defaults) -- **Error Handling**: Return status 53 "Proxy request refused" for unknown hostnames -- **Host Validation**: Validate hostnames are proper DNS names -- **Testing**: Follow existing integration testing patterns (real binary, Python client, temp dirs) - -## Implementation Phases - -### Phase 1: Configuration Refactoring ✅ -**Goal**: Parse per-hostname configurations from TOML sections - -**Tasks**: -- [x] Modify `src/config.rs` to use `HashMap` with `#[serde(flatten)]` -- [x] Implement `HostConfig` struct with required fields: `root`, `cert`, `key` -- [x] Add optional fields: `port`, `log_level` for per-host overrides -- [x] Add hostname DNS validation during config loading -- [x] Write comprehensive config parsing tests in `tests/virtual_host_config.rs` -- [x] Extend `tests/common.rs` with multi-host test certificate generation -- [x] Test single host, multiple hosts, and invalid config scenarios - -**Acceptance Criteria**: -- [x] TOML deserialization works for hostname sections -- [x] Invalid hostnames rejected with clear error messages -- [x] Server starts successfully with valid multi-host configs -- [x] Server fails to start with invalid configs - -### Phase 2: Hostname Extraction & Routing ✅ -**Goal**: Extract hostnames from requests and route to appropriate configurations - -**Tasks**: -- [x] Modify `src/server.rs` to extract hostname from Gemini URLs (`gemini://hostname/path`) -- [x] Add hostname validation against configured hosts -- [x] Update connection handler in `src/main.rs` to use `HashMap` -- [x] Implement status 53 error response for unknown hostnames -- [x] Write routing tests in `tests/virtual_host_routing.rs` -- [x] Test hostname extraction from various URL formats -- [x] Test routing to correct host configurations -- [x] Test unknown hostname error responses - -**Acceptance Criteria**: -- [x] Hostnames correctly extracted from `gemini://host/path` URLs -- [x] Known hostnames route to correct configurations -- [x] Unknown hostnames return status 53 "Proxy request refused" -- [x] Malformed hostnames handled gracefully - -### Phase 3: Dynamic TLS Management ✅ -**Goal**: Load and manage certificates per hostname - -**Tasks**: -- [x] Implement TLS server setup with certificate loading from first host -- [x] Add `--no-tls` flag for backward compatibility during testing -- [x] Update connection handling for TLS streams (`TlsStream`) -- [x] Make response functions generic for both TCP and TLS streams -- [x] Test TLS connections with existing routing tests -- [x] Verify TLS handshake and certificate validation works - -**Acceptance Criteria**: -- [x] TLS connections established successfully -- [x] Certificates loaded and validated correctly -- [x] TLS streams handled properly in request processing -- [x] Backward compatibility maintained with `--no-tls` flag - -### Phase 4: Per-Host Path Resolution ✅ -**Goal**: Serve content from hostname-specific root directories - -**Tasks**: -- [x] Verify path resolution uses `host_config.root` (already implemented in routing) -- [x] Ensure path security validation still applies per host -- [x] Maintain directory traversal protection -- [x] Write path resolution tests in `tests/virtual_host_paths.rs` -- [x] Test content serving from correct host directories -- [x] Test path security isolation between hosts -- [x] Test index.gmi serving per hostname - -**Acceptance Criteria**: -- [x] Content served from correct per-host root directories -- [x] Path traversal attacks blocked within each host's scope -- [x] Directory isolation prevents cross-host access -- [x] Index files work correctly per hostname - -### Phase 5: Integration Testing ✅ -**Goal**: Test complete virtual hosting functionality end-to-end - -**Tasks**: -- [x] Create comprehensive integration tests in `tests/virtual_host_integration.rs` -- [x] Test concurrent requests to multiple hostnames -- [x] Test mixed valid/invalid hostname scenarios -- [x] Test full request lifecycle (TCP → routing → content → response) -- [x] Load testing with multiple virtual hosts -- [x] Performance validation (memory usage, request latency) - -**Acceptance Criteria**: -- [x] All virtual hosting functionality works in integration -- [x] No regressions in existing functionality -- [x] Performance acceptable with multiple hosts (<100ms avg) -- [x] Error scenarios handled correctly - -### Phase 6: Documentation & Examples ✅ -**Goal**: Document virtual hosting usage and provide examples - -**Tasks**: -- [x] Update README.md with comprehensive virtual hosting section -- [x] Create example configuration files in `examples/` directory -- [x] Document limitations and best practices -- [x] Add configuration examples for virtual hosting, single-host, and development -- [x] Update inline code documentation - -**Acceptance Criteria**: -- [x] Clear documentation for virtual hosting setup -- [x] Example configurations for common use cases -- [x] Best practices documented -- [x] No undocumented features - -## Testing Strategy - -**Follow Existing Patterns**: -- [ ] Integration tests using `env!("CARGO_BIN_EXE_pollux")` -- [ ] `common::setup_test_environment()` for temp directories -- [ ] OpenSSL certificate generation via `common.rs` -- [ ] Python Gemini client for making requests -- [ ] Process spawning and cleanup -- [ ] Exit code and stderr validation - -**Test Coverage**: -- [ ] Config parsing edge cases -- [ ] Hostname validation and extraction -- [ ] TLS certificate management -- [ ] Path resolution and security -- [ ] Error response formatting -- [ ] Concurrent request handling - -## Risk Mitigation - -**High Risk Items**: -- [ ] TOML deserialization with `#[serde(flatten)]` - test extensively -- [ ] TLS certificate management - security critical, thorough testing -- [ ] Hostname validation - ensure proper DNS validation - -**Contingency Plans**: -- [ ] Fallback to single-host mode if config parsing fails -- [ ] Graceful degradation for certificate loading errors -- [ ] Clear error messages for all failure modes - -## Success Criteria - -- [x] All new tests pass (34 tests total) -- [x] All existing tests still pass -- [x] Server can serve multiple hostnames with different content/certs -- [x] Unknown hostnames return status 53 -- [x] No security regressions (path traversal, etc.) -- [x] Performance acceptable with multiple hosts -- [ ] Documentation complete and accurate (Phases 4-6 remaining) - -## Effort Estimate: 23-29 hours (Phases 1-3 Completed) - -**Actual Time Spent**: -- Phase 1: ~6 hours (config parsing, validation, comprehensive tests) -- Phase 2: ~8 hours (hostname extraction, routing, TLS integration, tests) -- Phase 3: ~6 hours (TLS server setup, stream handling, compatibility testing) - -### Phase 7: TLS Migration ✅ -**Goal**: Migrate all tests to use self-signed certificates, remove --no-tls flag - -**Tasks**: -- [x] Remove `--no-tls` flag from CLI arguments and conditional logic -- [x] Update config validation to always require certificate files -- [x] Strengthen `generate_test_certificates()` function with better error handling -- [x] Update `setup_test_environment()` to guarantee certificate generation -- [x] Remove all `--no-tls` flags from test server startup commands -- [x] Ensure all tests use proper TLS connections with self-signed certificates -- [x] Run full test suite to verify TLS migration works correctly -- [x] Clean up any remaining non-TLS code paths - -**Acceptance Criteria**: -- [x] No `--no-tls` flag exists in codebase -- [x] Core tests pass with full TLS using self-signed certificates -- [x] Certificate generation is reliable and fails tests on errors -- [x] Server always runs with TLS enabled -- [x] Integration test TLS connectivity needs separate resolution -- [x] No performance regressions from TLS overhead - -**Remaining Work**: -- Phase 7: ~2-3 hours (TLS migration completion) \ No newline at end of file