@@ -326,6 +326,10 @@ pub struct Builder {
326326 /// Maximum number of locally reset streams to keep at a time.
327327 reset_stream_max : usize ,
328328
329+ /// Maximum number of remotely reset streams to allow in the pending
330+ /// accept queue.
331+ pending_accept_reset_stream_max : usize ,
332+
329333 /// Initial `Settings` frame to send as part of the handshake.
330334 settings : Settings ,
331335
@@ -634,6 +638,7 @@ impl Builder {
634638 max_send_buffer_size : proto:: DEFAULT_MAX_SEND_BUFFER_SIZE ,
635639 reset_stream_duration : Duration :: from_secs ( proto:: DEFAULT_RESET_STREAM_SECS ) ,
636640 reset_stream_max : proto:: DEFAULT_RESET_STREAM_MAX ,
641+ pending_accept_reset_stream_max : proto:: DEFAULT_REMOTE_RESET_STREAM_MAX ,
637642 initial_target_connection_window_size : None ,
638643 initial_max_send_streams : usize:: MAX ,
639644 settings : Default :: default ( ) ,
@@ -966,6 +971,49 @@ impl Builder {
966971 self
967972 }
968973
974+ /// Sets the maximum number of pending-accept remotely-reset streams.
975+ ///
976+ /// Streams that have been received by the peer, but not accepted by the
977+ /// user, can also receive a RST_STREAM. This is a legitimate pattern: one
978+ /// could send a request and then shortly after, realize it is not needed,
979+ /// sending a CANCEL.
980+ ///
981+ /// However, since those streams are now "closed", they don't count towards
982+ /// the max concurrent streams. So, they will sit in the accept queue,
983+ /// using memory.
984+ ///
985+ /// When the number of remotely-reset streams sitting in the pending-accept
986+ /// queue reaches this maximum value, a connection error with the code of
987+ /// `ENHANCE_YOUR_CALM` will be sent to the peer, and returned by the
988+ /// `Future`.
989+ ///
990+ /// The default value is currently 20, but could change.
991+ ///
992+ /// # Examples
993+ ///
994+ /// ```
995+ /// # use tokio::io::{AsyncRead, AsyncWrite};
996+ /// # use h2::client::*;
997+ /// # use bytes::Bytes;
998+ /// #
999+ /// # async fn doc<T: AsyncRead + AsyncWrite + Unpin>(my_io: T)
1000+ /// # -> Result<((SendRequest<Bytes>, Connection<T, Bytes>)), h2::Error>
1001+ /// # {
1002+ /// // `client_fut` is a future representing the completion of the HTTP/2
1003+ /// // handshake.
1004+ /// let client_fut = Builder::new()
1005+ /// .max_pending_accept_reset_streams(100)
1006+ /// .handshake(my_io);
1007+ /// # client_fut.await
1008+ /// # }
1009+ /// #
1010+ /// # pub fn main() {}
1011+ /// ```
1012+ pub fn max_pending_accept_reset_streams ( & mut self , max : usize ) -> & mut Self {
1013+ self . pending_accept_reset_stream_max = max;
1014+ self
1015+ }
1016+
9691017 /// Sets the maximum send buffer size per stream.
9701018 ///
9711019 /// Once a stream has buffered up to (or over) the maximum, the stream's
@@ -1209,6 +1257,7 @@ where
12091257 max_send_buffer_size : builder. max_send_buffer_size ,
12101258 reset_stream_duration : builder. reset_stream_duration ,
12111259 reset_stream_max : builder. reset_stream_max ,
1260+ remote_reset_stream_max : builder. pending_accept_reset_stream_max ,
12121261 settings : builder. settings . clone ( ) ,
12131262 } ,
12141263 ) ;
0 commit comments