@@ -336,6 +336,12 @@ pub struct Builder {
336
336
/// The stream ID of the first (lowest) stream. Subsequent streams will use
337
337
/// monotonically increasing stream IDs.
338
338
stream_id : StreamId ,
339
+
340
+ /// Maximum number of locally reset streams due to protocol error across
341
+ /// the lifetime of the connection.
342
+ ///
343
+ /// When this gets exceeded, we issue GOAWAYs.
344
+ local_max_error_reset_streams : Option < usize > ,
339
345
}
340
346
341
347
#[ derive( Debug ) ]
@@ -510,8 +516,10 @@ where
510
516
self . inner
511
517
. send_request ( request, end_of_stream, self . pending . as_ref ( ) )
512
518
. map_err ( Into :: into)
513
- . map ( |stream| {
514
- if stream. is_pending_open ( ) {
519
+ . map ( |( stream, is_full) | {
520
+ if stream. is_pending_open ( ) && is_full {
521
+ // Only prevent sending another request when the request queue
522
+ // is not full.
515
523
self . pending = Some ( stream. clone_to_opaque ( ) ) ;
516
524
}
517
525
@@ -643,6 +651,7 @@ impl Builder {
643
651
initial_max_send_streams : usize:: MAX ,
644
652
settings : Default :: default ( ) ,
645
653
stream_id : 1 . into ( ) ,
654
+ local_max_error_reset_streams : Some ( proto:: DEFAULT_LOCAL_RESET_COUNT_MAX ) ,
646
655
}
647
656
}
648
657
@@ -971,6 +980,23 @@ impl Builder {
971
980
self
972
981
}
973
982
983
+ /// Sets the maximum number of local resets due to protocol errors made by the remote end.
984
+ ///
985
+ /// Invalid frames and many other protocol errors will lead to resets being generated for those streams.
986
+ /// Too many of these often indicate a malicious client, and there are attacks which can abuse this to DOS servers.
987
+ /// This limit protects against these DOS attacks by limiting the amount of resets we can be forced to generate.
988
+ ///
989
+ /// When the number of local resets exceeds this threshold, the client will close the connection.
990
+ ///
991
+ /// If you really want to disable this, supply [`Option::None`] here.
992
+ /// Disabling this is not recommended and may expose you to DOS attacks.
993
+ ///
994
+ /// The default value is currently 1024, but could change.
995
+ pub fn max_local_error_reset_streams ( & mut self , max : Option < usize > ) -> & mut Self {
996
+ self . local_max_error_reset_streams = max;
997
+ self
998
+ }
999
+
974
1000
/// Sets the maximum number of pending-accept remotely-reset streams.
975
1001
///
976
1002
/// Streams that have been received by the peer, but not accepted by the
@@ -1021,7 +1047,7 @@ impl Builder {
1021
1047
/// stream have been written to the connection, the send buffer capacity
1022
1048
/// will be freed up again.
1023
1049
///
1024
- /// The default is currently ~400MB , but may change.
1050
+ /// The default is currently ~400KB , but may change.
1025
1051
///
1026
1052
/// # Panics
1027
1053
///
@@ -1070,6 +1096,39 @@ impl Builder {
1070
1096
self
1071
1097
}
1072
1098
1099
+ /// Sets the header table size.
1100
+ ///
1101
+ /// This setting informs the peer of the maximum size of the header compression
1102
+ /// table used to encode header blocks, in octets. The encoder may select any value
1103
+ /// equal to or less than the header table size specified by the sender.
1104
+ ///
1105
+ /// The default value is 4,096.
1106
+ ///
1107
+ /// # Examples
1108
+ ///
1109
+ /// ```
1110
+ /// # use tokio::io::{AsyncRead, AsyncWrite};
1111
+ /// # use h2::client::*;
1112
+ /// # use bytes::Bytes;
1113
+ /// #
1114
+ /// # async fn doc<T: AsyncRead + AsyncWrite + Unpin>(my_io: T)
1115
+ /// # -> Result<((SendRequest<Bytes>, Connection<T, Bytes>)), h2::Error>
1116
+ /// # {
1117
+ /// // `client_fut` is a future representing the completion of the HTTP/2
1118
+ /// // handshake.
1119
+ /// let client_fut = Builder::new()
1120
+ /// .header_table_size(1_000_000)
1121
+ /// .handshake(my_io);
1122
+ /// # client_fut.await
1123
+ /// # }
1124
+ /// #
1125
+ /// # pub fn main() {}
1126
+ /// ```
1127
+ pub fn header_table_size ( & mut self , size : u32 ) -> & mut Self {
1128
+ self . settings . set_header_table_size ( Some ( size) ) ;
1129
+ self
1130
+ }
1131
+
1073
1132
/// Sets the first stream ID to something other than 1.
1074
1133
#[ cfg( feature = "unstable" ) ]
1075
1134
pub fn initial_stream_id ( & mut self , stream_id : u32 ) -> & mut Self {
@@ -1258,6 +1317,7 @@ where
1258
1317
reset_stream_duration : builder. reset_stream_duration ,
1259
1318
reset_stream_max : builder. reset_stream_max ,
1260
1319
remote_reset_stream_max : builder. pending_accept_reset_stream_max ,
1320
+ local_error_reset_streams_max : builder. local_max_error_reset_streams ,
1261
1321
settings : builder. settings . clone ( ) ,
1262
1322
} ,
1263
1323
) ;
@@ -1571,9 +1631,11 @@ impl proto::Peer for Peer {
1571
1631
proto:: DynPeer :: Client
1572
1632
}
1573
1633
1634
+ /*
1574
1635
fn is_server() -> bool {
1575
1636
false
1576
1637
}
1638
+ */
1577
1639
1578
1640
fn convert_poll_message (
1579
1641
pseudo : Pseudo ,
0 commit comments