From 01db1dc0b67ffe37aa9140b26ea6dafcf30cfed6 Mon Sep 17 00:00:00 2001 From: David Pedersen Date: Wed, 12 May 2021 01:56:01 +0200 Subject: [PATCH] docs(server): add bigger example to server module (#2539) It can sometimes be tricky to discover where to use `move` closures, `async move {}`, and `.clone()` when creating a server. This adds a slightly more bigger example that will hopefully help some. Fixes https://github.com/hyperium/hyper/issues/2446 --- src/server/mod.rs | 63 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/src/server/mod.rs b/src/server/mod.rs index 7647449adf..690c8127a7 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -16,7 +16,7 @@ //! //! [`Server`](Server) accepts connections in both HTTP1 and HTTP2 by default. //! -//! ## Example +//! ## Examples //! //! ```no_run //! use std::convert::Infallible; @@ -84,6 +84,67 @@ //! # fn main() {} //! ``` //! +//! Passing data to your request handler can be done like so: +//! +//! ```no_run +//! use std::convert::Infallible; +//! use std::net::SocketAddr; +//! use hyper::{Body, Request, Response, Server}; +//! use hyper::service::{make_service_fn, service_fn}; +//! use hyper::server::conn::AddrStream; +//! +//! #[derive(Clone)] +//! struct AppContext { +//! // Whatever data your application needs can go here +//! } +//! +//! async fn handle( +//! context: AppContext, +//! addr: SocketAddr, +//! req: Request +//! ) -> Result, Infallible> { +//! Ok(Response::new(Body::from("Hello World"))) +//! } +//! +//! # #[cfg(feature = "runtime")] +//! #[tokio::main] +//! async fn main() { +//! let context = AppContext { +//! // ... +//! }; +//! +//! // A `MakeService` that produces a `Service` to handle each connection. +//! let make_service = make_service_fn(move |conn: &AddrStream| { +//! // We have to clone the context to share it with each invocation of +//! // `make_service`. If your data doesn't implement `Clone` consider using +//! // an `std::sync::Arc`. +//! let context = context.clone(); +//! +//! // You can grab the address of the incoming connection like so. +//! let addr = conn.remote_addr(); +//! +//! // Create a `Service` for responding to the request. +//! let service = service_fn(move |req| { +//! handle(context.clone(), addr, req) +//! }); +//! +//! // Return the service to hyper. +//! async move { Ok::<_, Infallible>(service) } +//! }); +//! +//! // Run the server like above... +//! let addr = SocketAddr::from(([127, 0, 0, 1], 3000)); +//! +//! let server = Server::bind(&addr).serve(make_service); +//! +//! if let Err(e) = server.await { +//! eprintln!("server error: {}", e); +//! } +//! } +//! # #[cfg(not(feature = "runtime"))] +//! # fn main() {} +//! ``` +//! //! [`tower::make::Shared`]: https://docs.rs/tower/latest/tower/make/struct.Shared.html pub mod accept;