summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--mullvad-api/src/domain_fronting/client.rs82
1 files changed, 82 insertions, 0 deletions
diff --git a/mullvad-api/src/domain_fronting/client.rs b/mullvad-api/src/domain_fronting/client.rs
index 8e90da5604..f7a42e2256 100644
--- a/mullvad-api/src/domain_fronting/client.rs
+++ b/mullvad-api/src/domain_fronting/client.rs
@@ -475,6 +475,88 @@ mod tests {
const TEST_SESSION_HEADER: &str = "X-Test-Session";
#[tokio::test]
+ async fn test_client_write_without_read() {
+ let listener = TcpListener::bind("127.0.0.1:0")
+ .await
+ .expect("Failed to bind echo server");
+ let echo_addr = listener.local_addr().expect("Failed to get local addr");
+
+ let server_task = tokio::spawn(async move {
+ let (mut socket, _) = match listener.accept().await {
+ Ok(conn) => conn,
+ Err(_) => panic!("failed to accept connection"),
+ };
+
+ let mut buf = vec![0u8; 4096];
+ let n = socket
+ .read(&mut buf)
+ .await
+ .expect("Failed to read from socket");
+
+ assert_eq!(&buf[..n], b"Hello from client");
+
+ socket
+ .write_all(&buf[..n])
+ .await
+ .expect("Failed to write to socket");
+ });
+
+ // Create in-memory transport between client and proxy server HTTP layers
+ let (client_stream, server_stream) = duplex(8192);
+
+ // Start proxy server with default TCP connector pointing to echo server
+ let sessions = server::Sessions::new(echo_addr, TEST_SESSION_HEADER.to_string());
+ let sessions_clone = sessions.clone();
+
+ // Spawn HTTP server on server_stream
+ tokio::spawn(async move {
+ let io = TokioIo::new(server_stream);
+ let service = hyper::service::service_fn(move |req| {
+ let sessions = sessions_clone.clone();
+ async move { Ok::<_, Infallible>(sessions.handle_request(req).await) }
+ });
+
+ let _ = hyper::server::conn::http1::Builder::new()
+ .serve_connection(io, service)
+ .await;
+ });
+
+ // Create client connection using the in-memory stream (no TLS)
+ let proxy_config = ProxyConfig::new(
+ echo_addr,
+ DomainFronting::new(
+ "example.com".to_string(),
+ "api.example.com".to_string(),
+ TEST_SESSION_HEADER.to_string(),
+ ),
+ );
+
+ let mut client = proxy_config
+ .connect_with_stream(client_stream, false)
+ .await
+ .expect("Failed to create client connection");
+
+ // Test: write to client, should echo back
+ let test_data = b"Hello from client";
+ client
+ .write_all(test_data)
+ .await
+ .expect("Failed to write to client");
+
+ // server_task never receives anything unless we read here
+ /*
+ let mut buffer = vec![0u8; 1024];
+ client
+ .read(&mut buffer)
+ .await
+ .expect("Failed to read from client");
+ */
+
+ // This hangs
+ server_task.await.expect("Server task failed");
+ }
+
+ #[tokio::test]
async fn test_client_server_bidirectional() {
// Spawn echo server that will be the upstream target
let echo_addr = spawn_echo_server().await;