Rust: Create a basic web/HTTP server
Mar 25, 2022
For the web server we're going to use the same HTTP library we used for making requests, Hyper
. The Hyper docs actually have a really great guide for creating a server which is exactly what this has been based off. Here's my version:
use hyper::{Body, Request, Response, Server, Method, StatusCode};
use hyper::service::{make_service_fn, service_fn};
async fn echo(req: Request<Body>) -> Result<Response<Body>, hyper::Error> {
match (req.method(), req.uri().path()) {
// Serve some instructions at /
(&Method::GET, "/") => Ok(Response::new(Body::from(
"Welcome! Try a GET to /hello",
))),
(&Method::GET, "/hello") => Ok(Response::new(Body::from(
"World!",
))),
// Simply echo the body back to the client.
(&Method::POST, "/echo") => Ok(Response::new(req.into_body())),
// Return the 404 Not Found for other routes.
_ => {
let mut not_found = Response::default();
*not_found.status_mut() = StatusCode::NOT_FOUND;
Ok(not_found)
}
}
}
async fn shutdown_signal() {
// Wait for the CTRL+C signal
tokio::signal::ctrl_c()
.await
.expect("failed to install CTRL+C signal handler");
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let addr = ([127, 0, 0, 1], 3000).into();
let service = make_service_fn(|_| async { Ok::<_, hyper::Error>(service_fn(echo)) });
let server = Server::bind(&addr).serve(service);
println!("Listening on http://{}", addr);
let graceful = server.with_graceful_shutdown(shutdown_signal());
// Run this server for... forever!
if let Err(e) = graceful.await {
eprintln!("server error: {}", e);
}
Ok(())
}
Hi, I'm Glenn! 👋 I'm currently Director of Product (Terraform) @ HashiCorp, and we're hiring! If you'd like to come and work with me and help make Terraform Cloud even more amazing we have multiple positions opening in Product Management, Design, and Engineering & Engineering Management across a range of levels (i.e., junior through to senior). Please send in an application ASAP so we can get in touch.