feat: Implement virtual hosting for multi-domain Gemini server

- Add hostname-based request routing for multiple capsules per server
- Parse virtual host configs from TOML sections ([hostname])
- Implement per-host certificate and content isolation
- Add comprehensive virtual host testing and validation
- Update docs and examples for multi-host deployments

This enables Pollux to serve multiple Gemini domains from one instance,
providing the foundation for multi-tenant Gemini hosting.
This commit is contained in:
Jeena 2026-01-22 02:38:09 +00:00
parent c193d831ed
commit 0459cb6220
22 changed files with 2296 additions and 406 deletions

30
examples/development.toml Normal file
View file

@ -0,0 +1,30 @@
# Pollux Development Configuration
#
# Example configuration for local development with self-signed certificates.
# NOT suitable for production use.
bind_host = "127.0.0.1"
port = 1965
log_level = "debug"
max_concurrent_requests = 100
# Local development site
["localhost"]
root = "./content"
cert = "./tmp/cert.pem"
key = "./tmp/key.pem"
# Alternative hostname for testing
["gemini.local"]
root = "./content"
cert = "./tmp/cert.pem"
key = "./tmp/key.pem"
# Generate self-signed certificates with:
# mkdir -p tmp
# openssl req -x509 -newkey rsa:2048 \
# -keyout tmp/key.pem \
# -out tmp/cert.pem \
# -days 365 \
# -nodes \
# -subj "/CN=localhost"

16
examples/single-host.toml Normal file
View file

@ -0,0 +1,16 @@
# Pollux Single Host Example Configuration
#
# Example configuration for a single Gemini capsule.
# For multiple hosts, use virtual hosting instead.
# Global settings
bind_host = "127.0.0.1"
port = 1965
log_level = "info"
max_concurrent_requests = 100
# Host configuration
["example.com"]
root = "./content"
cert = "./tmp/cert.pem"
key = "./tmp/key.pem"

View file

@ -0,0 +1,35 @@
# Pollux Virtual Hosting Example Configuration
#
# This example shows how to configure multiple Gemini capsules
# on a single server instance.
# Global settings (applied to all hosts unless overridden)
bind_host = "0.0.0.0"
port = 1965
log_level = "info"
max_concurrent_requests = 1000
# Main website
["example.com"]
root = "/var/gemini/example.com"
cert = "/etc/ssl/example.com.crt"
key = "/etc/ssl/example.com.key"
# Blog subdomain
["blog.example.com"]
root = "/var/gemini/blog"
cert = "/etc/ssl/blog.example.com.crt"
key = "/etc/ssl/blog.example.com.key"
# Personal site
["tilde.example.com"]
root = "/home/user/public_gemini"
cert = "/etc/ssl/tilde.crt"
key = "/etc/ssl/tilde.key"
# Development site (different port)
["dev.example.com"]
root = "/home/dev/gemini"
cert = "/etc/ssl/dev.crt"
key = "/etc/ssl/dev.key"
port = 1966