#![doc(
html_favicon_url = "https://raw.githubusercontent.com/plabayo/rama/main/docs/img/old_logo.png"
)]
#![doc(html_logo_url = "https://raw.githubusercontent.com/plabayo/rama/main/docs/img/old_logo.png")]
#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg))]
#![cfg_attr(test, allow(clippy::float_cmp))]
#![cfg_attr(not(test), warn(clippy::print_stdout, clippy::dbg_macro))]
pub mod client;
pub mod server;
#[cfg(test)]
mod tests {
use super::{client::HttpConnector, server::HttpServer};
use futures::future::join;
use rama_core::{Context, Service, rt::Executor, service::service_fn};
use rama_http_types::{Body, Request, Response, Version};
use rama_net::test_utils::client::MockConnectorService;
use std::{
convert::Infallible,
time::{Duration, Instant},
};
use tokio::time::sleep;
#[tokio::test]
async fn test_http11_pipelining() {
let ctx = Context::default();
let connector = HttpConnector::new(MockConnectorService::new(|| {
HttpServer::auto(Executor::default()).service(service_fn(server_svc_fn))
}));
let conn = connector
.serve(ctx, create_test_request(Version::HTTP_11))
.await
.unwrap()
.conn;
let start = Instant::now();
let (res1, res2) = join(
conn.serve(Context::default(), create_test_request(Version::HTTP_11)),
conn.serve(Context::default(), create_test_request(Version::HTTP_11)),
)
.await;
let duration = start.elapsed();
res1.unwrap();
res2.unwrap();
assert!(duration > Duration::from_millis(200));
}
#[tokio::test]
async fn test_http2_multiplex() {
let ctx = Context::default();
let connector = HttpConnector::new(MockConnectorService::new(|| {
HttpServer::auto(Executor::default()).service(service_fn(server_svc_fn))
}));
let conn = connector
.serve(ctx, create_test_request(Version::HTTP_2))
.await
.unwrap()
.conn;
let start = Instant::now();
let (res1, res2) = join(
conn.serve(Context::default(), create_test_request(Version::HTTP_2)),
conn.serve(Context::default(), create_test_request(Version::HTTP_2)),
)
.await;
let duration = start.elapsed();
res1.unwrap();
res2.unwrap();
assert!(duration < Duration::from_millis(200));
}
async fn server_svc_fn(_ctx: Context<()>, _req: Request) -> Result<Response, Infallible> {
sleep(Duration::from_millis(100)).await;
Ok(Response::new(Body::from("a random response body")))
}
fn create_test_request(version: Version) -> Request {
Request::builder()
.uri("https://www.example.com")
.version(version)
.body(Body::from("a reandom request body"))
.unwrap()
}
}