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
use std::future::Future; use std::net::SocketAddr; use std::sync::Arc; use hyper::{service, Body, Request, Response}; mod blocking_handler; mod error; pub use blocking_handler::BlockingHandler; pub use error::ServiceError; /// A builder for a `hyper::Service`. #[derive(Debug)] pub struct Service; impl Service { /// Turn a conduit handler into a `Service` which can be bound to a `hyper::Server`. /// /// The returned service can be built into a `hyper::Server` using `make_service_fn` and /// capturing the socket `remote_addr`. /// /// ```no_run /// # use std::sync::Arc; /// # use conduit_hyper::{BlockingHandler, Service}; /// # use conduit::{box_error, Body, Handler, HandlerResult, RequestExt, Response}; /// # /// # struct Endpoint(); /// # impl Handler for Endpoint { /// # fn call(&self, _: &mut dyn RequestExt) -> HandlerResult { /// # Response::builder().body(Body::empty()).map_err(box_error) /// # } /// # } /// # let app = Endpoint(); /// let handler = Arc::new(BlockingHandler::new(app)); /// let make_service = /// hyper::service::make_service_fn(move |socket: &hyper::server::conn::AddrStream| { /// let addr = socket.remote_addr(); /// let handler = handler.clone(); /// async move { Service::from_blocking(handler, addr) } /// }); /// /// # let port = 0; /// let addr = ([127, 0, 0, 1], port).into(); /// let server = hyper::Server::bind(&addr).serve(make_service); /// ``` pub fn from_blocking<H: conduit::Handler>( handler: Arc<BlockingHandler<H>>, remote_addr: SocketAddr, ) -> Result< impl tower_service::Service< Request<Body>, Response = Response<Body>, Error = ServiceError, Future = impl Future<Output = Result<Response<Body>, ServiceError>> + Send + 'static, >, ServiceError, > { Ok(service::service_fn(move |request: Request<Body>| { handler.clone().blocking_handler(request, remote_addr) })) } }