mirror of
https://github.com/actix/actix-extras.git
synced 2025-06-26 10:27:42 +02:00
CORS builder rework (#119)
This commit is contained in:
@ -10,12 +10,15 @@ use regex::bytes::Regex;
|
||||
|
||||
use actix_cors::Cors;
|
||||
|
||||
fn val_as_str(val: &HeaderValue) -> &str {
|
||||
val.to_str().unwrap()
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
#[should_panic]
|
||||
async fn test_wildcard_origin() {
|
||||
Cors::new()
|
||||
Cors::default()
|
||||
.allowed_origin("*")
|
||||
.finish()
|
||||
.new_transform(test::ok_service())
|
||||
.await
|
||||
.unwrap();
|
||||
@ -23,7 +26,7 @@ async fn test_wildcard_origin() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_not_allowed_origin_fn() {
|
||||
let mut cors = Cors::new()
|
||||
let mut cors = Cors::default()
|
||||
.allowed_origin("https://www.example.com")
|
||||
.allowed_origin_fn(|req| {
|
||||
req.headers
|
||||
@ -32,7 +35,6 @@ async fn test_not_allowed_origin_fn() {
|
||||
.filter(|b| b.ends_with(b".unknown.com"))
|
||||
.is_some()
|
||||
})
|
||||
.finish()
|
||||
.new_transform(test::ok_service())
|
||||
.await
|
||||
.unwrap();
|
||||
@ -68,7 +70,7 @@ async fn test_not_allowed_origin_fn() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_allowed_origin_fn() {
|
||||
let mut cors = Cors::new()
|
||||
let mut cors = Cors::default()
|
||||
.allowed_origin("https://www.example.com")
|
||||
.allowed_origin_fn(|req| {
|
||||
req.headers
|
||||
@ -77,7 +79,6 @@ async fn test_allowed_origin_fn() {
|
||||
.filter(|b| b.ends_with(b".unknown.com"))
|
||||
.is_some()
|
||||
})
|
||||
.finish()
|
||||
.new_transform(test::ok_service())
|
||||
.await
|
||||
.unwrap();
|
||||
@ -92,8 +93,7 @@ async fn test_allowed_origin_fn() {
|
||||
"https://www.example.com",
|
||||
resp.headers()
|
||||
.get(header::ACCESS_CONTROL_ALLOW_ORIGIN)
|
||||
.unwrap()
|
||||
.to_str()
|
||||
.map(val_as_str)
|
||||
.unwrap()
|
||||
);
|
||||
|
||||
@ -114,7 +114,7 @@ async fn test_allowed_origin_fn() {
|
||||
#[actix_rt::test]
|
||||
async fn test_allowed_origin_fn_with_environment() {
|
||||
let regex = Regex::new("https:.+\\.unknown\\.com").unwrap();
|
||||
let mut cors = Cors::new()
|
||||
let mut cors = Cors::default()
|
||||
.allowed_origin("https://www.example.com")
|
||||
.allowed_origin_fn(move |req| {
|
||||
req.headers
|
||||
@ -123,7 +123,6 @@ async fn test_allowed_origin_fn_with_environment() {
|
||||
.filter(|b| regex.is_match(b))
|
||||
.is_some()
|
||||
})
|
||||
.finish()
|
||||
.new_transform(test::ok_service())
|
||||
.await
|
||||
.unwrap();
|
||||
@ -138,8 +137,7 @@ async fn test_allowed_origin_fn_with_environment() {
|
||||
"https://www.example.com",
|
||||
resp.headers()
|
||||
.get(header::ACCESS_CONTROL_ALLOW_ORIGIN)
|
||||
.unwrap()
|
||||
.to_str()
|
||||
.map(val_as_str)
|
||||
.unwrap()
|
||||
);
|
||||
|
||||
@ -159,11 +157,10 @@ async fn test_allowed_origin_fn_with_environment() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_multiple_origins_preflight() {
|
||||
let mut cors = Cors::new()
|
||||
let mut cors = Cors::default()
|
||||
.allowed_origin("https://example.com")
|
||||
.allowed_origin("https://example.org")
|
||||
.allowed_methods(vec![Method::GET])
|
||||
.finish()
|
||||
.new_transform(test::ok_service())
|
||||
.await
|
||||
.unwrap();
|
||||
@ -175,11 +172,10 @@ async fn test_multiple_origins_preflight() {
|
||||
|
||||
let resp = test::call_service(&mut cors, req).await;
|
||||
assert_eq!(
|
||||
&b"https://example.com"[..],
|
||||
Some(&b"https://example.com"[..]),
|
||||
resp.headers()
|
||||
.get(header::ACCESS_CONTROL_ALLOW_ORIGIN)
|
||||
.unwrap()
|
||||
.as_bytes()
|
||||
.map(HeaderValue::as_bytes)
|
||||
);
|
||||
|
||||
let req = TestRequest::with_header("Origin", "https://example.org")
|
||||
@ -189,21 +185,19 @@ async fn test_multiple_origins_preflight() {
|
||||
|
||||
let resp = test::call_service(&mut cors, req).await;
|
||||
assert_eq!(
|
||||
&b"https://example.org"[..],
|
||||
Some(&b"https://example.org"[..]),
|
||||
resp.headers()
|
||||
.get(header::ACCESS_CONTROL_ALLOW_ORIGIN)
|
||||
.unwrap()
|
||||
.as_bytes()
|
||||
.map(HeaderValue::as_bytes)
|
||||
);
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_multiple_origins() {
|
||||
let mut cors = Cors::new()
|
||||
let mut cors = Cors::default()
|
||||
.allowed_origin("https://example.com")
|
||||
.allowed_origin("https://example.org")
|
||||
.allowed_methods(vec![Method::GET])
|
||||
.finish()
|
||||
.new_transform(test::ok_service())
|
||||
.await
|
||||
.unwrap();
|
||||
@ -214,11 +208,10 @@ async fn test_multiple_origins() {
|
||||
|
||||
let resp = test::call_service(&mut cors, req).await;
|
||||
assert_eq!(
|
||||
&b"https://example.com"[..],
|
||||
Some(&b"https://example.com"[..]),
|
||||
resp.headers()
|
||||
.get(header::ACCESS_CONTROL_ALLOW_ORIGIN)
|
||||
.unwrap()
|
||||
.as_bytes()
|
||||
.map(HeaderValue::as_bytes)
|
||||
);
|
||||
|
||||
let req = TestRequest::with_header("Origin", "https://example.org")
|
||||
@ -227,18 +220,18 @@ async fn test_multiple_origins() {
|
||||
|
||||
let resp = test::call_service(&mut cors, req).await;
|
||||
assert_eq!(
|
||||
&b"https://example.org"[..],
|
||||
Some(&b"https://example.org"[..]),
|
||||
resp.headers()
|
||||
.get(header::ACCESS_CONTROL_ALLOW_ORIGIN)
|
||||
.unwrap()
|
||||
.as_bytes()
|
||||
.map(HeaderValue::as_bytes)
|
||||
);
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_response() {
|
||||
let exposed_headers = vec![header::AUTHORIZATION, header::ACCEPT];
|
||||
let mut cors = Cors::new()
|
||||
let mut cors = Cors::default()
|
||||
.allow_any_origin()
|
||||
.send_wildcard()
|
||||
.disable_preflight()
|
||||
.max_age(3600)
|
||||
@ -246,7 +239,6 @@ async fn test_response() {
|
||||
.allowed_headers(exposed_headers.clone())
|
||||
.expose_headers(exposed_headers.clone())
|
||||
.allowed_header(header::CONTENT_TYPE)
|
||||
.finish()
|
||||
.new_transform(test::ok_service())
|
||||
.await
|
||||
.unwrap();
|
||||
@ -254,18 +246,16 @@ async fn test_response() {
|
||||
let req = TestRequest::with_header("Origin", "https://www.example.com")
|
||||
.method(Method::OPTIONS)
|
||||
.to_srv_request();
|
||||
|
||||
let resp = test::call_service(&mut cors, req).await;
|
||||
assert_eq!(
|
||||
&b"*"[..],
|
||||
Some(&b"*"[..]),
|
||||
resp.headers()
|
||||
.get(header::ACCESS_CONTROL_ALLOW_ORIGIN)
|
||||
.unwrap()
|
||||
.as_bytes()
|
||||
.map(HeaderValue::as_bytes)
|
||||
);
|
||||
assert_eq!(
|
||||
&b"Origin"[..],
|
||||
resp.headers().get(header::VARY).unwrap().as_bytes()
|
||||
Some(&b"Origin"[..]),
|
||||
resp.headers().get(header::VARY).map(HeaderValue::as_bytes)
|
||||
);
|
||||
|
||||
#[allow(clippy::needless_collect)]
|
||||
@ -273,20 +263,21 @@ async fn test_response() {
|
||||
let headers = resp
|
||||
.headers()
|
||||
.get(header::ACCESS_CONTROL_EXPOSE_HEADERS)
|
||||
.unwrap()
|
||||
.to_str()
|
||||
.map(val_as_str)
|
||||
.unwrap()
|
||||
.split(',')
|
||||
.map(|s| s.trim())
|
||||
.collect::<Vec<&str>>();
|
||||
|
||||
// TODO: use HashSet subset check
|
||||
for h in exposed_headers {
|
||||
assert!(headers.contains(&h.as_str()));
|
||||
}
|
||||
}
|
||||
|
||||
let exposed_headers = vec![header::AUTHORIZATION, header::ACCEPT];
|
||||
let mut cors = Cors::new()
|
||||
let mut cors = Cors::default()
|
||||
.allow_any_origin()
|
||||
.send_wildcard()
|
||||
.disable_preflight()
|
||||
.max_age(3600)
|
||||
@ -294,28 +285,28 @@ async fn test_response() {
|
||||
.allowed_headers(exposed_headers.clone())
|
||||
.expose_headers(exposed_headers.clone())
|
||||
.allowed_header(header::CONTENT_TYPE)
|
||||
.finish()
|
||||
.new_transform(fn_service(|req: ServiceRequest| {
|
||||
ok(req.into_response(
|
||||
HttpResponse::Ok().header(header::VARY, "Accept").finish(),
|
||||
))
|
||||
ok(req.into_response({
|
||||
HttpResponse::Ok().header(header::VARY, "Accept").finish()
|
||||
}))
|
||||
}))
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
let req = TestRequest::with_header("Origin", "https://www.example.com")
|
||||
.method(Method::OPTIONS)
|
||||
.to_srv_request();
|
||||
let resp = test::call_service(&mut cors, req).await;
|
||||
assert_eq!(
|
||||
&b"Accept, Origin"[..],
|
||||
resp.headers().get(header::VARY).unwrap().as_bytes()
|
||||
Some(&b"Accept, Origin"[..]),
|
||||
resp.headers().get(header::VARY).map(HeaderValue::as_bytes)
|
||||
);
|
||||
|
||||
let mut cors = Cors::new()
|
||||
let mut cors = Cors::default()
|
||||
.disable_vary_header()
|
||||
.allowed_methods(vec!["POST"])
|
||||
.allowed_origin("https://www.example.com")
|
||||
.allowed_origin("https://www.google.com")
|
||||
.finish()
|
||||
.new_transform(test::ok_service())
|
||||
.await
|
||||
.unwrap();
|
||||
@ -325,22 +316,17 @@ async fn test_response() {
|
||||
.header(header::ACCESS_CONTROL_REQUEST_METHOD, "POST")
|
||||
.to_srv_request();
|
||||
let resp = test::call_service(&mut cors, req).await;
|
||||
|
||||
let origins_str = resp
|
||||
.headers()
|
||||
.get(header::ACCESS_CONTROL_ALLOW_ORIGIN)
|
||||
.unwrap()
|
||||
.to_str()
|
||||
.unwrap();
|
||||
|
||||
assert_eq!("https://www.example.com", origins_str);
|
||||
.map(val_as_str);
|
||||
assert_eq!(Some("https://www.example.com"), origins_str);
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_validate_origin() {
|
||||
let mut cors = Cors::new()
|
||||
let mut cors = Cors::default()
|
||||
.allowed_origin("https://www.example.com")
|
||||
.finish()
|
||||
.new_transform(test::ok_service())
|
||||
.await
|
||||
.unwrap();
|
||||
@ -355,9 +341,8 @@ async fn test_validate_origin() {
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn test_no_origin_response() {
|
||||
let mut cors = Cors::new()
|
||||
let mut cors = Cors::permissive()
|
||||
.disable_preflight()
|
||||
.finish()
|
||||
.new_transform(test::ok_service())
|
||||
.await
|
||||
.unwrap();
|
||||
@ -374,18 +359,16 @@ async fn test_no_origin_response() {
|
||||
.to_srv_request();
|
||||
let resp = test::call_service(&mut cors, req).await;
|
||||
assert_eq!(
|
||||
&b"https://www.example.com"[..],
|
||||
Some(&b"https://www.example.com"[..]),
|
||||
resp.headers()
|
||||
.get(header::ACCESS_CONTROL_ALLOW_ORIGIN)
|
||||
.unwrap()
|
||||
.as_bytes()
|
||||
.map(HeaderValue::as_bytes)
|
||||
);
|
||||
}
|
||||
|
||||
#[actix_rt::test]
|
||||
async fn validate_origin_allows_all_origins() {
|
||||
let mut cors = Cors::new()
|
||||
.finish()
|
||||
let mut cors = Cors::permissive()
|
||||
.new_transform(test::ok_service())
|
||||
.await
|
||||
.unwrap();
|
||||
|
Reference in New Issue
Block a user