2019-08-28 16:37:57 +03:00
use std ::future ::Future ;
use std ::pin ::Pin ;
use std ::task ::{ Context , Poll } ;
2020-12-04 14:59:34 +03:00
use anyhow ::Error ;
2019-08-28 16:37:57 +03:00
use futures ::future ::TryFutureExt ;
use futures ::stream ::Stream ;
use tokio ::net ::TcpStream ;
2019-06-29 11:08:12 +03:00
// Simple H2 client to test H2 download speed using h2server.rs
struct Process {
body : h2 ::RecvStream ,
trailers : bool ,
bytes : usize ,
}
impl Future for Process {
2019-08-28 16:37:57 +03:00
type Output = Result < usize , Error > ;
fn poll ( self : Pin < & mut Self > , cx : & mut Context ) -> Poll < Self ::Output > {
let this = self . get_mut ( ) ;
2019-06-29 11:08:12 +03:00
loop {
2019-08-28 16:37:57 +03:00
if this . trailers {
match futures ::ready! ( this . body . poll_trailers ( cx ) ) {
Ok ( Some ( trailers ) ) = > println! ( " trailers: {:?} " , trailers ) ,
Ok ( None ) = > ( ) ,
Err ( err ) = > return Poll ::Ready ( Err ( Error ::from ( err ) ) ) ,
2019-06-29 11:08:12 +03:00
}
2019-08-28 16:37:57 +03:00
println! ( " Received {} bytes " , this . bytes ) ;
return Poll ::Ready ( Ok ( this . bytes ) ) ;
2019-06-29 11:08:12 +03:00
} else {
2019-08-28 16:37:57 +03:00
match futures ::ready! ( Pin ::new ( & mut this . body ) . poll_next ( cx ) ) {
Some ( Ok ( chunk ) ) = > {
2019-12-12 17:27:07 +03:00
this . body . flow_control ( ) . release_capacity ( chunk . len ( ) ) ? ;
2019-08-28 16:37:57 +03:00
this . bytes + = chunk . len ( ) ;
2019-06-29 11:08:12 +03:00
// println!("GOT FRAME {}", chunk.len());
2020-12-04 14:59:34 +03:00
}
2019-08-28 16:37:57 +03:00
Some ( Err ( err ) ) = > return Poll ::Ready ( Err ( Error ::from ( err ) ) ) ,
2019-06-29 11:08:12 +03:00
None = > {
2019-08-28 16:37:57 +03:00
this . trailers = true ;
2020-12-04 14:59:34 +03:00
}
2019-06-29 11:08:12 +03:00
}
}
}
}
}
2019-08-28 16:37:57 +03:00
fn send_request (
mut client : h2 ::client ::SendRequest < bytes ::Bytes > ,
) -> impl Future < Output = Result < usize , Error > > {
2019-06-29 11:08:12 +03:00
println! ( " sending request " ) ;
let request = http ::Request ::builder ( )
. uri ( " http://localhost/ " )
. body ( ( ) )
. unwrap ( ) ;
let ( response , _stream ) = client . send_request ( request , true ) . unwrap ( ) ;
2020-12-04 14:59:34 +03:00
response . map_err ( Error ::from ) . and_then ( | response | Process {
body : response . into_body ( ) ,
trailers : false ,
bytes : 0 ,
} )
2019-06-29 11:08:12 +03:00
}
2020-01-20 14:52:22 +03:00
fn main ( ) -> Result < ( ) , Error > {
2021-11-19 19:36:06 +03:00
proxmox_async ::runtime ::main ( run ( ) )
2020-01-20 14:52:22 +03:00
}
async fn run ( ) -> Result < ( ) , Error > {
2019-06-29 11:08:12 +03:00
let start = std ::time ::SystemTime ::now ( ) ;
2020-12-04 14:59:34 +03:00
let conn = TcpStream ::connect ( std ::net ::SocketAddr ::from ( ( [ 127 , 0 , 0 , 1 ] , 8008 ) ) ) . await ? ;
conn . set_nodelay ( true ) . unwrap ( ) ;
2019-06-29 11:08:12 +03:00
2019-08-28 16:37:57 +03:00
let ( client , h2 ) = h2 ::client ::Builder ::new ( )
2020-12-04 14:59:34 +03:00
. initial_connection_window_size ( 1024 * 1024 * 1024 )
. initial_window_size ( 1024 * 1024 * 1024 )
. max_frame_size ( 4 * 1024 * 1024 )
2019-08-28 16:37:57 +03:00
. handshake ( conn )
. await ? ;
tokio ::spawn ( async move {
if let Err ( err ) = h2 . await {
println! ( " GOT ERR= {:?} " , err ) ;
}
} ) ;
let mut bytes = 0 ;
for _ in 0 .. 2000 {
bytes + = send_request ( client . clone ( ) ) . await ? ;
}
let elapsed = start . elapsed ( ) . unwrap ( ) ;
2020-12-04 14:59:34 +03:00
let elapsed = ( elapsed . as_secs ( ) as f64 ) + ( elapsed . subsec_millis ( ) as f64 ) / 1000.0 ;
2019-06-29 11:08:12 +03:00
2020-12-04 14:59:34 +03:00
println! (
" Downloaded {} bytes, {} MB/s " ,
bytes ,
( bytes as f64 ) / ( elapsed * 1024.0 * 1024.0 )
) ;
2019-06-29 11:08:12 +03:00
Ok ( ( ) )
}