Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Reverse Proxy

BWS provides comprehensive reverse proxy functionality with load balancing and WebSocket support.

Basic Configuration

[[sites]]
name = "proxy"
hostname = "api.example.com"
port = 80
static_dir = "static"

[sites.proxy]
enabled = true

# Backend servers
[[sites.proxy.upstreams]]
name = "backend"
url = "http://127.0.0.1:3001"
weight = 1

[[sites.proxy.upstreams]]
name = "backend" 
url = "http://127.0.0.1:3002"
weight = 2

# Routes
[[sites.proxy.routes]]
path = "/api/"
upstream = "backend"
strip_prefix = false

# Load balancing
[sites.proxy.load_balancing]
method = "round_robin"

Load Balancing Methods

Round Robin

[sites.proxy.load_balancing]
method = "round_robin"    # Distribute requests evenly

Weighted Round Robin

[[sites.proxy.upstreams]]
name = "backend"
url = "http://server1:3001"
weight = 3               # Gets 3x more requests

[[sites.proxy.upstreams]]
name = "backend"
url = "http://server2:3001"
weight = 1               # Gets 1x requests

[sites.proxy.load_balancing]
method = "weighted"

Least Connections

[sites.proxy.load_balancing]
method = "least_connections"  # Route to server with fewest active connections

Route Configuration

Path-Based Routing

# API routes to backend
[[sites.proxy.routes]]
path = "/api/"
upstream = "api-backend"
strip_prefix = false     # Keep /api/ in forwarded path

# Admin routes to different backend
[[sites.proxy.routes]]
path = "/admin/"
upstream = "admin-backend"
strip_prefix = true      # Remove /admin/ from forwarded path

WebSocket Proxying

[[sites.proxy.routes]]
path = "/ws"
upstream = "websocket-backend"
websocket = true         # Enable WebSocket support
strip_prefix = false

[[sites.proxy.upstreams]]
name = "websocket-backend"
url = "http://127.0.0.1:3001"  # Will proxy WebSocket connections

Header Management

Automatic Headers

[sites.proxy.headers]
add_x_forwarded = true   # Add X-Forwarded-For, X-Forwarded-Proto
add_forwarded = true     # Add standard Forwarded header

Custom Headers

[sites.proxy.headers.add]
"X-API-Gateway" = "BWS"
"X-Request-ID" = "auto"

[sites.proxy.headers.remove]
"Server" = true
"X-Powered-By" = true

Timeout Configuration

[sites.proxy.timeout]
read = 30               # Read timeout in seconds
write = 30              # Write timeout in seconds
connect = 5             # Connection timeout in seconds

Complete Example

[server]
name = "BWS Proxy Server"

# Main site with mixed static/proxy
[[sites]]
name = "main"
hostname = "example.com"
port = 80
static_dir = "static"

[sites.proxy]
enabled = true

# API backend cluster
[[sites.proxy.upstreams]]
name = "api-cluster"
url = "http://api1.internal:3001"
weight = 2

[[sites.proxy.upstreams]]
name = "api-cluster"
url = "http://api2.internal:3001"
weight = 1

# WebSocket backend
[[sites.proxy.upstreams]]
name = "websocket-backend"
url = "http://ws.internal:3002"

# Route API requests
[[sites.proxy.routes]]
path = "/api/"
upstream = "api-cluster"
strip_prefix = false

# Route WebSocket connections
[[sites.proxy.routes]]
path = "/ws"
upstream = "websocket-backend"
websocket = true

# Load balancing
[sites.proxy.load_balancing]
method = "weighted"

# Timeouts
[sites.proxy.timeout]
read = 30
write = 30
connect = 5

# Headers
[sites.proxy.headers]
add_x_forwarded = true
add_forwarded = true

[sites.proxy.headers.add]
"X-Gateway" = "BWS"

Testing Proxy Setup

Start Backend Services

# Start test backends
python3 -m http.server 3001 &
python3 -m http.server 3002 &

# Or use Node.js
npx http-server -p 3001 &
npx http-server -p 3002 &

Test Load Balancing

# Test multiple requests to see load balancing
for i in {1..10}; do
  curl -H "X-Request-ID: $i" http://localhost/api/test
done

# Check which backend handled each request
curl -v http://localhost/api/test

WebSocket Testing

# Test WebSocket connection
npx wscat -c ws://localhost/ws

# Test through proxy
curl --upgrade websocket http://localhost/ws

Monitoring

Health Checks

# Check proxy status
curl http://localhost/api/health

# Monitor backend connectivity
curl -v http://localhost/api/test

Log Analysis

# Monitor proxy logs
tail -f /var/log/bws.log | grep proxy

# Check upstream connections
netstat -an | grep :3001

Production Considerations

High Availability

# Multiple backend servers
[[sites.proxy.upstreams]]
name = "production-api"
url = "http://api1.prod:3001"
weight = 1

[[sites.proxy.upstreams]]
name = "production-api"
url = "http://api2.prod:3001"
weight = 1

[[sites.proxy.upstreams]]
name = "production-api"
url = "http://api3.prod:3001"
weight = 1

# Conservative timeouts
[sites.proxy.timeout]
read = 60
write = 60
connect = 10

Security Headers

[sites.proxy.headers.add]
"X-Content-Type-Options" = "nosniff"
"X-Frame-Options" = "DENY"
"X-XSS-Protection" = "1; mode=block"

[sites.proxy.headers.remove]
"Server" = true
"X-Powered-By" = true

SSL Termination

# Terminate SSL at BWS, HTTP to backends
[[sites]]
name = "ssl-proxy"
hostname = "api.example.com"
port = 443
static_dir = "static"

[sites.ssl]
enabled = true
auto_cert = true
domains = ["api.example.com"]

[sites.ssl.acme]
enabled = true
email = "admin@example.com"

[sites.proxy]
enabled = true

[[sites.proxy.upstreams]]
name = "backend"
url = "http://internal-api:3001"  # HTTP to internal backend