easy-http-proxy-server 0.0.1

A simple HTTP/HTTPS proxy server with connection pooling support
Documentation

Easy HTTP Proxy Server

A simple HTTP/HTTPS proxy server with connection pooling support, written in Rust.

Features

  • HTTP/HTTPS Proxy Support: Handle both HTTP and HTTPS (CONNECT method) requests
  • Connection Pooling: Reuse TCP connections for better performance
  • Configurable: Command-line interface with customizable host, port, and logging options
  • Async: Built on Tokio for high-performance asynchronous I/O
  • Library + Binary: Can be used as both a standalone binary and a Rust library
  • Apache 2.0 Licensed: Open source under Apache License 2.0

Installation

From Source

git clone https://github.com/yourusername/easy-http-proxy-server.git
cd easy-http-proxy-server
cargo build --release

From Crates.io

cargo install easy-http-proxy-server

As a Library

Add this to your Cargo.toml:

[dependencies]
easy-http-proxy-server = "0.1.0"

Quick Start

Command Line Usage

# Start proxy server on default port 3128
cargo run --bin easy-http-proxy-server

# Custom host and port
cargo run --bin easy-http-proxy-server -- --host 0.0.0.0 --port 8080

# Enable verbose logging
cargo run --bin easy-http-proxy-server -- --verbose

# Show help
cargo run --bin easy-http-proxy-server -- --help

Library Usage

use easy_http_proxy_server::{ProxyServer, ProxyConfig};
use std::net::SocketAddr;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let addr: SocketAddr = "127.0.0.1:3128".parse()?;
    let config = ProxyConfig::new(addr, true);
    let server = ProxyServer::new(config);
    
    println!("Starting proxy server on {}", addr);
    server.run().await?;
    
    Ok(())
}

Configuration

Command Line Options

USAGE:
    easy-http-proxy-server [OPTIONS]

OPTIONS:
    --host <HOST>    Host to bind to [default: 127.0.0.1]
    -p, --port <PORT>    Port to bind to [default: 3128]
    -v, --verbose    Enable verbose logging
    -h, --help       Print help information

Environment Variables

  • RUST_LOG: Set logging level (e.g., RUST_LOG=debug)

API Documentation

ProxyServer

The main proxy server struct that handles incoming connections.

pub struct ProxyServer {
    // ...
}

impl ProxyServer {
    /// Create a new proxy server with the given configuration
    pub fn new(config: ProxyConfig) -> Self;
    
    /// Create a new proxy server with custom connection pool
    pub fn with_pool(config: ProxyConfig, pool: ConnectionPool) -> Self;
    
    /// Run the proxy server (blocks indefinitely)
    pub async fn run(&self) -> Result<()>;
    
    /// Get total connections handled
    pub fn total_connections(&self) -> u64;
    
    /// Get total requests handled
    pub fn total_requests(&self) -> u64;
    
    /// Get connection pool reference
    pub fn connection_pool(&self) -> &Arc<ConnectionPool>;
}

ProxyConfig

Configuration for the proxy server.

pub struct ProxyConfig {
    pub addr: SocketAddr,
    pub verbose: bool,
}

impl ProxyConfig {
    /// Create a new proxy configuration
    pub fn new(addr: SocketAddr, verbose: bool) -> Self;
    
    /// Create a configuration with default address
    pub fn localhost(port: u16, verbose: bool) -> Self;
}

ConnectionPool

Connection pool for managing reusable TCP connections.

pub struct ConnectionPool {
    // ...
}

impl ConnectionPool {
    /// Create a new connection pool
    pub fn new() -> Self;
    
    /// Get or create a connection to the specified address
    pub async fn get_or_create(&self, addr: &str) -> Result<TcpStream>;
    
    /// Get a connection from the pool if available
    pub async fn get(&self, addr: &str) -> Option<TcpStream>;
    
    /// Put a connection back into the pool
    pub async fn put(&self, addr: String, stream: TcpStream);
    
    /// Clean up expired connections
    pub async fn cleanup_expired(&self);
}

Error Handling

The library uses a custom ProxyError enum for consistent error handling:

pub enum ProxyError {
    Io(std::io::Error),
    Hyper(hyper::Error),
    AddressParse(std::net::AddrParseError),
    Other(String),
}

Architecture

The proxy server consists of several key components:

  1. ProxyServer: Main server that accepts connections and spawns handlers
  2. ConnectionPool: Manages reusable TCP connections to improve performance
  3. Request Handlers: Separate handlers for HTTP and HTTPS (CONNECT) requests
  4. Async I/O: Built on Tokio for high-performance asynchronous networking

HTTP Proxy Flow

  1. Client connects to proxy server
  2. Proxy server parses HTTP request
  3. For HTTP requests: Proxy server forwards request to target server and relays response
  4. For HTTPS requests: Proxy server establishes CONNECT tunnel and relays encrypted data

Connection Pooling

  • TCP connections are pooled and reused for better performance
  • Connections are automatically cleaned up when expired
  • Thread-safe implementation using Arc and Mutex

Performance

  • Connection Pooling: Reuses TCP connections to reduce connection overhead
  • Async I/O: Non-blocking I/O operations using Tokio
  • Zero-copy: Efficient data transfer where possible
  • Memory Efficient: Minimal memory footprint with efficient data structures

Security Considerations

  • No authentication mechanisms currently implemented
  • No rate limiting or request filtering
  • Basic proxy functionality without access controls
  • Suitable for development and testing environments

Limitations

  • The current implementation uses Connection: close headers, which means connections are not actually reused in practice
  • Basic connection pooling without advanced features like connection limits or health checks
  • No authentication or access control mechanisms
  • Limited error recovery and retry logic
  • HTTP/1.1 only (no HTTP/2 support)

Development

Building

# Debug build
cargo build

# Release build
cargo build --release

# Run tests
cargo test

# Run with logging
RUST_LOG=debug cargo run

Testing

# Run all tests
cargo test

# Run library tests only
cargo test --lib

# Run documentation tests
cargo test --doc

# Run with verbose output
cargo test -- --nocapture

Contributing

Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License

This project is licensed under the Apache License 2.0 - see the LICENSE file for details.

Copyright 2024

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Changelog

v0.1.0

  • Initial release
  • HTTP/HTTPS proxy support
  • Connection pooling
  • Command-line interface
  • Library API

Future Improvements

  • Implement proper HTTP/1.1 connection reuse
  • Add connection pool configuration options
  • Implement connection health checking
  • Add support for HTTP/2
  • Add authentication mechanisms
  • Implement request/response logging and metrics
  • Add support for proxy chaining
  • Implement rate limiting and throttling
  • Add WebSocket support
  • Implement request filtering and blocking
  • Add SSL/TLS termination support

Support

If you encounter any issues or have questions, please file an issue on the issue tracker.