mirror of
https://github.com/actix/actix-extras.git
synced 2024-11-23 23:51:06 +01:00
document settings crate (#271)
This commit is contained in:
parent
ab3f591307
commit
b054733854
@ -62,7 +62,7 @@ async fn main() -> std::io::Result<()> {
|
|||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initialize the logging infrastructure
|
/// Initialize the logging infrastructure.
|
||||||
fn init_logger(settings: &Settings) {
|
fn init_logger(settings: &Settings) {
|
||||||
if !settings.actix.enable_log {
|
if !settings.actix.enable_log {
|
||||||
return;
|
return;
|
||||||
|
@ -21,19 +21,19 @@ num-workers = "default"
|
|||||||
# Takes a string value: Either "default", or an integer N > 0 e.g. "6".
|
# Takes a string value: Either "default", or an integer N > 0 e.g. "6".
|
||||||
backlog = "default"
|
backlog = "default"
|
||||||
|
|
||||||
# Sets the maximum per-worker number of concurrent connections. All socket listeners
|
# Sets the per-worker maximum number of concurrent connections. All socket listeners
|
||||||
# will stop accepting connections when this limit is reached for each worker.
|
# will stop accepting connections when this limit is reached for each worker.
|
||||||
# By default max connections is set to a 25k.
|
# By default max connections is set to a 25k.
|
||||||
# Takes a string value: Either "default", or an integer N > 0 e.g. "6".
|
# Takes a string value: Either "default", or an integer N > 0 e.g. "6".
|
||||||
max-connections = "default"
|
max-connections = "default"
|
||||||
|
|
||||||
# Sets the maximum per-worker concurrent connection establish process. All listeners
|
# Sets the per-worker maximum concurrent connection establish process. All listeners
|
||||||
# will stop accepting connections when this limit is reached. It can be used to limit
|
# will stop accepting connections when this limit is reached. It can be used to limit
|
||||||
# the global TLS CPU usage. By default max connections is set to a 256.
|
# the global TLS CPU usage. By default max connections is set to a 256.
|
||||||
# Takes a string value: Either "default", or an integer N > 0 e.g. "6".
|
# Takes a string value: Either "default", or an integer N > 0 e.g. "6".
|
||||||
max-connection-rate = "default"
|
max-connection-rate = "default"
|
||||||
|
|
||||||
# Set server keep-alive setting. By default keep alive is set to 5 seconds.
|
# Set server keep-alive preference. By default keep alive is set to 5 seconds.
|
||||||
# Takes a string value: Either "default", "disabled", "os",
|
# Takes a string value: Either "default", "disabled", "os",
|
||||||
# or a string of the format "N seconds" where N is an integer > 0 e.g. "6 seconds".
|
# or a string of the format "N seconds" where N is an integer > 0 e.g. "6 seconds".
|
||||||
keep-alive = "default"
|
keep-alive = "default"
|
||||||
|
@ -2,12 +2,20 @@ use std::{env::VarError, io, num::ParseIntError, path::PathBuf, str::ParseBoolEr
|
|||||||
|
|
||||||
use toml::de::Error as TomlError;
|
use toml::de::Error as TomlError;
|
||||||
|
|
||||||
|
/// Convenience type alias for `Result<T, AtError>`.
|
||||||
pub type AtResult<T> = std::result::Result<T, AtError>;
|
pub type AtResult<T> = std::result::Result<T, AtError>;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
/// Errors that can be returned from methods in this crate.
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
pub enum AtError {
|
pub enum AtError {
|
||||||
|
/// Environment variable does not exists or is invalid.
|
||||||
EnvVarError(VarError),
|
EnvVarError(VarError),
|
||||||
|
|
||||||
|
/// File already exists on disk.
|
||||||
FileExists(PathBuf),
|
FileExists(PathBuf),
|
||||||
|
|
||||||
|
/// Invalid value.
|
||||||
|
#[allow(missing_docs)]
|
||||||
InvalidValue {
|
InvalidValue {
|
||||||
expected: &'static str,
|
expected: &'static str,
|
||||||
got: String,
|
got: String,
|
||||||
@ -15,10 +23,20 @@ pub enum AtError {
|
|||||||
line: u32,
|
line: u32,
|
||||||
column: u32,
|
column: u32,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/// I/O error.
|
||||||
IoError(ioe::IoError),
|
IoError(ioe::IoError),
|
||||||
|
|
||||||
|
/// Value is not a boolean.
|
||||||
ParseBoolError(ParseBoolError),
|
ParseBoolError(ParseBoolError),
|
||||||
|
|
||||||
|
/// Value is not an integer.
|
||||||
ParseIntError(ParseIntError),
|
ParseIntError(ParseIntError),
|
||||||
|
|
||||||
|
/// Value is not an address.
|
||||||
ParseAddressError(String),
|
ParseAddressError(String),
|
||||||
|
|
||||||
|
/// Error deserializing as TOML.
|
||||||
TomlError(TomlError),
|
TomlError(TomlError),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,68 @@
|
|||||||
//! Easily manage Actix Web's settings from a TOML file and environment variables.
|
//! Easily manage Actix Web's settings from a TOML file and environment variables.
|
||||||
|
//!
|
||||||
|
//! To get started add a [`Settings::parse_toml("./Server.toml")`](Settings::parse_toml) call to the
|
||||||
|
//! top of your main function. This will create a template file with descriptions of all the
|
||||||
|
//! configurable settings. You can change or remove anything in that file and it will be picked up
|
||||||
|
//! the next time you run your application.
|
||||||
|
//!
|
||||||
|
//! Overriding parts of the file can be done from values using [`Settings::override_field`] or from
|
||||||
|
//! the environment using [`Settings::override_field_with_env_var`].
|
||||||
|
//!
|
||||||
|
//! # Examples
|
||||||
|
//!
|
||||||
|
//! See examples folder on GitHub for complete example.
|
||||||
|
//!
|
||||||
|
//! ```ignore
|
||||||
|
//! # use actix_web::{
|
||||||
|
//! # get,
|
||||||
|
//! # middleware::{Compress, Condition, Logger},
|
||||||
|
//! # web, App, HttpServer,
|
||||||
|
//! # };
|
||||||
|
//! use actix_settings::{ApplySettings as _, Mode, Settings};
|
||||||
|
//!
|
||||||
|
//! #[actix_web::main]
|
||||||
|
//! async fn main() -> std::io::Result<()> {
|
||||||
|
//! let mut settings = Settings::parse_toml("./Server.toml")
|
||||||
|
//! .expect("Failed to parse `Settings` from Server.toml");
|
||||||
|
//!
|
||||||
|
//! // If the environment variable `$APPLICATION__HOSTS` is set,
|
||||||
|
//! // have its value override the `settings.actix.hosts` setting:
|
||||||
|
//! Settings::override_field_with_env_var(&mut settings.actix.hosts, "APPLICATION__HOSTS")?;
|
||||||
|
//!
|
||||||
|
//! init_logger(&settings);
|
||||||
|
//!
|
||||||
|
//! HttpServer::new({
|
||||||
|
//! // clone settings into each worker thread
|
||||||
|
//! let settings = settings.clone();
|
||||||
|
//!
|
||||||
|
//! move || {
|
||||||
|
//! App::new()
|
||||||
|
//! // Include this `.wrap()` call for compression settings to take effect
|
||||||
|
//! .wrap(Condition::new(
|
||||||
|
//! settings.actix.enable_compression,
|
||||||
|
//! Compress::default(),
|
||||||
|
//! ))
|
||||||
|
//!
|
||||||
|
//! // add request logger
|
||||||
|
//! .wrap(Logger::default())
|
||||||
|
//!
|
||||||
|
//! // make `Settings` available to handlers
|
||||||
|
//! .app_data(web::Data::new(settings.clone()))
|
||||||
|
//!
|
||||||
|
//! // add request handlers as normal
|
||||||
|
//! .service(index)
|
||||||
|
//! }
|
||||||
|
//! })
|
||||||
|
//! // apply the `Settings` to Actix Web's `HttpServer`
|
||||||
|
//! .apply_settings(&settings)
|
||||||
|
//! .run()
|
||||||
|
//! .await
|
||||||
|
//! }
|
||||||
|
//! ```
|
||||||
|
|
||||||
#![forbid(unsafe_code)]
|
#![forbid(unsafe_code)]
|
||||||
#![deny(rust_2018_idioms, nonstandard_style)]
|
#![deny(rust_2018_idioms, nonstandard_style)]
|
||||||
#![warn(future_incompatible, missing_debug_implementations)]
|
#![warn(future_incompatible, missing_docs, missing_debug_implementations)]
|
||||||
// #![warn(missing_docs)]
|
|
||||||
#![doc(html_logo_url = "https://actix.rs/img/logo.png")]
|
#![doc(html_logo_url = "https://actix.rs/img/logo.png")]
|
||||||
#![doc(html_favicon_url = "https://actix.rs/favicon.ico")]
|
#![doc(html_favicon_url = "https://actix.rs/favicon.ico")]
|
||||||
|
|
||||||
@ -37,15 +96,21 @@ pub use self::settings::{
|
|||||||
NumWorkers, Timeout, Tls,
|
NumWorkers, Timeout, Tls,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Wrapper for server and application-specific settings.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize)]
|
||||||
#[serde(bound = "A: Deserialize<'de>")]
|
#[serde(bound = "A: Deserialize<'de>")]
|
||||||
pub struct BasicSettings<A> {
|
pub struct BasicSettings<A> {
|
||||||
|
/// Actix Web server settings.
|
||||||
pub actix: ActixSettings,
|
pub actix: ActixSettings,
|
||||||
|
|
||||||
|
/// Application-specific settings.
|
||||||
pub application: A,
|
pub application: A,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Convenience type alias for [`BasicSettings`] with no defined application-specific settings.
|
||||||
pub type Settings = BasicSettings<NoSettings>;
|
pub type Settings = BasicSettings<NoSettings>;
|
||||||
|
|
||||||
|
/// Marker type representing no defined application-specific settings.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize)]
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
pub struct NoSettings {/* NOTE: turning this into a unit struct will cause deserialization failures. */}
|
pub struct NoSettings {/* NOTE: turning this into a unit struct will cause deserialization failures. */}
|
||||||
@ -54,14 +119,16 @@ impl<A> BasicSettings<A>
|
|||||||
where
|
where
|
||||||
A: de::DeserializeOwned,
|
A: de::DeserializeOwned,
|
||||||
{
|
{
|
||||||
/// NOTE **DO NOT** mess with the ordering of the tables in this template.
|
// NOTE **DO NOT** mess with the ordering of the tables in the default template.
|
||||||
/// Especially the `[application]` table needs to be last in order
|
// Especially the `[application]` table needs to be last in order
|
||||||
/// for some tests to keep working.
|
// for some tests to keep working.
|
||||||
|
/// Default settings file contents.
|
||||||
pub(crate) const DEFAULT_TOML_TEMPLATE: &'static str = include_str!("./defaults.toml");
|
pub(crate) const DEFAULT_TOML_TEMPLATE: &'static str = include_str!("./defaults.toml");
|
||||||
|
|
||||||
/// Parse an instance of `Self` from a `TOML` file located at `filepath`.
|
/// Parse an instance of `Self` from a TOML file located at `filepath`.
|
||||||
/// If the file doesn't exist, it is generated from the default `TOML`
|
///
|
||||||
/// template, after which the newly generated file is read in and parsed.
|
/// If the file doesn't exist, it is generated from the default TOML template, after which the
|
||||||
|
/// newly generated file is read in and parsed.
|
||||||
pub fn parse_toml<P>(filepath: P) -> AtResult<Self>
|
pub fn parse_toml<P>(filepath: P) -> AtResult<Self>
|
||||||
where
|
where
|
||||||
P: AsRef<Path>,
|
P: AsRef<Path>,
|
||||||
@ -73,43 +140,62 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut f = File::open(filepath)?;
|
let mut f = File::open(filepath)?;
|
||||||
|
// TODO: don't bail on metadata fail
|
||||||
let mut contents = String::with_capacity(f.metadata()?.len() as usize);
|
let mut contents = String::with_capacity(f.metadata()?.len() as usize);
|
||||||
f.read_to_string(&mut contents)?;
|
f.read_to_string(&mut contents)?;
|
||||||
|
|
||||||
Ok(toml::from_str::<Self>(&contents)?)
|
Ok(toml::from_str::<Self>(&contents)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse an instance of `Self` straight from the default `TOML` template.
|
/// Parse an instance of `Self` straight from the default TOML template.
|
||||||
|
// TODO: make infallible
|
||||||
|
// TODO: consider "template" rename
|
||||||
pub fn from_default_template() -> AtResult<Self> {
|
pub fn from_default_template() -> AtResult<Self> {
|
||||||
Self::from_template(Self::DEFAULT_TOML_TEMPLATE)
|
Self::from_template(Self::DEFAULT_TOML_TEMPLATE)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse an instance of `Self` straight from the default `TOML` template.
|
/// Parse an instance of `Self` straight from the default TOML template.
|
||||||
|
// TODO: consider "template" rename
|
||||||
pub fn from_template(template: &str) -> AtResult<Self> {
|
pub fn from_template(template: &str) -> AtResult<Self> {
|
||||||
Ok(toml::from_str(template)?)
|
Ok(toml::from_str(template)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write the default `TOML` template to a new file, to be located
|
/// Writes the default TOML template to a new file, located at `filepath`.
|
||||||
/// at `filepath`. Return a `Error::FileExists(_)` error if a
|
///
|
||||||
/// file already exists at that location.
|
/// # Errors
|
||||||
|
/// Returns a [`FileExists`](crate::AtError::FileExists) error if a file already exists at that
|
||||||
|
/// location.
|
||||||
pub fn write_toml_file<P>(filepath: P) -> AtResult<()>
|
pub fn write_toml_file<P>(filepath: P) -> AtResult<()>
|
||||||
where
|
where
|
||||||
P: AsRef<Path>,
|
P: AsRef<Path>,
|
||||||
{
|
{
|
||||||
let filepath = filepath.as_ref();
|
let filepath = filepath.as_ref();
|
||||||
let contents = Self::DEFAULT_TOML_TEMPLATE.trim();
|
|
||||||
|
|
||||||
if filepath.exists() {
|
if filepath.exists() {
|
||||||
return Err(AtError::FileExists(filepath.to_path_buf()));
|
return Err(AtError::FileExists(filepath.to_path_buf()));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut file = File::create(filepath)?;
|
let mut file = File::create(filepath)?;
|
||||||
file.write_all(contents.as_bytes())?;
|
file.write_all(Self::DEFAULT_TOML_TEMPLATE.trim().as_bytes())?;
|
||||||
file.flush()?;
|
file.flush()?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Attempts to parse `value` and override the referenced `field`.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
/// ```
|
||||||
|
/// use actix_settings::{Settings, Mode};
|
||||||
|
///
|
||||||
|
/// # fn inner() -> actix_settings::AtResult<()> {
|
||||||
|
/// let mut settings = Settings::from_default_template()?;
|
||||||
|
/// assert_eq!(settings.actix.mode, Mode::Development);
|
||||||
|
///
|
||||||
|
/// Settings::override_field(&mut settings.actix.mode, "production")?;
|
||||||
|
/// assert_eq!(settings.actix.mode, Mode::Production);
|
||||||
|
/// # Ok(()) }
|
||||||
|
/// ```
|
||||||
pub fn override_field<F, V>(field: &mut F, value: V) -> AtResult<()>
|
pub fn override_field<F, V>(field: &mut F, value: V) -> AtResult<()>
|
||||||
where
|
where
|
||||||
F: Parse,
|
F: Parse,
|
||||||
@ -119,6 +205,22 @@ where
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Attempts to read an environment variable, parse it, and override the referenced `field`.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
/// ```
|
||||||
|
/// use actix_settings::{Settings, Mode};
|
||||||
|
///
|
||||||
|
/// std::env::set_var("OVERRIDE__MODE", "production");
|
||||||
|
///
|
||||||
|
/// # fn inner() -> actix_settings::AtResult<()> {
|
||||||
|
/// let mut settings = Settings::from_default_template()?;
|
||||||
|
/// assert_eq!(settings.actix.mode, Mode::Development);
|
||||||
|
///
|
||||||
|
/// Settings::override_field_with_env_var(&mut settings.actix.mode, "OVERRIDE__MODE")?;
|
||||||
|
/// assert_eq!(settings.actix.mode, Mode::Production);
|
||||||
|
/// # Ok(()) }
|
||||||
|
/// ```
|
||||||
pub fn override_field_with_env_var<F, N>(field: &mut F, var_name: N) -> AtResult<()>
|
pub fn override_field_with_env_var<F, N>(field: &mut F, var_name: N) -> AtResult<()>
|
||||||
where
|
where
|
||||||
F: Parse,
|
F: Parse,
|
||||||
@ -132,6 +234,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Extension trait for applying parsed settings to the server object.
|
||||||
pub trait ApplySettings {
|
pub trait ApplySettings {
|
||||||
/// Apply a [`BasicSettings`] value to `self`.
|
/// Apply a [`BasicSettings`] value to `self`.
|
||||||
///
|
///
|
||||||
@ -200,9 +303,9 @@ where
|
|||||||
self = match settings.actix.client_timeout {
|
self = match settings.actix.client_timeout {
|
||||||
Timeout::Default => self,
|
Timeout::Default => self,
|
||||||
Timeout::Milliseconds(n) => {
|
Timeout::Milliseconds(n) => {
|
||||||
self.client_disconnect_timeout(Duration::from_millis(n as u64))
|
self.client_request_timeout(Duration::from_millis(n as u64))
|
||||||
}
|
}
|
||||||
Timeout::Seconds(n) => self.client_disconnect_timeout(Duration::from_secs(n as u64)),
|
Timeout::Seconds(n) => self.client_request_timeout(Duration::from_secs(n as u64)),
|
||||||
};
|
};
|
||||||
|
|
||||||
self = match settings.actix.client_shutdown {
|
self = match settings.actix.client_shutdown {
|
||||||
|
@ -2,7 +2,9 @@ use std::{path::PathBuf, str::FromStr};
|
|||||||
|
|
||||||
use crate::AtError;
|
use crate::AtError;
|
||||||
|
|
||||||
|
/// A specialized `FromStr` trait that returns [`AtError`] errors
|
||||||
pub trait Parse: Sized {
|
pub trait Parse: Sized {
|
||||||
|
/// Parse `Self` from `string`.
|
||||||
fn parse(string: &str) -> Result<Self, AtError>;
|
fn parse(string: &str) -> Result<Self, AtError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,9 +37,13 @@ static ADDR_LIST_REGEX: Lazy<Regex> = Lazy::new(|| {
|
|||||||
.expect("Failed to compile regex: ADDRS_REGEX")
|
.expect("Failed to compile regex: ADDRS_REGEX")
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/// A host/port pair for the server to bind to.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize)]
|
||||||
pub struct Address {
|
pub struct Address {
|
||||||
|
/// Host part of address.
|
||||||
pub host: String,
|
pub host: String,
|
||||||
|
|
||||||
|
/// Port part of address.
|
||||||
pub port: u16,
|
pub port: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,9 +4,20 @@ use serde::de;
|
|||||||
|
|
||||||
use crate::{AtError, AtResult, Parse};
|
use crate::{AtError, AtResult, Parse};
|
||||||
|
|
||||||
|
/// The maximum number of pending connections.
|
||||||
|
///
|
||||||
|
/// This refers to the number of clients that can be waiting to be served. Exceeding this number
|
||||||
|
/// results in the client getting an error when attempting to connect. It should only affect servers
|
||||||
|
/// under significant load.
|
||||||
|
///
|
||||||
|
/// Generally set in the 64–2048 range. The default value is 2048. Takes a string value: Either
|
||||||
|
/// "default", or an integer N > 0 e.g. "6".
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub enum Backlog {
|
pub enum Backlog {
|
||||||
|
/// The default number of connections. See struct docs.
|
||||||
Default,
|
Default,
|
||||||
|
|
||||||
|
/// A specific number of connections.
|
||||||
Manual(usize),
|
Manual(usize),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,11 +6,24 @@ use serde::de;
|
|||||||
|
|
||||||
use crate::{AtError, AtResult, Parse};
|
use crate::{AtError, AtResult, Parse};
|
||||||
|
|
||||||
|
/// The server keep-alive preference.
|
||||||
|
///
|
||||||
|
/// By default keep alive is set to 5 seconds. Takes a string value: Either "default", "disabled",
|
||||||
|
/// "os", or a string of the format "N seconds" where N is an integer > 0 e.g. "6 seconds".
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub enum KeepAlive {
|
pub enum KeepAlive {
|
||||||
|
/// The default keep-alive as defined by Actix Web.
|
||||||
Default,
|
Default,
|
||||||
|
|
||||||
|
/// Disable keep-alive.
|
||||||
Disabled,
|
Disabled,
|
||||||
|
|
||||||
|
/// Let the OS determine keep-alive duration.
|
||||||
|
///
|
||||||
|
/// Note: this is usually quite long.
|
||||||
Os,
|
Os,
|
||||||
|
|
||||||
|
/// A specific keep-alive duration (in seconds).
|
||||||
Seconds(usize),
|
Seconds(usize),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,9 +4,17 @@ use serde::de;
|
|||||||
|
|
||||||
use crate::{AtError, AtResult, Parse};
|
use crate::{AtError, AtResult, Parse};
|
||||||
|
|
||||||
|
/// The maximum per-worker concurrent TLS connection limit.
|
||||||
|
///
|
||||||
|
/// All listeners will stop accepting connections when this limit is reached. It can be used to
|
||||||
|
/// limit the global TLS CPU usage. By default max connections is set to a 256. Takes a string
|
||||||
|
/// value: Either "default", or an integer N > 0 e.g. "6".
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub enum MaxConnectionRate {
|
pub enum MaxConnectionRate {
|
||||||
|
/// The default connection limit. See struct docs.
|
||||||
Default,
|
Default,
|
||||||
|
|
||||||
|
/// A specific connection limit.
|
||||||
Manual(usize),
|
Manual(usize),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,9 +4,17 @@ use serde::de;
|
|||||||
|
|
||||||
use crate::{AtError, AtResult, Parse};
|
use crate::{AtError, AtResult, Parse};
|
||||||
|
|
||||||
|
/// The maximum per-worker number of concurrent connections.
|
||||||
|
///
|
||||||
|
/// All socket listeners will stop accepting connections when this limit is reached for each worker.
|
||||||
|
/// By default max connections is set to a 25k. Takes a string value: Either "default", or an
|
||||||
|
/// integer N > 0 e.g. "6".
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub enum MaxConnections {
|
pub enum MaxConnections {
|
||||||
|
/// The default number of connections. See struct docs.
|
||||||
Default,
|
Default,
|
||||||
|
|
||||||
|
/// A specific number of connections.
|
||||||
Manual(usize),
|
Manual(usize),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,17 +24,42 @@ pub use self::tls::Tls;
|
|||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize)]
|
||||||
#[serde(rename_all = "kebab-case")]
|
#[serde(rename_all = "kebab-case")]
|
||||||
pub struct ActixSettings {
|
pub struct ActixSettings {
|
||||||
|
/// List of addresses for the server to bind to.
|
||||||
pub hosts: Vec<Address>,
|
pub hosts: Vec<Address>,
|
||||||
pub mode: mode::Mode,
|
|
||||||
|
/// Marker of intended deployment environment.
|
||||||
|
pub mode: Mode,
|
||||||
|
|
||||||
|
/// True if the [`Compress`](actix_web::middleware::Compress) middleware should be enabled.
|
||||||
pub enable_compression: bool,
|
pub enable_compression: bool,
|
||||||
|
|
||||||
|
/// True if the [`Logger`](actix_web::middleware::Logger) middleware should be enabled.
|
||||||
pub enable_log: bool,
|
pub enable_log: bool,
|
||||||
|
|
||||||
|
/// The number of workers that the server should start.
|
||||||
pub num_workers: NumWorkers,
|
pub num_workers: NumWorkers,
|
||||||
|
|
||||||
|
/// The maximum number of pending connections.
|
||||||
pub backlog: Backlog,
|
pub backlog: Backlog,
|
||||||
|
|
||||||
|
/// The per-worker maximum number of concurrent connections.
|
||||||
pub max_connections: MaxConnections,
|
pub max_connections: MaxConnections,
|
||||||
|
|
||||||
|
/// The per-worker maximum concurrent TLS connection limit.
|
||||||
pub max_connection_rate: MaxConnectionRate,
|
pub max_connection_rate: MaxConnectionRate,
|
||||||
|
|
||||||
|
/// Server keep-alive preference.
|
||||||
pub keep_alive: KeepAlive,
|
pub keep_alive: KeepAlive,
|
||||||
|
|
||||||
|
/// Timeout duration for reading client request header.
|
||||||
pub client_timeout: Timeout,
|
pub client_timeout: Timeout,
|
||||||
|
|
||||||
|
/// Timeout duration for connection shutdown.
|
||||||
pub client_shutdown: Timeout,
|
pub client_shutdown: Timeout,
|
||||||
|
|
||||||
|
/// Timeout duration for graceful worker shutdown.
|
||||||
pub shutdown_timeout: Timeout,
|
pub shutdown_timeout: Timeout,
|
||||||
|
|
||||||
|
/// TLS (HTTPS) configuration.
|
||||||
pub tls: Tls,
|
pub tls: Tls,
|
||||||
}
|
}
|
||||||
|
@ -2,10 +2,14 @@ use serde::Deserialize;
|
|||||||
|
|
||||||
use crate::{AtResult, Parse};
|
use crate::{AtResult, Parse};
|
||||||
|
|
||||||
|
/// Marker of intended deployment environment.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize)]
|
||||||
#[serde(rename_all = "lowercase")]
|
#[serde(rename_all = "lowercase")]
|
||||||
pub enum Mode {
|
pub enum Mode {
|
||||||
|
/// Marks development environment.
|
||||||
Development,
|
Development,
|
||||||
|
|
||||||
|
/// Marks production environment.
|
||||||
Production,
|
Production,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,9 +4,16 @@ use serde::de;
|
|||||||
|
|
||||||
use crate::{AtError, AtResult, Parse};
|
use crate::{AtError, AtResult, Parse};
|
||||||
|
|
||||||
|
/// The number of workers that the server should start.
|
||||||
|
///
|
||||||
|
/// By default the number of available logical cpu cores is used. Takes a string value: Either
|
||||||
|
/// "default", or an integer N > 0 e.g. "6".
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub enum NumWorkers {
|
pub enum NumWorkers {
|
||||||
|
/// The default number of workers. See struct docs.
|
||||||
Default,
|
Default,
|
||||||
|
|
||||||
|
/// A specific number of workers.
|
||||||
Manual(usize),
|
Manual(usize),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,10 +6,16 @@ use serde::de;
|
|||||||
|
|
||||||
use crate::{AtError, AtResult, Parse};
|
use crate::{AtError, AtResult, Parse};
|
||||||
|
|
||||||
|
/// A timeout duration in milliseconds or seconds.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub enum Timeout {
|
pub enum Timeout {
|
||||||
|
/// The default timeout. Depends on context.
|
||||||
Default,
|
Default,
|
||||||
|
|
||||||
|
/// Timeout in milliseconds.
|
||||||
Milliseconds(usize),
|
Milliseconds(usize),
|
||||||
|
|
||||||
|
/// Timeout in seconds.
|
||||||
Seconds(usize),
|
Seconds(usize),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,18 +40,22 @@ impl Parse for Timeout {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
match string {
|
match string {
|
||||||
"default" => Ok(Timeout::Default),
|
"default" => Ok(Timeout::Default),
|
||||||
|
|
||||||
string if !FMT.is_match(string) => invalid_value!(string),
|
string if !FMT.is_match(string) => invalid_value!(string),
|
||||||
|
|
||||||
string => match (DIGITS.find(string), UNIT.find(string)) {
|
string => match (DIGITS.find(string), UNIT.find(string)) {
|
||||||
(None, _) => invalid_value!(string),
|
(None, _) | (_, None) => invalid_value!(string),
|
||||||
(_, None) => invalid_value!(string),
|
|
||||||
(Some(dmatch), Some(umatch)) => {
|
(Some(digits), Some(unit)) => {
|
||||||
let digits = &string[dmatch.start()..dmatch.end()];
|
let digits = &string[digits.range()];
|
||||||
let unit = &string[umatch.start()..umatch.end()];
|
let unit = &string[unit.range()];
|
||||||
|
|
||||||
match (digits.parse(), unit) {
|
match (digits.parse(), unit) {
|
||||||
(Ok(v), "milliseconds") => Ok(Timeout::Milliseconds(v)),
|
(Ok(n), "milliseconds") => Ok(Timeout::Milliseconds(n)),
|
||||||
(Ok(v), "seconds") => Ok(Timeout::Seconds(v)),
|
(Ok(n), "seconds") => Ok(Timeout::Seconds(n)),
|
||||||
_ => invalid_value!(string),
|
_ => invalid_value!(string),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,10 +2,17 @@ use std::path::PathBuf;
|
|||||||
|
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
/// TLS (HTTPS) configuration.
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize)]
|
||||||
#[serde(rename_all = "kebab-case")]
|
#[serde(rename_all = "kebab-case")]
|
||||||
|
#[doc(alias = "ssl", alias = "https")]
|
||||||
pub struct Tls {
|
pub struct Tls {
|
||||||
|
/// Tru if accepting TLS connections should be enabled.
|
||||||
pub enabled: bool,
|
pub enabled: bool,
|
||||||
|
|
||||||
|
/// Path to certificate `.pem` file.
|
||||||
pub certificate: PathBuf,
|
pub certificate: PathBuf,
|
||||||
|
|
||||||
|
/// Path to private key `.pem` file.
|
||||||
pub private_key: PathBuf,
|
pub private_key: PathBuf,
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user