The lifetime workaround is no longer required due to changes in rustc. This removes the line and comment from the example.
80 lines
2.2 KiB
Rust
80 lines
2.2 KiB
Rust
#![deny(warnings)]
|
|
|
|
use tokio::io::AsyncReadExt;
|
|
use tokio_fs::File;
|
|
|
|
use hyper::{Body, Method, Result, Request, Response, Server, StatusCode};
|
|
use hyper::service::{make_service_fn, service_fn};
|
|
|
|
static INDEX: &str = "examples/send_file_index.html";
|
|
static INTERNAL_SERVER_ERROR: &[u8] = b"Internal Server Error";
|
|
static NOTFOUND: &[u8] = b"Not Found";
|
|
|
|
#[tokio::main]
|
|
async fn main() {
|
|
pretty_env_logger::init();
|
|
|
|
let addr = "127.0.0.1:1337".parse().unwrap();
|
|
|
|
let make_service = make_service_fn(|_| async {
|
|
Ok::<_, hyper::Error>(service_fn(response_examples))
|
|
});
|
|
|
|
let server = Server::bind(&addr)
|
|
.serve(make_service);
|
|
|
|
println!("Listening on http://{}", addr);
|
|
|
|
if let Err(e) = server.await {
|
|
eprintln!("server error: {}", e);
|
|
}
|
|
}
|
|
|
|
async fn response_examples(req: Request<Body>) -> Result<Response<Body>> {
|
|
match (req.method(), req.uri().path()) {
|
|
(&Method::GET, "/") |
|
|
(&Method::GET, "/index.html") |
|
|
(&Method::GET, "/big_file.html") => {
|
|
simple_file_send(INDEX).await
|
|
}
|
|
(&Method::GET, "/no_file.html") => {
|
|
// Test what happens when file cannot be be found
|
|
simple_file_send("this_file_should_not_exist.html").await
|
|
}
|
|
_ => Ok(not_found())
|
|
}
|
|
}
|
|
|
|
/// HTTP status code 404
|
|
fn not_found() -> Response<Body> {
|
|
Response::builder()
|
|
.status(StatusCode::NOT_FOUND)
|
|
.body(NOTFOUND.into())
|
|
.unwrap()
|
|
}
|
|
|
|
/// HTTP status code 500
|
|
fn internal_server_error() -> Response<Body> {
|
|
Response::builder()
|
|
.status(StatusCode::INTERNAL_SERVER_ERROR)
|
|
.body(INTERNAL_SERVER_ERROR.into())
|
|
.unwrap()
|
|
}
|
|
|
|
async fn simple_file_send(filename: &str) -> Result<Response<Body>> {
|
|
// Serve a file by asynchronously reading it entirely into memory.
|
|
// Uses tokio_fs to open file asynchronously, then tokio::io::AsyncReadExt
|
|
// to read into memory asynchronously.
|
|
|
|
if let Ok(mut file) = File::open(filename).await {
|
|
let mut buf = Vec::new();
|
|
if let Ok(_) = file.read_to_end(&mut buf).await {
|
|
return Ok(Response::new(buf.into()));
|
|
}
|
|
|
|
return Ok(internal_server_error());
|
|
}
|
|
|
|
return Ok(not_found());
|
|
}
|