wtx 0.43.0

A collection of different transport implementations and related tools focused primarily on web technologies.
Documentation
use crate::http2::{
  MAX_BODY_LEN, MAX_CONCURRENT_STREAMS_NUM, MAX_FRAME_LEN, MAX_FRAME_LEN_LOWER_BOUND,
  MAX_FRAME_LEN_UPPER_BOUND, MAX_HEADERS_LEN, MAX_HPACK_LEN, MAX_RECV_STREAMS_NUM, READ_BUFFER_LEN,
  settings_frame::SettingsFrame, u31::U31,
};

/// Indicates to a remote peer the receiving parameters of a connection as well as its streams.
///
/// Also states some configurations for local structures.
#[derive(Debug)]
pub struct Http2Params {
  enable_connect_protocol: bool,
  initial_window_len: U31,
  max_body_len: u32,
  max_concurrent_streams_num: u32,
  max_frame_len: u32,
  max_headers_len: u32,
  max_hpack_len: (u32, u32),
  max_recv_streams_num: u32,
  read_buffer_len: u32,
}

impl Http2Params {
  /// New instance with the default parameters declared in the RFC.
  #[inline]
  pub const fn with_default_params() -> Self {
    Self {
      enable_connect_protocol: false,
      initial_window_len: U31::from_u32(initial_window_len!()),
      max_body_len: MAX_BODY_LEN,
      max_concurrent_streams_num: MAX_CONCURRENT_STREAMS_NUM,
      max_frame_len: MAX_FRAME_LEN,
      max_headers_len: MAX_HEADERS_LEN,
      max_hpack_len: (MAX_HPACK_LEN, MAX_HPACK_LEN),
      max_recv_streams_num: MAX_RECV_STREAMS_NUM,
      read_buffer_len: READ_BUFFER_LEN,
    }
  }

  /// New instance with optioned default parameters that allows the interaction with most
  /// modern websites.
  #[inline]
  pub const fn from_optioned_params() -> Self {
    crate::http::conn_params::ConnParams::new()._to_hp()
  }

  /// Enable connect protocol
  ///
  /// Servers only. Allows the execution of other protocols like WebSockets within HTTP/2
  /// connections.
  ///
  /// Corresponds to `SETTINGS_ENABLE_CONNECT_PROTOCOL`. Defaults to `false`.
  #[inline]
  pub const fn enable_connect_protocol(&self) -> bool {
    self.enable_connect_protocol
  }

  /// Initial window length
  ///
  /// The initial amount of "credit" a counterpart can have for sending data.
  ///
  /// Corresponds to `SETTINGS_INITIAL_WINDOW_SIZE`. Capped within 0 ~ (2^31 - 1) bytes. Defaults
  /// to
  #[doc = concat!(initial_window_len!())]
  /// bytes.
  #[inline]
  pub const fn initial_window_len(&self) -> u32 {
    self.initial_window_len.u32()
  }

  /// Maximum request/response body length
  ///
  /// Or the maximum size allowed for the sum of the length of all data frames.
  ///
  /// Defaults to
  #[doc = concat!(max_body_len!())]
  /// bytes.
  #[inline]
  pub const fn max_body_len(&self) -> u32 {
    self.max_body_len
  }

  /// Maximum number of active concurrent streams
  ///
  /// Corresponds to `SETTINGS_MAX_CONCURRENT_STREAMS`. Defaults to
  #[doc = concat!(max_concurrent_streams_num!())]
  /// streams
  #[inline]
  pub const fn max_concurrent_streams_num(&self) -> u32 {
    self.max_concurrent_streams_num
  }

  /// Maximum headers length
  ///
  /// The final Request/Response header is composed by the sum of headers and trailers. Contents
  /// may or may not originate from the HPACK structure that holds cached decoded headers.
  ///
  /// Corresponds to `SETTINGS_MAX_HEADER_LIST_SIZE`. Defaults to
  #[doc = concat!(max_headers_len!())]
  /// bytes.
  #[inline]
  pub const fn max_headers_len(&self) -> u32 {
    self.max_headers_len
  }

  /// Maximum HPACK length
  ///
  /// Indicates the maximum length of the HPACK structure that holds cached decoded headers
  /// received from a counterpart.
  ///
  /// * The first parameter indicates the local HPACK ***decoder*** length that is externally
  ///   advertised and can become the remote HPACK ***encoder*** length.
  /// * The second parameter indicates the maximum local HPACK ***encoder*** length. In other words,
  ///   it doesn't allow external actors to dictate very large lengths.
  ///
  /// Corresponds to `SETTINGS_HEADER_TABLE_SIZE`. Defaults to
  #[doc = concat!(max_hpack_len!())]
  /// bytes.
  #[inline]
  pub const fn max_hpack_len(&self) -> (u32, u32) {
    self.max_hpack_len
  }

