]>
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(); | |
34f71311 DM |
71 | let mut builder = native_tls::TlsConnector::builder(); |
72 | builder.danger_accept_invalid_certs(true); | |
73 | let connector = builder.build().unwrap(); | |
74 | let connector = tokio_tls::TlsConnector::from(connector); | |
75 | connector.connect("localhost", c) | |
5ed2277f | 76 | .map_err(Error::from) |
5ed2277f | 77 | }) |
34f71311 DM |
78 | .map_err(Error::from) |
79 | .and_then(|c| { | |
80 | h2::client::Builder::new() | |
81 | .initial_connection_window_size(1024*1024*1024) | |
82 | .initial_window_size(1024*1024*1024) | |
83 | .max_frame_size(4*1024*1024) | |
84 | .handshake(c) | |
85 | .map_err(Error::from) | |
86 | }) | |
87 | .and_then(|(client, h2)| { | |
88 | ||
89 | // Spawn a task to run the conn... | |
90 | tokio::spawn(h2.map_err(|e| println!("GOT ERR={:?}", e))); | |
91 | ||
92 | futures::stream::repeat(()) | |
93 | .take(100) | |
94 | .and_then(move |_| send_request(client.clone())) | |
95 | .fold(0, move |mut acc, size| { | |
96 | acc += size; | |
97 | Ok::<_, Error>(acc) | |
98 | }) | |
5ed2277f DM |
99 | }) |
100 | .then(move |result| { | |
101 | match result { | |
102 | Err(err) => { | |
103 | println!("ERROR {}", err); | |
104 | } | |
105 | Ok(bytes) => { | |
106 | let elapsed = start.elapsed().unwrap(); | |
107 | let elapsed = (elapsed.as_secs() as f64) + | |
108 | (elapsed.subsec_millis() as f64)/1000.0; | |
109 | ||
110 | println!("Downloaded {} bytes, {} MB/s", bytes, (bytes as f64)/(elapsed*1024.0*1024.0)); | |
111 | } | |
112 | } | |
113 | Ok(()) | |
114 | }); | |
115 | ||
34f71311 | 116 | tokio::run(tcp); |
5ed2277f DM |
117 | |
118 | Ok(()) | |
119 | } |