use std::{
sync::{Arc, Mutex},
time::Duration,
};
use axum::{
response::Response,
routing::{get, post},
Extension, Router,
};
use bytes::Bytes;
use tokio::{net::TcpListener, task::AbortHandle};
async fn fail(Extension(state): Extension<Arc<Mutex<State>>>) -> Response {
let mut headers = http::HeaderMap::new();
state.lock().unwrap().fail += 1;
headers.insert("Content-Length", "1000".parse().unwrap());
let stream = async_stream::stream! {
yield Ok::<_, hyper::Error>(Bytes::try_from("hello").unwrap());
};
let response = Response::builder()
.header("Content-Length", "1000")
.body(axum::body::Body::from_stream(stream))
.unwrap();
response
}
async fn chunk_timeout(Extension(state): Extension<Arc<Mutex<State>>>) -> Response {
state.lock().unwrap().chunk_timeout += 1;
let stream = async_stream::stream! {
for _ in 0..10{
yield Ok::<_, hyper::Error>(Bytes::try_from("hello").unwrap());
tokio::time::sleep(Duration::from_millis(100)).await;
}
};
let response = Response::builder()
.body(axum::body::Body::from_stream(stream))
.unwrap();
response
}
async fn time_to_first_byte() -> String {
tokio::time::sleep(Duration::from_millis(500)).await;
"hello".to_owned()
}
pub struct DroppingAbortHandler(AbortHandle);
impl Drop for DroppingAbortHandler {
fn drop(&mut self) {
self.0.abort();
}
}
#[derive(Debug, Clone, Default)]
pub struct State {
pub fail: usize,
pub chunk_timeout: usize,
}
pub async fn create_server() -> anyhow::Result<(url::Url, DroppingAbortHandler, Arc<Mutex<State>>)>
{
let listener = TcpListener::bind("[::]:0").await?;
let url = format!("http://127.0.0.1:{}/", listener.local_addr()?.port()).parse()?;
let state = Arc::new(Mutex::new(State::default()));
let app = Router::new()
.route("/fail", get(fail))
.route("/chunk_timeout", get(chunk_timeout))
.route("/web.dwh", post(chunk_timeout))
.route("/time_to_first_byte", get(time_to_first_byte))
.layer(Extension(state.clone()));
let abort_handler = tokio::spawn(async move {
axum::serve(listener, app).await.unwrap();
})
.abort_handle();
Ok((url, DroppingAbortHandler(abort_handler), state))
}