  /// Maximum frame ***payload*** length
  ///
  /// Avoids the reading of very large payload frames sent by external actors.
  ///
  /// Corresponds to `SETTINGS_MAX_FRAME_SIZE`. Capped within
  #[doc = concat!(max_frame_len_lower_bound!())]
  /// ~
  #[doc = concat!(max_frame_len_upper_bound!())]
  /// bytes. Defaults to
  #[doc = concat!(max_frame_len!())]
  /// bytes.
  #[inline]
  pub const fn max_frame_len(&self) -> u32 {
    self.max_frame_len
  }

  /// Maximum number of receiving streams
  ///
  /// Servers only. Prevents clients from opening more than the specified number of streams.
  ///
  /// Defaults to
  #[doc = concat!(max_recv_streams_num!())]
  /// streams
  #[inline]
  pub const fn max_recv_streams_num(&self) -> u32 {
    self.max_recv_streams_num
  }

  /// Read Buffer Length.
  ///
  /// Allocated space intended to read bytes sent by external actors.
  ///
  /// Defaults to
  #[doc = concat!(read_buffer_len!())]
  /// streams
  #[inline]
  pub const fn read_buffer_len(&self) -> u32 {
    self.read_buffer_len
  }

  /// Mutable version of [`Self::enable_connect_protocol`].
  #[inline]
  #[must_use]
  pub const fn set_enable_connect_protocol(mut self, value: bool) -> Self {
    self.enable_connect_protocol = value;
    self
  }

  /// Mutable version of [`Self::initial_window_len`].
  #[inline]
  #[must_use]
  pub const fn set_initial_window_len(mut self, value: u32) -> Self {
    self.initial_window_len = U31::from_u32(value);
    self
  }

  /// Mutable version of [`Self::max_body_len`].
  #[inline]
  #[must_use]
  pub const fn set_max_body_len(mut self, value: u32) -> Self {
    self.max_body_len = value;
    self
  }

  /// Mutable version of [`Self::max_concurrent_streams_num`].
  #[inline]
  #[must_use]
  pub const fn set_max_concurrent_streams_num(mut self, value: u32) -> Self {
    self.max_concurrent_streams_num = value;
    self
  }

  /// Mutable version of [`Self::max_headers_len`].
  #[inline]
  #[must_use]
  pub const fn set_max_headers_len(mut self, value: u32) -> Self {
    self.max_headers_len = value;
    self
  }

  /// Mutable version of [`Self::max_hpack_len`].
  #[inline]
  #[must_use]
  pub const fn set_max_hpack_len(mut self, value: (u32, u32)) -> Self {
    self.max_hpack_len = value;
    self
  }

  /// Mutable version of [`Self::max_frame_len`].
  #[inline]
  #[must_use]
  pub const fn set_max_frame_len(mut self, value: u32) -> Self {
    // FIXME(STABLE): Use constant `clamp`
    self.max_frame_len = if value < MAX_FRAME_LEN_LOWER_BOUND {
      MAX_FRAME_LEN_LOWER_BOUND
    } else if value > MAX_FRAME_LEN_UPPER_BOUND {
      MAX_FRAME_LEN_UPPER_BOUND
    } else {
      value
    };
    self
  }

  /// Mutable version of [`Self::max_recv_streams_num`].
  #[inline]
  #[must_use]
  pub const fn set_max_recv_streams_num(mut self, value: u32) -> Self {
    self.max_recv_streams_num = value;
    self
  }

  /// Mutable version of [`Self::read_buffer_len`].
  #[inline]
  #[must_use]
  pub const fn set_read_buffer_len(mut self, value: u32) -> Self {
    self.read_buffer_len = value;
    self
  }

  #[inline]
  pub(crate) fn to_settings_frame(&self) -> SettingsFrame {
    let mut settings_frame = SettingsFrame::empty();
    settings_frame.set_enable_connect_protocol(Some(self.enable_connect_protocol));
    settings_frame.set_header_table_size(Some(self.max_hpack_len.0));
    settings_frame.set_initial_window_size(Some(self.initial_window_len));
    settings_frame.set_max_concurrent_streams(Some(self.max_concurrent_streams_num));
    settings_frame.set_max_frame_size(Some(self.max_frame_len));
    settings_frame.set_max_header_list_size(Some(self.max_headers_len));
    settings_frame
  }
}

impl Default for Http2Params {
  #[inline]
  fn default() -> Self {
    Self::with_default_params()
  }
}