mirror of https://github.com/rwf2/Rocket.git
Introduce the 'private-cookies' feature.
This commit is contained in:
parent
b16269a30e
commit
53758c6dd7
|
@ -6,6 +6,7 @@ env:
|
||||||
- TEST_FLAGS=
|
- TEST_FLAGS=
|
||||||
- TEST_FLAGS=--release
|
- TEST_FLAGS=--release
|
||||||
- TEST_FLAGS=--contrib
|
- TEST_FLAGS=--contrib
|
||||||
|
- TEST_FLAGS=--core
|
||||||
rust:
|
rust:
|
||||||
- nightly
|
- nightly
|
||||||
script: ./scripts/test.sh $TEST_FLAGS
|
script: ./scripts/test.sh $TEST_FLAGS
|
||||||
|
|
|
@ -15,6 +15,7 @@ categories = ["web-programming"]
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
tls = ["rustls", "hyper-sync-rustls"]
|
tls = ["rustls", "hyper-sync-rustls"]
|
||||||
|
private-cookies = ["cookie/secure"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
smallvec = "0.6"
|
smallvec = "0.6"
|
||||||
|
@ -24,7 +25,7 @@ time = "0.1"
|
||||||
indexmap = "1.0"
|
indexmap = "1.0"
|
||||||
rustls = { version = "0.14", optional = true }
|
rustls = { version = "0.14", optional = true }
|
||||||
state = "0.4"
|
state = "0.4"
|
||||||
cookie = { version = "0.11", features = ["percent-encode", "secure"] }
|
cookie = { version = "0.11", features = ["percent-encode"] }
|
||||||
pear = "0.1"
|
pear = "0.1"
|
||||||
unicode-xid = "0.1"
|
unicode-xid = "0.1"
|
||||||
|
|
||||||
|
|
|
@ -2,10 +2,16 @@ use std::fmt;
|
||||||
use std::cell::RefMut;
|
use std::cell::RefMut;
|
||||||
|
|
||||||
use cookie::Delta;
|
use cookie::Delta;
|
||||||
pub use cookie::{Cookie, Key, CookieJar, SameSite};
|
pub use cookie::{Cookie, CookieJar, SameSite};
|
||||||
|
|
||||||
|
#[cfg(feature = "private-cookies")]
|
||||||
|
pub use cookie::Key;
|
||||||
|
|
||||||
use Header;
|
use Header;
|
||||||
|
|
||||||
|
#[cfg(not(feature = "private-cookies"))]
|
||||||
|
type Key = ();
|
||||||
|
|
||||||
/// Collection of one or more HTTP cookies.
|
/// Collection of one or more HTTP cookies.
|
||||||
///
|
///
|
||||||
/// The `Cookies` type allows for retrieval of cookies from an incoming request
|
/// The `Cookies` type allows for retrieval of cookies from an incoming request
|
||||||
|
@ -166,28 +172,6 @@ impl<'a> Cookies<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a reference to the `Cookie` inside this collection with the name
|
|
||||||
/// `name` and authenticates and decrypts the cookie's value, returning a
|
|
||||||
/// `Cookie` with the decrypted value. If the cookie cannot be found, or the
|
|
||||||
/// cookie fails to authenticate or decrypt, `None` is returned.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```rust
|
|
||||||
/// # extern crate rocket;
|
|
||||||
/// use rocket::http::Cookies;
|
|
||||||
///
|
|
||||||
/// fn handler(mut cookies: Cookies) {
|
|
||||||
/// let cookie = cookies.get_private("name");
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
pub fn get_private(&mut self, name: &str) -> Option<Cookie<'static>> {
|
|
||||||
match *self {
|
|
||||||
Cookies::Jarred(ref mut jar, key) => jar.private(key).get(name),
|
|
||||||
Cookies::Empty(_) => None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Adds `cookie` to this collection.
|
/// Adds `cookie` to this collection.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
|
@ -213,6 +197,90 @@ impl<'a> Cookies<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Removes `cookie` from this collection and generates a "removal" cookies
|
||||||
|
/// to send to the client on response. For correctness, `cookie` must
|
||||||
|
/// contain the same `path` and `domain` as the cookie that was initially
|
||||||
|
/// set. Failure to provide the initial `path` and `domain` will result in
|
||||||
|
/// cookies that are not properly removed.
|
||||||
|
///
|
||||||
|
/// A "removal" cookie is a cookie that has the same name as the original
|
||||||
|
/// cookie but has an empty value, a max-age of 0, and an expiration date
|
||||||
|
/// far in the past.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// # extern crate rocket;
|
||||||
|
/// use rocket::http::{Cookie, Cookies};
|
||||||
|
///
|
||||||
|
/// fn handler(mut cookies: Cookies) {
|
||||||
|
/// cookies.remove(Cookie::named("name"));
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
pub fn remove(&mut self, cookie: Cookie<'static>) {
|
||||||
|
if let Cookies::Jarred(ref mut jar, _) = *self {
|
||||||
|
jar.remove(cookie)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns an iterator over all of the cookies present in this collection.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// # extern crate rocket;
|
||||||
|
/// use rocket::http::Cookies;
|
||||||
|
///
|
||||||
|
/// fn handler(cookies: Cookies) {
|
||||||
|
/// for c in cookies.iter() {
|
||||||
|
/// println!("Name: '{}', Value: '{}'", c.name(), c.value());
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
pub fn iter(&self) -> impl Iterator<Item=&Cookie<'static>> {
|
||||||
|
match *self {
|
||||||
|
Cookies::Jarred(ref jar, _) => jar.iter(),
|
||||||
|
Cookies::Empty(ref jar) => jar.iter()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// WARNING: This is unstable! Do not use this method outside of Rocket!
|
||||||
|
#[doc(hidden)]
|
||||||
|
#[inline]
|
||||||
|
pub fn delta(&self) -> Delta {
|
||||||
|
match *self {
|
||||||
|
Cookies::Jarred(ref jar, _) => jar.delta(),
|
||||||
|
Cookies::Empty(ref jar) => jar.delta()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "private-cookies")]
|
||||||
|
impl<'a> Cookies<'a> {
|
||||||
|
/// Returns a reference to the `Cookie` inside this collection with the name
|
||||||
|
/// `name` and authenticates and decrypts the cookie's value, returning a
|
||||||
|
/// `Cookie` with the decrypted value. If the cookie cannot be found, or the
|
||||||
|
/// cookie fails to authenticate or decrypt, `None` is returned.
|
||||||
|
///
|
||||||
|
/// This method is only available when the `private-cookies` feature is enabled.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// # extern crate rocket;
|
||||||
|
/// use rocket::http::Cookies;
|
||||||
|
///
|
||||||
|
/// fn handler(mut cookies: Cookies) {
|
||||||
|
/// let cookie = cookies.get_private("name");
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
pub fn get_private(&mut self, name: &str) -> Option<Cookie<'static>> {
|
||||||
|
match *self {
|
||||||
|
Cookies::Jarred(ref mut jar, key) => jar.private(key).get(name),
|
||||||
|
Cookies::Empty(_) => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Adds `cookie` to the collection. The cookie's value is encrypted with
|
/// Adds `cookie` to the collection. The cookie's value is encrypted with
|
||||||
/// authenticated encryption assuring confidentiality, integrity, and
|
/// authenticated encryption assuring confidentiality, integrity, and
|
||||||
/// authenticity. The cookie can later be retrieved using
|
/// authenticity. The cookie can later be retrieved using
|
||||||
|
@ -230,6 +298,8 @@ impl<'a> Cookies<'a> {
|
||||||
/// These defaults ensure maximum usability and security. For additional
|
/// These defaults ensure maximum usability and security. For additional
|
||||||
/// security, you may wish to set the `secure` flag.
|
/// security, you may wish to set the `secure` flag.
|
||||||
///
|
///
|
||||||
|
/// This method is only available when the `private-cookies` feature is enabled.
|
||||||
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
|
@ -267,6 +337,8 @@ impl<'a> Cookies<'a> {
|
||||||
/// * `HttpOnly`: `true`
|
/// * `HttpOnly`: `true`
|
||||||
/// * `Expires`: 1 week from now
|
/// * `Expires`: 1 week from now
|
||||||
///
|
///
|
||||||
|
/// This method is only available when the `private-cookies` feature is enabled.
|
||||||
|
///
|
||||||
fn set_private_defaults(cookie: &mut Cookie<'static>) {
|
fn set_private_defaults(cookie: &mut Cookie<'static>) {
|
||||||
if cookie.path().is_none() {
|
if cookie.path().is_none() {
|
||||||
cookie.set_path("/");
|
cookie.set_path("/");
|
||||||
|
@ -285,38 +357,14 @@ impl<'a> Cookies<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Removes `cookie` from this collection and generates a "removal" cookies
|
|
||||||
/// to send to the client on response. For correctness, `cookie` must
|
|
||||||
/// contain the same `path` and `domain` as the cookie that was initially
|
|
||||||
/// set. Failure to provide the initial `path` and `domain` will result in
|
|
||||||
/// cookies that are not properly removed.
|
|
||||||
///
|
|
||||||
/// A "removal" cookie is a cookie that has the same name as the original
|
|
||||||
/// cookie but has an empty value, a max-age of 0, and an expiration date
|
|
||||||
/// far in the past.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```rust
|
|
||||||
/// # extern crate rocket;
|
|
||||||
/// use rocket::http::{Cookie, Cookies};
|
|
||||||
///
|
|
||||||
/// fn handler(mut cookies: Cookies) {
|
|
||||||
/// cookies.remove(Cookie::named("name"));
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
pub fn remove(&mut self, cookie: Cookie<'static>) {
|
|
||||||
if let Cookies::Jarred(ref mut jar, _) = *self {
|
|
||||||
jar.remove(cookie)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Removes the private `cookie` from the collection.
|
/// Removes the private `cookie` from the collection.
|
||||||
///
|
///
|
||||||
/// For correct removal, the passed in `cookie` must contain the same `path`
|
/// For correct removal, the passed in `cookie` must contain the same `path`
|
||||||
/// and `domain` as the cookie that was initially set. If a path is not set
|
/// and `domain` as the cookie that was initially set. If a path is not set
|
||||||
/// on `cookie`, the `"/"` path will automatically be set.
|
/// on `cookie`, the `"/"` path will automatically be set.
|
||||||
///
|
///
|
||||||
|
/// This method is only available when the `private-cookies` feature is enabled.
|
||||||
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
|
@ -336,37 +384,6 @@ impl<'a> Cookies<'a> {
|
||||||
jar.private(key).remove(cookie)
|
jar.private(key).remove(cookie)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns an iterator over all of the cookies present in this collection.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```rust
|
|
||||||
/// # extern crate rocket;
|
|
||||||
/// use rocket::http::Cookies;
|
|
||||||
///
|
|
||||||
/// fn handler(cookies: Cookies) {
|
|
||||||
/// for c in cookies.iter() {
|
|
||||||
/// println!("Name: '{}', Value: '{}'", c.name(), c.value());
|
|
||||||
/// }
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
pub fn iter(&self) -> impl Iterator<Item=&Cookie<'static>> {
|
|
||||||
match *self {
|
|
||||||
Cookies::Jarred(ref jar, _) => jar.iter(),
|
|
||||||
Cookies::Empty(ref jar) => jar.iter()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// WARNING: This is unstable! Do not use this method outside of Rocket!
|
|
||||||
#[doc(hidden)]
|
|
||||||
#[inline]
|
|
||||||
pub fn delta(&self) -> Delta {
|
|
||||||
match *self {
|
|
||||||
Cookies::Jarred(ref jar, _) => jar.delta(),
|
|
||||||
Cookies::Empty(ref jar) => jar.delta()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> fmt::Debug for Cookies<'a> {
|
impl<'a> fmt::Debug for Cookies<'a> {
|
||||||
|
|
|
@ -59,7 +59,8 @@ pub mod uncased;
|
||||||
#[doc(hidden)] pub use smallvec::{SmallVec, Array};
|
#[doc(hidden)] pub use smallvec::{SmallVec, Array};
|
||||||
|
|
||||||
// This one we need to expose for core.
|
// This one we need to expose for core.
|
||||||
#[doc(hidden)] pub use cookies::{Key, CookieJar};
|
#[doc(hidden)] pub use cookies::CookieJar;
|
||||||
|
#[doc(hidden)] #[cfg(feature = "private-cookies")] pub use cookies::Key;
|
||||||
|
|
||||||
pub use method::Method;
|
pub use method::Method;
|
||||||
pub use content_type::ContentType;
|
pub use content_type::ContentType;
|
||||||
|
|
|
@ -16,6 +16,7 @@ categories = ["web-programming::http-server"]
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
tls = ["rocket_http/tls"]
|
tls = ["rocket_http/tls"]
|
||||||
|
private-cookies = ["rocket_http/private-cookies"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
rocket_codegen = { version = "0.4.0-rc.1", path = "../codegen" }
|
rocket_codegen = { version = "0.4.0-rc.1", path = "../codegen" }
|
||||||
|
|
|
@ -10,7 +10,8 @@ use {num_cpus, base64};
|
||||||
use config::Environment::*;
|
use config::Environment::*;
|
||||||
use config::{Result, ConfigBuilder, Environment, ConfigError, LoggingLevel};
|
use config::{Result, ConfigBuilder, Environment, ConfigError, LoggingLevel};
|
||||||
use config::{Table, Value, Array, Datetime};
|
use config::{Table, Value, Array, Datetime};
|
||||||
use http::Key;
|
|
||||||
|
#[cfg(feature = "private-cookies")] use http::Key;
|
||||||
|
|
||||||
/// Structure for Rocket application configuration.
|
/// Structure for Rocket application configuration.
|
||||||
///
|
///
|
||||||
|
@ -49,6 +50,7 @@ pub struct Config {
|
||||||
/// How much information to log.
|
/// How much information to log.
|
||||||
pub log_level: LoggingLevel,
|
pub log_level: LoggingLevel,
|
||||||
/// The secret key.
|
/// The secret key.
|
||||||
|
#[cfg(feature = "private-cookies")]
|
||||||
crate secret_key: SecretKey,
|
crate secret_key: SecretKey,
|
||||||
/// TLS configuration.
|
/// TLS configuration.
|
||||||
crate tls: Option<TlsConfig>,
|
crate tls: Option<TlsConfig>,
|
||||||
|
@ -231,6 +233,7 @@ impl Config {
|
||||||
let default_workers = (num_cpus::get() * 2) as u16;
|
let default_workers = (num_cpus::get() * 2) as u16;
|
||||||
|
|
||||||
// Use a generated secret key by default.
|
// Use a generated secret key by default.
|
||||||
|
#[cfg(feature = "private-cookies")]
|
||||||
let key = SecretKey::Generated(Key::generate());
|
let key = SecretKey::Generated(Key::generate());
|
||||||
|
|
||||||
Ok(match env {
|
Ok(match env {
|
||||||
|
@ -242,6 +245,7 @@ impl Config {
|
||||||
workers: default_workers,
|
workers: default_workers,
|
||||||
keep_alive: Some(5),
|
keep_alive: Some(5),
|
||||||
log_level: LoggingLevel::Normal,
|
log_level: LoggingLevel::Normal,
|
||||||
|
#[cfg(feature = "private-cookies")]
|
||||||
secret_key: key,
|
secret_key: key,
|
||||||
tls: None,
|
tls: None,
|
||||||
limits: Limits::default(),
|
limits: Limits::default(),
|
||||||
|
@ -257,6 +261,7 @@ impl Config {
|
||||||
workers: default_workers,
|
workers: default_workers,
|
||||||
keep_alive: Some(5),
|
keep_alive: Some(5),
|
||||||
log_level: LoggingLevel::Normal,
|
log_level: LoggingLevel::Normal,
|
||||||
|
#[cfg(feature = "private-cookies")]
|
||||||
secret_key: key,
|
secret_key: key,
|
||||||
tls: None,
|
tls: None,
|
||||||
limits: Limits::default(),
|
limits: Limits::default(),
|
||||||
|
@ -272,6 +277,7 @@ impl Config {
|
||||||
workers: default_workers,
|
workers: default_workers,
|
||||||
keep_alive: Some(5),
|
keep_alive: Some(5),
|
||||||
log_level: LoggingLevel::Critical,
|
log_level: LoggingLevel::Critical,
|
||||||
|
#[cfg(feature = "private-cookies")]
|
||||||
secret_key: key,
|
secret_key: key,
|
||||||
tls: None,
|
tls: None,
|
||||||
limits: Limits::default(),
|
limits: Limits::default(),
|
||||||
|
@ -473,6 +479,7 @@ impl Config {
|
||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
|
#[cfg(feature = "private-cookies")]
|
||||||
pub fn set_secret_key<K: Into<String>>(&mut self, key: K) -> Result<()> {
|
pub fn set_secret_key<K: Into<String>>(&mut self, key: K) -> Result<()> {
|
||||||
let key = key.into();
|
let key = key.into();
|
||||||
let error = self.bad_type("secret_key", "string",
|
let error = self.bad_type("secret_key", "string",
|
||||||
|
@ -490,6 +497,10 @@ impl Config {
|
||||||
self.secret_key = SecretKey::Provided(Key::from_master(&bytes));
|
self.secret_key = SecretKey::Provided(Key::from_master(&bytes));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
#[cfg(not(feature = "private-cookies"))]
|
||||||
|
pub fn set_secret_key<K: Into<String>>(&mut self, key: K) -> Result<()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Sets the logging level for `self` to `log_level`.
|
/// Sets the logging level for `self` to `log_level`.
|
||||||
///
|
///
|
||||||
|
@ -663,6 +674,7 @@ impl Config {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Retrieves the secret key from `self`.
|
/// Retrieves the secret key from `self`.
|
||||||
|
#[cfg(feature = "private-cookies")]
|
||||||
#[inline]
|
#[inline]
|
||||||
crate fn secret_key(&self) -> &Key {
|
crate fn secret_key(&self) -> &Key {
|
||||||
self.secret_key.inner()
|
self.secret_key.inner()
|
||||||
|
|
|
@ -3,14 +3,17 @@ use std::fmt;
|
||||||
#[cfg(feature = "tls")] use http::tls::{Certificate, PrivateKey};
|
#[cfg(feature = "tls")] use http::tls::{Certificate, PrivateKey};
|
||||||
|
|
||||||
use config::{Result, Config, Value, ConfigError, LoggingLevel};
|
use config::{Result, Config, Value, ConfigError, LoggingLevel};
|
||||||
use http::Key;
|
|
||||||
|
|
||||||
|
#[cfg(feature = "private-cookies")] use http::Key;
|
||||||
|
|
||||||
|
#[cfg(feature = "private-cookies")]
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub enum SecretKey {
|
pub enum SecretKey {
|
||||||
Generated(Key),
|
Generated(Key),
|
||||||
Provided(Key)
|
Provided(Key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "private-cookies")]
|
||||||
impl SecretKey {
|
impl SecretKey {
|
||||||
#[inline]
|
#[inline]
|
||||||
crate fn inner(&self) -> &Key {
|
crate fn inner(&self) -> &Key {
|
||||||
|
@ -28,6 +31,7 @@ impl SecretKey {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "private-cookies")]
|
||||||
impl fmt::Display for SecretKey {
|
impl fmt::Display for SecretKey {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match *self {
|
match *self {
|
||||||
|
|
|
@ -269,6 +269,8 @@ impl<'c> LocalRequest<'c> {
|
||||||
///
|
///
|
||||||
/// [private cookie]: ::http::Cookies::add_private()
|
/// [private cookie]: ::http::Cookies::add_private()
|
||||||
///
|
///
|
||||||
|
/// This method is only available when the `private-cookies` feature is enabled.
|
||||||
|
///
|
||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// Add `user_id` as a private cookie:
|
/// Add `user_id` as a private cookie:
|
||||||
|
@ -281,6 +283,7 @@ impl<'c> LocalRequest<'c> {
|
||||||
/// # #[allow(unused_variables)]
|
/// # #[allow(unused_variables)]
|
||||||
/// let req = client.get("/").private_cookie(Cookie::new("user_id", "sb"));
|
/// let req = client.get("/").private_cookie(Cookie::new("user_id", "sb"));
|
||||||
/// ```
|
/// ```
|
||||||
|
#[cfg(feature = "private-cookies")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn private_cookie(self, cookie: Cookie<'static>) -> Self {
|
pub fn private_cookie(self, cookie: Cookie<'static>) -> Self {
|
||||||
self.request.cookies().add_original_private(cookie);
|
self.request.cookies().add_original_private(cookie);
|
||||||
|
|
|
@ -290,7 +290,10 @@ impl<'r> Request<'r> {
|
||||||
pub fn cookies(&self) -> Cookies {
|
pub fn cookies(&self) -> Cookies {
|
||||||
// FIXME: Can we do better? This is disappointing.
|
// FIXME: Can we do better? This is disappointing.
|
||||||
match self.state.cookies.try_borrow_mut() {
|
match self.state.cookies.try_borrow_mut() {
|
||||||
|
#[cfg(feature = "private-cookies")]
|
||||||
Ok(jar) => Cookies::new(jar, self.state.config.secret_key()),
|
Ok(jar) => Cookies::new(jar, self.state.config.secret_key()),
|
||||||
|
#[cfg(not(feature = "private-cookies"))]
|
||||||
|
Ok(jar) => Cookies::new(jar, &()),
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
error_!("Multiple `Cookies` instances are active at once.");
|
error_!("Multiple `Cookies` instances are active at once.");
|
||||||
info_!("An instance of `Cookies` must be dropped before another \
|
info_!("An instance of `Cookies` must be dropped before another \
|
||||||
|
|
|
@ -396,6 +396,7 @@ impl Rocket {
|
||||||
launch_info_!("port: {}", Paint::white(&config.port));
|
launch_info_!("port: {}", Paint::white(&config.port));
|
||||||
launch_info_!("log: {}", Paint::white(config.log_level));
|
launch_info_!("log: {}", Paint::white(config.log_level));
|
||||||
launch_info_!("workers: {}", Paint::white(config.workers));
|
launch_info_!("workers: {}", Paint::white(config.workers));
|
||||||
|
#[cfg(feature = "private-cookies")]
|
||||||
launch_info_!("secret key: {}", Paint::white(&config.secret_key));
|
launch_info_!("secret key: {}", Paint::white(&config.secret_key));
|
||||||
launch_info_!("limits: {}", Paint::white(&config.limits));
|
launch_info_!("limits: {}", Paint::white(&config.limits));
|
||||||
|
|
||||||
|
@ -414,8 +415,10 @@ impl Rocket {
|
||||||
launch_info_!("tls: {}", Paint::white("disabled"));
|
launch_info_!("tls: {}", Paint::white("disabled"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.secret_key.is_generated() && config.environment.is_prod() {
|
#[cfg(feature = "private-cookies")] {
|
||||||
warn!("environment is 'production', but no `secret_key` is configured");
|
if config.secret_key.is_generated() && config.environment.is_prod() {
|
||||||
|
warn!("environment is 'production', but no `secret_key` is configured");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (name, value) in config.extras() {
|
for (name, value) in config.extras() {
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
use rocket::http::Cookies;
|
use rocket::http::Cookies;
|
||||||
|
|
||||||
|
#[cfg(feature = "private-cookies")]
|
||||||
#[get("/")]
|
#[get("/")]
|
||||||
fn return_private_cookie(mut cookies: Cookies) -> Option<String> {
|
fn return_private_cookie(mut cookies: Cookies) -> Option<String> {
|
||||||
match cookies.get_private("cookie_name") {
|
match cookies.get_private("cookie_name") {
|
||||||
|
@ -12,6 +13,7 @@ fn return_private_cookie(mut cookies: Cookies) -> Option<String> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "private-cookies")]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use rocket::local::Client;
|
use rocket::local::Client;
|
||||||
|
|
|
@ -5,7 +5,7 @@ workspace = "../../"
|
||||||
publish = false
|
publish = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
rocket = { path = "../../core/lib" }
|
rocket = { path = "../../core/lib", features = ["private-cookies"] }
|
||||||
|
|
||||||
[dependencies.rocket_contrib]
|
[dependencies.rocket_contrib]
|
||||||
path = "../../contrib/lib"
|
path = "../../contrib/lib"
|
||||||
|
|
|
@ -107,6 +107,26 @@ if [ "$1" = "--contrib" ]; then
|
||||||
CARGO_INCREMENTAL=0 cargo test --no-default-features --features "${feature}"
|
CARGO_INCREMENTAL=0 cargo test --no-default-features --features "${feature}"
|
||||||
done
|
done
|
||||||
|
|
||||||
|
popd > /dev/null 2>&1
|
||||||
|
elif [ "$1" = "--core" ]; then
|
||||||
|
FEATURES=(
|
||||||
|
private-cookies
|
||||||
|
tls
|
||||||
|
)
|
||||||
|
|
||||||
|
pushd "${CORE_ROOT}" > /dev/null 2>&1
|
||||||
|
|
||||||
|
echo ":: Building and testing core [no features]..."
|
||||||
|
CARGO_INCREMENTAL=0 cargo test --no-default-features
|
||||||
|
|
||||||
|
echo ":: Building and testing core [default]..."
|
||||||
|
CARGO_INCREMENTAL=0 cargo test
|
||||||
|
|
||||||
|
for feature in "${FEATURES[@]}"; do
|
||||||
|
echo ":: Building and testing core [${feature}]..."
|
||||||
|
CARGO_INCREMENTAL=0 cargo test --no-default-features --features "${feature}"
|
||||||
|
done
|
||||||
|
|
||||||
popd > /dev/null 2>&1
|
popd > /dev/null 2>&1
|
||||||
else
|
else
|
||||||
echo ":: Bootstrapping examples..."
|
echo ":: Bootstrapping examples..."
|
||||||
|
|
|
@ -503,6 +503,15 @@ fn logout(mut cookies: Cookies) -> Flash<Redirect> {
|
||||||
|
|
||||||
[`Cookies::add()`]: @api/rocket/http/enum.Cookies.html#method.add
|
[`Cookies::add()`]: @api/rocket/http/enum.Cookies.html#method.add
|
||||||
|
|
||||||
|
Private Cookies can be omitted at build time by excluding the feature
|
||||||
|
`private-cookies`. You can do this by setting the `default-features`
|
||||||
|
directive to `false` in your `Cargo.toml`:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[dependencies.rocket]
|
||||||
|
default-features = false
|
||||||
|
```
|
||||||
|
|
||||||
### Secret Key
|
### Secret Key
|
||||||
|
|
||||||
To encrypt private cookies, Rocket uses the 256-bit key specified in the
|
To encrypt private cookies, Rocket uses the 256-bit key specified in the
|
||||||
|
|
Loading…
Reference in New Issue