use std::error::Error as StdError;
pub use http_body_util;
pub use hyper;
use hyper::{
body::{Body, Incoming},
client::conn::http1::SendRequest,
server::conn::http1,
Request, Response,
};
use crate::{
compat::{Compat, Duplex},
spawn,
};
type BoxError = Box<dyn StdError + Send + Sync>;
pub async fn serve_connection<S, Svc, B>(io: S, service: Svc) -> hyper::Result<()>
where
S: Duplex,
Svc: hyper::service::Service<Request<Incoming>, Response = Response<B>>,
Svc::Error: Into<BoxError>,
Svc::Future: 'static,
B: Body + 'static,
B::Error: Into<BoxError>,
{
http1::Builder::new()
.serve_connection(Compat::new(io), service)
.await
}
pub struct Client<B> {
sender: SendRequest<B>,
}
pub async fn connect<S, B>(io: S) -> hyper::Result<Client<B>>
where
S: Duplex,
B: Body + 'static,
B::Data: Send,
B::Error: Into<BoxError>,
{
let (sender, conn) = hyper::client::conn::http1::handshake(Compat::new(io)).await?;
drop(spawn(async move {
let _ = conn.await;
}));
Ok(Client { sender })
}
impl<B> Client<B>
where
B: Body + 'static,
{
pub async fn send(&mut self, req: Request<B>) -> hyper::Result<Response<Incoming>> {
self.sender.ready().await?;
self.sender.send_request(req).await
}
pub fn is_closed(&self) -> bool {
self.sender.is_closed()
}
}