use std::time::Duration;
use tokio::io::AsyncReadExt;
use tokio::io::AsyncWriteExt;
#[tokio::test]
async fn slowloris_connection_is_reaped() {
let app = axum::Router::new().route("/", axum::routing::get(|| async { "ok" }));
let config =
sui_http::Config::default().http1_header_read_timeout(Some(Duration::from_millis(500)));
let handle = sui_http::Builder::new()
.config(config)
.serve(("localhost", 0), app)
.unwrap();
let mut socket = tokio::net::TcpStream::connect(handle.local_addr())
.await
.unwrap();
socket
.write_all(b"GET / HTTP/1.1\r\nHost: localhost\r\n")
.await
.unwrap();
let read_until_closed = async {
let mut buf = Vec::new();
let _ = socket.read_to_end(&mut buf).await;
};
tokio::time::timeout(Duration::from_secs(10), read_until_closed)
.await
.expect("slowloris connection still open: header read timeout is not armed");
tokio::time::timeout(Duration::from_secs(10), async {
while handle.number_of_connections() > 0 {
tokio::time::sleep(Duration::from_millis(10)).await;
}
})
.await
.expect("connection was never removed from the active set");
}