Skip to content

Commit 1cc6621

Browse files
committed
test: add integration test for proxy server and client
1 parent 93331d8 commit 1cc6621

87 files changed

Lines changed: 349 additions & 1 deletion

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Cargo.lock

Lines changed: 98 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

h3proxy-lib/Cargo.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,7 @@ hyper-util = { version = "0.1", features = ["client-legacy", "http1", "tokio"] }
1919
anyhow = "1.0"
2020
tracing = "0.1"
2121
futures = "0.3"
22-
rustls = { version = "0.23", features = ["ring"] }
22+
rustls = { version = "0.23", features = ["ring"] }
23+
24+
[dev-dependencies]
25+
rcgen = "0.12"
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
use anyhow::Result;
2+
use h3proxy_lib::client::{ClientConfig, ProxyClient};
3+
use h3proxy_lib::config::ProxyConfig;
4+
use h3proxy_lib::server::ProxyServer;
5+
use rustls_pki_types::{CertificateDer, PrivateKeyDer};
6+
use std::net::SocketAddr;
7+
use tokio::net::TcpListener;
8+
use tokio::time::{sleep, Duration};
9+
10+
/// Helper to generate a self-signed cert for tests in-memory using `rcgen`.
11+
fn generate_test_cert() -> Result<(Vec<CertificateDer<'static>>, PrivateKeyDer<'static>)> {
12+
let subject_alt_names = vec!["localhost".to_string(), "127.0.0.1".to_string()];
13+
let cert = rcgen::generate_simple_self_signed(subject_alt_names)?;
14+
let cert_der = cert.serialize_der()?;
15+
let priv_key_der = cert.serialize_private_key_der();
16+
17+
let cert_chain = vec![CertificateDer::from(cert_der)];
18+
let priv_key = PrivateKeyDer::Pkcs8(priv_key_der.into());
19+
20+
Ok((cert_chain, priv_key))
21+
}
22+
23+
#[tokio::test]
24+
async fn test_proxy_server_and_client_connect() -> Result<()> {
25+
// 1. Generate test TLS certificates
26+
let (cert_chain, priv_key) = generate_test_cert()?;
27+
28+
// 2. Start a dummy local TCP echo server (simulate target website)
29+
let target_listener = TcpListener::bind("127.0.0.1:0").await?;
30+
let target_addr = target_listener.local_addr()?;
31+
32+
tokio::spawn(async move {
33+
if let Ok((mut socket, _)) = target_listener.accept().await {
34+
use tokio::io::{AsyncReadExt, AsyncWriteExt};
35+
let mut buf = [0u8; 1024];
36+
if let Ok(n) = socket.read(&mut buf).await {
37+
// Echo what was received for simplicity
38+
let _ = socket.write_all(&buf[..n]).await;
39+
}
40+
}
41+
});
42+
43+
// 3. Start the h3proxy Server on a random port
44+
let proxy_addr: SocketAddr = "127.0.0.1:4433".parse()?; // Fixed port to simplify config
45+
46+
let server_config = ProxyConfig {
47+
listen_addr: proxy_addr,
48+
cert_chain: cert_chain.clone(),
49+
priv_key,
50+
};
51+
52+
let server = ProxyServer::new(server_config);
53+
54+
tokio::spawn(async move {
55+
let _ = server.serve().await;
56+
});
57+
58+
// Give server a moment to bind
59+
sleep(Duration::from_millis(500)).await;
60+
61+
// 4. Run the Client and make a CONNECT request
62+
let client_config = ClientConfig {
63+
proxy_addr,
64+
target_url: format!("https://{}", target_addr),
65+
root_certs: cert_chain,
66+
};
67+
68+
let client = ProxyClient::new(client_config);
69+
70+
// We expect the run function to succeed and print out the echo response.
71+
// If the tunnel works, the `run` method completes `Ok(())`
72+
let result = client.run().await;
73+
assert!(result.is_ok(), "Client run failed: {:?}", result.err());
74+
75+
Ok(())
76+
}
14 Bytes
Binary file not shown.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
This file has an mtime of when this was started.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
01fd29d12e9ff707
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"rustc":8323788817864214825,"features":"[\"alloc\", \"std\"]","declared_features":"[\"alloc\", \"default\", \"std\"]","target":13060062996227388079,"profile":2241668132362809309,"path":16246736394679250058,"deps":[],"local":[{"CheckDepInfo":{"dep_info":"debug\\.fingerprint\\base64-95b222e6c8c4ec0b\\dep-lib-base64","checksum":false}}],"rustflags":[],"config":2069994364910194474,"compile_kind":0}
Binary file not shown.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
This file has an mtime of when this was started.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
61b498a0fdfd9881

0 commit comments

Comments
 (0)