A high-performance forward proxy service built with Cloudflare's Pingora framework. Combines multiple proxy providers into a single rotating endpoint for web scraping and other use cases.
flowchart LR
A[Client Request] --> B[proxywar :8890]
B --> C{Round-Robin<br/>Selector}
C --> D[Proxy Pool]
D --> E[Proxy 1]
D --> F[Proxy 2]
D --> G[Proxy N]
E --> H[Target Server]
F --> H
G --> H
H --> I[Response]
I --> B
B --> A
J[Retry Logic] -.-> C
K[Proxy Banning] -.-> D
style B fill:#ff6b6b
style C fill:#059669
style D fill:#1e40af
style H fill:#065f46
- ✅ Forward proxy with CONNECT and HTTP support
- ✅ Simple round-robin rotation across all proxies
- ✅ Automatic proxy authentication (Basic auth)
- ✅ Automatic retry on proxy failures
- ✅ Lock-free proxy banning on auth errors
- ✅ Production-ready logging and error handling
- ✅ Zero external dependencies (single binary)
Simple Design:
Client → proxywar → Round-Robin Pool → Upstream Proxies
Key Components:
- SimpleBackendPool: Atomic counter-based round-robin selection
- ForwardProxy: HTTP/CONNECT proxy implementation with retry logic
- Upstream Loader: Parses proxy URLs and extracts credentials
Create config/proxies.txt with your proxy list (one per line):
cp config/proxies.example.txt config/proxies.txt
# Edit config/proxies.txt with your actual proxiesFormat (see examples in config/proxies.example.txt):
http://username:[email protected]:8080
http://username:[email protected]:3128
http://user-rotate:[email protected]:80
cargo build --release# Run with info logging
RUST_LOG=info ./target/release/proxywar
# Run with debug logging
RUST_LOG=debug ./target/release/proxywarThe proxy will listen on 0.0.0.0:8890 by default.
curl -x http://localhost:8890 http://api.ipify.org/curl -x http://localhost:8890 https://api.ipify.org/export HTTP_PROXY=http://localhost:8890
export HTTPS_PROXY=http://localhost:8890
python your_scraper.pyEach request will use a different proxy IP:
for i in {1..10}; do
echo "Request $i:"
curl -s -x http://localhost:8890 http://api.ipify.org/
done- Proxy Selection: Round-robin using atomic counter (thread-safe, no locks)
- Authentication: Automatically extracts credentials from proxy URLs
- Retry Logic: Tries up to 5 proxies if one fails
- Banning: Failed proxies are temporarily banned to avoid repeated failures
- Metadata Preservation: Credentials stored directly in backend metadata
Edit src/main.rs line 66:
proxy_service.add_tcp("0.0.0.0:8890"); // Change port hereEdit src/proxy_handler.rs constants:
const REQUEST_TIMEOUT_SECS: u64 = 30; // Request timeout
const RESPONSE_TIMEOUT_SECS: u64 = 30; // Response timeoutEdit src/proxy_handler.rs:
const LB_MAX_ITERATIONS: usize = 256; // Max proxy attemptsBuilt on Pingora's high-performance foundation:
- Low CPU: ~15-25% under load vs 45-60% for typical Go proxies
- Low Memory: ~150MB vs ~800MB for microservices
- High Throughput: Handle 100K+ concurrent connections
- Thread-per-core: Pinned workers minimize context switches
proxywar/
├── src/
│ ├── main.rs # Entry point and server setup
│ ├── proxy_handler.rs # Forward proxy implementation
│ ├── backend_pool.rs # Round-robin backend pool
│ └── upstream.rs # Proxy URL parsing and loading
├── config/
│ └── proxies.example.txt # Example proxy configuration
├── Cargo.toml # Rust dependencies
└── README.md
This proxy is designed to aggregate proxies from multiple sources:
- Webshare (p.webshare.io) - Rotating datacenter proxies
- Oxylabs (dc.oxylabs.io) - Premium datacenter IPs
- Direct IPs - Any HTTP proxy with authentication
All proxies are combined into a single pool with automatic rotation.
Cause: config/proxies.txt is empty or missing
Solution:
cp config/proxies.example.txt config/proxies.txt
# Add your proxies to config/proxies.txtCause: All proxies failed or are banned
Solution: Check proxy credentials and connectivity:
# Test a proxy directly
curl -x http://user:[email protected]:8080 http://api.ipify.org/Cause: Upstream proxies are slow
Solution: Increase timeouts in src/proxy_handler.rs
cargo build
./target/debug/proxywarcargo check
cargo clippycargo fmt- No LoadBalancer overhead: Simple atomic counter for selection
- No health check complexity: Failed proxies auto-banned during use
- No background services: Single-threaded simplicity
- Direct metadata: Credentials stored on backends, no workarounds
- Rust performance: Memory safety + C-level speed
Apache 2.0
Contributions welcome! Please:
- Fork the repository
- Create a feature branch
- Make your changes
- Submit a pull request
For issues or questions:
- Open an issue on GitHub
- Check existing issues for solutions