@@ -1903,6 +1903,94 @@ async fn http2_keep_alive_with_responsive_client() {
1903
1903
client. send_request ( req) . await . expect ( "client.send_request" ) ;
1904
1904
}
1905
1905
1906
+ fn is_ping_frame ( buf : & [ u8 ] ) -> bool {
1907
+ buf[ 3 ] == 6
1908
+ }
1909
+
1910
+ fn assert_ping_frame ( buf : & [ u8 ] , len : usize ) {
1911
+ // Assert the StreamId is zero
1912
+ let mut ubuf = [ 0 ; 4 ] ;
1913
+ ubuf. copy_from_slice ( & buf[ 5 ..9 ] ) ;
1914
+ let unpacked = u32:: from_be_bytes ( ubuf) ;
1915
+ assert_eq ! ( unpacked & !( 1 << 31 ) , 0 ) ;
1916
+
1917
+ // Assert ACK flag is unset (only set for PONG).
1918
+ let flags = buf[ 4 ] ;
1919
+ assert_eq ! ( flags & 0x1 , 0 ) ;
1920
+
1921
+ // Assert total frame size
1922
+ assert_eq ! ( len, 17 ) ;
1923
+ }
1924
+
1925
+ async fn write_pong_frame ( conn : & mut TkTcpStream ) {
1926
+ conn. write_all ( & [
1927
+ 0 , 0 , 8 , // len
1928
+ 6 , // kind
1929
+ 0x1 , // flag
1930
+ 0 , 0 , 0 , 0 , // stream id
1931
+ 0x3b , 0x7c , 0xdb , 0x7a , 0x0b , 0x87 , 0x16 , 0xb4 , // payload
1932
+ ] )
1933
+ . await
1934
+ . expect ( "client pong" ) ;
1935
+ }
1936
+
1937
+ #[ tokio:: test]
1938
+ async fn http2_keep_alive_count_server_pings ( ) {
1939
+ let _ = pretty_env_logger:: try_init ( ) ;
1940
+
1941
+ let mut listener = tcp_bind ( & "127.0.0.1:0" . parse ( ) . unwrap ( ) ) . unwrap ( ) ;
1942
+ let addr = listener. local_addr ( ) . unwrap ( ) ;
1943
+
1944
+ tokio:: spawn ( async move {
1945
+ let ( socket, _) = listener. accept ( ) . await . expect ( "accept" ) ;
1946
+
1947
+ Http :: new ( )
1948
+ . http2_only ( true )
1949
+ . http2_keep_alive_interval ( Duration :: from_secs ( 1 ) )
1950
+ . http2_keep_alive_timeout ( Duration :: from_secs ( 1 ) )
1951
+ . serve_connection ( socket, unreachable_service ( ) )
1952
+ . await
1953
+ . expect ( "serve_connection" ) ;
1954
+ } ) ;
1955
+
1956
+ // Spawn a "client" conn that only reads until EOF
1957
+ let mut conn = connect_async ( addr) . await ;
1958
+
1959
+ // write h2 magic preface and settings frame
1960
+ conn. write_all ( b"PRI * HTTP/2.0\r \n \r \n SM\r \n \r \n " )
1961
+ . await
1962
+ . expect ( "client preface" ) ;
1963
+ conn. write_all ( & [
1964
+ 0 , 0 , 0 , // len
1965
+ 4 , // kind
1966
+ 0 , // flag
1967
+ 0 , 0 , 0 , 0 , // stream id
1968
+ ] )
1969
+ . await
1970
+ . expect ( "client settings" ) ;
1971
+
1972
+ let read_pings = async {
1973
+ // read until 3 pings are received
1974
+ let mut pings = 0 ;
1975
+ let mut buf = [ 0u8 ; 1024 ] ;
1976
+ while pings < 3 {
1977
+ let n = conn. read ( & mut buf) . await . expect ( "client.read" ) ;
1978
+ assert ! ( n != 0 ) ;
1979
+
1980
+ if is_ping_frame ( & buf) {
1981
+ assert_ping_frame ( & buf, n) ;
1982
+ write_pong_frame ( & mut conn) . await ;
1983
+ pings += 1 ;
1984
+ }
1985
+ }
1986
+ } ;
1987
+
1988
+ // Expect all pings to occurs under 5 seconds
1989
+ tokio:: time:: timeout ( Duration :: from_secs ( 5 ) , read_pings)
1990
+ . await
1991
+ . expect ( "timed out waiting for pings" ) ;
1992
+ }
1993
+
1906
1994
// -------------------------------------------------
1907
1995
// the Server that is used to run all the tests with
1908
1996
// -------------------------------------------------
0 commit comments