Use request local cache for fairing implementation (#50)
This commit is contained in:
parent
21444e90c4
commit
9cb16ba01d
|
@ -1,47 +1,19 @@
|
||||||
//! Fairing implementation
|
//! Fairing implementation
|
||||||
use std::str::FromStr;
|
|
||||||
|
|
||||||
use log::{error, info, log};
|
use log::{error, info, log};
|
||||||
use rocket::http::{self, uri::Origin, Header, Status};
|
use rocket::http::{self, uri::Origin, Status};
|
||||||
use rocket::{self, error_, info_, log_, Outcome, Request};
|
use rocket::{self, error_, info_, log_, Outcome, Request};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
actual_request_response, origin, preflight_response, request_headers, validate, Cors, Error,
|
actual_request_response, origin, preflight_response, request_headers, validate, Cors, Error,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// An injected header to quickly give the result of CORS
|
/// Request Local State to store CORS validation results
|
||||||
static CORS_HEADER: &str = "ROCKET-CORS";
|
enum CorsValidation {
|
||||||
enum InjectedHeader {
|
|
||||||
Success,
|
Success,
|
||||||
Failure,
|
Failure,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InjectedHeader {
|
|
||||||
fn to_str(&self) -> &'static str {
|
|
||||||
match *self {
|
|
||||||
InjectedHeader::Success => "Success",
|
|
||||||
InjectedHeader::Failure => "Failure",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FromStr for InjectedHeader {
|
|
||||||
type Err = Error;
|
|
||||||
fn from_str(s: &str) -> Result<Self, Error> {
|
|
||||||
match s {
|
|
||||||
"Success" => Ok(InjectedHeader::Success),
|
|
||||||
"Failure" => Ok(InjectedHeader::Failure),
|
|
||||||
other => {
|
|
||||||
error_!(
|
|
||||||
"Unknown injected header encountered: {}\nThis is probably a bug.",
|
|
||||||
other
|
|
||||||
);
|
|
||||||
Err(Error::UnknownInjectedHeader)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Route for Fairing error handling
|
/// Route for Fairing error handling
|
||||||
pub(crate) fn fairing_error_route<'r>(
|
pub(crate) fn fairing_error_route<'r>(
|
||||||
request: &'r Request,
|
request: &'r Request,
|
||||||
|
@ -71,11 +43,6 @@ fn route_to_fairing_error_handler(options: &Cors, status: u16, request: &mut Req
|
||||||
request.set_uri(origin);
|
request.set_uri(origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Inject a header into the Request with result
|
|
||||||
fn inject_request_header(header: &InjectedHeader, request: &mut Request) {
|
|
||||||
request.replace_header(Header::new(CORS_HEADER, header.to_str()));
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_response_wrapper(
|
fn on_response_wrapper(
|
||||||
options: &Cors,
|
options: &Cors,
|
||||||
request: &Request,
|
request: &Request,
|
||||||
|
@ -89,14 +56,9 @@ fn on_response_wrapper(
|
||||||
Some(origin) => origin,
|
Some(origin) => origin,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Get validation result from injected header
|
let result = request.local_cache(|| unreachable!("This should not be executed so late"));
|
||||||
let injected_header = request
|
|
||||||
.headers()
|
|
||||||
.get_one(CORS_HEADER)
|
|
||||||
.ok_or_else(|| Error::MissingInjectedHeader)?;
|
|
||||||
let result = InjectedHeader::from_str(injected_header)?;
|
|
||||||
|
|
||||||
if let InjectedHeader::Failure = result {
|
if let &CorsValidation::Failure = result {
|
||||||
// Nothing else for us to do
|
// Nothing else for us to do
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
@ -151,17 +113,17 @@ impl rocket::fairing::Fairing for Cors {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_request(&self, request: &mut Request, _: &rocket::Data) {
|
fn on_request(&self, request: &mut Request, _: &rocket::Data) {
|
||||||
let injected_header = match validate(self, request) {
|
let result = match validate(self, request) {
|
||||||
Ok(_) => InjectedHeader::Success,
|
Ok(_) => CorsValidation::Success,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
error_!("CORS Error: {}", err);
|
error_!("CORS Error: {}", err);
|
||||||
let status = err.status();
|
let status = err.status();
|
||||||
route_to_fairing_error_handler(self, status.code, request);
|
route_to_fairing_error_handler(self, status.code, request);
|
||||||
InjectedHeader::Failure
|
CorsValidation::Failure
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
inject_request_header(&injected_header, request);
|
let _ = request.local_cache(|| result);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_response(&self, request: &Request, response: &mut rocket::Response) {
|
fn on_response(&self, request: &Request, response: &mut rocket::Response) {
|
||||||
|
|
10
src/lib.rs
10
src/lib.rs
|
@ -637,9 +637,6 @@ pub enum Error {
|
||||||
/// The `on_response` handler of Fairing could not find the injected header from the Request.
|
/// The `on_response` handler of Fairing could not find the injected header from the Request.
|
||||||
/// Either some other fairing has removed it, or this is a bug.
|
/// Either some other fairing has removed it, or this is a bug.
|
||||||
MissingInjectedHeader,
|
MissingInjectedHeader,
|
||||||
/// The `on_response` handler of Fairing found an unknown injected header value from the
|
|
||||||
/// Request. Either some other fairing has modified it, or this is a bug.
|
|
||||||
UnknownInjectedHeader,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Error {
|
impl Error {
|
||||||
|
@ -651,8 +648,7 @@ impl Error {
|
||||||
| Error::HeadersNotAllowed => Status::Forbidden,
|
| Error::HeadersNotAllowed => Status::Forbidden,
|
||||||
Error::CredentialsWithWildcardOrigin
|
Error::CredentialsWithWildcardOrigin
|
||||||
| Error::MissingCorsInRocketState
|
| Error::MissingCorsInRocketState
|
||||||
| Error::MissingInjectedHeader
|
| Error::MissingInjectedHeader => Status::InternalServerError,
|
||||||
| Error::UnknownInjectedHeader => Status::InternalServerError,
|
|
||||||
_ => Status::BadRequest,
|
_ => Status::BadRequest,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -688,10 +684,6 @@ impl error::Error for Error {
|
||||||
"The `on_response` handler of Fairing could not find the injected header from the \
|
"The `on_response` handler of Fairing could not find the injected header from the \
|
||||||
Request. Either some other fairing has removed it, or this is a bug."
|
Request. Either some other fairing has removed it, or this is a bug."
|
||||||
}
|
}
|
||||||
Error::UnknownInjectedHeader => {
|
|
||||||
"The `on_response` handler of Fairing found an unknown injected header value from \
|
|
||||||
the Request. Either some other fairing has modified it, or this is a bug."
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue