Files
telemt/src/web/http/decoy_dns_tests.rs
T

56 lines
2.4 KiB
Rust

use super::*;
use arc_swap::ArcSwap;
use std::sync::Arc;
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::net::TcpListener;
use crate::config::WebCarrier;
use crate::maestro::generation::test_runtime_generation;
use crate::web::http::tests::{request, runtime_config};
#[tokio::test]
async fn decoy_dns_pinned_socket_keeps_configured_hostname_in_actual_http_request() {
let origin = TcpListener::bind("127.0.0.1:0").await.unwrap();
let mut config = runtime_config([17; 32], WebCarrier::Https);
let snapshot = Arc::get_mut(config.web.runtime.as_mut().unwrap()).unwrap();
let vhost = Arc::get_mut(snapshot.vhosts.get_mut("proxy.example.com").unwrap()).unwrap();
// A public hostname deliberately paired with a loopback socket proves no request-time lookup.
vhost.decoy = WebRuntimeDecoy::HttpUpstream {
addr: origin.local_addr().unwrap(),
authority: "bsi.bund.de:8080".to_string(),
};
let generation = test_runtime_generation(1, config);
let runtime = WebProcessRuntime::start(Arc::new(ArcSwap::from(generation.clone())));
let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
let receive = async {
let (mut socket, _) = origin.accept().await.unwrap();
let mut bytes = Vec::new();
let mut buf = [0; 1024];
while !bytes.windows(4).any(|part| part == b"\r\n\r\n") {
let count = socket.read(&mut buf).await.unwrap();
assert_ne!(count, 0);
bytes.extend_from_slice(&buf[..count]);
}
socket
.write_all(b"HTTP/1.1 200 OK\r\nContent-Length: 2\r\nConnection: close\r\n\r\nOK")
.await
.unwrap();
String::from_utf8(bytes).unwrap()
};
let (response, upstream) = tokio::time::timeout(std::time::Duration::from_secs(5), async {
tokio::join!(request(&listener, &runtime, b"GET /site?q=1 HTTP/1.1\r\nHost: proxy.example.com\r\nX-Forwarded-For: 192.0.2.10\r\nConnection: close\r\n\r\n".to_vec()), receive)
}).await.unwrap();
assert!(upstream.starts_with("GET /site?q=1 HTTP/1.1\r\n"));
assert!(
upstream
.to_ascii_lowercase()
.contains("\r\nhost: bsi.bund.de:8080\r\n")
);
assert!(response.starts_with(b"HTTP/1.1 200"));
assert!(response.ends_with(b"OK"));
runtime.shutdown().await;
generation.stop_sessions().await;
generation.stop_background_tasks().await;
}