mirror of https://github.com/rwf2/Rocket.git
Protect the session_key from external libs. Clean-up config docs.
This commit is contained in:
parent
cf9f746ee2
commit
471239c567
|
@ -1,6 +1,8 @@
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::net::ToSocketAddrs;
|
use std::net::ToSocketAddrs;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
use std::cell::RefCell;
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
use config::Environment::*;
|
use config::Environment::*;
|
||||||
use config::{self, Environment, ConfigError};
|
use config::{self, Environment, ConfigError};
|
||||||
|
@ -8,13 +10,13 @@ use config::{self, Environment, ConfigError};
|
||||||
use logger::LoggingLevel;
|
use logger::LoggingLevel;
|
||||||
use toml::Value;
|
use toml::Value;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(PartialEq)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub address: String,
|
pub address: String,
|
||||||
pub port: usize,
|
pub port: usize,
|
||||||
pub log_level: LoggingLevel,
|
pub log_level: LoggingLevel,
|
||||||
pub session_key: Option<String>,
|
|
||||||
pub env: Environment,
|
pub env: Environment,
|
||||||
|
session_key: RefCell<Option<String>>,
|
||||||
extra: HashMap<String, Value>,
|
extra: HashMap<String, Value>,
|
||||||
filename: String,
|
filename: String,
|
||||||
}
|
}
|
||||||
|
@ -41,7 +43,7 @@ impl Config {
|
||||||
address: "localhost".to_string(),
|
address: "localhost".to_string(),
|
||||||
port: 8000,
|
port: 8000,
|
||||||
log_level: LoggingLevel::Normal,
|
log_level: LoggingLevel::Normal,
|
||||||
session_key: None,
|
session_key: RefCell::new(None),
|
||||||
extra: HashMap::new(),
|
extra: HashMap::new(),
|
||||||
env: env,
|
env: env,
|
||||||
filename: filename.to_string(),
|
filename: filename.to_string(),
|
||||||
|
@ -52,7 +54,7 @@ impl Config {
|
||||||
address: "0.0.0.0".to_string(),
|
address: "0.0.0.0".to_string(),
|
||||||
port: 80,
|
port: 80,
|
||||||
log_level: LoggingLevel::Normal,
|
log_level: LoggingLevel::Normal,
|
||||||
session_key: None,
|
session_key: RefCell::new(None),
|
||||||
extra: HashMap::new(),
|
extra: HashMap::new(),
|
||||||
env: env,
|
env: env,
|
||||||
filename: filename.to_string(),
|
filename: filename.to_string(),
|
||||||
|
@ -63,7 +65,7 @@ impl Config {
|
||||||
address: "0.0.0.0".to_string(),
|
address: "0.0.0.0".to_string(),
|
||||||
port: 80,
|
port: 80,
|
||||||
log_level: LoggingLevel::Critical,
|
log_level: LoggingLevel::Critical,
|
||||||
session_key: None,
|
session_key: RefCell::new(None),
|
||||||
extra: HashMap::new(),
|
extra: HashMap::new(),
|
||||||
env: env,
|
env: env,
|
||||||
filename: filename.to_string(),
|
filename: filename.to_string(),
|
||||||
|
@ -101,7 +103,7 @@ impl Config {
|
||||||
return Err(self.bad_type(name, val, "a 192-bit base64 string"));
|
return Err(self.bad_type(name, val, "a 192-bit base64 string"));
|
||||||
}
|
}
|
||||||
|
|
||||||
self.session_key = Some(key.to_string());
|
self.session_key = RefCell::new(Some(key.to_string()));
|
||||||
} else if name == "log" {
|
} else if name == "log" {
|
||||||
let level_str = parse!(self, name, val, as_str, "a string")?;
|
let level_str = parse!(self, name, val, as_str, "a string")?;
|
||||||
self.log_level = match level_str.parse() {
|
self.log_level = match level_str.parse() {
|
||||||
|
@ -116,6 +118,16 @@ impl Config {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn take_session_key(&self) -> Option<String> {
|
||||||
|
self.session_key.borrow_mut().take()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn extras<'a>(&'a self) -> impl Iterator<Item=(&'a String, &'a Value)> {
|
||||||
|
self.extra.iter()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_str<'a>(&'a self, name: &str) -> config::Result<&'a str> {
|
pub fn get_str<'a>(&'a self, name: &str) -> config::Result<&'a str> {
|
||||||
let value = self.extra.get(name).ok_or_else(|| ConfigError::NotFound)?;
|
let value = self.extra.get(name).ok_or_else(|| ConfigError::NotFound)?;
|
||||||
parse!(self, name, value, as_str, "a string")
|
parse!(self, name, value, as_str, "a string")
|
||||||
|
@ -143,11 +155,6 @@ impl Config {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn extras<'a>(&'a self) -> impl Iterator<Item=(&'a String, &'a Value)> {
|
|
||||||
self.extra.iter()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Builder pattern below, mostly for testing.
|
// Builder pattern below, mostly for testing.
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
@ -170,7 +177,7 @@ impl Config {
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn session_key(mut self, var: String) -> Self {
|
pub fn session_key(mut self, var: String) -> Self {
|
||||||
self.session_key = Some(var);
|
self.session_key = RefCell::new(Some(var));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,3 +187,10 @@ impl Config {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Debug for Config {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(f, "Config[{}] {{ address: {}, port: {}, log_level: {:?} }}",
|
||||||
|
self.env, self.address, self.port, self.log_level)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -11,8 +11,8 @@ use std::env;
|
||||||
|
|
||||||
pub use self::error::{ConfigError, ParsingError};
|
pub use self::error::{ConfigError, ParsingError};
|
||||||
pub use self::environment::Environment;
|
pub use self::environment::Environment;
|
||||||
|
pub use self::config::Config;
|
||||||
use self::Environment::*;
|
use self::Environment::*;
|
||||||
use self::config::Config;
|
|
||||||
|
|
||||||
use toml::{self, Table};
|
use toml::{self, Table};
|
||||||
use logger::{self, LoggingLevel};
|
use logger::{self, LoggingLevel};
|
||||||
|
@ -23,7 +23,7 @@ const CONFIG_FILENAME: &'static str = "Rocket.toml";
|
||||||
|
|
||||||
pub type Result<T> = ::std::result::Result<T, ConfigError>;
|
pub type Result<T> = ::std::result::Result<T, ConfigError>;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq)]
|
||||||
pub struct RocketConfig {
|
pub struct RocketConfig {
|
||||||
pub active_env: Environment,
|
pub active_env: Environment,
|
||||||
config: HashMap<Environment, Config>,
|
config: HashMap<Environment, Config>,
|
||||||
|
@ -152,14 +152,16 @@ impl RocketConfig {
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// If there is a problem, prints a nice error message and bails.
|
/// If there is a problem, prints a nice error message and bails. This function
|
||||||
|
/// also panics if it is called more than once.
|
||||||
///
|
///
|
||||||
/// # Thread-Safety
|
/// # Thread-Safety
|
||||||
///
|
///
|
||||||
/// This function is _not_ thread-safe. It should be called by a single thread.
|
/// This function is _not_ thread-safe. It should be called by a single thread.
|
||||||
|
#[doc(hidden)]
|
||||||
pub fn init() -> &'static Config {
|
pub fn init() -> &'static Config {
|
||||||
if let Some(config) = active() {
|
if active().is_some() {
|
||||||
return config;
|
panic!("Configuration has already been initialized!")
|
||||||
}
|
}
|
||||||
|
|
||||||
let bail = |e: ConfigError| -> ! {
|
let bail = |e: ConfigError| -> ! {
|
||||||
|
@ -192,6 +194,7 @@ pub fn init() -> &'static Config {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Retrieve the active configuration, if there is one.
|
||||||
pub fn active() -> Option<&'static Config> {
|
pub fn active() -> Option<&'static Config> {
|
||||||
unsafe { CONFIG.as_ref().map(|c| c.active()) }
|
unsafe { CONFIG.as_ref().map(|c| c.active()) }
|
||||||
}
|
}
|
||||||
|
@ -225,9 +228,9 @@ mod test {
|
||||||
);
|
);
|
||||||
|
|
||||||
($env:expr, $rconfig:expr, $econfig:expr) => (
|
($env:expr, $rconfig:expr, $econfig:expr) => (
|
||||||
match $rconfig.clone() {
|
match $rconfig {
|
||||||
Ok(config) => assert_eq!(config.get($env), &$econfig),
|
Ok(ref config) => assert_eq!(config.get($env), &$econfig),
|
||||||
Err(e) => panic!("Config {} failed: {:?}", stringify!($rconfig), e)
|
Err(ref e) => panic!("Config {} failed: {:?}", stringify!($rconfig), e)
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -306,11 +309,12 @@ mod test {
|
||||||
pi = 3.14
|
pi = 3.14
|
||||||
"#;
|
"#;
|
||||||
|
|
||||||
let mut expected = default_config(Development);
|
let mut expected = default_config(Development)
|
||||||
expected.address = "1.2.3.4".to_string();
|
.address("1.2.3.4".to_string())
|
||||||
expected.port = 7810;
|
.port(7810)
|
||||||
expected.log_level = LoggingLevel::Critical;
|
.log_level(LoggingLevel::Critical)
|
||||||
expected.session_key = Some("01234567890123456789012345678901".to_string());
|
.session_key("01234567890123456789012345678901".into());
|
||||||
|
|
||||||
expected.set("template_dir", &Value::String("mine".into())).unwrap();
|
expected.set("template_dir", &Value::String("mine".into())).unwrap();
|
||||||
expected.set("json", &Value::Boolean(true)).unwrap();
|
expected.set("json", &Value::Boolean(true)).unwrap();
|
||||||
expected.set("pi", &Value::Float(3.14)).unwrap();
|
expected.set("pi", &Value::Float(3.14)).unwrap();
|
||||||
|
|
|
@ -235,7 +235,7 @@ impl Rocket {
|
||||||
White.paint(&config.address),
|
White.paint(&config.address),
|
||||||
White.paint(&config.port));
|
White.paint(&config.port));
|
||||||
info_!("logging: {:?}", White.paint(config.log_level));
|
info_!("logging: {:?}", White.paint(config.log_level));
|
||||||
info_!("session key: {}", White.paint(config.session_key.is_some()));
|
info_!("session key: {}", White.paint(config.take_session_key().is_some()));
|
||||||
for (name, value) in config.extras() {
|
for (name, value) in config.extras() {
|
||||||
info_!("{} {}: {}", Yellow.paint("[extra]"), name, White.paint(value));
|
info_!("{} {}: {}", Yellow.paint("[extra]"), name, White.paint(value));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue