mirror of https://github.com/rwf2/Rocket.git
Fixup docs for 'proxy_proto_header'.
This commit is contained in:
parent
5c85ea3db5
commit
e9b568d9b2
|
@ -2,15 +2,30 @@ use std::fmt;
|
||||||
|
|
||||||
use uncased::{UncasedStr, AsUncased};
|
use uncased::{UncasedStr, AsUncased};
|
||||||
|
|
||||||
/// A protocol used to identify a specific protocol forwarded by an HTTP proxy.
|
/// Parsed [`Config::proxy_proto_header`] value: identifies a forwarded HTTP
|
||||||
/// Value are case-insensitive.
|
/// protocol (aka [X-Forwarded-Proto]).
|
||||||
|
///
|
||||||
|
/// The value of the header with name [`Config::proxy_proto_header`] is parsed
|
||||||
|
/// case-insensitively into this `enum`. For a given request, the parsed value,
|
||||||
|
/// if the header was present, can be retrieved via [`Request::proxy_proto()`]
|
||||||
|
/// or directly as a [request guard]. That value is used to determine whether a
|
||||||
|
/// request's context is likely secure ([`Request::context_is_likely_secure()`])
|
||||||
|
/// which in-turn is used to determine whether the `Secure` cookie flag is set
|
||||||
|
/// by default when [cookies are added] to a `CookieJar`.
|
||||||
|
///
|
||||||
|
/// [X-Forwarded-Proto]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto
|
||||||
|
/// [`Config::proxy_proto_header`]: ../../rocket/struct.Config.html#structfield.proxy_proto_header
|
||||||
|
/// [`Request::proxy_proto()`]: ../../rocket/request/struct.Request.html#method.proxy_proto
|
||||||
|
/// [`Request::context_is_likely_secure()`]: ../../rocket/request/struct.Request.html#method.context_is_likely_secure
|
||||||
|
/// [cookies are added]: ../..//rocket/http/struct.CookieJar.html#method.add
|
||||||
|
/// [request guard]: ../../rocket/request/trait.FromRequest.html#provided-implementations
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
pub enum ProxyProto<'a> {
|
pub enum ProxyProto<'a> {
|
||||||
/// `http` value, Hypertext Transfer Protocol.
|
/// `"http"`: Hypertext Transfer Protocol.
|
||||||
Http,
|
Http,
|
||||||
/// `https` value, Hypertext Transfer Protocol Secure.
|
/// `"https"`: Hypertext Transfer Protocol Secure.
|
||||||
Https,
|
Https,
|
||||||
/// Any protocol name other than `http` or `https`.
|
/// Any protocol name other than `"http"` or `"https"`.
|
||||||
Unknown(&'a UncasedStr),
|
Unknown(&'a UncasedStr),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -93,18 +93,24 @@ pub struct Config {
|
||||||
#[serde(deserialize_with = "crate::config::http_header::deserialize")]
|
#[serde(deserialize_with = "crate::config::http_header::deserialize")]
|
||||||
pub ip_header: Option<Uncased<'static>>,
|
pub ip_header: Option<Uncased<'static>>,
|
||||||
/// The name of a header, whose value is typically set by an intermediary
|
/// The name of a header, whose value is typically set by an intermediary
|
||||||
/// server or proxy, which contains the protocol (HTTP or HTTPS) used by the
|
/// server or proxy, which contains the protocol ("http" or "https") used by
|
||||||
/// connecting client. This should probably be [`X-Forwarded-Proto`], as
|
/// the connecting client. This is usually [`"X-Forwarded-Proto"`], as that
|
||||||
/// that is the de facto standard. Used by [`Request::forwarded_proto()`]
|
/// is the de-facto standard.
|
||||||
/// to determine the forwarded protocol and [`Request::forwarded_secure()`]
|
|
||||||
/// to determine whether a request is handled in a secure context.
|
|
||||||
///
|
///
|
||||||
/// [`X-Forwarded-Proto`]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto
|
/// The header value is parsed into a [`ProxyProto`], accessible via
|
||||||
|
/// [`Request::proxy_proto()`]. The value influences
|
||||||
|
/// [`Request::context_is_likely_secure()`] and the default value for the
|
||||||
|
/// `Secure` flag in cookies added to [`CookieJar`]s.
|
||||||
///
|
///
|
||||||
/// To disable using any header for this purpose, set this value to `false`
|
/// To disable using any header for this purpose, set this value to `false`
|
||||||
/// or `None`. Deserialization semantics are identical to those of [`ip_header`].
|
/// or `None`. Deserialization semantics are identical to those of
|
||||||
|
/// [`Config::ip_header`] (the value must be a valid HTTP header name).
|
||||||
///
|
///
|
||||||
/// **(default: `None`)**
|
/// **(default: `None`)**
|
||||||
|
///
|
||||||
|
/// [`CookieJar`]: crate::http::CookieJar
|
||||||
|
/// [`ProxyProto`]: crate::http::ProxyProto
|
||||||
|
/// [`"X-Forwarded-Proto"`]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto
|
||||||
#[serde(deserialize_with = "crate::config::http_header::deserialize")]
|
#[serde(deserialize_with = "crate::config::http_header::deserialize")]
|
||||||
pub proxy_proto_header: Option<Uncased<'static>>,
|
pub proxy_proto_header: Option<Uncased<'static>>,
|
||||||
/// Streaming read size limits. **(default: [`Limits::default()`])**
|
/// Streaming read size limits. **(default: [`Limits::default()`])**
|
||||||
|
|
|
@ -278,12 +278,13 @@ impl<'a> CookieJar<'a> {
|
||||||
///
|
///
|
||||||
/// * `path`: `"/"`
|
/// * `path`: `"/"`
|
||||||
/// * `SameSite`: `Strict`
|
/// * `SameSite`: `Strict`
|
||||||
|
/// * `Secure`: `true` if [`Request::context_is_likely_secure()`]
|
||||||
///
|
///
|
||||||
/// Furthermore, if TLS is enabled or handled by a proxy (as determined by
|
|
||||||
/// [`Request::context_is_likely_secure()`]), the `Secure` cookie flag is set.
|
|
||||||
/// 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 explicitly.
|
/// security, you may wish to set the `secure` flag explicitly.
|
||||||
///
|
///
|
||||||
|
/// [`Request::context_is_likely_secure()`]: crate::Request::context_is_likely_secure()
|
||||||
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
|
@ -321,11 +322,13 @@ impl<'a> CookieJar<'a> {
|
||||||
/// * `SameSite`: `Strict`
|
/// * `SameSite`: `Strict`
|
||||||
/// * `HttpOnly`: `true`
|
/// * `HttpOnly`: `true`
|
||||||
/// * `Expires`: 1 week from now
|
/// * `Expires`: 1 week from now
|
||||||
|
/// * `Secure`: `true` if [`Request::context_is_likely_secure()`]
|
||||||
///
|
///
|
||||||
/// Furthermore, if TLS is enabled or handled by a proxy (as determined by
|
|
||||||
/// [`Request::context_is_likely_secure()`]), the `Secure` cookie flag is set.
|
|
||||||
/// 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 explicitly.
|
/// security, you may wish to set the `secure` flag explicitly and
|
||||||
|
/// unconditionally.
|
||||||
|
///
|
||||||
|
/// [`Request::context_is_likely_secure()`]: crate::Request::context_is_likely_secure()
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
|
@ -510,9 +513,7 @@ impl<'a> CookieJar<'a> {
|
||||||
///
|
///
|
||||||
/// * `path`: `"/"`
|
/// * `path`: `"/"`
|
||||||
/// * `SameSite`: `Strict`
|
/// * `SameSite`: `Strict`
|
||||||
///
|
/// * `Secure`: `true` if `Request::context_is_likely_secure()`
|
||||||
/// Furthermore, if TLS is enabled or handled by a proxy (as determined by
|
|
||||||
/// [`Request::context_is_likely_secure()`]), the `Secure` cookie flag is set.
|
|
||||||
fn set_defaults(&self, cookie: &mut Cookie<'static>) {
|
fn set_defaults(&self, cookie: &mut Cookie<'static>) {
|
||||||
if cookie.path().is_none() {
|
if cookie.path().is_none() {
|
||||||
cookie.set_path("/");
|
cookie.set_path("/");
|
||||||
|
@ -550,9 +551,7 @@ impl<'a> CookieJar<'a> {
|
||||||
/// * `SameSite`: `Strict`
|
/// * `SameSite`: `Strict`
|
||||||
/// * `HttpOnly`: `true`
|
/// * `HttpOnly`: `true`
|
||||||
/// * `Expires`: 1 week from now
|
/// * `Expires`: 1 week from now
|
||||||
///
|
/// * `Secure`: `true` if `Request::context_is_likely_secure()`
|
||||||
/// Furthermore, if TLS is enabled or handled by a proxy (as determined by
|
|
||||||
/// [`Request::context_is_likely_secure()`]), the `Secure` cookie flag is set.
|
|
||||||
#[cfg(feature = "secrets")]
|
#[cfg(feature = "secrets")]
|
||||||
#[cfg_attr(nightly, doc(cfg(feature = "secrets")))]
|
#[cfg_attr(nightly, doc(cfg(feature = "secrets")))]
|
||||||
fn set_private_defaults(&self, cookie: &mut Cookie<'static>) {
|
fn set_private_defaults(&self, cookie: &mut Cookie<'static>) {
|
||||||
|
|
|
@ -87,9 +87,10 @@ impl<'c> LocalResponse<'c> {
|
||||||
let request: &'c Request<'c> = unsafe { &*(&*boxed_req as *const _) };
|
let request: &'c Request<'c> = unsafe { &*(&*boxed_req as *const _) };
|
||||||
|
|
||||||
async move {
|
async move {
|
||||||
// NOTE: The new `secure` cookie jar state will not reflect the last
|
// NOTE: The cookie jar `secure` state will not reflect the last
|
||||||
// known value in `request.cookies()`. This is okay as new cookies
|
// known value in `request.cookies()`. This is okay: new cookies
|
||||||
// should never be added to the resulting jar.
|
// should never be added to the resulting jar which is the only time
|
||||||
|
// the value is used to set cookie defaults.
|
||||||
let response: Response<'c> = f(request).await;
|
let response: Response<'c> = f(request).await;
|
||||||
let mut cookies = CookieJar::new(None, request.rocket());
|
let mut cookies = CookieJar::new(None, request.rocket());
|
||||||
for cookie in response.cookies() {
|
for cookie in response.cookies() {
|
||||||
|
|
|
@ -3,7 +3,7 @@ use std::fmt::Debug;
|
||||||
use std::net::{IpAddr, SocketAddr};
|
use std::net::{IpAddr, SocketAddr};
|
||||||
|
|
||||||
use crate::{Request, Route};
|
use crate::{Request, Route};
|
||||||
use crate::outcome::{self, Outcome::*};
|
use crate::outcome::{self, IntoOutcome, Outcome::*};
|
||||||
|
|
||||||
use crate::http::uri::{Host, Origin};
|
use crate::http::uri::{Host, Origin};
|
||||||
use crate::http::{Status, ContentType, Accept, Method, ProxyProto, CookieJar};
|
use crate::http::{Status, ContentType, Accept, Method, ProxyProto, CookieJar};
|
||||||
|
@ -163,8 +163,8 @@ pub type Outcome<S, E> = outcome::Outcome<S, (Status, E), Status>;
|
||||||
/// * **ProxyProto**
|
/// * **ProxyProto**
|
||||||
///
|
///
|
||||||
/// Extracts the protocol of the incoming request as a [`ProxyProto`] via
|
/// Extracts the protocol of the incoming request as a [`ProxyProto`] via
|
||||||
/// [`Request::proxy_proto()`] (HTTP or HTTPS). If value of the header is
|
/// [`Request::proxy_proto()`]. If no such header is present, the request is
|
||||||
/// not known, the request is forwarded with a 404 Not Found status.
|
/// forwarded with a 500 Internal Server Error status.
|
||||||
///
|
///
|
||||||
/// * **SocketAddr**
|
/// * **SocketAddr**
|
||||||
///
|
///
|
||||||
|
@ -481,10 +481,7 @@ impl<'r> FromRequest<'r> for ProxyProto<'r> {
|
||||||
type Error = std::convert::Infallible;
|
type Error = std::convert::Infallible;
|
||||||
|
|
||||||
async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
|
async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
|
||||||
match request.proxy_proto() {
|
request.proxy_proto().or_forward(Status::InternalServerError)
|
||||||
Some(proto) => Success(proto),
|
|
||||||
None => Forward(Status::InternalServerError),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -389,8 +389,9 @@ impl<'r> Request<'r> {
|
||||||
///
|
///
|
||||||
/// The value is determined by inspecting the header named
|
/// The value is determined by inspecting the header named
|
||||||
/// [`proxy_proto_header`](crate::Config::proxy_proto_header), if
|
/// [`proxy_proto_header`](crate::Config::proxy_proto_header), if
|
||||||
/// configured. If parameter isn't configured or the request doesn't contain
|
/// configured, and parsing it case-insensitivity. If the parameter isn't
|
||||||
/// a header named as indicated, this method returns `None`.
|
/// configured or the request doesn't contain a header named as indicated,
|
||||||
|
/// this method returns `None`.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
|
@ -413,7 +414,7 @@ impl<'r> Request<'r> {
|
||||||
/// assert_eq!(req.proxy_proto(), Some(ProxyProto::Https));
|
/// assert_eq!(req.proxy_proto(), Some(ProxyProto::Https));
|
||||||
///
|
///
|
||||||
/// # let req = c.get("/");
|
/// # let req = c.get("/");
|
||||||
/// let req = req.header(Header::new("x-forwarded-proto", "http"));
|
/// let req = req.header(Header::new("x-forwarded-proto", "HTTP"));
|
||||||
/// assert_eq!(req.proxy_proto(), Some(ProxyProto::Http));
|
/// assert_eq!(req.proxy_proto(), Some(ProxyProto::Http));
|
||||||
///
|
///
|
||||||
/// # let req = c.get("/");
|
/// # let req = c.get("/");
|
||||||
|
@ -438,7 +439,7 @@ impl<'r> Request<'r> {
|
||||||
/// be in a secure context. We say _likely_ because it is entirely possible
|
/// be in a secure context. We say _likely_ because it is entirely possible
|
||||||
/// for the header to indicate that the connection is being proxied via
|
/// for the header to indicate that the connection is being proxied via
|
||||||
/// HTTPS while reality differs. As such, this value should not be trusted
|
/// HTTPS while reality differs. As such, this value should not be trusted
|
||||||
/// when security is a concern.
|
/// when 100% confidence is a necessity.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
|
|
|
@ -1,22 +1,13 @@
|
||||||
use rocket::http::ProxyProto;
|
#[macro_use] extern crate rocket;
|
||||||
|
|
||||||
#[macro_use]
|
|
||||||
extern crate rocket;
|
|
||||||
|
|
||||||
#[get("/")]
|
#[get("/")]
|
||||||
fn inspect_proto(proto: Option<ProxyProto>) -> String {
|
fn inspect_proto(proto: rocket::http::ProxyProto) -> String {
|
||||||
proto
|
proto.to_string()
|
||||||
.map(|proto| match proto {
|
|
||||||
ProxyProto::Http => "http".to_owned(),
|
|
||||||
ProxyProto::Https => "https".to_owned(),
|
|
||||||
ProxyProto::Unknown(s) => s.to_string(),
|
|
||||||
})
|
|
||||||
.unwrap_or("<none>".to_owned())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mod tests {
|
mod tests {
|
||||||
use rocket::{Rocket, Build, Route};
|
use rocket::{Rocket, Build, Route};
|
||||||
use rocket::http::Header;
|
use rocket::http::{Header, Status};
|
||||||
use rocket::local::blocking::Client;
|
use rocket::local::blocking::Client;
|
||||||
use rocket::figment::Figment;
|
use rocket::figment::Figment;
|
||||||
|
|
||||||
|
@ -32,8 +23,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn check_proxy_proto_header_works() {
|
fn check_proxy_proto_header_works() {
|
||||||
let rocket = rocket_with_proto_header(Some("X-Url-Scheme"));
|
let client = Client::debug(rocket_with_proto_header(Some("X-Url-Scheme"))).unwrap();
|
||||||
let client = Client::debug(rocket).unwrap();
|
|
||||||
let response = client.get("/")
|
let response = client.get("/")
|
||||||
.header(Header::new("X-Forwarded-Proto", "https"))
|
.header(Header::new("X-Forwarded-Proto", "https"))
|
||||||
.header(Header::new("X-Url-Scheme", "http"))
|
.header(Header::new("X-Url-Scheme", "http"))
|
||||||
|
@ -41,22 +31,18 @@ mod tests {
|
||||||
|
|
||||||
assert_eq!(response.into_string().unwrap(), "http");
|
assert_eq!(response.into_string().unwrap(), "http");
|
||||||
|
|
||||||
let response = client.get("/")
|
let response = client.get("/").header(Header::new("X-Url-Scheme", "https")).dispatch();
|
||||||
.header(Header::new("X-Url-Scheme", "https"))
|
|
||||||
.dispatch();
|
|
||||||
|
|
||||||
assert_eq!(response.into_string().unwrap(), "https");
|
assert_eq!(response.into_string().unwrap(), "https");
|
||||||
|
|
||||||
let response = client.get("/").dispatch();
|
let response = client.get("/").dispatch();
|
||||||
assert_eq!(response.into_string().unwrap(), "<none>");
|
assert_eq!(response.status(), Status::InternalServerError);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn check_proxy_proto_header_works_again() {
|
fn check_proxy_proto_header_works_again() {
|
||||||
let client = Client::debug(rocket_with_proto_header(Some("x-url-scheme"))).unwrap();
|
let client = Client::debug(rocket_with_proto_header(Some("x-url-scheme"))).unwrap();
|
||||||
let response = client
|
let response = client.get("/")
|
||||||
.get("/")
|
.header(Header::new("X-Url-Scheme", "hTTpS"))
|
||||||
.header(Header::new("X-Url-Scheme", "https"))
|
|
||||||
.dispatch();
|
.dispatch();
|
||||||
|
|
||||||
assert_eq!(response.into_string().unwrap(), "https");
|
assert_eq!(response.into_string().unwrap(), "https");
|
||||||
|
@ -65,9 +51,8 @@ mod tests {
|
||||||
.merge(("proxy_proto_header", "x-url-scheme"));
|
.merge(("proxy_proto_header", "x-url-scheme"));
|
||||||
|
|
||||||
let client = Client::debug(rocket::custom(config).mount("/", routes())).unwrap();
|
let client = Client::debug(rocket::custom(config).mount("/", routes())).unwrap();
|
||||||
let response = client
|
let response = client.get("/")
|
||||||
.get("/")
|
.header(Header::new("X-url-Scheme", "HTTPS"))
|
||||||
.header(Header::new("X-url-Scheme", "https"))
|
|
||||||
.dispatch();
|
.dispatch();
|
||||||
|
|
||||||
assert_eq!(response.into_string().unwrap(), "https");
|
assert_eq!(response.into_string().unwrap(), "https");
|
||||||
|
@ -76,12 +61,11 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn check_default_proxy_proto_header_works() {
|
fn check_default_proxy_proto_header_works() {
|
||||||
let client = Client::debug_with(routes()).unwrap();
|
let client = Client::debug_with(routes()).unwrap();
|
||||||
let response = client
|
let response = client.get("/")
|
||||||
.get("/")
|
|
||||||
.header(Header::new("X-Forwarded-Proto", "https"))
|
.header(Header::new("X-Forwarded-Proto", "https"))
|
||||||
.dispatch();
|
.dispatch();
|
||||||
|
|
||||||
assert_eq!(response.into_string(), Some("<none>".into()));
|
assert_eq!(response.status(), Status::InternalServerError);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -91,25 +75,23 @@ mod tests {
|
||||||
.header(Header::new("X-Forwarded-Proto", "https"))
|
.header(Header::new("X-Forwarded-Proto", "https"))
|
||||||
.dispatch();
|
.dispatch();
|
||||||
|
|
||||||
assert_eq!(response.into_string(), Some("<none>".into()));
|
assert_eq!(response.status(), Status::InternalServerError);
|
||||||
|
|
||||||
let config =
|
let config =
|
||||||
Figment::from(rocket::Config::debug_default()).merge(("proxy_proto_header", false));
|
Figment::from(rocket::Config::debug_default()).merge(("proxy_proto_header", false));
|
||||||
|
|
||||||
let client = Client::debug(rocket::custom(config).mount("/", routes())).unwrap();
|
let client = Client::debug(rocket::custom(config).mount("/", routes())).unwrap();
|
||||||
let response = client
|
let response = client.get("/")
|
||||||
.get("/")
|
|
||||||
.header(Header::new("X-Forwarded-Proto", "https"))
|
.header(Header::new("X-Forwarded-Proto", "https"))
|
||||||
.dispatch();
|
.dispatch();
|
||||||
|
|
||||||
assert_eq!(response.into_string(), Some("<none>".into()));
|
assert_eq!(response.status(), Status::InternalServerError);
|
||||||
|
|
||||||
let config = Figment::from(rocket::Config::debug_default())
|
let config = Figment::from(rocket::Config::debug_default())
|
||||||
.merge(("proxy_proto_header", "x-forwarded-proto"));
|
.merge(("proxy_proto_header", "x-forwarded-proto"));
|
||||||
|
|
||||||
let client = Client::debug(rocket::custom(config).mount("/", routes())).unwrap();
|
let client = Client::debug(rocket::custom(config).mount("/", routes())).unwrap();
|
||||||
let response = client
|
let response = client.get("/")
|
||||||
.get("/")
|
|
||||||
.header(Header::new("x-Forwarded-Proto", "https"))
|
.header(Header::new("x-Forwarded-Proto", "https"))
|
||||||
.dispatch();
|
.dispatch();
|
||||||
|
|
||||||
|
|
|
@ -152,8 +152,8 @@ workers = 16
|
||||||
max_blocking = 512
|
max_blocking = 512
|
||||||
keep_alive = 5
|
keep_alive = 5
|
||||||
ident = "Rocket"
|
ident = "Rocket"
|
||||||
ip_header = "X-Real-IP" # set to `false` or `None` to disable
|
ip_header = "X-Real-IP" # set to `false` (the default) to disable
|
||||||
proxy_proto_header = `false` # set to `false` or `None` to disable
|
proxy_proto_header = `false` # set to `false` (the default) to disable
|
||||||
log_level = "normal"
|
log_level = "normal"
|
||||||
temp_dir = "/tmp"
|
temp_dir = "/tmp"
|
||||||
cli_colors = true
|
cli_colors = true
|
||||||
|
@ -365,22 +365,30 @@ mutual TLS.
|
||||||
|
|
||||||
### Proxied TLS
|
### Proxied TLS
|
||||||
|
|
||||||
If Rocket is running behind a reverse proxy that terminates TLS, it is useful to
|
The `proxy_proto_header` configuration parameter allows Rocket applications to
|
||||||
know whether the original connection was made securely. Therefore, Rocket offers
|
determine when and if a client's initial connection was likely made in a secure
|
||||||
the option to configure a `proxy_proto_header` that is used to determine if the
|
context by examining the header with the configured name. The header's value is
|
||||||
request is handled in a secure context. The outcome is available via
|
parsed into a [`ProxyProto`], retrievable via [`Request::proxy_proto()`].
|
||||||
[`Request::context_is_likely_secure()`] and used to set cookies' secure flag by
|
|
||||||
default. To enable this behaviour, configure the header as set by your reverse
|
That value is in-turn inspected to determine if the initial connection was
|
||||||
proxy. For example:
|
secure (i.e, made over TLS) and the outcome made available via
|
||||||
|
[`Request::context_is_likely_secure()`]. The value returned by this method
|
||||||
|
influences cookie defaults. In particular, if the method returns `true` (i.e,
|
||||||
|
the request context is likely secure), the `Secure` cookie flag is set by
|
||||||
|
default when a cookie is added to a [`CookieJar`].
|
||||||
|
|
||||||
|
To enable this behaviour, configure the header as set by your reverse proxy or
|
||||||
|
forwarding entity. For example, to set the header name to `X-Forwarded-Proto`
|
||||||
|
via a TOML file:
|
||||||
|
|
||||||
```toml,ignore
|
```toml,ignore
|
||||||
proxy_proto_header = 'X-Forwarded-Proto'
|
proxy_proto_header = "X-Forwarded-Proto"
|
||||||
```
|
```
|
||||||
|
|
||||||
Note that this only sets the cookies' secure flag when not configured
|
[`Request::proxy_proto()`]: @api/rocket/request/struct.Request.html#method.proxy_proto
|
||||||
explicitly. This setting also provides the [request guard `ProxyProto`].
|
[`ProxyProto`]: @api/rocket/http/enum.ProxyProto.html
|
||||||
|
[`CookieJar`]: @api/rocket/http/struct.CookieJar.html
|
||||||
[`ProxyProto`]: @api/rocket/request/trait.FromRequest.html#impl-FromRequest%3C'r%3E-for-%26ProxyProto
|
[`Request::context_is_likely_secure()`]: @api/rocket/request/struct.Request.html#method.context_is_likely_secure
|
||||||
|
|
||||||
### Workers
|
### Workers
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue