Skip to content

Commit f6bc0cc

Browse files
author
Fuyang Liu
committed
Update example echo
1 parent 2eee793 commit f6bc0cc

File tree

1 file changed

+38
-38
lines changed

1 file changed

+38
-38
lines changed

examples/echo.rs

+38-38
Original file line numberDiff line numberDiff line change
@@ -1,80 +1,80 @@
1+
#![feature(async_await)]
12
#![deny(warnings)]
2-
extern crate futures;
3+
34
extern crate hyper;
45

5-
use futures::future;
6-
use hyper::rt::{Future, Stream};
7-
use hyper::service::service_fn;
86
use hyper::{Body, Method, Request, Response, Server, StatusCode};
9-
10-
/// We need to return different futures depending on the route matched,
11-
/// and we can do that with an enum, such as `futures::Either`, or with
12-
/// trait objects.
13-
///
14-
/// A boxed Future (trait object) is used as it is easier to understand
15-
/// and extend with more types. Advanced users could switch to `Either`.
16-
type BoxFut = Box<dyn Future<Item = Response<Body>, Error = hyper::Error> + Send>;
7+
use hyper::service::{make_service_fn, service_fn};
8+
use futures_util::TryStreamExt;
179

1810
/// This is our service handler. It receives a Request, routes on its
1911
/// path, and returns a Future of a Response.
20-
fn echo(req: Request<Body>) -> BoxFut {
21-
let mut response = Response::new(Body::empty());
12+
async fn echo(req: Request<Body>) -> Result<Response<Body>, hyper::Error> {
2213

2314
match (req.method(), req.uri().path()) {
2415
// Serve some instructions at /
2516
(&Method::GET, "/") => {
26-
*response.body_mut() = Body::from("Try POSTing data to /echo");
17+
Ok(Response::new(Body::from("Try POSTing data to /echo such as: `curl localhost:3000/echo -XPOST -d 'hello world'`")))
2718
}
2819

2920
// Simply echo the body back to the client.
3021
(&Method::POST, "/echo") => {
31-
*response.body_mut() = req.into_body();
22+
Ok(Response::new(req.into_body()))
3223
}
3324

34-
// Convert to uppercase before sending back to client.
25+
// Convert to uppercase before sending back to client using a stream.
3526
(&Method::POST, "/echo/uppercase") => {
36-
let mapping = req.into_body().map(|chunk| {
27+
let mapping = req.into_body().map_ok(|chunk| {
3728
chunk
3829
.iter()
3930
.map(|byte| byte.to_ascii_uppercase())
4031
.collect::<Vec<u8>>()
4132
});
42-
43-
*response.body_mut() = Body::wrap_stream(mapping);
33+
Ok(Response::new(Body::wrap_stream(mapping)))
4434
}
4535

4636
// Reverse the entire body before sending back to the client.
4737
//
4838
// Since we don't know the end yet, we can't simply stream
49-
// the chunks as they arrive. So, this returns a different
50-
// future, waiting on concatenating the full body, so that
51-
// it can be reversed. Only then can we return a `Response`.
39+
// the chunks as they arrive as we did with the above uppercase endpoint.
40+
// So here we do `.await` on the future, waiting on concatenating the full body,
41+
// then afterwards the content can be reversed. Only then can we return a `Response`.
5242
(&Method::POST, "/echo/reversed") => {
53-
let reversed = req.into_body().concat2().map(move |chunk| {
54-
let body = chunk.iter().rev().cloned().collect::<Vec<u8>>();
55-
*response.body_mut() = Body::from(body);
56-
response
57-
});
43+
let chunks = req.into_body().try_concat().await;
44+
45+
let reversed_body = chunks.map(move |chunk| {
46+
chunk.iter().rev().cloned().collect::<Vec<u8>>()
5847

59-
return Box::new(reversed);
48+
})?;
49+
Ok(Response::new(Body::from(reversed_body)))
6050
}
6151

62-
// The 404 Not Found route...
52+
// Return The 404 Not Found for other routes.
6353
_ => {
64-
*response.status_mut() = StatusCode::NOT_FOUND;
54+
let mut not_found = Response::new(Body::empty());
55+
*not_found.status_mut() = StatusCode::NOT_FOUND;
56+
Ok(not_found)
6557
}
66-
};
67-
68-
Box::new(future::ok(response))
58+
}
6959
}
7060

71-
fn main() {
61+
62+
#[tokio::main]
63+
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
7264
let addr = ([127, 0, 0, 1], 3000).into();
7365

66+
let service = make_service_fn(|_| {
67+
async {
68+
Ok::<_, hyper::Error>(service_fn(echo))
69+
}
70+
});
71+
7472
let server = Server::bind(&addr)
75-
.serve(|| service_fn(echo))
76-
.map_err(|e| eprintln!("server error: {}", e));
73+
.serve(service);
7774

7875
println!("Listening on http://{}", addr);
79-
hyper::rt::run(server);
76+
77+
server.await?;
78+
79+
Ok(())
8080
}

0 commit comments

Comments
 (0)