1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
|
#![allow(unused_imports)]
use http_body_util::{BodyExt, Full};
use std::{error::Error, fs, path::Path};
use hyper::{body::Bytes, service::service_fn, Response};
use hyper_util::{client::legacy::Client, rt::TokioIo};
#[cfg(all(feature = "client", feature = "server"))]
use hyperlocal::{UnixClientExt, UnixConnector, Uri};
use tokio::net::UnixListener;
const PHRASE: &str = "It works!";
#[derive(Debug, thiserror::Error)]
enum ListenerError {
#[error("Failed to accept connection: {0}")]
Accepting(std::io::Error),
#[error("Failed to serve connection: {0}")]
Serving(hyper::Error),
}
#[tokio::test]
#[cfg(all(feature = "client", feature = "server"))]
async fn test_server_client() -> Result<(), Box<dyn Error + Send + Sync>> {
let path = Path::new("/tmp/hyperlocal.sock");
if path.exists() {
fs::remove_file(path)?;
}
let svc_fn =
service_fn(|_req| async { Ok::<_, hyper::Error>(Response::new(PHRASE.to_string())) });
let listener = UnixListener::bind(path)?;
let _server_task = tokio::spawn(async move {
let (stream, _) = listener.accept().await.map_err(ListenerError::Accepting)?;
let io = TokioIo::new(stream);
hyper::server::conn::http1::Builder::new()
.serve_connection(io, svc_fn)
.await
.map_err(ListenerError::Serving)
});
let client: Client<UnixConnector, Full<Bytes>> = Client::unix();
let url = Uri::new(path, "/").into();
let mut response = client.get(url).await?;
let mut bytes = Vec::default();
while let Some(frame_result) = response.frame().await {
let frame = frame_result?;
if let Some(segment) = frame.data_ref() {
bytes.extend(segment.iter().as_slice());
}
}
let string = String::from_utf8(bytes)?;
assert_eq!(PHRASE, string);
Ok(())
}
|