extern crate bytes; extern crate env_logger; extern crate futures; extern crate h2; extern crate http; #[macro_use] extern crate log; extern crate tokio_core; extern crate tower; extern crate tower_h2; use bytes::Bytes; use futures::*; use http::Request; use tokio_core::net::TcpListener; use tokio_core::reactor::Core; use tower::{NewService, Service}; use tower_h2::{Body, Server, RecvBody}; type Response = http::Response; struct RspBody(Option); impl RspBody { fn new(body: Bytes) -> Self { RspBody(Some(body)) } fn empty() -> Self { RspBody(None) } } impl Body for RspBody { type Data = Bytes; fn is_end_stream(&self) -> bool { self.0.as_ref().map(|b| b.is_empty()).unwrap_or(false) } fn poll_data(&mut self) -> Poll, h2::Error> { let data = self.0 .take() .and_then(|b| if b.is_empty() { None } else { Some(b) }); Ok(Async::Ready(data)) } } //const ROOT: &'static str = "/"; const ROOT: &'static str = "/helloworld.Greeter/SayHello"; #[derive(Debug)] struct Svc; impl Service for Svc { type Request = Request; type Response = Response; type Error = h2::Error; type Future = future::FutureResult; fn poll_ready(&mut self) -> Poll<(), Self::Error> { Ok(Async::Ready(())) } fn call(&mut self, req: Self::Request) -> Self::Future { let mut rsp = http::Response::builder(); rsp.version(http::Version::HTTP_2); let uri = req.uri(); if uri.path() != ROOT { let body = RspBody::empty(); let rsp = rsp.status(404).body(body).unwrap(); return future::ok(rsp); } let body = RspBody::new("heyo!".into()); let rsp = rsp.status(200).body(body).unwrap(); future::ok(rsp) } } #[derive(Debug)] struct NewSvc; impl NewService for NewSvc { type Request = Request; type Response = Response; type Error = h2::Error; type InitError = ::std::io::Error; type Service = Svc; type Future = future::FutureResult; fn new_service(&self) -> Self::Future { future::ok(Svc) } } fn main() { drop(env_logger::init()); let mut core = Core::new().unwrap(); let reactor = core.handle(); let h2 = Server::new(NewSvc, Default::default(), reactor.clone()); let addr = "[::1]:8888".parse().unwrap(); let bind = TcpListener::bind(&addr, &reactor).expect("bind"); let serve = bind.incoming() .fold((h2, reactor), |(h2, reactor), (sock, _)| { if let Err(e) = sock.set_nodelay(true) { return Err(e); } let serve = h2.serve(sock); reactor.spawn(serve.map_err(|e| error!("h2 error: {:?}", e))); Ok((h2, reactor)) }); core.run(serve).unwrap(); }