From f82fa091695b1190bead2397ecbc98cd9d4dbe59 Mon Sep 17 00:00:00 2001 From: Nihal T M Date: Mon, 15 Jul 2024 15:04:36 +0530 Subject: [PATCH 1/4] add hello http2 example --- examples/hello-http2.rs | 81 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 examples/hello-http2.rs diff --git a/examples/hello-http2.rs b/examples/hello-http2.rs new file mode 100644 index 0000000000..65507732d5 --- /dev/null +++ b/examples/hello-http2.rs @@ -0,0 +1,81 @@ +#![deny(warnings)] + +use std::convert::Infallible; +use std::net::SocketAddr; + +use hyper::body::Bytes; +use http_body_util::Full; +use hyper::server::conn::http2; +use hyper::service::service_fn; +use hyper::{Request, Response}; +use tokio::net::TcpListener; + +// This would normally come from the `hyper-util` crate, but we can't depend +// on that here because it would be a cyclical dependency. +#[path = "../benches/support/mod.rs"] +mod support; +use support::{TokioIo, TokioTimer}; + +// An async function that consumes a request, does nothing with it and returns a +// response. +async fn hello(_: Request) -> Result>, Infallible> { + Ok(Response::new(Full::new(Bytes::from("Hello, World!")))) +} + +#[derive(Clone)] +// An Executor that uses the tokio runtime. +pub struct TokioExecutor; + +// Implement the `hyper::rt::Executor` trait for `TokioExecutor` so that it can be used to spawn +// tasks in the hyper runtime. +// An Executor allows us to manage execution of tasks which can help us improve the efficiency and +// scalability of the server. +impl hyper::rt::Executor for TokioExecutor +where + F: std::future::Future + Send + 'static, + F::Output: Send + 'static, + { + fn execute(&self, fut: F) { + tokio::task::spawn(fut); + } +} + +#[tokio::main] +async fn main() -> Result<(), Box> { + pretty_env_logger::init(); + + // This address is localhost + let addr = SocketAddr::from(([127,0,0,1], 3000)); + + // Bind to the port and listen for incoming TCP connections + let listener = TcpListener::bind(addr).await?; + + loop { + // When an incoming TCP connection is received grab a TCP stream for + // client<->server communication. + // + // Note, this is a .await point, this loop will loop forever but is not a busy loop. The + // .await point allows the Tokio runtime to pull the task off of the thread until the task + // has work to do. In this case, a connection arrives on the port we are listening on and + // the task is woken up, at which point the task is then put back on a thread, and is + // driven forward by the runtime, eventually yielding a TCP stream. + let (stream, _) = listener.accept().await?; + // Use an adapter to access something implementing `tokio::io` traits as if they implement + // `hyper::rt` IO traits. + let io = TokioIo::new(stream); + + // Spin up a new task in Tokio so we can continue to listen for new TCP connection on the + // current task without waiting for the processing of the HTTP2 connection we just received + // to finish + tokio::task::spawn(async move{ + // Handle the connection from the client using HTTP2 with an executor and pass any + // HTTP requests received on that connection to the `hello` function + if let Err(err) = http2::Builder::new(TokioExecutor) + .serve_connection(io, service_fn(hello)) + .await + { + eprintln!("Error serving connection: {}", err); + } + }); + } +} From 3b4302f14483911b3de14e089abd6586f271ed58 Mon Sep 17 00:00:00 2001 From: Nihal T M Date: Mon, 15 Jul 2024 17:54:47 +0530 Subject: [PATCH 2/4] fixes after proofreading --- examples/hello-http2.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/hello-http2.rs b/examples/hello-http2.rs index 65507732d5..9f0d68f3ea 100644 --- a/examples/hello-http2.rs +++ b/examples/hello-http2.rs @@ -42,7 +42,7 @@ where #[tokio::main] async fn main() -> Result<(), Box> { - pretty_env_logger::init(); + pretty_env_logger::init(); // This address is localhost let addr = SocketAddr::from(([127,0,0,1], 3000)); @@ -52,7 +52,7 @@ async fn main() -> Result<(), Box> { loop { // When an incoming TCP connection is received grab a TCP stream for - // client<->server communication. + // client-server communication. // // Note, this is a .await point, this loop will loop forever but is not a busy loop. The // .await point allows the Tokio runtime to pull the task off of the thread until the task @@ -65,10 +65,10 @@ async fn main() -> Result<(), Box> { let io = TokioIo::new(stream); // Spin up a new task in Tokio so we can continue to listen for new TCP connection on the - // current task without waiting for the processing of the HTTP2 connection we just received + // current task without waiting for the processing of the HTTP/2 connection we just received // to finish tokio::task::spawn(async move{ - // Handle the connection from the client using HTTP2 with an executor and pass any + // Handle the connection from the client using HTTP/2 with an executor and pass any // HTTP requests received on that connection to the `hello` function if let Err(err) = http2::Builder::new(TokioExecutor) .serve_connection(io, service_fn(hello)) From c04fcb9b94b5cf53f18b66e964e778a666bad411 Mon Sep 17 00:00:00 2001 From: Nihal T M Date: Tue, 16 Jul 2024 12:12:04 +0530 Subject: [PATCH 3/4] Made changes after cargo fmt check --- examples/hello-http2.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/hello-http2.rs b/examples/hello-http2.rs index 9f0d68f3ea..c6dadb5249 100644 --- a/examples/hello-http2.rs +++ b/examples/hello-http2.rs @@ -3,8 +3,8 @@ use std::convert::Infallible; use std::net::SocketAddr; -use hyper::body::Bytes; use http_body_util::Full; +use hyper::body::Bytes; use hyper::server::conn::http2; use hyper::service::service_fn; use hyper::{Request, Response}; @@ -27,25 +27,25 @@ async fn hello(_: Request) -> Result pub struct TokioExecutor; // Implement the `hyper::rt::Executor` trait for `TokioExecutor` so that it can be used to spawn -// tasks in the hyper runtime. +// tasks in the hyper runtime. // An Executor allows us to manage execution of tasks which can help us improve the efficiency and // scalability of the server. impl hyper::rt::Executor for TokioExecutor where F: std::future::Future + Send + 'static, F::Output: Send + 'static, - { - fn execute(&self, fut: F) { - tokio::task::spawn(fut); +{ + fn execute(&self, fut: F) { + tokio::task::spawn(fut); } } #[tokio::main] async fn main() -> Result<(), Box> { - pretty_env_logger::init(); + pretty_env_logger::init(); // This address is localhost - let addr = SocketAddr::from(([127,0,0,1], 3000)); + let addr = SocketAddr::from(([127, 0, 0, 1], 3000)); // Bind to the port and listen for incoming TCP connections let listener = TcpListener::bind(addr).await?; @@ -67,7 +67,7 @@ async fn main() -> Result<(), Box> { // Spin up a new task in Tokio so we can continue to listen for new TCP connection on the // current task without waiting for the processing of the HTTP/2 connection we just received // to finish - tokio::task::spawn(async move{ + tokio::task::spawn(async move { // Handle the connection from the client using HTTP/2 with an executor and pass any // HTTP requests received on that connection to the `hello` function if let Err(err) = http2::Builder::new(TokioExecutor) From 8d2c76065ea47e17d6008d4d01950faa7a03adee Mon Sep 17 00:00:00 2001 From: Nihal T M Date: Tue, 17 Sep 2024 18:04:27 +0530 Subject: [PATCH 4/4] Removed unused imports --- examples/hello-http2.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/hello-http2.rs b/examples/hello-http2.rs index c6dadb5249..54bdef0885 100644 --- a/examples/hello-http2.rs +++ b/examples/hello-http2.rs @@ -14,7 +14,7 @@ use tokio::net::TcpListener; // on that here because it would be a cyclical dependency. #[path = "../benches/support/mod.rs"] mod support; -use support::{TokioIo, TokioTimer}; +use support::TokioIo; // An async function that consumes a request, does nothing with it and returns a // response.