diff --git a/config/examples/cors-headers.kdl b/config/examples/cors-headers.kdl new file mode 100644 index 0000000..2f104e9 --- /dev/null +++ b/config/examples/cors-headers.kdl @@ -0,0 +1,120 @@ +// Example: CORS Headers Configuration +// +// Configure Cross-Origin Resource Sharing (CORS) for API routes: +// - Pre-flight request handling +// - Origin whitelisting +// - Credential support +// - Custom headers + +system { + worker-threads 0 + max-connections 10000 + graceful-shutdown-timeout-secs 30 +} + +listeners { + listener "http" { + address "0.0.0.0:8080" + protocol "http" + request-timeout-secs 60 + } +} + +upstreams { + upstream "api" { + endpoint "api-1" { + address "localhost:3000" + } + } +} + +routes { + // Public API: Open CORS for specific origins + route "public-api" { + priority "high" + matches { + path-prefix "/api/public" + } + upstream "api" + cors { + enabled true + + // Allowed origins (use "*" for all, but not recommended for production) + allowed-origins [ + "https://example.com", + "https://app.example.com", + "https://staging.example.com" + ] + + // Allowed HTTP methods + allowed-methods ["GET", "POST", "PUT", "DELETE", "OPTIONS"] + + // Allowed request headers + allowed-headers [ + "Content-Type", + "Authorization", + "X-Requested-With", + "X-API-Key" + ] + + // Headers exposed to client + exposed-headers ["X-Total-Count", "X-Page-Count"] + + // Allow cookies/credentials + allow-credentials true + + // Pre-flight cache duration (in seconds) + max-age 3600 // 1 hour + } + } + + // Private API: Strict CORS with credentials + route "private-api" { + priority "high" + matches { + path-prefix "/api/private" + } + upstream "api" + cors { + enabled true + allowed-origins ["https://app.example.com"] + allowed-methods ["GET", "POST", "PUT", "DELETE"] + allowed-headers ["Content-Type", "Authorization"] + allow-credentials true + max-age 3600 + } + } + + // Development API: Open CORS (development only!) + route "dev-api" { + priority "low" + matches { + path-prefix "/api/dev" + } + upstream "api" + cors { + enabled true + allowed-origins ["*"] // WARNING: Only for development! + allowed-methods ["*"] + allowed-headers ["*"] + allow-credentials false // Cannot be true with "*" + max-age 86400 // 24 hours + } + } + + // WebSocket route with CORS + route "websocket" { + priority "high" + matches { + path-prefix "/ws" + } + upstream "api" + cors { + enabled true + allowed-origins ["https://app.example.com"] + allowed-methods ["GET"] + allowed-headers ["*"] + allow-credentials true + } + } +} diff --git a/config/examples/multiple-upstreams-health-check.kdl b/config/examples/multiple-upstreams-health-check.kdl new file mode 100644 index 0000000..dcc3c8d --- /dev/null +++ b/config/examples/multiple-upstreams-health-check.kdl @@ -0,0 +1,116 @@ +// Example: Multiple Upstreams with Health Checks +// +// Load balance across multiple backend servers with: +// - Active health checks (HTTP probes) +// - Passive health checks (connection failures) +// - Automatic failover +// - Weighted load balancing + +system { + worker-threads 0 + max-connections 10000 + graceful-shutdown-timeout-secs 30 +} + +listeners { + listener "http" { + address "0.0.0.0:8080" + protocol "http" + request-timeout-secs 60 + } +} + +upstreams { + upstream "backend" { + // Load balancing strategy: round-robin (default), least-connections, ip-hash + strategy "least-connections" + + // Health check configuration + health-check { + enabled true + interval-secs 10 // Check every 10 seconds + timeout-secs 5 // Health check timeout + unhealthy-threshold 3 // Mark unhealthy after 3 failures + healthy-threshold 2 // Mark healthy after 2 successes + + // HTTP health check endpoint + http { + path "/health" + expected-status 200 + } + } + + // Backend servers + endpoint "backend-1" { + address "10.0.1.10:3000" + weight 100 + } + + endpoint "backend-2" { + address "10.0.1.11:3000" + weight 100 + } + + endpoint "backend-3" { + address "10.0.1.12:3000" + weight 50 // Lower weight = less traffic + } + } + + // Secondary upstream with different health check + upstream "api" { + strategy "round-robin" + + health-check { + enabled true + interval-secs 5 + timeout-secs 2 + unhealthy-threshold 2 + healthy-threshold 1 + + http { + path "/api/health" + expected-status 200 + // Optional: check response body + expected-body "OK" + } + } + + endpoint "api-1" { + address "10.0.2.10:4000" + } + + endpoint "api-2" { + address "10.0.2.11:4000" + } + } +} + +routes { + // Route to backend upstream + route "backend-route" { + priority "high" + matches { + path-prefix "/app" + } + upstream "backend" + policies { + timeout-secs 30 + retry-attempts 2 + failure-mode "open" // Open circuit breaker on failure + } + } + + // Route to API upstream + route "api-route" { + priority "high" + matches { + path-prefix "/api" + } + upstream "api" + policies { + timeout-secs 15 + retry-attempts 3 + } + } +} diff --git a/config/examples/rate-limiting-per-route.kdl b/config/examples/rate-limiting-per-route.kdl new file mode 100644 index 0000000..44b9673 --- /dev/null +++ b/config/examples/rate-limiting-per-route.kdl @@ -0,0 +1,107 @@ +// Example: Rate Limiting Per Route +// +// Configure different rate limits for different routes: +// - Strict limits for /api endpoints +// - Relaxed limits for /static content +// - No limits for health checks +// - Custom rate limit responses + +system { + worker-threads 0 + max-connections 10000 + graceful-shutdown-timeout-secs 30 +} + +listeners { + listener "http" { + address "0.0.0.0:8080" + protocol "http" + request-timeout-secs 60 + } +} + +upstreams { + upstream "api" { + endpoint "api-1" { + address "localhost:3000" + } + } + + upstream "static" { + endpoint "static-1" { + address "localhost:4000" + } + } +} + +routes { + // API routes: 100 requests per minute per IP + route "api" { + priority "high" + matches { + path-prefix "/api" + } + upstream "api" + rate-limit { + enabled true + requests-per-minute 100 + burst-size 20 // Allow temporary bursts + key-source "ip" // Rate limit per IP address + + // Custom response when rate limited + response { + status-code 429 + content-type "application/json" + body '{"error": "rate_limit_exceeded", "message": "Too many requests"}' + } + } + } + + // Login/Auth routes: Very strict limits (10 per minute) + route "auth" { + priority "critical" + matches { + path-prefix "/api/auth" + } + upstream "api" + rate-limit { + enabled true + requests-per-minute 10 + burst-size 3 + key-source "ip" + + response { + status-code 429 + content-type "application/json" + body '{"error": "too_many_attempts", "retry_after": 60}' + } + } + } + + // Static content: Generous limits (1000 per minute) + route "static" { + priority "low" + matches { + path-prefix "/static" + } + upstream "static" + rate-limit { + enabled true + requests-per-minute 1000 + burst-size 200 + key-source "ip" + } + } + + // Health check: No rate limiting + route "health" { + priority "critical" + matches { + exact-path "/health" + } + upstream "api" + rate-limit { + enabled false + } + } +}