prox

module
v0.15.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 24, 2026 License: MIT

README

prox

Modular reverse proxy with config-driven routing, load balancing, L4/L7 dispatching, hot reload, and plugin middleware.

CI Go Reference Go Report Card GitHub Release Go Version License

Documentation · Getting Started · Configuration · Plugins · Deployment

⚠️ Note: This project is currently under active development. Core features, APIs, and configuration structures may undergo significant breaking changes.

Quick Start

go install github.com/dortanes/prox/cmd/prox@latest

prox serve -config config.json5

Or build from source:

go build -o prox ./cmd/prox

Docker

services:
  prox:
    image: ghcr.io/dortanes/prox:latest
    ports:
      - "443:443"
      - "8080:8080"
    volumes:
      - ./config/:/etc/prox/config/
      - ./certs/:/etc/prox/certs/
    command: ["serve", "-config", "/etc/prox/config/"]

Features

  • Config-driven routing — JSON5 config with services, actions, and resources
  • Domain matching — segment wildcards (*.example.com, cdn-*.**)
  • L4 dispatching — SNI-based TCP pass-through alongside HTTP on the same port
  • Load balancing — round-robin, random, least-connections with connection tracking
  • Plugin middleware — auth, response modification, L4 gating via Go SDK
  • Dynamic targets — plugin-based service discovery with grouped targeting
  • Hot reload — zero-downtime config changes with file watcher
  • Logging — colorized console, leveled output, file-based access/error logs
  • WebSocket — transparent proxy with session pinning
  • TLS — multi-cert SNI, directory-based cert loading
  • HTTP/2 — full-duplex h2c upstream support
  • Fully concurrent — goroutine-per-connection across all CPU cores

Config

{
  services: {
    web: {
      listen: ":8080",
      routes: [
        { match: { domain: "api.example.com", path: "/v1/*" }, action: "api" },
        { match: { domain: "*.example.com" }, action: "site" },
        { action: { type: "drop" } },
      ],
    },
  },
  actions: {
    api: { type: "proxy", upstream: "localhost:3000", timeout: "5s" },
    site: { type: "serve", root: "./public" },
  },
}
Action Description
proxy Reverse proxy with WebSocket, load balancing, custom headers
static Fixed response with status, headers, template variables
serve File server — directory or single file (SPA)
pass L4 TCP pass-through — raw TLS relay
drop Silently close the connection

Plugins

Extend prox with auth, response modification, and L4 gating via the Go SDK:

p := sdk.New()
p.OnRequest(func(req *sdk.Request) *sdk.Response {
    if req.Header("Authorization") == "" {
        return sdk.Deny(401, "Unauthorized")
    }
    return sdk.Allow()
})
p.Run()
{
  plugins: {
    auth: { path: "./plugins/auth.go" },
  },
  services: {
    web: {
      routes: [
        {
          match: { domain: "*.example.com", path: "/api/*" },
          plugins: ["auth"],
          plugin_timeout: "2s",
          action: { type: "proxy", upstream: "localhost:3000" },
        }
      ]
    }
  }
}

Plugins with autostart: true are spawned at proxy startup without requiring route bindings — useful for background routines, health monitors, metrics exporters, and other global tasks:

plugins: {
  routines: { path: "./plugins/routines", autostart: true },
}

Logging

Colorized console output with structured key-value fields. Log level can be set via environment variable, CLI flag, or config file:

# Environment variable (highest priority)
LOG_LEVEL=debug prox serve

# CLI flag
prox serve -log-level debug

File-based logging with global and per-route access logs:

{
  logging: {
    level: "info",                           // overridden by LOG_LEVEL env
    access_log: "/var/log/prox/access.log",  // global access log (JSON lines)
    error_log: "/var/log/prox/error.log",    // warn/error level messages
  },
  services: {
    web: {
      routes: [
        {
          match: { path: "/api/*" },
          access_log: "/var/log/prox/api.log",  // per-route access log
          action: { type: "proxy", upstream: "localhost:3000" },
        },
      ],
    },
  },
}

Log files support rotation via SIGHUP — send the signal to reopen all log files after rotating them with tools like logrotate.

Performance

~90K requests/sec with 2.8 ms average latency (HTTP/1.1 reverse proxy, no TLS, single node).

Comparison with popular proxies — same machine, same upstream, same load tool (wrk, 256 connections):

Proxy Req/s Avg latency P99 latency
prox 90,212 2.83 ms 3.72 ms
HAProxy 89,950 2.79 ms 4.00 ms
Nginx 87,626 2.89 ms 3.78 ms
Traefik 83,325 3.06 ms 5.63 ms
Caddy 12,432 25.55 ms 118.78 ms
Benchmark details
  • Machine: Apple M4 Pro (12-core), 24 GB RAM, macOS
  • Load: wrk -t4 -c256 -d10s, 3 runs per proxy, best result used
  • Upstream: Go HTTP server returning 200 OK (2 bytes)
  • Config: Minimal reverse proxy config, logging disabled, no TLS
  • Tuning: SO_REUSEPORT enabled with multiple parallel acceptor loops (tuned to PROX_WORKERS=2 on macOS to eliminate kqueue scheduler contention), platform-specific socket optimizations (like TCP_DEFER_ACCEPT on Linux to avoid waking worker threads until request data is ready to read), production Go compiler optimizations (-ldflags="-s -w"), and disabled background GC sweeps (GOGC=off for benchmark duration) to maximize raw scheduler throughput.
  • Reproduce: bash bench/run.sh (requires brew install wrk nginx haproxy caddy traefik)

Results depend on hardware, OS, and workload. Run bench/run.sh on your own machine for accurate numbers.

License

MIT

Directories

Path Synopsis
cmd
prox command
prox is a modular reverse proxy with config-driven routing.
prox is a modular reverse proxy with config-driven routing.
internal
action
Package action implements request handlers (proxy, static, serve, pass, drop).
Package action implements request handlers (proxy, static, serve, pass, drop).
balancer
Package balancer implements load balancing strategies for upstream selection.
Package balancer implements load balancing strategies for upstream selection.
config
Package config defines the configuration model for prox.
Package config defines the configuration model for prox.
dispatcher
Package dispatcher implements L4 TCP dispatching based on TLS SNI.
Package dispatcher implements L4 TCP dispatching based on TLS SNI.
logger
Package logger provides colorized console logging and file-based access/error logging.
Package logger provides colorized console logging and file-based access/error logging.
plugin
Package plugin implements external plugin process management.
Package plugin implements external plugin process management.
resource
Package resource resolves named resources into their content.
Package resource resolves named resources into their content.
router
Package router implements first-match HTTP request routing.
Package router implements first-match HTTP request routing.
server
Package server manages HTTP/HTTPS listener lifecycle and hot reload.
Package server manages HTTP/HTTPS listener lifecycle and hot reload.
watcher
Package watcher monitors config files for changes using stat-based polling.
Package watcher monitors config files for changes using stat-based polling.
sdk module

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL