1
0
Fork 0
mirror of https://github.com/actix/actix-web.git synced 2024-12-19 14:49:01 +00:00

CORS: Do not validate Origin header on non-OPTION requests #271

This commit is contained in:
Nikolay Kim 2018-06-05 07:39:47 -07:00
parent f7b7d282bf
commit afa67b838a

View file

@ -19,16 +19,16 @@
//! //!
//! ```rust //! ```rust
//! # extern crate actix_web; //! # extern crate actix_web;
//! use actix_web::{http, App, HttpRequest, HttpResponse};
//! use actix_web::middleware::cors::Cors; //! use actix_web::middleware::cors::Cors;
//! use actix_web::{http, App, HttpRequest, HttpResponse};
//! //!
//! fn index(mut req: HttpRequest) -> &'static str { //! fn index(mut req: HttpRequest) -> &'static str {
//! "Hello world" //! "Hello world"
//! } //! }
//! //!
//! fn main() { //! fn main() {
//! let app = App::new() //! let app = App::new().configure(|app| {
//! .configure(|app| Cors::for_app(app) // <- Construct CORS middleware builder //! Cors::for_app(app) // <- Construct CORS middleware builder
//! .allowed_origin("https://www.rust-lang.org/") //! .allowed_origin("https://www.rust-lang.org/")
//! .allowed_methods(vec!["GET", "POST"]) //! .allowed_methods(vec!["GET", "POST"])
//! .allowed_headers(vec![http::header::AUTHORIZATION, http::header::ACCEPT]) //! .allowed_headers(vec![http::header::AUTHORIZATION, http::header::ACCEPT])
@ -38,7 +38,8 @@
//! r.method(http::Method::GET).f(|_| HttpResponse::Ok()); //! r.method(http::Method::GET).f(|_| HttpResponse::Ok());
//! r.method(http::Method::HEAD).f(|_| HttpResponse::MethodNotAllowed()); //! r.method(http::Method::HEAD).f(|_| HttpResponse::MethodNotAllowed());
//! }) //! })
//! .register()); //! .register()
//! });
//! } //! }
//! ``` //! ```
//! In this example custom *CORS* middleware get registered for "/index.html" //! In this example custom *CORS* middleware get registered for "/index.html"
@ -232,18 +233,20 @@ impl Cors {
/// ///
/// ```rust /// ```rust
/// # extern crate actix_web; /// # extern crate actix_web;
/// use actix_web::{http, App, HttpResponse};
/// use actix_web::middleware::cors::Cors; /// use actix_web::middleware::cors::Cors;
/// use actix_web::{http, App, HttpResponse};
/// ///
/// fn main() { /// fn main() {
/// let app = App::new() /// let app = App::new().configure(
/// .configure(|app| Cors::for_app(app) // <- Construct CORS builder /// |app| {
/// Cors::for_app(app) // <- Construct CORS builder
/// .allowed_origin("https://www.rust-lang.org/") /// .allowed_origin("https://www.rust-lang.org/")
/// .resource("/resource", |r| { // register resource /// .resource("/resource", |r| { // register resource
/// r.method(http::Method::GET).f(|_| HttpResponse::Ok()); /// r.method(http::Method::GET).f(|_| HttpResponse::Ok());
/// }) /// })
/// .register() // construct CORS and return application instance /// .register()
/// ); /// }, // construct CORS and return application instance
/// );
/// } /// }
/// ``` /// ```
pub fn for_app<S: 'static>(app: App<S>) -> CorsBuilder<S> { pub fn for_app<S: 'static>(app: App<S>) -> CorsBuilder<S> {
@ -420,7 +423,10 @@ impl<S> Middleware<S> for Cors {
.finish(), .finish(),
)) ))
} else { } else {
self.validate_origin(req)?; // Only check requests with a origin header.
if req.headers().contains_key(header::ORIGIN) {
self.validate_origin(req)?;
}
Ok(Started::Done) Ok(Started::Done)
} }
@ -491,8 +497,8 @@ impl<S> Middleware<S> for Cors {
/// ```rust /// ```rust
/// # extern crate http; /// # extern crate http;
/// # extern crate actix_web; /// # extern crate actix_web;
/// use http::header;
/// use actix_web::middleware::cors; /// use actix_web::middleware::cors;
/// use http::header;
/// ///
/// # fn main() { /// # fn main() {
/// let cors = cors::Cors::build() /// let cors = cors::Cors::build()
@ -764,12 +770,13 @@ impl<S: 'static> CorsBuilder<S> {
/// ///
/// ```rust /// ```rust
/// # extern crate actix_web; /// # extern crate actix_web;
/// use actix_web::{http, App, HttpResponse};
/// use actix_web::middleware::cors::Cors; /// use actix_web::middleware::cors::Cors;
/// use actix_web::{http, App, HttpResponse};
/// ///
/// fn main() { /// fn main() {
/// let app = App::new() /// let app = App::new().configure(
/// .configure(|app| Cors::for_app(app) // <- Construct CORS builder /// |app| {
/// Cors::for_app(app) // <- Construct CORS builder
/// .allowed_origin("https://www.rust-lang.org/") /// .allowed_origin("https://www.rust-lang.org/")
/// .allowed_methods(vec!["GET", "POST"]) /// .allowed_methods(vec!["GET", "POST"])
/// .allowed_header(http::header::CONTENT_TYPE) /// .allowed_header(http::header::CONTENT_TYPE)
@ -781,8 +788,9 @@ impl<S: 'static> CorsBuilder<S> {
/// r.method(http::Method::HEAD) /// r.method(http::Method::HEAD)
/// .f(|_| HttpResponse::MethodNotAllowed()); /// .f(|_| HttpResponse::MethodNotAllowed());
/// }) /// })
/// .register() // construct CORS and return application instance /// .register()
/// ); /// }, // construct CORS and return application instance
/// );
/// } /// }
/// ``` /// ```
pub fn resource<F, R>(&mut self, path: &str, f: F) -> &mut CorsBuilder<S> pub fn resource<F, R>(&mut self, path: &str, f: F) -> &mut CorsBuilder<S>
@ -1001,16 +1009,15 @@ mod tests {
assert!(cors.start(&mut req).unwrap().is_done()); assert!(cors.start(&mut req).unwrap().is_done());
} }
#[test] // #[test]
#[should_panic(expected = "MissingOrigin")] // #[should_panic(expected = "MissingOrigin")]
fn test_validate_missing_origin() { // fn test_validate_missing_origin() {
let cors = Cors::build() // let mut cors = Cors::build()
.allowed_origin("https://www.example.com") // .allowed_origin("https://www.example.com")
.finish(); // .finish();
// let mut req = HttpRequest::default();
let mut req = HttpRequest::default(); // cors.start(&mut req).unwrap();
cors.start(&mut req).unwrap(); // }
}
#[test] #[test]
#[should_panic(expected = "OriginNotAllowed")] #[should_panic(expected = "OriginNotAllowed")]
@ -1127,10 +1134,19 @@ mod tests {
}) })
}); });
let request = srv.get().uri(srv.url("/test")).finish().unwrap(); let request = srv
.get()
.uri(srv.url("/test"))
.header("ORIGIN", "https://www.example2.com")
.finish()
.unwrap();
let response = srv.execute(request.send()).unwrap(); let response = srv.execute(request.send()).unwrap();
assert_eq!(response.status(), StatusCode::BAD_REQUEST); assert_eq!(response.status(), StatusCode::BAD_REQUEST);
let request = srv.get().uri(srv.url("/test")).finish().unwrap();
let response = srv.execute(request.send()).unwrap();
assert_eq!(response.status(), StatusCode::OK);
let request = srv let request = srv
.get() .get()
.uri(srv.url("/test")) .uri(srv.url("/test"))