A high-performance Go-based middleware proxy server that supports HTTP, HTTPS, and raw socket connections with advanced queue-based request processing, comprehensive monitoring, and flexible configuration options.
- 🔗 Multi-protocol support: HTTP, HTTPS, and raw socket connections
- 📥 Queue-based processing: All requests are queued and processed sequentially with configurable queue size and header-based routing
- 🔒 Persistent headers: Force specific headers that cannot be overwritten by clients (e.g., User-Agent: mobile)
- ⏱ Configurable delays: Set random delays between requests (min/max range in milliseconds)
- ⚙️ Flexible configuration: Environment variables and command-line flags with precedence handling
- 🛡️ Connection management: Proper timeout handling, resource cleanup, and context-based cancellation
- 📊 Prometheus metrics: Built-in metrics collection for monitoring request throughput, errors, and performance
- ❤️ Health checks: Comprehensive health and readiness endpoints with detailed status information
- 🌐 Flexible port configuration: Support for shared or dedicated ports for health checks and metrics
- 📝 Structured logging: JSON-formatted logs with configurable levels and detailed request/response tracking
- 🐳 Docker support: Ready-to-use Docker images with multi-stage builds and health checks
- 🔧 Cross-platform builds: Support for multiple architectures (Linux, macOS, Windows on AMD64/ARM64)
- Go 1.23.0 or later (using toolchain go1.24.7)
- Make (optional, for using Makefile)
- Docker and Docker Compose (optional, for containerized deployment)
# Build for current platform
go build -o proxy-queue main.go
# Or use Makefile
make buildUse the provided Makefile to build for different platforms:
# Build for specific platforms
make build-linux # Linux x86_64
make build-linux-arm64 # Linux ARM64
make build-ubuntu # Ubuntu (same as Linux x86_64)
make build-macos # macOS x86_64
make build-macos-arm64 # macOS ARM64 (Apple Silicon)
make build-windows # Windows x86_64
make build-windows-arm64 # Windows ARM64
# Build for all platforms
make build-all
# Create distribution packages
make distmake help # Show all available targets
make clean # Clean build artifacts
make deps # Install dependencies
make test # Run tests
make test-race # Run tests with race detection
make lint # Run linter (requires golangci-lint)
make fmt # Format code
make vet # Vet code
make dev # Development build with debug info
make install # Install to GOPATH/bin
make info # Show build information
make check-version # Check Go version compatibility# Run with default settings (proxy to localhost:443 with HTTPS)
./proxy-queue
# Run with custom target
./proxy-queue -target-host=example.com -target-port=8080
# Run with HTTPS target
./proxy-queue -target-host=api.example.com -target-port=443 -https=true
# Configure delays and queue size
./proxy-queue -delay-min=1000 -delay-max=3000 -queue-size=500
# Configure request timeout (30 seconds for all timeout types)
./proxy-queue -timeout=30 -target-host=api.example.com
# Set longer timeout for slow APIs (120 seconds)
./proxy-queue -timeout=120 -target-host=slow-api.example.com
# Configure header-based queues for AWS requests
./proxy-queue -header-queues="X-Amz-Security-Token,Authorization" -target-host=api.example.com
# Configure persistent headers that cannot be overwritten
./proxy-queue -persistent-headers="User-Agent:mobile,X-Source:proxy" -target-host=api.example.com
# Full configuration example with timeout and persistent headers
./proxy-queue -target-host=thanhlv.com -target-port=443 -port=6789 -delay-min=1 -delay-max=5 -timeout=60 -persistent-headers="User-Agent:mobile"
# Quick run with Makefile
make run # Build and run with defaults
make run-example # Run with example configurationThe application supports both environment variables (prioritized) and command line flags. Environment variables take precedence when both are provided.
| Environment Variable | Command Line Flag | Default | Description |
|---|---|---|---|
PROXY_LISTEN_PORT |
-port |
6789 | Port to listen on |
PROXY_TARGET_HOST |
-target-host |
localhost | Target host to proxy to |
PROXY_TARGET_PORT |
-target-port |
443 | Target port to proxy to |
PROXY_DELAY_MIN |
-delay-min |
1000 | Minimum delay between requests (ms) |
PROXY_DELAY_MAX |
-delay-max |
5000 | Maximum delay between requests (ms) |
PROXY_USE_HTTPS |
-https |
true | Use HTTPS for target connections |
PROXY_MAX_QUEUE_SIZE |
-queue-size |
1000 | Maximum queue size |
PROXY_METRICS_PORT |
-metrics-port |
9090 | Port for Prometheus metrics |
PROXY_HEALTH_PORT |
-health-port |
8081 | Port for health checks |
PROXY_LOG_LEVEL |
-log-level |
info | Log level (debug, info, warn, error) |
PROXY_SHARED_HEALTH_PORT |
-shared-health-port |
false | Serve health checks on HTTP proxy port 🚩 |
PROXY_SHARED_METRICS_PORT |
-shared-metrics-port |
false | Serve metrics on HTTP proxy port 📊 |
PROXY_HEADER_QUEUES |
-header-queues |
X-Amz-Security-Token | Comma-separated headers for dedicated queues |
PROXY_PERSISTENT_HEADERS |
-persistent-headers |
(empty) | Persistent headers that cannot be overwritten 🔒 |
PROXY_TIMEOUT |
-timeout |
0 | Request timeout in seconds (0 = infinite ⏳) |
PROXY_URL |
-proxy-url |
(empty) | Proxy URL for TARGET_HOST connections 🌐 |
PROXY_AUTH |
-proxy-auth |
(empty) | Proxy authentication (username:password) 🔐 |
The proxy supports adding persistent headers that are always included in outgoing requests and cannot be overwritten by clients. This is useful for enforcing specific headers like User-Agent, API keys, or authentication tokens that must remain constant.
Persistent headers are configured using a comma-separated list of key:value pairs:
# Command line flag
./proxy-queue -persistent-headers "User-Agent:mobile,X-API-Version:v2.1,Authorization:Bearer fixed-token"
# Environment variable
export PROXY_PERSISTENT_HEADERS="User-Agent:mobile,X-API-Version:v2.1,Authorization:Bearer fixed-token"
./proxy-queue| Use Case | Example Configuration | Description |
|---|---|---|
| Mobile User Agent | User-Agent:mobile |
Force all requests to appear as mobile |
| API Versioning | X-API-Version:v2.1,Accept:application/json |
Enforce specific API version and content type |
| Fixed Authentication | Authorization:Bearer token123 |
Use a fixed auth token that clients cannot override |
| Custom Headers | X-Source:proxy-queue,X-Environment:production |
Add metadata headers for tracking |
- Non-overwriteable: Client headers with the same name are ignored
- Always applied: Persistent headers are added to every HTTP/HTTPS request
- Debug logging: Header application is logged at debug level for troubleshooting
- Flexible format: Supports any valid HTTP header name and value
# Ensure all requests use mobile user agent
./proxy-queue -persistent-headers "User-Agent:mobile" -target-host=api.example.com
# Multiple persistent headers
./proxy-queue -persistent-headers "User-Agent:mobile,X-Source:proxy,Accept:application/json"
# Environment variable approach
export PROXY_PERSISTENT_HEADERS="User-Agent:mobile,X-Custom:always-present"
./proxy-queue -target-host=api.example.comThe proxy-queue can route all TARGET_HOST connections through an upstream proxy server. This is useful when your network requires proxy access to reach external services, or when you need to add an additional layer of routing.
| Proxy Type | URL Format | Features |
|---|---|---|
| HTTP | http://proxy.example.com:8080 |
✅ HTTP requests ❌ Socket connections |
| HTTPS | https://proxy.example.com:8080 |
✅ HTTP requests ❌ Socket connections |
| SOCKS5 | socks5://proxy.example.com:1080 |
✅ HTTP requests ✅ Socket connections |
# Command line flags
./proxy-queue \
-target-host=api.example.com \
-proxy-url=socks5://proxy.company.com:1080 \
-proxy-auth=username:password
# Environment variables
export PROXY_URL=http://corporate-proxy:8080
export PROXY_AUTH=myuser:mypass
./proxy-queue -target-host=api.example.com
# Docker environment
docker run -e PROXY_URL=socks5://proxy:1080 -e PROXY_AUTH=user:pass proxy-queueThe proxy supports username/password authentication for all proxy types:
# Include auth in URL (HTTP/HTTPS only)
export PROXY_URL=http://username:password@proxy.example.com:8080
# Separate auth parameter (recommended for security)
export PROXY_URL=socks5://proxy.example.com:1080
export PROXY_AUTH=username:password- No credential logging: Proxy authentication is never logged in plaintext
- Fallback behavior: If proxy connection fails, falls back to direct connection
- Connection validation: Invalid proxy URLs are detected and logged
- Debug visibility: Proxy usage is logged at debug level for troubleshooting
| Connection Type | Proxy Required | Fallback Behavior |
|---|---|---|
| HTTP/HTTPS | Optional | Falls back to direct connection |
| Socket | Optional | Falls back to direct connection |
| Both | Optional | Each connection type handles its own |
The proxy supports routing requests to dedicated queues based on specific HTTP headers. This is particularly useful for managing different authentication systems or API providers that require rate limiting.
| System | Headers | Description |
|---|---|---|
| AWS Services, claude cli 🔑 | X-Amz-Security-Token |
Routes AWS API requests with temporary credentials or IAM authentication |
| ChatGPT/OpenAI 🤖 | Authorization, OpenAI-Organization |
Handles OpenAI API requests with API keys and organization routing |
| Claude/Anthropic 🌐 | Authorization, anthropic-version |
Manages Anthropic API requests with proper versioning |
| Google Cloud ☁️ | Authorization, X-Goog-User-Project |
Routes Google Cloud API requests with project-specific billing |
| Azure 🟦 | Authorization, Ocp-Apim-Subscription-Key |
Handles Azure API Management requests |
| Custom APIs 🔧 | X-API-Key, Authorization, X-Custom-Token |
Generic headers for custom authentication systems |
# AWS-specific configuration
./proxy-queue -header-queues="X-Amz-Security-Token,Authorization" -target-host=xxx
# Environment variable approach
export PROXY_HEADER_QUEUES="Authorization,X-Amz-Security-Token,OpenAI-Organization"
./proxy-queue- Request Analysis: Incoming requests are inspected for configured headers
- Queue Selection: Requests with matching headers are routed to dedicated queues
- Isolated Processing: Each header-based queue processes requests independently
- Rate Limiting: Different queues can have different processing rates and delays
- Fallback: Requests without matching headers go to the main queue
# Copy and modify the example environment file
cp .env.example .env
# Or set environment variables directly
export PROXY_TARGET_HOST=api.example.com
export PROXY_TARGET_PORT=443
export PROXY_LOG_LEVEL=debug
export PROXY_HEADER_QUEUES=X-Amz-Security-Token
export PROXY_PERSISTENT_HEADERS="User-Agent:mobile,X-Source:proxy-queue"
export PROXY_TIMEOUT=45 # 45 seconds timeout for all operations
./proxy-queue- HTTP/HTTPS Proxy: Listens on the specified port (default: 6789) 🌐
- Socket Proxy: Listens on the specified port + 10 (default: 6799)
- Health Checks: Listens on health-port (default: 8081) OR on HTTP proxy port if
-shared-health-port=true🚩 - Metrics: Listens on metrics-port (default: 9090) OR on HTTP proxy port if
-shared-metrics-port=true📊
# Start proxy
./proxy-queue -target-host=httpbin.org -target-port=80 -https=false
# Test with curl
curl http://localhost:6789/get# Start HTTPS proxy
./proxy-queue -target-host=httpbin.org -target-port=443 -https=true
# Test with curl
curl http://localhost:6789/get# Start proxy
./proxy-queue -target-host=example.com -target-port=22
# Test with telnet or netcat (socket proxy runs on port + 10)
telnet localhost 6799# Check application health
curl http://localhost:8081/health
# Check readiness
curl http://localhost:8081/ready
# View Prometheus metrics
curl http://localhost:9090/metrics# Start proxy with shared ports
./proxy-queue -shared-health-port=true -shared-metrics-port=true
# Check application health (now on proxy port)
curl http://localhost:6789/health
# Check readiness (now on proxy port)
curl http://localhost:6789/ready
# View Prometheus metrics (now on proxy port)
curl http://localhost:6789/metricsThe application exposes the following Prometheus metrics:
proxy_requests_total(Counter): Total number of proxy requests processedproxy_request_duration_seconds(Histogram): Duration of proxy requests in secondsproxy_queue_size(Gauge): Current number of requests in queueproxy_errors_total(Counter): Total number of proxy errorsproxy_concurrent_requests(Gauge): Number of concurrent requests being processed
These metrics can be scraped by Prometheus and visualized using Grafana dashboards.
The application uses structured JSON logging with the following features:
- Configurable log levels:
debug,info,warn,error - Request tracking: Each request gets a unique ID for end-to-end tracing
- Detailed request/response logging: At debug level, full HTTP headers, bodies, and socket data are logged
- Performance metrics: Request duration, queue length, and processing statistics
- Connection details: Client IPs, connection states, and data transfer amounts
Example debug log output:
{
"level": "debug",
"msg": "📥 HTTP Request Details",
"request_id": "http-1672531200123456789",
"method": "GET",
"url": "/api/data",
"headers": { "User-Agent": "curl/7.81.0" },
"remote_ip": "192.168.1.100",
"timestamp": "2023-01-01T12:00:00.123456789Z"
}# Only health checks on shared port, metrics separate
./proxy-queue -shared-health-port=true
# Health checks on proxy port: http://localhost:6789/health
# Metrics still on separate port: http://localhost:9090/metrics# Development build with debug info
make dev
# Run tests
make test
# Run tests with race detection
make test-race
# Format and lint code
make fmt
make lint
make vet- Queue System: All incoming requests (HTTP, HTTPS, socket) are added to either the main queue or header-specific queues based on configured header routing
- Header-Based Routing: Requests with specific headers (e.g.,
X-Amz-Security-Token,Authorization) can be routed to dedicated queues for isolated processing - Sequential Processing: Requests are processed one by one in FIFO order by dedicated goroutines for each queue
- Configurable Delays: After processing each request, the system waits for a random delay calculated between the configured min/max values
- Connection Forwarding:
- HTTP/HTTPS requests are forwarded with proper header and body copying, including SSL/TLS support
- Socket connections use bidirectional data copying with enhanced logging and error handling
- Request Tracking: Each request gets a unique ID for tracking throughout the processing pipeline
- Metrics Collection: Real-time metrics are collected for requests, errors, queue size, processing duration, and concurrent operations across all queues
- Health Monitoring: Continuous health status monitoring with automatic degradation detection based on error rates, including per-queue status
# Build and run with default configuration
docker-compose up --build
# Run in background
docker-compose up -d
# View logs
docker-compose logs -f proxy-queue
# Stop services
docker-compose down# Run with local development profile
docker-compose --profile local up
# Run with monitoring stack (Prometheus + Grafana)
docker-compose --profile monitoring up
# Run all services
docker-compose --profile local --profile monitoring up# Build custom image
docker build -t my-proxy-queue .
# Run with custom environment variables
docker run -d \
-p 6789:6789 \
-p 6799:6799 \
-e PROXY_TARGET_HOST=api.example.com \
-e PROXY_TARGET_PORT=443 \
-e PROXY_LOG_LEVEL=debug \
my-proxy-queue# Copy and modify environment file
cp .env.example .env
# Use with docker-compose
docker-compose --env-file .env upAccess the monitoring stack:
- Proxy Queue: http://localhost:6789
- Prometheus: http://localhost:9091
- Grafana: http://localhost:3000 (admin/admin)
QueueManager: Main orchestrator managing multiple queues (main + header-based queues)ProxyQueue: Individual queue manager with thread-safe operations, metrics collection, and request processingConfig: Configuration structure supporting both environment variables and command-line flagsHTTPRequestData/SocketRequestData: Type-safe request data structures with client informationProxyRequest/ProxyResponse: Queue communication protocol with response channelsMetrics: Prometheus metrics collection with counters, histograms, and gauges (shared across queues)
- Main Goroutine: Configuration loading, server initialization, and coordination
- Queue Manager: Orchestrates multiple queues and routes requests based on headers
- Queue Processors: Dedicated goroutines for each queue (main + header-based) with sequential processing
- HTTP Proxy Server: Goroutine handling HTTP/HTTPS requests on the main port with header-based routing
- Socket Proxy Server: Goroutine handling raw socket connections on port+10 (uses main queue)
- Health Server: Optional dedicated goroutine for health checks (port 8081)
- Metrics Server: Optional dedicated goroutine for Prometheus metrics (port 9090)
- Connection Handlers: Per-connection goroutines for socket bidirectional copying
- Context-based Cancellation: Proper shutdown handling across all components
- Thread-safe Operations: Mutex-protected shared state and atomic counters
- Request Identification: Unique request IDs with timestamp-based generation
- Comprehensive Logging: Structured JSON logging with configurable levels and detailed request/response tracking
- Error Handling: Graceful error recovery with metrics tracking and client notification
- Resource Management: Proper connection cleanup and timeout handling
The project uses minimal external dependencies to ensure reliability and security:
- logrus v1.9.3: Structured logging with JSON formatting
- prometheus/client_golang v1.23.2: Metrics collection and exposition
All dependencies are automatically managed through Go modules (go.mod/go.sum).
- TLS Support: Configurable HTTPS/TLS for target connections with
InsecureSkipVerifyoption - Client IP Detection: Proper client IP extraction supporting
X-Forwarded-ForandX-Real-IPheaders - Resource Limits: Configurable queue size limits to prevent memory exhaustion
- Timeout Protection: Configurable timeouts for HTTP requests, socket connections, HTTP proxy responses, and socket connection handling - all customizable via
-timeoutflag. Note: There's a bug in the HTTP request timeout logic (main.go:787-788) where timeout=0 incorrectly sets 30s instead of infinite - Connection Cleanup: Proper resource cleanup and connection closing
- Buffered Channels: Queue implementation uses buffered channels for efficient request handling
- Connection Pooling: HTTP client with configurable transport settings
- Concurrent Processing: Separate goroutines for different protocol handlers
- Memory Management: 32KB buffers for socket data copying to balance memory usage and performance
- Atomic Operations: Lock-free counters for high-frequency metrics updates
- Queue Sizing: Choose appropriate
PROXY_MAX_QUEUE_SIZEbased on expected load and available memory - Delay Configuration: Set
PROXY_DELAY_MIN/PROXY_DELAY_MAXaccording to target server capacity - Timeout Configuration: Set appropriate
PROXY_TIMEOUTvalues based on target server response times. Different timeout behavior:- HTTP client requests: Uses config.Timeout value (bug: timeout=0 sets 30s instead of infinite)
- HTTP proxy responses: Uses config.Timeout value (timeout=0 sets 60min, >0 multiplies by seconds)
- Socket connections: Uses config.Timeout value (timeout=0 sets 30min, >0 multiplies by seconds)
- Socket connection handling: Uses config.Timeout value (timeout=0 uses config.Timeout as-is, >0 multiplies by seconds)
- Note: The timeout logic has inconsistencies across different components
- Log Level: Use
debuglevel cautiously in production as it logs full request/response bodies - Health Checks: Configure monitoring systems to use
/healthand/readyendpoints - Resource Monitoring: Monitor queue size and error rate metrics for capacity planning