Skip to content

Commit

Permalink
Clean up and complete PR.
Browse files Browse the repository at this point in the history
  • Loading branch information
SergioBenitez committed Dec 16, 2023
1 parent d1e8bc4 commit bfe6ece
Show file tree
Hide file tree
Showing 9 changed files with 184 additions and 150 deletions.
22 changes: 12 additions & 10 deletions core/http/src/header/proxy_proto.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,25 @@
use std::fmt;

use uncased::{UncasedStr, AsUncased};

/// A protocol used to identify a specific protocol forwarded by an HTTP proxy.
// Names are case-insensitive
/// Value are case-insensitive.
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum ProxyProto<'a> {
/// `http` value, Hypertext Transfer Protocol
/// `http` value, Hypertext Transfer Protocol.
Http,
/// `https` value, Hypertext Transfer Protocol Secure
/// `https` value, Hypertext Transfer Protocol Secure.
Https,
/// Any other protocol name not known to us
Unknown(&'a uncased::UncasedStr),
/// Any protocol name other than `http` or `https`.
Unknown(&'a UncasedStr),
}

impl<'a> From<&'a str> for ProxyProto<'a> {
fn from(s: &'a str) -> ProxyProto<'a> {
match s.to_lowercase().as_str() {
"http" => ProxyProto::Http,
"https" => ProxyProto::Https,
_ => ProxyProto::Unknown(s.into()),
fn from(value: &'a str) -> ProxyProto<'a> {
match value.as_uncased() {
v if v == "http" => ProxyProto::Http,
v if v == "https" => ProxyProto::Https,
v => ProxyProto::Unknown(v)
}
}
}
Expand Down
10 changes: 6 additions & 4 deletions core/lib/src/config/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,9 @@ impl Config {
/// The stringy parameter name for setting/extracting [`Config::ip_header`].
pub const IP_HEADER: &'static str = "ip_header";

/// The stringy parameter name for setting/extracting [`Config::proxy_proto_header`].
pub const PROXY_PROTO_HEADER: &'static str = "proxy_proto_header";

/// The stringy parameter name for setting/extracting [`Config::limits`].
pub const LIMITS: &'static str = "limits";

Expand All @@ -557,10 +560,9 @@ impl Config {

/// An array of all of the stringy parameter names.
pub const PARAMETERS: &'static [&'static str] = &[
Self::ADDRESS, Self::PORT, Self::WORKERS, Self::MAX_BLOCKING,
Self::KEEP_ALIVE, Self::IDENT, Self::IP_HEADER, Self::LIMITS, Self::TLS,
Self::SECRET_KEY, Self::TEMP_DIR, Self::LOG_LEVEL, Self::SHUTDOWN,
Self::CLI_COLORS,
Self::ADDRESS, Self::PORT, Self::WORKERS, Self::MAX_BLOCKING, Self::KEEP_ALIVE,
Self::IDENT, Self::IP_HEADER, Self::PROXY_PROTO_HEADER, Self::LIMITS, Self::TLS,
Self::SECRET_KEY, Self::TEMP_DIR, Self::LOG_LEVEL, Self::SHUTDOWN, Self::CLI_COLORS,
];
}

Expand Down
90 changes: 48 additions & 42 deletions core/lib/src/cookies.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ use std::fmt;

use parking_lot::Mutex;

use crate::Config;
use crate::http::private::cookie;

#[doc(inline)]
Expand Down Expand Up @@ -154,19 +153,14 @@ pub use self::cookie::{Cookie, SameSite, Iter};
pub struct CookieJar<'a> {
jar: cookie::CookieJar,
ops: Mutex<Vec<Op>>,
config: &'a Config,
secure_context: bool,
pub(crate) state: CookieState<'a>,
}

impl<'a> Clone for CookieJar<'a> {
fn clone(&self) -> Self {
CookieJar {
jar: self.jar.clone(),
ops: Mutex::new(self.ops.lock().clone()),
config: self.config,
secure_context: self.secure_context,
}
}
#[derive(Copy, Clone)]
pub(crate) struct CookieState<'a> {
pub secure: bool,
#[cfg_attr(not(feature = "secrets"), allow(unused))]
pub config: &'a crate::Config,
}

#[derive(Clone)]
Expand All @@ -175,30 +169,12 @@ enum Op {
Remove(Cookie<'static>, bool),
}

impl Op {
fn cookie(&self) -> &Cookie<'static> {
match self {
Op::Add(c, _) | Op::Remove(c, _) => c
}
}
}

impl<'a> CookieJar<'a> {
#[inline(always)]
pub(crate) fn new(config: &'a Config, secure_context: bool) -> Self {
CookieJar::from(cookie::CookieJar::new(), config, secure_context)
}

pub(crate) fn from(
jar: cookie::CookieJar,
config: &'a Config,
secure_context: bool,
) -> Self {
pub(crate) fn new(base: Option<cookie::CookieJar>, state: impl Into<CookieState<'a>>) -> Self {
CookieJar {
jar,
config,
jar: base.unwrap_or_default(),
ops: Mutex::new(Vec::new()),
secure_context,
state: state.into(),
}
}

Expand Down Expand Up @@ -247,7 +223,7 @@ impl<'a> CookieJar<'a> {
#[cfg(feature = "secrets")]
#[cfg_attr(nightly, doc(cfg(feature = "secrets")))]
pub fn get_private(&self, name: &str) -> Option<Cookie<'static>> {
self.jar.private(&self.config.secret_key.key).get(name)
self.jar.private(&self.state.config.secret_key.key).get(name)
}

/// Returns a reference to the _original or pending_ `Cookie` inside this
Expand Down Expand Up @@ -320,7 +296,7 @@ impl<'a> CookieJar<'a> {
/// ```
pub fn add<C: Into<Cookie<'static>>>(&self, cookie: C) {
let mut cookie = cookie.into();
Self::set_defaults(self.secure_context, &mut cookie);
self.set_defaults(&mut cookie);
self.ops.lock().push(Op::Add(cookie, false));
}

Expand Down Expand Up @@ -357,7 +333,7 @@ impl<'a> CookieJar<'a> {
#[cfg_attr(nightly, doc(cfg(feature = "secrets")))]
pub fn add_private<C: Into<Cookie<'static>>>(&self, cookie: C) {
let mut cookie = cookie.into();
Self::set_private_defaults(self.secure_context, &mut cookie);
self.set_private_defaults(&mut cookie);
self.ops.lock().push(Op::Add(cookie, true));
}

Expand Down Expand Up @@ -487,7 +463,7 @@ impl<'a> CookieJar<'a> {
Op::Add(c, false) => jar.add(c),
#[cfg(feature = "secrets")]
Op::Add(c, true) => {
jar.private_mut(&self.config.secret_key.key).add(c);
jar.private_mut(&self.state.config.secret_key.key).add(c);
}
Op::Remove(mut c, _) => {
if self.jar.get(c.name()).is_some() {
Expand Down Expand Up @@ -516,7 +492,7 @@ impl<'a> CookieJar<'a> {
#[cfg_attr(nightly, doc(cfg(feature = "secrets")))]
#[inline(always)]
pub(crate) fn add_original_private(&mut self, cookie: Cookie<'static>) {
self.jar.private_mut(&self.config.secret_key.key).add_original(cookie);
self.jar.private_mut(&self.state.config.secret_key.key).add_original(cookie);
}

/// For each property mentioned below, this method checks if there is a
Expand All @@ -528,7 +504,7 @@ impl<'a> CookieJar<'a> {
///
/// Furthermore, if TLS is enabled or handled by a proxy, the `Secure`
/// cookie flag is set.
fn set_defaults(secure_context: bool, cookie: &mut Cookie<'static>) {
fn set_defaults(&self, cookie: &mut Cookie<'static>) {
if cookie.path().is_none() {
cookie.set_path("/");
}
Expand All @@ -537,7 +513,7 @@ impl<'a> CookieJar<'a> {
cookie.set_same_site(SameSite::Strict);
}

if cookie.secure().is_none() && secure_context {
if cookie.secure().is_none() && self.state.secure {
cookie.set_secure(true);
}
}
Expand Down Expand Up @@ -570,7 +546,7 @@ impl<'a> CookieJar<'a> {
/// cookie flag is set.
#[cfg(feature = "secrets")]
#[cfg_attr(nightly, doc(cfg(feature = "secrets")))]
fn set_private_defaults(secure_context: bool, cookie: &mut Cookie<'static>) {
fn set_private_defaults(&self, cookie: &mut Cookie<'static>) {
if cookie.path().is_none() {
cookie.set_path("/");
}
Expand All @@ -587,7 +563,7 @@ impl<'a> CookieJar<'a> {
cookie.set_expires(time::OffsetDateTime::now_utc() + time::Duration::weeks(1));
}

if cookie.secure().is_none() && secure_context {
if cookie.secure().is_none() && self.state.secure {
cookie.set_secure(true);
}
}
Expand All @@ -607,3 +583,33 @@ impl fmt::Debug for CookieJar<'_> {
.finish()
}
}

impl<'a> Clone for CookieJar<'a> {
fn clone(&self) -> Self {
CookieJar {
jar: self.jar.clone(),
ops: Mutex::new(self.ops.lock().clone()),
state: self.state,
}
}
}

impl Op {
fn cookie(&self) -> &Cookie<'static> {
match self {
Op::Add(c, _) | Op::Remove(c, _) => c
}
}
}

impl<'r> From<&'_ crate::Request<'r>> for CookieState<'r> {
fn from(r: &'_ crate::Request<'r>) -> Self {
CookieState { secure: r.context_is_likely_secure(), config: &r.rocket().config }
}
}

impl<'r> From<&'r crate::Rocket<crate::Orbit>> for CookieState<'r> {
fn from(r: &'r crate::Rocket<crate::Orbit>) -> Self {
CookieState { secure: r.config.tls_enabled(), config: &r.config }
}
}
5 changes: 1 addition & 4 deletions core/lib/src/local/asynchronous/response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,7 @@ impl<'c> LocalResponse<'c> {

async move {
let response: Response<'c> = f(request).await;
let mut cookies = CookieJar::new(
request.rocket().config(),
request.context_is_likely_secure(),
);
let mut cookies = CookieJar::new(None, request);
for cookie in response.cookies() {
cookies.add_original(cookie.into_owned());
}
Expand Down
3 changes: 1 addition & 2 deletions core/lib/src/local/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,9 +181,8 @@ macro_rules! pub_client_impl {
/// ```
#[inline(always)]
pub fn cookies(&self) -> crate::http::CookieJar<'_> {
let config = &self.rocket().config();
let jar = self._with_raw_cookies(|jar| jar.clone());
crate::http::CookieJar::from(jar, config, config.tls_enabled())
crate::http::CookieJar::new(Some(jar), self.rocket())
}

req_method!($import, "GET", get, Method::Get);
Expand Down
10 changes: 5 additions & 5 deletions core/lib/src/request/from_request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,11 +160,11 @@ pub type Outcome<S, E> = outcome::Outcome<S, (Status, E), Status>;
/// via [`Request::client_ip()`]. If the client's IP address is not known,
/// the request is forwarded with a 500 Internal Server Error status.
///
/// * **Protocol**
/// * **ProxyProto**
///
/// Extracts the protocol of the incoming request as a [`Protocol`] via
/// [`Request::forwarded_proto()`] (HTTP or HTTPS). If the used protocol is
/// not known, the request is forwarded.
/// Extracts the protocol of the incoming request as a [`ProxyProto`] via
/// [`Request::proxy_proto()`] (HTTP or HTTPS). If value of the header is
/// not known, the request is forwarded with a 404 Not Found status.
///
/// * **SocketAddr**
///
Expand Down Expand Up @@ -483,7 +483,7 @@ impl<'r> FromRequest<'r> for ProxyProto<'r> {
async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
match request.proxy_proto() {
Some(proto) => Success(proto),
None => Forward(())
None => Forward(Status::NotFound),
}
}
}
Expand Down
Loading

0 comments on commit bfe6ece

Please sign in to comment.