@@ -1898,3 +1898,96 @@ async fn window_size_decremented_past_zero() {
1898
1898
1899
1899
join ( client, srv) . await ;
1900
1900
}
1901
+
1902
+ #[ tokio:: test]
1903
+ async fn reclaim_reserved_capacity ( ) {
1904
+ use futures:: channel:: oneshot;
1905
+
1906
+ h2_support:: trace_init!( ) ;
1907
+
1908
+ let ( io, mut srv) = mock:: new ( ) ;
1909
+ let ( depleted_tx, depleted_rx) = oneshot:: channel ( ) ;
1910
+
1911
+ let mock = async move {
1912
+ let settings = srv. assert_client_handshake ( ) . await ;
1913
+ assert_default_settings ! ( settings) ;
1914
+
1915
+ srv. recv_frame ( frames:: headers ( 1 ) . request ( "POST" , "https://www.example.com/" ) )
1916
+ . await ;
1917
+ srv. send_frame ( frames:: headers ( 1 ) . response ( 200 ) ) . await ;
1918
+
1919
+ srv. recv_frame ( frames:: data ( 1 , vec ! [ 0 ; 16384 ] ) ) . await ;
1920
+ srv. recv_frame ( frames:: data ( 1 , vec ! [ 0 ; 16384 ] ) ) . await ;
1921
+ srv. recv_frame ( frames:: data ( 1 , vec ! [ 0 ; 16384 ] ) ) . await ;
1922
+ srv. recv_frame ( frames:: data ( 1 , vec ! [ 0 ; 16383 ] ) ) . await ;
1923
+ depleted_tx. send ( ( ) ) . unwrap ( ) ;
1924
+
1925
+ // By now, this peer's connection window is completely depleted.
1926
+
1927
+ srv. recv_frame ( frames:: headers ( 3 ) . request ( "POST" , "https://www.example.com/" ) )
1928
+ . await ;
1929
+ srv. send_frame ( frames:: headers ( 3 ) . response ( 200 ) ) . await ;
1930
+
1931
+ srv. recv_frame ( frames:: reset ( 1 ) . cancel ( ) ) . await ;
1932
+ } ;
1933
+
1934
+ let h2 = async move {
1935
+ let ( mut client, mut h2) = client:: handshake ( io) . await . unwrap ( ) ;
1936
+
1937
+ let mut depleting_stream = {
1938
+ let request = Request :: builder ( )
1939
+ . method ( Method :: POST )
1940
+ . uri ( "https://www.example.com/" )
1941
+ . body ( ( ) )
1942
+ . unwrap ( ) ;
1943
+
1944
+ let ( resp, stream) = client. send_request ( request, false ) . unwrap ( ) ;
1945
+
1946
+ {
1947
+ let resp = h2. drive ( resp) . await . unwrap ( ) ;
1948
+ assert_eq ! ( resp. status( ) , StatusCode :: OK ) ;
1949
+ }
1950
+
1951
+ stream
1952
+ } ;
1953
+
1954
+ depleting_stream
1955
+ . send_data ( vec ! [ 0 ; 65535 ] . into ( ) , false )
1956
+ . unwrap ( ) ;
1957
+ h2. drive ( depleted_rx) . await . unwrap ( ) ;
1958
+
1959
+ // By now, the client knows it has completely depleted the server's
1960
+ // connection window.
1961
+
1962
+ depleting_stream. reserve_capacity ( 1 ) ;
1963
+
1964
+ let mut starved_stream = {
1965
+ let request = Request :: builder ( )
1966
+ . method ( Method :: POST )
1967
+ . uri ( "https://www.example.com/" )
1968
+ . body ( ( ) )
1969
+ . unwrap ( ) ;
1970
+
1971
+ let ( resp, stream) = client. send_request ( request, false ) . unwrap ( ) ;
1972
+
1973
+ {
1974
+ let resp = h2. drive ( resp) . await . unwrap ( ) ;
1975
+ assert_eq ! ( resp. status( ) , StatusCode :: OK ) ;
1976
+ }
1977
+
1978
+ stream
1979
+ } ;
1980
+
1981
+ // The following call puts starved_stream in pending_send, as the
1982
+ // server's connection window is completely empty.
1983
+ starved_stream. send_data ( vec ! [ 0 ; 1 ] . into ( ) , false ) . unwrap ( ) ;
1984
+
1985
+ // This drop should change nothing, as it didn't actually reserve
1986
+ // any available connection window, only requested it.
1987
+ drop ( depleting_stream) ;
1988
+
1989
+ h2. await . unwrap ( ) ;
1990
+ } ;
1991
+
1992
+ join ( mock, h2) . await ;
1993
+ }
0 commit comments