use super::*; #[test] fn http1_http2_tls_streams_roundtrip_and_buffered_limits_remain_enforced() { for http2 in [false, true] { for secure in [false, true] { runtime() .run(async |scope| { let listener = net::listen("127.0.0.1", 0, scope).await.unwrap(); let port = listener.port().unwrap(); let limits = Limits { connections: 1, http2: http2.then(Default::default), ..Default::default() }; let incoming = listener.clone(); let protocol = limits.clone(); let server = scope .spawn(move |child| async move { if secure { let tls = tls::server( super::super::tls::CERTIFICATE, super::super::tls::KEY, ) .unwrap(); http::serve_tls::<_, _, false>( &incoming, &protocol, &child, &tls, route, ) .await } else { http::serve::<_, _, false>(&incoming, &protocol, &child, route) .await } }) .unwrap(); let origin = format!( "{}://localhost:{port}", if secure { "https" } else { "http" } ); let trust = tls::client(super::super::tls::ROOT).unwrap(); let client = http::client( &origin, &trust, &Limits { body_bytes: 1, ..limits }, &PoolLimits { chunk_bytes: 3, ..Default::default() }, scope, ) .unwrap(); let body = AsyncStream::values([ Ok(Bytes::from_static(b"abc")), Ok(Bytes::from_static(b"def")), ]); let request = StreamRequest { method: "POST".into(), target: "/echo".into(), headers: vec![], body, }; let response = client.open_stream(request, event, event).await.unwrap(); assert_eq!(collect(&response.body, 3).await, b"abcdef"); let mut request = message(); request.body = b"ab".to_vec().into(); assert!( client .open(request.clone(), event) .await .unwrap_err() .contains("byte limit") ); assert!( client .request(request) .await .unwrap_err() .contains("byte limit") ); client.close().await.unwrap(); listener.close().unwrap(); server.wait().await.unwrap().unwrap(); }) .unwrap(); } } } #[test] fn http2_closing_one_response_preserves_neighbor_and_releases_only_its_slot() { runtime() .run(async |scope| { let listener = net::listen("127.0.0.1", 0, scope).await.unwrap(); let port = listener.port().unwrap(); let limits = Limits { connections: 1, http2: Some(http::Http2Limits { streams: 2, ..Default::default() }), ..Default::default() }; let incoming = listener.clone(); let protocol = limits.clone(); let server = scope .spawn(move |child| async move { http::serve_live( &incoming, &protocol, &http::LiveLimits::default(), &child, |request: Request, reply: http::HttpReply, _| async move { if request.target == "/ordinary" { return reply .respond(Response { status: 200, headers: vec![], body: b"ok".to_vec().into(), }) .await .map_err(|error| error.to_string()); } reply .start(200, vec![]) .await .map_err(|error| error.to_string())?; reply .write(b"first") .await .map_err(|error| error.to_string())?; tokio::time::sleep(Duration::from_millis(150)).await; reply .write(b"last") .await .map_err(|error| error.to_string()) }, ) .await }) .unwrap(); let client = client( scope, port as u16, &limits, &PoolLimits { idle_ms: 20, ..Default::default() }, ); let first = client.open(message(), event).await.unwrap(); let second = client.open(message(), event).await.unwrap(); assert_eq!( first.body.next().await.unwrap().unwrap().unwrap(), b"first"[..] ); assert_eq!( second.body.next().await.unwrap().unwrap().unwrap(), b"first"[..] ); first.body.close(); let mut ordinary = message(); ordinary.target = "/ordinary".into(); assert_eq!(client.request(ordinary).await.unwrap().body.as_ref(), b"ok"); assert_eq!(collect(&second.body, 65536).await, b"last"); client.close().await.unwrap(); listener.close().unwrap(); server.wait().await.unwrap().unwrap(); }) .unwrap(); }