sozu-command-lib 2.3.4

configuration library to command a sozu instance
Documentation
//! Tools and types used to communicate with Sōzu.

#[macro_use]
extern crate serde;

/// The floor each H2 listener knob must meet — the single list, expanded once
/// per validator that enforces it (sozu-proxy/sozu#1418).
///
/// Expands `$callback!($config, <field>, <minimum>)` once per knob, in a fixed
/// order, so the five doors into a listener configuration share one list
/// instead of five copies of it: `ListenerBuilder::validate_h2_thresholds`
/// (`crate::config`, the config file and `sozu ctl add listener`),
/// `validate_h2_flood_knobs_http`/`_https` (`crate::state`,
/// `UpdateHttp(s)Listener`) and `validate_h2_flood_knobs_http_listener`/
/// `_https_listener` (`crate::state`, a raw protobuf
/// `Add{Http,Https}Listener`). Each supplies its own one-knob callback because
/// the error types differ — `ConfigError::H2ThresholdBelowMinimum` names the
/// listener, `StateError::InvalidValue` names the field — but none supplies
/// its own list. Adding a knob to one door and forgetting another is what
/// reopens sozu#1418 one level up; with the list here it is not expressible.
///
/// `h2_graceful_shutdown_deadline_seconds` is deliberately absent: `0` there
/// means "wait forever (no forced close after GOAWAY)".
macro_rules! for_each_h2_knob_floor {
    ($callback:ident, $config:ident) => {
        $callback!($config, h2_max_rst_stream_per_window, 1);
        $callback!($config, h2_max_ping_per_window, 1);
        $callback!($config, h2_max_settings_per_window, 1);
        $callback!($config, h2_max_empty_data_per_window, 1);
        $callback!($config, h2_max_window_update_stream0_per_window, 1);
        $callback!($config, h2_max_continuation_frames, 1);
        $callback!($config, h2_max_glitch_count, 1);
        $callback!($config, h2_max_rst_stream_lifetime, 1);
        $callback!($config, h2_max_rst_stream_abusive_lifetime, 1);
        $callback!($config, h2_max_rst_stream_emitted_lifetime, 1);
        $callback!($config, h2_max_header_list_size, 1);
        $callback!($config, h2_max_header_table_size, 1);
        $callback!($config, h2_max_header_fields, 1);
        $callback!($config, h2_max_concurrent_streams, 1);
        // The runtime floor is 2 (`lib/src/protocol/mux/h2.rs`'s `.max(2)`);
        // anything lower is silently promoted, so refuse it instead.
        $callback!($config, h2_stream_shrink_ratio, 2);
    };
}
pub(crate) use for_each_h2_knob_floor;

#[macro_use]
/// custom made logging macros
pub mod logging;
/// Custom buffer used for parsing within the Sōzu codebase.
pub mod buffer;
/// TLS certificates
pub mod certificate;
/// channels used for communication between main process and workers
pub mod channel;
/// parse TOML config and generate requests from it
pub mod config;
/// listener identity: socket address plus optional network interface
pub mod listener_key;
/// parse Requests
pub mod parser;
/// two-phase coordination of protected health-check headers
pub mod protected_transaction;
/// Contains Rust types generated by [`prost`](https://docs.rs/prost/latest/prost/)
/// using the protobuf definition in `command.proto`.
///
/// The two main types are `Request` and `Response`.
///
/// Because these types were originally defined in Rust, and later adapted for protobuf,
/// the Rust translation of the protobuf definition looks a bit weird. Instead of having
/// `Request` being a simple enum with Payload like this:
///
/// ```ignore
/// pub enum Request {
///     SaveState(String),
///     LoadState(String),
///     // ...
/// }
/// ```
///
/// It is defined with `oneof` in protobuf. and looks like this in Rust:
///
/// ```ignore
/// pub struct Request {
///     pub request_type: ::core::option::Option<request::RequestType>,
/// }
///
/// pub mod request {
///     pub enum RequestType {
///         #[prost(string, tag = "1")]
///         SaveState(::prost::alloc::string::String),
///         /// load a state file, given its path
///         #[prost(string, tag = "2")]
///         LoadState(::prost::alloc::string::String),
///     }
/// }
/// ```
///
/// but can be instantiated this way:
///
/// ```ignore
/// let load_state_request: Request = RequestType::LoadState(path).into();
/// ```
///
/// A bit cumbersome, but it is the only way to benefit from protobuf in Rust.
pub mod proto;
/// File descriptor readiness
pub mod ready;
/// Helper functions around types received by Sōzu
pub mod request;
/// Helper functions around types sent by Sōzu
pub mod response;
/// sockets used to pass file descriptors
pub mod scm_socket;
/// systemd `sd_notify` integration (READY=1 / STOPPING=1 / etc.)
pub mod sd_notify;
/// protected health-check header values and their keyed fingerprints
pub mod secret;
/// A representation of Sōzu's state
pub mod state;
/// A writer used for logging
pub mod writer;

/// Used only when returning errors
#[derive(Debug)]
pub enum ObjectKind {
    Backend,
    Certificate,
    Cluster,
    HttpFrontend,
    HttpsFrontend,
    HttpListener,
    HttpsListener,
    Listener,
    TcpCluster,
    TcpListener,
    TcpFrontend,
    UdpListener,
    UdpFrontend,
}

pub trait AsString {
    fn as_string_or(&self, default: &'static str) -> String;
}

impl<T: ToString> AsString for Option<T> {
    fn as_string_or(&self, default: &'static str) -> String {
        match self {
            None => default.to_string(),
            Some(t) => t.to_string(),
        }
    }
}

pub trait AsStr {
    fn as_str_or(&self, default: &'static str) -> &str;
}

impl<T: AsRef<str>> AsStr for Option<T> {
    fn as_str_or(&self, default: &'static str) -> &str {
        match self {
            None => default,
            Some(s) => s.as_ref(),
        }
    }
}