@@ -1661,6 +1661,167 @@ async fn client_builder_header_table_size() {
1661
1661
join ( srv, h2) . await ;
1662
1662
}
1663
1663
1664
+ #[ tokio:: test]
1665
+ async fn configured_max_concurrent_send_streams_and_update_it_based_on_empty_settings_frame ( ) {
1666
+ h2_support:: trace_init!( ) ;
1667
+ let ( io, mut srv) = mock:: new ( ) ;
1668
+
1669
+ let srv = async move {
1670
+ // Send empty SETTINGS frame (no MAX_CONCURRENT_STREAMS is provided)
1671
+ srv. send_frame ( frames:: settings ( ) ) . await ;
1672
+ } ;
1673
+
1674
+ let h2 = async move {
1675
+ let ( _client, h2) = client:: Builder :: new ( )
1676
+ // Configure the initial value to 2024
1677
+ . initial_max_send_streams ( 2024 )
1678
+ . handshake :: < _ , bytes:: Bytes > ( io)
1679
+ . await
1680
+ . unwrap ( ) ;
1681
+ let mut h2 = std:: pin:: pin!( h2) ;
1682
+ // It should be pre-configured value before it receives the initial
1683
+ // SETTINGS frame from the server
1684
+ assert_eq ! ( h2. max_concurrent_send_streams( ) , 2024 ) ;
1685
+ h2. as_mut ( ) . await . unwrap ( ) ;
1686
+ // If the server's initial SETTINGS frame does not include
1687
+ // MAX_CONCURRENT_STREAMS, this should be updated to usize::MAX.
1688
+ assert_eq ! ( h2. max_concurrent_send_streams( ) , usize :: MAX ) ;
1689
+ } ;
1690
+
1691
+ join ( srv, h2) . await ;
1692
+ }
1693
+
1694
+ #[ tokio:: test]
1695
+ async fn configured_max_concurrent_send_streams_and_update_it_based_on_non_empty_settings_frame ( ) {
1696
+ h2_support:: trace_init!( ) ;
1697
+ let ( io, mut srv) = mock:: new ( ) ;
1698
+
1699
+ let srv = async move {
1700
+ // Send SETTINGS frame with MAX_CONCURRENT_STREAMS set to 42
1701
+ srv. send_frame ( frames:: settings ( ) . max_concurrent_streams ( 42 ) )
1702
+ . await ;
1703
+ } ;
1704
+
1705
+ let h2 = async move {
1706
+ let ( _client, h2) = client:: Builder :: new ( )
1707
+ // Configure the initial value to 2024
1708
+ . initial_max_send_streams ( 2024 )
1709
+ . handshake :: < _ , bytes:: Bytes > ( io)
1710
+ . await
1711
+ . unwrap ( ) ;
1712
+ let mut h2 = std:: pin:: pin!( h2) ;
1713
+ // It should be pre-configured value before it receives the initial
1714
+ // SETTINGS frame from the server
1715
+ assert_eq ! ( h2. max_concurrent_send_streams( ) , 2024 ) ;
1716
+ h2. as_mut ( ) . await . unwrap ( ) ;
1717
+ // Now the client has received the initial SETTINGS frame from the
1718
+ // server, which should update the value accordingly
1719
+ assert_eq ! ( h2. max_concurrent_send_streams( ) , 42 ) ;
1720
+ } ;
1721
+
1722
+ join ( srv, h2) . await ;
1723
+ }
1724
+
1725
+ #[ tokio:: test]
1726
+ async fn receive_settings_frame_twice_with_second_one_empty ( ) {
1727
+ h2_support:: trace_init!( ) ;
1728
+ let ( io, mut srv) = mock:: new ( ) ;
1729
+
1730
+ let srv = async move {
1731
+ // Send the initial SETTINGS frame with MAX_CONCURRENT_STREAMS set to 42
1732
+ srv. send_frame ( frames:: settings ( ) . max_concurrent_streams ( 42 ) )
1733
+ . await ;
1734
+
1735
+ // Handle the client's connection preface
1736
+ srv. read_preface ( ) . await . unwrap ( ) ;
1737
+ match srv. next ( ) . await {
1738
+ Some ( frame) => match frame. unwrap ( ) {
1739
+ h2:: frame:: Frame :: Settings ( _) => {
1740
+ let ack = frame:: Settings :: ack ( ) ;
1741
+ srv. send ( ack. into ( ) ) . await . unwrap ( ) ;
1742
+ }
1743
+ frame => {
1744
+ panic ! ( "unexpected frame: {:?}" , frame) ;
1745
+ }
1746
+ } ,
1747
+ None => {
1748
+ panic ! ( "unexpected EOF" ) ;
1749
+ }
1750
+ }
1751
+
1752
+ // Should receive the ack for the server's initial SETTINGS frame
1753
+ let frame = assert_settings ! ( srv. next( ) . await . unwrap( ) . unwrap( ) ) ;
1754
+ assert ! ( frame. is_ack( ) ) ;
1755
+
1756
+ // Send another SETTINGS frame with no MAX_CONCURRENT_STREAMS
1757
+ // This should not update the max_concurrent_send_streams value that
1758
+ // the client manages.
1759
+ srv. send_frame ( frames:: settings ( ) ) . await ;
1760
+ } ;
1761
+
1762
+ let h2 = async move {
1763
+ let ( _client, h2) = client:: handshake ( io) . await . unwrap ( ) ;
1764
+ let mut h2 = std:: pin:: pin!( h2) ;
1765
+ assert_eq ! ( h2. max_concurrent_send_streams( ) , usize :: MAX ) ;
1766
+ h2. as_mut ( ) . await . unwrap ( ) ;
1767
+ // Even though the second SETTINGS frame contained no value for
1768
+ // MAX_CONCURRENT_STREAMS, update to usize::MAX should not happen
1769
+ assert_eq ! ( h2. max_concurrent_send_streams( ) , 42 ) ;
1770
+ } ;
1771
+
1772
+ join ( srv, h2) . await ;
1773
+ }
1774
+
1775
+ #[ tokio:: test]
1776
+ async fn receive_settings_frame_twice_with_second_one_non_empty ( ) {
1777
+ h2_support:: trace_init!( ) ;
1778
+ let ( io, mut srv) = mock:: new ( ) ;
1779
+
1780
+ let srv = async move {
1781
+ // Send the initial SETTINGS frame with MAX_CONCURRENT_STREAMS set to 42
1782
+ srv. send_frame ( frames:: settings ( ) . max_concurrent_streams ( 42 ) )
1783
+ . await ;
1784
+
1785
+ // Handle the client's connection preface
1786
+ srv. read_preface ( ) . await . unwrap ( ) ;
1787
+ match srv. next ( ) . await {
1788
+ Some ( frame) => match frame. unwrap ( ) {
1789
+ h2:: frame:: Frame :: Settings ( _) => {
1790
+ let ack = frame:: Settings :: ack ( ) ;
1791
+ srv. send ( ack. into ( ) ) . await . unwrap ( ) ;
1792
+ }
1793
+ frame => {
1794
+ panic ! ( "unexpected frame: {:?}" , frame) ;
1795
+ }
1796
+ } ,
1797
+ None => {
1798
+ panic ! ( "unexpected EOF" ) ;
1799
+ }
1800
+ }
1801
+
1802
+ // Should receive the ack for the server's initial SETTINGS frame
1803
+ let frame = assert_settings ! ( srv. next( ) . await . unwrap( ) . unwrap( ) ) ;
1804
+ assert ! ( frame. is_ack( ) ) ;
1805
+
1806
+ // Send another SETTINGS frame with no MAX_CONCURRENT_STREAMS
1807
+ // This should not update the max_concurrent_send_streams value that
1808
+ // the client manages.
1809
+ srv. send_frame ( frames:: settings ( ) . max_concurrent_streams ( 2024 ) )
1810
+ . await ;
1811
+ } ;
1812
+
1813
+ let h2 = async move {
1814
+ let ( _client, h2) = client:: handshake ( io) . await . unwrap ( ) ;
1815
+ let mut h2 = std:: pin:: pin!( h2) ;
1816
+ assert_eq ! ( h2. max_concurrent_send_streams( ) , usize :: MAX ) ;
1817
+ h2. as_mut ( ) . await . unwrap ( ) ;
1818
+ // The most-recently advertised value should be used
1819
+ assert_eq ! ( h2. max_concurrent_send_streams( ) , 2024 ) ;
1820
+ } ;
1821
+
1822
+ join ( srv, h2) . await ;
1823
+ }
1824
+
1664
1825
const SETTINGS : & [ u8 ] = & [ 0 , 0 , 0 , 4 , 0 , 0 , 0 , 0 , 0 ] ;
1665
1826
const SETTINGS_ACK : & [ u8 ] = & [ 0 , 0 , 0 , 4 , 1 , 0 , 0 , 0 , 0 ] ;
1666
1827
0 commit comments