1
0
mirror of https://github.com/fafhrd91/actix-web synced 2025-08-29 00:07:48 +02:00

add rustfmt config

This commit is contained in:
Nikolay Kim
2018-04-13 16:02:01 -07:00
parent 95f6277007
commit 113f5ad1a8
91 changed files with 8057 additions and 5509 deletions

View File

@@ -7,7 +7,8 @@
//!
//! 1. Call [`Cors::build`](struct.Cors.html#method.build) to start building.
//! 2. Use any of the builder methods to set fields in the backend.
//! 3. Call [finish](struct.Cors.html#method.finish) to retrieve the constructed backend.
//! 3. Call [finish](struct.Cors.html#method.finish) to retrieve the
//! constructed backend.
//!
//! Cors middleware could be used as parameter for `App::middleware()` or
//! `ResourceHandler::middleware()` methods. But you have to use
@@ -40,65 +41,69 @@
//! .register());
//! }
//! ```
//! In this example custom *CORS* middleware get registered for "/index.html" endpoint.
//! In this example custom *CORS* middleware get registered for "/index.html"
//! endpoint.
//!
//! Cors middleware automatically handle *OPTIONS* preflight request.
use std::collections::HashSet;
use std::iter::FromIterator;
use std::rc::Rc;
use http::{self, Method, HttpTryFrom, Uri, StatusCode};
use http::header::{self, HeaderName, HeaderValue};
use http::{self, HttpTryFrom, Method, StatusCode, Uri};
use application::App;
use error::{Result, ResponseError};
use resource::ResourceHandler;
use error::{ResponseError, Result};
use httpmessage::HttpMessage;
use httprequest::HttpRequest;
use httpresponse::HttpResponse;
use middleware::{Middleware, Response, Started};
use resource::ResourceHandler;
/// A set of errors that can occur during processing CORS
#[derive(Debug, Fail)]
pub enum CorsError {
/// The HTTP request header `Origin` is required but was not provided
#[fail(display="The HTTP request header `Origin` is required but was not provided")]
#[fail(display = "The HTTP request header `Origin` is required but was not provided")]
MissingOrigin,
/// The HTTP request header `Origin` could not be parsed correctly.
#[fail(display="The HTTP request header `Origin` could not be parsed correctly.")]
#[fail(display = "The HTTP request header `Origin` could not be parsed correctly.")]
BadOrigin,
/// The request header `Access-Control-Request-Method` is required but is missing
#[fail(display="The request header `Access-Control-Request-Method` is required but is missing")]
/// The request header `Access-Control-Request-Method` is required but is
/// missing
#[fail(display = "The request header `Access-Control-Request-Method` is required but is missing")]
MissingRequestMethod,
/// The request header `Access-Control-Request-Method` has an invalid value
#[fail(display="The request header `Access-Control-Request-Method` has an invalid value")]
#[fail(display = "The request header `Access-Control-Request-Method` has an invalid value")]
BadRequestMethod,
/// The request header `Access-Control-Request-Headers` has an invalid value
#[fail(display="The request header `Access-Control-Request-Headers` has an invalid value")]
/// The request header `Access-Control-Request-Headers` has an invalid
/// value
#[fail(display = "The request header `Access-Control-Request-Headers` has an invalid value")]
BadRequestHeaders,
/// The request header `Access-Control-Request-Headers` is required but is missing.
#[fail(display="The request header `Access-Control-Request-Headers` is required but is
/// The request header `Access-Control-Request-Headers` is required but is
/// missing.
#[fail(display = "The request header `Access-Control-Request-Headers` is required but is
missing")]
MissingRequestHeaders,
/// Origin is not allowed to make this request
#[fail(display="Origin is not allowed to make this request")]
#[fail(display = "Origin is not allowed to make this request")]
OriginNotAllowed,
/// Requested method is not allowed
#[fail(display="Requested method is not allowed")]
#[fail(display = "Requested method is not allowed")]
MethodNotAllowed,
/// One or more headers requested are not allowed
#[fail(display="One or more headers requested are not allowed")]
#[fail(display = "One or more headers requested are not allowed")]
HeadersNotAllowed,
}
impl ResponseError for CorsError {
fn error_response(&self) -> HttpResponse {
HttpResponse::with_body(StatusCode::BAD_REQUEST, format!("{}", self))
}
}
/// An enum signifying that some of type T is allowed, or `All` (everything is allowed).
/// An enum signifying that some of type T is allowed, or `All` (everything is
/// allowed).
///
/// `Default` is implemented for this enum and is `All`.
#[derive(Clone, Debug, Eq, PartialEq)]
@@ -166,9 +171,16 @@ impl Default for Cors {
origins: AllOrSome::default(),
origins_str: None,
methods: HashSet::from_iter(
vec![Method::GET, Method::HEAD,
Method::POST, Method::OPTIONS, Method::PUT,
Method::PATCH, Method::DELETE].into_iter()),
vec![
Method::GET,
Method::HEAD,
Method::POST,
Method::OPTIONS,
Method::PUT,
Method::PATCH,
Method::DELETE,
].into_iter(),
),
headers: AllOrSome::All,
expose_hdrs: None,
max_age: None,
@@ -177,7 +189,9 @@ impl Default for Cors {
supports_credentials: false,
vary_header: true,
};
Cors{inner: Rc::new(inner)}
Cors {
inner: Rc::new(inner),
}
}
}
@@ -247,11 +261,13 @@ impl Cors {
/// This method register cors middleware with resource and
/// adds route for *OPTIONS* preflight requests.
///
/// It is possible to register *Cors* middleware with `ResourceHandler::middleware()`
/// method, but in that case *Cors* middleware wont be able to handle *OPTIONS*
/// requests.
/// It is possible to register *Cors* middleware with
/// `ResourceHandler::middleware()` method, but in that case *Cors*
/// middleware wont be able to handle *OPTIONS* requests.
pub fn register<S: 'static>(self, resource: &mut ResourceHandler<S>) {
resource.method(Method::OPTIONS).h(|_| HttpResponse::Ok());
resource
.method(Method::OPTIONS)
.h(|_| HttpResponse::Ok());
resource.middleware(self);
}
@@ -260,28 +276,32 @@ impl Cors {
if let Ok(origin) = hdr.to_str() {
return match self.inner.origins {
AllOrSome::All => Ok(()),
AllOrSome::Some(ref allowed_origins) => {
allowed_origins
.get(origin)
.and_then(|_| Some(()))
.ok_or_else(|| CorsError::OriginNotAllowed)
}
AllOrSome::Some(ref allowed_origins) => allowed_origins
.get(origin)
.and_then(|_| Some(()))
.ok_or_else(|| CorsError::OriginNotAllowed),
};
}
Err(CorsError::BadOrigin)
} else {
return match self.inner.origins {
AllOrSome::All => Ok(()),
_ => Err(CorsError::MissingOrigin)
}
_ => Err(CorsError::MissingOrigin),
};
}
}
fn validate_allowed_method<S>(&self, req: &mut HttpRequest<S>) -> Result<(), CorsError> {
if let Some(hdr) = req.headers().get(header::ACCESS_CONTROL_REQUEST_METHOD) {
fn validate_allowed_method<S>(
&self, req: &mut HttpRequest<S>
) -> Result<(), CorsError> {
if let Some(hdr) = req.headers()
.get(header::ACCESS_CONTROL_REQUEST_METHOD)
{
if let Ok(meth) = hdr.to_str() {
if let Ok(method) = Method::try_from(meth) {
return self.inner.methods.get(&method)
return self.inner
.methods
.get(&method)
.and_then(|_| Some(()))
.ok_or_else(|| CorsError::MethodNotAllowed);
}
@@ -292,24 +312,28 @@ impl Cors {
}
}
fn validate_allowed_headers<S>(&self, req: &mut HttpRequest<S>) -> Result<(), CorsError> {
fn validate_allowed_headers<S>(
&self, req: &mut HttpRequest<S>
) -> Result<(), CorsError> {
match self.inner.headers {
AllOrSome::All => Ok(()),
AllOrSome::Some(ref allowed_headers) => {
if let Some(hdr) = req.headers().get(header::ACCESS_CONTROL_REQUEST_HEADERS) {
if let Some(hdr) = req.headers()
.get(header::ACCESS_CONTROL_REQUEST_HEADERS)
{
if let Ok(headers) = hdr.to_str() {
let mut hdrs = HashSet::new();
for hdr in headers.split(',') {
match HeaderName::try_from(hdr.trim()) {
Ok(hdr) => hdrs.insert(hdr),
Err(_) => return Err(CorsError::BadRequestHeaders)
Err(_) => return Err(CorsError::BadRequestHeaders),
};
}
if !hdrs.is_empty() && !hdrs.is_subset(allowed_headers) {
return Err(CorsError::HeadersNotAllowed)
return Err(CorsError::HeadersNotAllowed);
}
return Ok(())
return Ok(());
}
Err(CorsError::BadRequestHeaders)
} else {
@@ -321,7 +345,6 @@ impl Cors {
}
impl<S> Middleware<S> for Cors {
fn start(&self, req: &mut HttpRequest<S>) -> Result<Started> {
if self.inner.preflight && Method::OPTIONS == *req.method() {
self.validate_origin(req)?;
@@ -330,9 +353,17 @@ impl<S> Middleware<S> for Cors {
// allowed headers
let headers = if let Some(headers) = self.inner.headers.as_ref() {
Some(HeaderValue::try_from(&headers.iter().fold(
String::new(), |s, v| s + "," + v.as_str()).as_str()[1..]).unwrap())
} else if let Some(hdr) = req.headers().get(header::ACCESS_CONTROL_REQUEST_HEADERS) {
Some(
HeaderValue::try_from(
&headers
.iter()
.fold(String::new(), |s, v| s + "," + v.as_str())
.as_str()[1..],
).unwrap(),
)
} else if let Some(hdr) = req.headers()
.get(header::ACCESS_CONTROL_REQUEST_HEADERS)
{
Some(hdr.clone())
} else {
None
@@ -342,31 +373,44 @@ impl<S> Middleware<S> for Cors {
HttpResponse::Ok()
.if_some(self.inner.max_age.as_ref(), |max_age, resp| {
let _ = resp.header(
header::ACCESS_CONTROL_MAX_AGE, format!("{}", max_age).as_str());})
header::ACCESS_CONTROL_MAX_AGE,
format!("{}", max_age).as_str(),
);
})
.if_some(headers, |headers, resp| {
let _ = resp.header(header::ACCESS_CONTROL_ALLOW_HEADERS, headers); })
let _ =
resp.header(header::ACCESS_CONTROL_ALLOW_HEADERS, headers);
})
.if_true(self.inner.origins.is_all(), |resp| {
if self.inner.send_wildcard {
resp.header(header::ACCESS_CONTROL_ALLOW_ORIGIN, "*");
} else {
let origin = req.headers().get(header::ORIGIN).unwrap();
resp.header(
header::ACCESS_CONTROL_ALLOW_ORIGIN, origin.clone());
header::ACCESS_CONTROL_ALLOW_ORIGIN,
origin.clone(),
);
}
})
.if_true(self.inner.origins.is_some(), |resp| {
resp.header(
header::ACCESS_CONTROL_ALLOW_ORIGIN,
self.inner.origins_str.as_ref().unwrap().clone());
self.inner.origins_str.as_ref().unwrap().clone(),
);
})
.if_true(self.inner.supports_credentials, |resp| {
resp.header(header::ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");
})
.header(
header::ACCESS_CONTROL_ALLOW_METHODS,
&self.inner.methods.iter().fold(
String::new(), |s, v| s + "," + v.as_str()).as_str()[1..])
.finish()))
&self.inner
.methods
.iter()
.fold(String::new(), |s, v| s + "," + v.as_str())
.as_str()[1..],
)
.finish(),
))
} else {
self.validate_origin(req)?;
@@ -374,32 +418,40 @@ impl<S> Middleware<S> for Cors {
}
}
fn response(&self, req: &mut HttpRequest<S>, mut resp: HttpResponse) -> Result<Response> {
fn response(
&self, req: &mut HttpRequest<S>, mut resp: HttpResponse
) -> Result<Response> {
match self.inner.origins {
AllOrSome::All => {
if self.inner.send_wildcard {
resp.headers_mut().insert(
header::ACCESS_CONTROL_ALLOW_ORIGIN, HeaderValue::from_static("*"));
header::ACCESS_CONTROL_ALLOW_ORIGIN,
HeaderValue::from_static("*"),
);
} else if let Some(origin) = req.headers().get(header::ORIGIN) {
resp.headers_mut().insert(
header::ACCESS_CONTROL_ALLOW_ORIGIN, origin.clone());
resp.headers_mut()
.insert(header::ACCESS_CONTROL_ALLOW_ORIGIN, origin.clone());
}
}
AllOrSome::Some(_) => {
resp.headers_mut().insert(
header::ACCESS_CONTROL_ALLOW_ORIGIN,
self.inner.origins_str.as_ref().unwrap().clone());
self.inner.origins_str.as_ref().unwrap().clone(),
);
}
}
if let Some(ref expose) = self.inner.expose_hdrs {
resp.headers_mut().insert(
header::ACCESS_CONTROL_EXPOSE_HEADERS,
HeaderValue::try_from(expose.as_str()).unwrap());
HeaderValue::try_from(expose.as_str()).unwrap(),
);
}
if self.inner.supports_credentials {
resp.headers_mut().insert(
header::ACCESS_CONTROL_ALLOW_CREDENTIALS, HeaderValue::from_static("true"));
header::ACCESS_CONTROL_ALLOW_CREDENTIALS,
HeaderValue::from_static("true"),
);
}
if self.inner.vary_header {
let value = if let Some(hdr) = resp.headers_mut().get(header::VARY) {
@@ -416,13 +468,15 @@ impl<S> Middleware<S> for Cors {
}
}
/// Structure that follows the builder pattern for building `Cors` middleware structs.
/// Structure that follows the builder pattern for building `Cors` middleware
/// structs.
///
/// To construct a cors:
///
/// 1. Call [`Cors::build`](struct.Cors.html#method.build) to start building.
/// 2. Use any of the builder methods to set fields in the backend.
/// 3. Call [finish](struct.Cors.html#method.finish) to retrieve the constructed backend.
/// 3. Call [finish](struct.Cors.html#method.finish) to retrieve the
/// constructed backend.
///
/// # Example
///
@@ -442,7 +496,7 @@ impl<S> Middleware<S> for Cors {
/// .finish();
/// # }
/// ```
pub struct CorsBuilder<S=()> {
pub struct CorsBuilder<S = ()> {
cors: Option<Inner>,
methods: bool,
error: Option<http::Error>,
@@ -451,26 +505,26 @@ pub struct CorsBuilder<S=()> {
app: Option<App<S>>,
}
fn cors<'a>(parts: &'a mut Option<Inner>, err: &Option<http::Error>)
-> Option<&'a mut Inner>
{
fn cors<'a>(
parts: &'a mut Option<Inner>, err: &Option<http::Error>
) -> Option<&'a mut Inner> {
if err.is_some() {
return None
return None;
}
parts.as_mut()
}
impl<S: 'static> CorsBuilder<S> {
/// Add an origin that are allowed to make requests.
/// Will be verified against the `Origin` request header.
///
/// When `All` is set, and `send_wildcard` is set, "*" will be sent in
/// the `Access-Control-Allow-Origin` response header. Otherwise, the client's `Origin` request
/// header will be echoed back in the `Access-Control-Allow-Origin` response header.
/// the `Access-Control-Allow-Origin` response header. Otherwise, the
/// client's `Origin` request header will be echoed back in the
/// `Access-Control-Allow-Origin` response header.
///
/// When `Some` is set, the client's `Origin` request header will be checked in a
/// case-sensitive manner.
/// When `Some` is set, the client's `Origin` request header will be
/// checked in a case-sensitive manner.
///
/// This is the `list of origins` in the
/// [Resource Processing Model](https://www.w3.org/TR/cors/#resource-processing-model).
@@ -497,15 +551,17 @@ impl<S: 'static> CorsBuilder<S> {
self
}
/// Set a list of methods which the allowed origins are allowed to access for
/// requests.
/// Set a list of methods which the allowed origins are allowed to access
/// for requests.
///
/// This is the `list of methods` in the
/// [Resource Processing Model](https://www.w3.org/TR/cors/#resource-processing-model).
///
/// Defaults to `[GET, HEAD, POST, OPTIONS, PUT, PATCH, DELETE]`
pub fn allowed_methods<U, M>(&mut self, methods: U) -> &mut CorsBuilder<S>
where U: IntoIterator<Item=M>, Method: HttpTryFrom<M>
where
U: IntoIterator<Item = M>,
Method: HttpTryFrom<M>,
{
self.methods = true;
if let Some(cors) = cors(&mut self.cors, &self.error) {
@@ -513,20 +569,21 @@ impl<S: 'static> CorsBuilder<S> {
match Method::try_from(m) {
Ok(method) => {
cors.methods.insert(method);
},
}
Err(e) => {
self.error = Some(e.into());
break
break;
}
}
};
}
}
self
}
/// Set an allowed header
pub fn allowed_header<H>(&mut self, header: H) -> &mut CorsBuilder<S>
where HeaderName: HttpTryFrom<H>
where
HeaderName: HttpTryFrom<H>,
{
if let Some(cors) = cors(&mut self.cors, &self.error) {
match HeaderName::try_from(header) {
@@ -547,15 +604,18 @@ impl<S: 'static> CorsBuilder<S> {
/// Set a list of header field names which can be used when
/// this resource is accessed by allowed origins.
///
/// If `All` is set, whatever is requested by the client in `Access-Control-Request-Headers`
/// will be echoed back in the `Access-Control-Allow-Headers` header.
/// If `All` is set, whatever is requested by the client in
/// `Access-Control-Request-Headers` will be echoed back in the
/// `Access-Control-Allow-Headers` header.
///
/// This is the `list of headers` in the
/// [Resource Processing Model](https://www.w3.org/TR/cors/#resource-processing-model).
///
/// Defaults to `All`.
pub fn allowed_headers<U, H>(&mut self, headers: U) -> &mut CorsBuilder<S>
where U: IntoIterator<Item=H>, HeaderName: HttpTryFrom<H>
where
U: IntoIterator<Item = H>,
HeaderName: HttpTryFrom<H>,
{
if let Some(cors) = cors(&mut self.cors, &self.error) {
for h in headers {
@@ -570,32 +630,35 @@ impl<S: 'static> CorsBuilder<S> {
}
Err(e) => {
self.error = Some(e.into());
break
break;
}
}
};
}
}
self
}
/// Set a list of headers which are safe to expose to the API of a CORS API specification.
/// This corresponds to the `Access-Control-Expose-Headers` response header.
/// Set a list of headers which are safe to expose to the API of a CORS API
/// specification. This corresponds to the
/// `Access-Control-Expose-Headers` response header.
///
/// This is the `list of exposed headers` in the
/// [Resource Processing Model](https://www.w3.org/TR/cors/#resource-processing-model).
///
/// This defaults to an empty set.
pub fn expose_headers<U, H>(&mut self, headers: U) -> &mut CorsBuilder<S>
where U: IntoIterator<Item=H>, HeaderName: HttpTryFrom<H>
where
U: IntoIterator<Item = H>,
HeaderName: HttpTryFrom<H>,
{
for h in headers {
match HeaderName::try_from(h) {
Ok(method) => {
self.expose_hdrs.insert(method);
},
}
Err(e) => {
self.error = Some(e.into());
break
break;
}
}
}
@@ -615,16 +678,17 @@ impl<S: 'static> CorsBuilder<S> {
/// Set a wildcard origins
///
/// If send wildcard is set and the `allowed_origins` parameter is `All`, a wildcard
/// `Access-Control-Allow-Origin` response header is sent, rather than the requests
/// `Origin` header.
/// If send wildcard is set and the `allowed_origins` parameter is `All`, a
/// wildcard `Access-Control-Allow-Origin` response header is sent,
/// rather than the requests `Origin` header.
///
/// This is the `supports credentials flag` in the
/// [Resource Processing Model](https://www.w3.org/TR/cors/#resource-processing-model).
///
/// This **CANNOT** be used in conjunction with `allowed_origins` set to `All` and
/// `allow_credentials` set to `true`. Depending on the mode of usage, this will either result
/// in an `Error::CredentialsWithWildcardOrigin` error during actix launch or runtime.
/// This **CANNOT** be used in conjunction with `allowed_origins` set to
/// `All` and `allow_credentials` set to `true`. Depending on the mode
/// of usage, this will either result in an `Error::
/// CredentialsWithWildcardOrigin` error during actix launch or runtime.
///
/// Defaults to `false`.
pub fn send_wildcard(&mut self) -> &mut CorsBuilder<S> {
@@ -636,11 +700,12 @@ impl<S: 'static> CorsBuilder<S> {
/// Allows users to make authenticated requests
///
/// If true, injects the `Access-Control-Allow-Credentials` header in responses.
/// This allows cookies and credentials to be submitted across domains.
/// If true, injects the `Access-Control-Allow-Credentials` header in
/// responses. This allows cookies and credentials to be submitted
/// across domains.
///
/// This option cannot be used in conjunction with an `allowed_origin` set to `All`
/// and `send_wildcards` set to `true`.
/// This option cannot be used in conjunction with an `allowed_origin` set
/// to `All` and `send_wildcards` set to `true`.
///
/// Defaults to `false`.
///
@@ -713,7 +778,8 @@ impl<S: 'static> CorsBuilder<S> {
/// }
/// ```
pub fn resource<F, R>(&mut self, path: &str, f: F) -> &mut CorsBuilder<S>
where F: FnOnce(&mut ResourceHandler<S>) -> R + 'static
where
F: FnOnce(&mut ResourceHandler<S>) -> R + 'static,
{
// add resource handler
let mut handler = ResourceHandler::default();
@@ -725,9 +791,15 @@ impl<S: 'static> CorsBuilder<S> {
fn construct(&mut self) -> Cors {
if !self.methods {
self.allowed_methods(vec![Method::GET, Method::HEAD,
Method::POST, Method::OPTIONS, Method::PUT,
Method::PATCH, Method::DELETE]);
self.allowed_methods(vec![
Method::GET,
Method::HEAD,
Method::POST,
Method::OPTIONS,
Method::PUT,
Method::PATCH,
Method::DELETE,
]);
}
if let Some(e) = self.error.take() {
@@ -741,16 +813,23 @@ impl<S: 'static> CorsBuilder<S> {
}
if let AllOrSome::Some(ref origins) = cors.origins {
let s = origins.iter().fold(String::new(), |s, v| s + &format!("{}", v));
let s = origins
.iter()
.fold(String::new(), |s, v| s + &format!("{}", v));
cors.origins_str = Some(HeaderValue::try_from(s.as_str()).unwrap());
}
if !self.expose_hdrs.is_empty() {
cors.expose_hdrs = Some(
self.expose_hdrs.iter().fold(
String::new(), |s, v| s + v.as_str())[1..].to_owned());
self.expose_hdrs
.iter()
.fold(String::new(), |s, v| s + v.as_str())[1..]
.to_owned(),
);
}
Cors {
inner: Rc::new(cors),
}
Cors{inner: Rc::new(cors)}
}
/// Finishes building and returns the built `Cors` instance.
@@ -758,13 +837,16 @@ impl<S: 'static> CorsBuilder<S> {
/// This method panics in case of any configuration error.
pub fn finish(&mut self) -> Cors {
if !self.resources.is_empty() {
panic!("CorsBuilder::resource() was used,
to construct CORS `.register(app)` method should be used");
panic!(
"CorsBuilder::resource() was used,
to construct CORS `.register(app)` method should be used"
);
}
self.construct()
}
/// Finishes building Cors middleware and register middleware for application
/// Finishes building Cors middleware and register middleware for
/// application
///
/// This method panics in case of any configuration error or if non of
/// resources are registered.
@@ -774,8 +856,9 @@ impl<S: 'static> CorsBuilder<S> {
}
let cors = self.construct();
let mut app = self.app.take().expect(
"CorsBuilder has to be constructed with Cors::for_app(app)");
let mut app = self.app
.take()
.expect("CorsBuilder has to be constructed with Cors::for_app(app)");
// register resources
for (path, mut resource) in self.resources.drain(..) {
@@ -787,7 +870,6 @@ impl<S: 'static> CorsBuilder<S> {
}
}
#[cfg(test)]
mod tests {
use super::*;
@@ -845,8 +927,8 @@ mod tests {
#[test]
fn validate_origin_allows_all_origins() {
let cors = Cors::default();
let mut req = TestRequest::with_header(
"Origin", "https://www.example.com").finish();
let mut req =
TestRequest::with_header("Origin", "https://www.example.com").finish();
assert!(cors.start(&mut req).ok().unwrap().is_done())
}
@@ -861,8 +943,7 @@ mod tests {
.allowed_header(header::CONTENT_TYPE)
.finish();
let mut req = TestRequest::with_header(
"Origin", "https://www.example.com")
let mut req = TestRequest::with_header("Origin", "https://www.example.com")
.method(Method::OPTIONS)
.finish();
@@ -877,23 +958,35 @@ mod tests {
let mut req = TestRequest::with_header("Origin", "https://www.example.com")
.header(header::ACCESS_CONTROL_REQUEST_METHOD, "POST")
.header(header::ACCESS_CONTROL_REQUEST_HEADERS, "AUTHORIZATION,ACCEPT")
.header(
header::ACCESS_CONTROL_REQUEST_HEADERS,
"AUTHORIZATION,ACCEPT",
)
.method(Method::OPTIONS)
.finish();
let resp = cors.start(&mut req).unwrap().response();
assert_eq!(
&b"*"[..],
resp.headers().get(header::ACCESS_CONTROL_ALLOW_ORIGIN).unwrap().as_bytes());
resp.headers()
.get(header::ACCESS_CONTROL_ALLOW_ORIGIN)
.unwrap()
.as_bytes()
);
assert_eq!(
&b"3600"[..],
resp.headers().get(header::ACCESS_CONTROL_MAX_AGE).unwrap().as_bytes());
resp.headers()
.get(header::ACCESS_CONTROL_MAX_AGE)
.unwrap()
.as_bytes()
);
//assert_eq!(
// &b"authorization,accept,content-type"[..],
// resp.headers().get(header::ACCESS_CONTROL_ALLOW_HEADERS).unwrap().as_bytes());
//assert_eq!(
// resp.headers().get(header::ACCESS_CONTROL_ALLOW_HEADERS).unwrap().
// as_bytes()); assert_eq!(
// &b"POST,GET,OPTIONS"[..],
// resp.headers().get(header::ACCESS_CONTROL_ALLOW_METHODS).unwrap().as_bytes());
// resp.headers().get(header::ACCESS_CONTROL_ALLOW_METHODS).unwrap().
// as_bytes());
Rc::get_mut(&mut cors.inner).unwrap().preflight = false;
assert!(cors.start(&mut req).unwrap().is_done());
@@ -903,7 +996,8 @@ mod tests {
#[should_panic(expected = "MissingOrigin")]
fn test_validate_missing_origin() {
let cors = Cors::build()
.allowed_origin("https://www.example.com").finish();
.allowed_origin("https://www.example.com")
.finish();
let mut req = HttpRequest::default();
cors.start(&mut req).unwrap();
@@ -913,7 +1007,8 @@ mod tests {
#[should_panic(expected = "OriginNotAllowed")]
fn test_validate_not_allowed_origin() {
let cors = Cors::build()
.allowed_origin("https://www.example.com").finish();
.allowed_origin("https://www.example.com")
.finish();
let mut req = TestRequest::with_header("Origin", "https://www.unknown.com")
.method(Method::GET)
@@ -924,7 +1019,8 @@ mod tests {
#[test]
fn test_validate_origin() {
let cors = Cors::build()
.allowed_origin("https://www.example.com").finish();
.allowed_origin("https://www.example.com")
.finish();
let mut req = TestRequest::with_header("Origin", "https://www.example.com")
.method(Method::GET)
@@ -940,16 +1036,23 @@ mod tests {
let mut req = TestRequest::default().method(Method::GET).finish();
let resp: HttpResponse = HttpResponse::Ok().into();
let resp = cors.response(&mut req, resp).unwrap().response();
assert!(resp.headers().get(header::ACCESS_CONTROL_ALLOW_ORIGIN).is_none());
assert!(
resp.headers()
.get(header::ACCESS_CONTROL_ALLOW_ORIGIN)
.is_none()
);
let mut req = TestRequest::with_header(
"Origin", "https://www.example.com")
let mut req = TestRequest::with_header("Origin", "https://www.example.com")
.method(Method::OPTIONS)
.finish();
let resp = cors.response(&mut req, resp).unwrap().response();
assert_eq!(
&b"https://www.example.com"[..],
resp.headers().get(header::ACCESS_CONTROL_ALLOW_ORIGIN).unwrap().as_bytes());
resp.headers()
.get(header::ACCESS_CONTROL_ALLOW_ORIGIN)
.unwrap()
.as_bytes()
);
}
#[test]
@@ -963,8 +1066,7 @@ mod tests {
.allowed_header(header::CONTENT_TYPE)
.finish();
let mut req = TestRequest::with_header(
"Origin", "https://www.example.com")
let mut req = TestRequest::with_header("Origin", "https://www.example.com")
.method(Method::OPTIONS)
.finish();
@@ -972,10 +1074,15 @@ mod tests {
let resp = cors.response(&mut req, resp).unwrap().response();
assert_eq!(
&b"*"[..],
resp.headers().get(header::ACCESS_CONTROL_ALLOW_ORIGIN).unwrap().as_bytes());
resp.headers()
.get(header::ACCESS_CONTROL_ALLOW_ORIGIN)
.unwrap()
.as_bytes()
);
assert_eq!(
&b"Origin"[..],
resp.headers().get(header::VARY).unwrap().as_bytes());
resp.headers().get(header::VARY).unwrap().as_bytes()
);
let resp: HttpResponse = HttpResponse::Ok()
.header(header::VARY, "Accept")
@@ -983,7 +1090,8 @@ mod tests {
let resp = cors.response(&mut req, resp).unwrap().response();
assert_eq!(
&b"Accept, Origin"[..],
resp.headers().get(header::VARY).unwrap().as_bytes());
resp.headers().get(header::VARY).unwrap().as_bytes()
);
let cors = Cors::build()
.disable_vary_header()
@@ -993,25 +1101,33 @@ mod tests {
let resp = cors.response(&mut req, resp).unwrap().response();
assert_eq!(
&b"https://www.example.com"[..],
resp.headers().get(header::ACCESS_CONTROL_ALLOW_ORIGIN).unwrap().as_bytes());
resp.headers()
.get(header::ACCESS_CONTROL_ALLOW_ORIGIN)
.unwrap()
.as_bytes()
);
}
#[test]
fn cors_resource() {
let mut srv = test::TestServer::with_factory(
|| App::new()
.configure(
|app| Cors::for_app(app)
.allowed_origin("https://www.example.com")
.resource("/test", |r| r.f(|_| HttpResponse::Ok()))
.register()));
let mut srv = test::TestServer::with_factory(|| {
App::new().configure(|app| {
Cors::for_app(app)
.allowed_origin("https://www.example.com")
.resource("/test", |r| r.f(|_| HttpResponse::Ok()))
.register()
})
});
let request = srv.get().uri(srv.url("/test")).finish().unwrap();
let response = srv.execute(request.send()).unwrap();
assert_eq!(response.status(), StatusCode::BAD_REQUEST);
let request = srv.get().uri(srv.url("/test"))
.header("ORIGIN", "https://www.example.com").finish().unwrap();
let request = srv.get()
.uri(srv.url("/test"))
.header("ORIGIN", "https://www.example.com")
.finish()
.unwrap();
let response = srv.execute(request.send()).unwrap();
assert_eq!(response.status(), StatusCode::OK);
}