]>
Commit | Line | Data |
---|---|---|
5ed2277f DM |
1 | use failure::*; |
2 | use futures::*; | |
3 | ||
4 | // Simple H2 client to test H2 download speed using h2s-server.rs | |
5 | ||
34f71311 DM |
6 | struct Process { |
7 | body: h2::RecvStream, | |
8 | trailers: bool, | |
9 | bytes: usize, | |
10 | } | |
11 | ||
12 | impl Future for Process { | |
13 | type Item = usize; | |
14 | type Error = Error; | |
15 | ||
16 | fn poll(&mut self) -> Poll<usize, Error> { | |
17 | loop { | |
18 | if self.trailers { | |
19 | let trailers = try_ready!(self.body.poll_trailers()); | |
20 | if let Some(trailers) = trailers { | |
21 | println!("trailers: {:?}", trailers); | |
22 | } | |
23 | println!("Received {} bytes", self.bytes); | |
24 | ||
25 | return Ok(Async::Ready(self.bytes)); | |
26 | } else { | |
27 | match try_ready!(self.body.poll()) { | |
28 | Some(chunk) => { | |
29 | self.body.release_capacity().release_capacity(chunk.len())?; | |
30 | self.bytes += chunk.len(); | |
31 | // println!("GOT FRAME {}", chunk.len()); | |
32 | }, | |
33 | None => { | |
34 | self.trailers = true; | |
35 | }, | |
36 | } | |
37 | } | |
38 | } | |
39 | } | |
40 | } | |
41 | ||
42 | fn send_request(mut client: h2::client::SendRequest<bytes::Bytes>) -> impl Future<Item=usize, Error=Error> { | |
43 | ||
44 | println!("sending request"); | |
45 | ||
46 | let request = http::Request::builder() | |
47 | .uri("http://localhost/") | |
48 | .body(()) | |
49 | .unwrap(); | |
50 | ||
51 | let (response, _stream) = client.send_request(request, true).unwrap(); | |
52 | ||
53 | response | |
54 | .map_err(Error::from) | |
55 | .and_then(|response| { | |
56 | Process { body: response.into_body(), trailers: false, bytes: 0 } | |
57 | }) | |
5ed2277f DM |
58 | } |
59 | ||
60 | pub fn main() -> Result<(), Error> { | |
61 | ||
34f71311 | 62 | let tcp_stream = tokio::net::TcpStream::connect(&"127.0.0.1:8008".parse().unwrap()); |
5ed2277f DM |
63 | |
64 | let start = std::time::SystemTime::now(); | |
65 | ||
34f71311 DM |
66 | let tcp = tcp_stream |
67 | .map_err(Error::from) | |
68 | .and_then(|c| { | |
dc9775d1 DM |
69 | c.set_nodelay(true).unwrap(); |
70 | c.set_recv_buffer_size(1024*1024).unwrap(); | |
6d1f61b2 DM |
71 | |
72 | use openssl::ssl::*; | |
73 | use tokio_openssl::SslConnectorExt; | |
74 | ||
75 | let mut ssl_connector_builder = SslConnector::builder(SslMethod::tls()).unwrap(); | |
76 | ssl_connector_builder.set_verify(openssl::ssl::SslVerifyMode::NONE); | |
77 | ||
78 | let connector = ssl_connector_builder.build(); | |
79 | ||
80 | connector.connect_async("localhost", c) | |
81 | .map_err(|err| format_err!("connect failed - {}", err)) | |
5ed2277f | 82 | }) |
34f71311 DM |
83 | .map_err(Error::from) |
84 | .and_then(|c| { | |
85 | h2::client::Builder::new() | |
86 | .initial_connection_window_size(1024*1024*1024) | |
87 | .initial_window_size(1024*1024*1024) | |
88 | .max_frame_size(4*1024*1024) | |
89 | .handshake(c) | |
90 | .map_err(Error::from) | |
91 | }) | |
92 | .and_then(|(client, h2)| { | |
93 | ||
94 | // Spawn a task to run the conn... | |
95 | tokio::spawn(h2.map_err(|e| println!("GOT ERR={:?}", e))); | |
96 | ||
97 | futures::stream::repeat(()) | |
98 | .take(100) | |
99 | .and_then(move |_| send_request(client.clone())) | |
100 | .fold(0, move |mut acc, size| { | |
101 | acc += size; | |
102 | Ok::<_, Error>(acc) | |
103 | }) | |
5ed2277f DM |
104 | }) |
105 | .then(move |result| { | |
106 | match result { | |
107 | Err(err) => { | |
108 | println!("ERROR {}", err); | |
109 | } | |
110 | Ok(bytes) => { | |
111 | let elapsed = start.elapsed().unwrap(); | |
112 | let elapsed = (elapsed.as_secs() as f64) + | |
113 | (elapsed.subsec_millis() as f64)/1000.0; | |
114 | ||
115 | println!("Downloaded {} bytes, {} MB/s", bytes, (bytes as f64)/(elapsed*1024.0*1024.0)); | |
116 | } | |
117 | } | |
118 | Ok(()) | |
119 | }); | |
120 | ||
34f71311 | 121 | tokio::run(tcp); |
5ed2277f DM |
122 | |
123 | Ok(()) | |
124 | } |