Repository navigation
Expand file tree
/
Copy pathhyper.rs
More file actions
94 lines (79 loc) · 2.93 KB
/
Copy pathhyper.rs
File metadata and controls
94 lines (79 loc) · 2.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
//! Service with async/await handlers.
//!
//! A service that demonstrates how to use Tower Web's experimental support for the upcoming
//! async/await syntax.
//!
//! # Overview
//!
//! async/await enables easier writing of asynchronous code. Handler functions are prefaced with
//! the `async` keyword. The async fn implementation may then use `await!` and call other `async`
//! functions. It requires using the Rust nightly channel as well as opting into unstable features.
//!
//! ## Usage
//!
//! From within the `examples/async-await` directory, run the example:
//!
//! cargo +nightly run --bin hyper
//!
//! Then send a request:
//!
//! curl -v http://localhost:8080/
#![feature(await_macro, async_await)]
use tokio::prelude::*;
use tokio::await;
use tower_web::ServiceBuilder;
use tower_web::impl_web;
use std::str;
// The HTTP client
type HttpClient = hyper::Client<hyper::client::HttpConnector>;
/// This type will be part of the web service as a resource.
#[derive(Clone, Debug)]
pub struct HelloWorld {
client: HttpClient,
}
/// To derive `Resource`, the implementation of `HelloWorld` is contained in the
/// `impl_web!` macro. This macro does not modify any of its contents. It will
/// inspect the implementation and, with the help of some annotations, generate
/// the necessary glue code to run the web service.
///
/// impl_web! is a temporary solution to enable tower-web to work with stable
/// rust. In the near future, this will be transitioned to use attribute macros.
impl_web! {
impl HelloWorld {
#[get("/")]
async fn hello_world(&self) -> String {
// Get the URI of the server by issuing a query to `/ip`.
let uri = "http://httpbin.org/ip".parse().unwrap();
// Issue the request and wait for the response
let response = await!(self.client.get(uri)).unwrap();
// Get the body component of the HTTP response. This is a stream and as such, it must
// be asynchronously collected.
let mut body = response.into_body();
// The body chunks will be appended to this string.
let mut ret = String::new();
while let Some(chunk) = await!(body.next()) {
let chunk = chunk.unwrap();
// Convert to a string
let chunk = str::from_utf8(&chunk[..]).unwrap();
// Append to buffer
ret.push_str(chunk);
}
// Return the collected string
ret
}
}
}
pub fn main() {
// Next, we must run our web service.
//
// The HTTP service will listen on this address and port.
let addr = "127.0.0.1:8080".parse().expect("Invalid address");
println!("Listening on http://{}", addr);
// A service builder is used to configure our service.
ServiceBuilder::new()
.resource(HelloWorld {
client: hyper::Client::new(),
})
.run(&addr)
.unwrap();
}