Document the `Limits` structure. Change default workers.

The default workers config parameter is now [num_cpus * 2].
This commit is contained in:
Sergio Benitez 2017-06-11 03:39:30 -07:00
parent ea485e52e8
commit 7cf3367183
6 changed files with 124 additions and 36 deletions

View File

@ -176,7 +176,7 @@ impl ConfigBuilder {
/// use rocket::config::{Config, Environment, Limits};
///
/// let mut config = Config::build(Environment::Staging)
/// .limits(Limits::default().add("json", 5 * (1 << 20)))
/// .limits(Limits::new().limit("json", 5 * (1 << 20)))
/// .unwrap();
/// ```
pub fn limits(mut self, limits: Limits) -> Self {

View File

@ -192,8 +192,8 @@ impl Config {
"Configuration files must be rooted in a directory."));
}
// Note: This may truncate if num_cpus::get() > u16::max. That's okay.
let default_workers = ::std::cmp::max(num_cpus::get(), 2) as u16;
// Note: This may truncate if num_cpus::get() / 2 > u16::max. That's okay.
let default_workers = (num_cpus::get() * 2) as u16;
// Use a generated secret key by default.
let key = SecretKey::Generated(Key::generate());

View File

@ -49,10 +49,36 @@ pub struct TlsConfig {
#[derive(Clone)]
pub struct TlsConfig;
// Size limit configuration. We cache those used by Rocket internally but don't
// share that fact in the API.
/// Mapping from data type to size limits.
///
/// A `Limits` structure contains a mapping from a given data type ("forms",
/// "json", and so on) to the maximum size in bytes that should be accepted by a
/// Rocket application for that data type. For instance, if the limit for
/// "forms" is set to `256`, only 256 bytes from an incoming form request will
/// be read.
///
/// # Defaults
///
/// As documented in the [config module](/rocket/config/), the default limits
/// are as follows:
///
/// * **forms**: 32KiB
///
/// # Usage
///
/// A `Limits` structure is created following the builder pattern:
///
/// ```rust
/// use rocket::config::Limits;
///
/// // Set a limit of 64KiB for forms and 3MiB for JSON.
/// let limits = Limits::new()
/// .limit("forms", 64 * 1024)
/// .limit("json", 3 * 1024 * 1024);
/// ```
#[derive(Debug, Clone)]
pub struct Limits {
// We cache this internally but don't share that fact in the API.
pub(crate) forms: u64,
extra: Vec<(String, u64)>
}
@ -65,16 +91,75 @@ impl Default for Limits {
}
impl Limits {
pub fn add<S: Into<String>>(mut self, name: S, limit: u64) -> Self {
/// Construct a new `Limits` structure with the default limits set.
///
/// # Example
///
/// ```rust
/// use rocket::config::Limits;
///
/// let limits = Limits::new();
/// assert_eq!(limits.get("forms"), Some(32 * 1024));
/// ```
#[inline]
pub fn new() -> Self {
Limits::default()
}
/// Adds or replaces a limit in `self`, consuming `self` anf returning a new
/// `Limits` structure with the added or replaced limit.
///
/// # Example
///
/// ```rust
/// use rocket::config::Limits;
///
/// let limits = Limits::new()
/// .limit("json", 1 * 1024 * 1024);
///
/// assert_eq!(limits.get("forms"), Some(32 * 1024));
/// assert_eq!(limits.get("json"), Some(1 * 1024 * 1024));
///
/// let new_limits = limits.limit("json", 64 * 1024 * 1024);
/// assert_eq!(new_limits.get("json"), Some(64 * 1024 * 1024));
/// ```
pub fn limit<S: Into<String>>(mut self, name: S, limit: u64) -> Self {
let name = name.into();
match name.as_str() {
"forms" => self.forms = limit,
_ => self.extra.push((name, limit))
_ => {
let mut found = false;
for tuple in self.extra.iter_mut() {
if tuple.0 == name {
tuple.1 = limit;
found = true;
break;
}
}
if !found {
self.extra.push((name, limit))
}
}
}
self
}
/// Retrieve the set limit, if any, for the data type with name `name`.
///
/// # Example
///
/// ```rust
/// use rocket::config::Limits;
///
/// let limits = Limits::new()
/// .limit("json", 64 * 1024 * 1024);
///
/// assert_eq!(limits.get("forms"), Some(32 * 1024));
/// assert_eq!(limits.get("json"), Some(64 * 1024 * 1024));
/// assert!(limits.get("msgpack").is_none());
/// ```
pub fn get(&self, name: &str) -> Option<u64> {
if name == "forms" {
return Some(self.forms);
@ -171,7 +256,7 @@ pub fn limits(conf: &Config, name: &str, value: &Value) -> Result<Limits> {
let mut limits = Limits::default();
for (key, val) in table {
let val = u64(conf, &format!("limits.{}", key), val)?;
limits = limits.add(key.as_str(), val);
limits = limits.limit(key.as_str(), val);
}
Ok(limits)

View File

@ -3,7 +3,7 @@
//! This module implements configuration handling for Rocket. It implements the
//! parsing and interpretation of the `Rocket.toml` config file and
//! `ROCKET_{PARAM}` environment variables. It also allows libraries to access
//! values that have been configured by the user.
//! user-configured values.
//!
//! ## Application Configuration
//!
@ -43,13 +43,15 @@
//! * **secret_key**: _[string]_ a 256-bit base64 encoded string (44
//! characters) to use as the secret key
//! * example: `"8Xui8SN4mI+7egV/9dlfYYLGQJeEx4+DwmSQLwDVXJg="`
//! * **tls**: _[table]_ a table with two keys: 1) `certs`: _[string]_ a path
//! to a certificate chain in PEM format, and 2) `key`: _[string]_ a path to a
//! private key file in PEM format for the certificate in `certs`
//! * **tls**: _[table]_ a table with two keys:
//! 1. `certs`: _[string]_ a path to a certificate chain in PEM format
//! 2. `key`: _[string]_ a path to a private key file in PEM format for the
//! certificate in `certs`
//!
//! * example: `{ certs = "/path/to/certs.pem", key = "/path/to/key.pem" }`
//! * **limits**: _[table]_ a table where the key _[string]_ corresponds to a
//! data type and the value _[u64]_ corresponds to the maximum size in bytes
//! Rocket should accept for that type.
//! * **limits**: _[table]_ a table where each key (_[string]_) corresponds to
//! a data type and the value (_[u64]_) corresponds to the maximum size in
//! bytes Rocket should accept for that type.
//! * example: `{ forms = 65536 }` (maximum form size to 64KiB)
//!
//! ### Rocket.toml
@ -58,7 +60,7 @@
//! each environment. The file is optional. If it is not present, the default
//! configuration parameters are used.
//!
//! The file must be a series of TOML tables, at most one for each environment
//! The file must be a series of TOML tables, at most one for each environment,
//! and an optional "global" table, where each table contains key-value pairs
//! corresponding to configuration parameters for that environment. If a
//! configuration parameter is missing, the default value is used. The following
@ -69,7 +71,7 @@
//! [development]
//! address = "localhost"
//! port = 8000
//! workers = max(number_of_cpus, 2)
//! workers = [number_of_cpus * 2]
//! log = "normal"
//! secret_key = [randomly generated at launch]
//! limits = { forms = 32768 }
@ -77,7 +79,7 @@
//! [staging]
//! address = "0.0.0.0"
//! port = 80
//! workers = max(number_of_cpus, 2)
//! workers = [number_of_cpus * 2]
//! log = "normal"
//! secret_key = [randomly generated at launch]
//! limits = { forms = 32768 }
@ -85,7 +87,7 @@
//! [production]
//! address = "0.0.0.0"
//! port = 80
//! workers = max(number_of_cpus, 2)
//! workers = [number_of_cpus * 2]
//! log = "critical"
//! secret_key = [randomly generated at launch]
//! limits = { forms = 32768 }
@ -115,6 +117,19 @@
//! address = "0.0.0.0"
//! ```
//!
//! ### TLS Configuration
//!
//! TLS can be enabled by specifying the `tls.key` and `tls.certs` parameters.
//! Rocket must be compiled with the `tls` feature enabled for the parameters to
//! take effect. The recommended way to specify the parameters is via the
//! `global` environment:
//!
//! ```toml
//! [global.tls]
//! certs = "/path/to/certs.pem"
//! key = "/path/to/key.pem"
//! ```
//!
//! ### Environment Variables
//!
//! All configuration parameters, including extras, can be overridden through
@ -142,19 +157,6 @@
//! ROCKET_DICT={key="abc",val=123}
//! ```
//!
//! ### TLS Configuration
//!
//! TLS can be enabled by specifying the `tls.key` and `tls.certs` parameters.
//! Rocket must be compiled with the `tls` feature enabled for the parameters to
//! take effect. The recommended way to specify the parameters is via the
//! `global` environment:
//!
//! ```toml
//! [global.tls]
//! certs = "/path/to/certs.pem"
//! key = "/path/to/key.pem"
//! ```
//!
//! ## Retrieving Configuration Parameters
//!
//! Configuration parameters for the currently active configuration environment

View File

@ -95,9 +95,10 @@
//!
//! ## Testing
//!
//! The [local](/rocket/local) module contains structures that are facilitate
//! unit and itegration testing of a Rocket application. The [top-level `local`
//! module documentation](/rocket/local) includes detailed examples.
//! The [local](/rocket/local) module contains structures that facilitate unit
//! and itegration testing of a Rocket application. The [top-level `local`
//! module documentation](/rocket/local) and the [testing chapter of the
//! guide](https://rocket.rs/guide/testing/#testing) include detailed examples.
#[macro_use] extern crate log;
#[macro_use] extern crate pear;

View File

@ -23,7 +23,7 @@ mod limits_tests {
fn rocket_with_forms_limit(limit: u64) -> rocket::Rocket {
let config = Config::build(Environment::Development)
.limits(Limits::default().add("forms", limit))
.limits(Limits::default().limit("forms", limit))
.unwrap();
rocket::custom(config, true).mount("/", routes![super::index])