rust-proxy 0.1.0

A simple HTTP/HTTPS proxy server written in Rust
//! HTTPS代理演示示例
//!
//! 这个示例展示了HTTPS代理如何通过CONNECT隧道工作

use std::io::{Read, Write};
use std::net::TcpStream;
use std::thread;
use std::time::Duration;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    println!("=== HTTPS代理工作原理演示 ===\n");

    // 演示1: 直接HTTPS连接(无代理)
    println!("1. 直接HTTPS连接(无代理):");
    demo_direct_https()?;

    println!("\n---\n");

    // 演示2: 通过代理的HTTPS连接
    println!("2. 通过代理的HTTPS连接:");
    demo_proxied_https()?;

    println!("\n=== 演示完成 ===");
    Ok(())
}

fn demo_direct_https() -> Result<(), Box<dyn std::error::Error>> {
    println!("连接到 https://httpbin.org:443 ...");

    let mut stream = TcpStream::connect("httpbin.org:443")?;
    println!("TCP连接已建立");

    // 注意:实际HTTPS需要TLS握手,这里只是演示TCP连接
    println!("(实际HTTPS连接需要TLS握手,此处省略)");

    Ok(())
}

fn demo_proxied_https() -> Result<(), Box<dyn std::error::Error>> {
    println!("假设代理服务器运行在 127.0.0.1:8080");
    println!("连接到代理服务器...");

    let mut proxy_stream = TcpStream::connect("127.0.0.1:8080")?;
    println!("已连接到代理服务器");

    // 发送CONNECT请求建立HTTPS隧道
    println!("\n发送CONNECT请求:");
    let connect_request = "CONNECT httpbin.org:443 HTTP/1.1\r\n\
                           Host: httpbin.org:443\r\n\
                           User-Agent: HTTPS-Demo/1.0\r\n\
                           \r\n";

    println!("请求内容:");
    println!("{}", connect_request);

    proxy_stream.write_all(connect_request.as_bytes())?;
    println!("CONNECT请求已发送");

    // 读取代理响应
    let mut buffer = [0; 1024];
    thread::sleep(Duration::from_millis(100)); // 等待响应
    let n = proxy_stream.read(&mut buffer)?;

    let response = String::from_utf8_lossy(&buffer[..n]);
    println!("\n代理服务器响应:");
    println!("{}", response);

    if response.contains("200 Connection Established") {
        println!("✓ HTTPS隧道已建立");
        println!("现在客户端可以与 httpbin.org:443 进行TLS握手");
        println!("所有加密数据将通过代理透明转发");
    } else {
        println!("✗ HTTPS隧道建立失败");
    }

    Ok(())
}

/// 演示CONNECT请求的格式
fn explain_connect_method() {
    println!("\nCONNECT方法说明:");
    println!("CONNECT是HTTP/1.1定义的方法,用于建立隧道连接");
    println!("格式: CONNECT {host}:{port} HTTP/1.1");
    println!("示例: CONNECT example.com:443 HTTP/1.1");
    println!("\n工作流程:");
    println!("1. 客户端发送CONNECT请求到代理");
    println!("2. 代理连接到目标服务器");
    println!("3. 代理返回 '200 Connection Established'");
    println!("4. 客户端与目标服务器进行TLS握手");
    println!("5. 代理透明转发所有加密数据");
}