use std::io::Write;
use std::net::TcpStream;
use std::num::{NonZeroU64, NonZeroUsize};
use std::sync::mpsc;
use super::fixtures::{LIST, Reply, Server, TestResult, config, refusal, request};
use super::native_call_fixture::Store;
#[test]
fn a_slow_header_connection_is_inside_the_connection_cap() -> TestResult {
let store = Store::start()?;
let mut config = config()?;
config.max_connections = NonZeroUsize::MIN;
config.header_timeout_ms = NonZeroU64::new(5000).ok_or("header deadline missing")?;
let (admitted, received) = mpsc::channel();
let mcp = Server::mcp_signalled(config, store.path.clone(), 131_072, 1, admitted)?;
let mut partial = TcpStream::connect(mcp.address)?;
partial.write_all(b"POST /mcp HTTP/1.1\r\n")?;
received.recv()?;
let next = Reply::read_frame(request(&mcp, "POST", LIST, true, &[])?)?;
refusal(&next, 503, "mcp_http_connection_busy")?;
assert!(store.asked()?.is_empty());
drop(partial);
mcp.finish()?;
store.finish()
}
#[test]
fn an_incomplete_header_ends_on_the_configured_header_deadline() -> TestResult {
let store = Store::start()?;
let mut config = config()?;
config.header_timeout_ms = NonZeroU64::new(50).ok_or("header deadline missing")?;
let (admitted, received) = mpsc::channel();
let mcp = Server::mcp_signalled(config, store.path.clone(), 131_072, 1, admitted)?;
let mut partial = TcpStream::connect(mcp.address)?;
partial.write_all(b"POST /mcp HTTP/1.1\r\n")?;
received.recv()?;
refusal(&Reply::read(partial)?, 408, "mcp_http_header_timeout")?;
assert!(store.asked()?.is_empty());
mcp.finish()?;
store.finish()
}
#[test]
fn a_retained_over_cap_peer_cannot_delay_the_next_refusal() -> TestResult {
let store = Store::start()?;
let mut config = config()?;
config.max_connections = NonZeroUsize::MIN;
config.header_timeout_ms = NonZeroU64::new(5000).ok_or("header deadline missing")?;
let (admitted, received) = mpsc::channel();
let mcp = Server::mcp_signalled(config, store.path.clone(), 131_072, 1, admitted)?;
let mut partial = TcpStream::connect(mcp.address)?;
partial.write_all(b"POST /mcp HTTP/1.1\r\n")?;
received.recv()?;
let started = std::time::Instant::now();
let mut retained = TcpStream::connect(mcp.address)?;
refusal(
&Reply::read_open(&mut retained)?,
503,
"mcp_http_connection_busy",
)?;
let next = Reply::read(TcpStream::connect(mcp.address)?)?;
assert!(started.elapsed() < std::time::Duration::from_secs(1));
refusal(&next, 503, "mcp_http_connection_busy")?;
assert!(store.asked()?.is_empty());
drop(retained);
drop(partial);
mcp.finish()?;
store.finish()
}