Skip to content

Commit

Permalink
fix cors expose_any_header behavior (#204)
Browse files Browse the repository at this point in the history
  • Loading branch information
robjtede authored Oct 21, 2021
1 parent 545873b commit 45643d4
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 9 deletions.
5 changes: 5 additions & 0 deletions actix-cors/CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
# Changes

## Unreleased - 2021-xx-xx


## 0.6.0-beta.3 - 2021-10-21
* Make `Cors` middleware generic over body type [#195]
* Fix `expose_any_header` behavior. [#204]
* Update `actix-web` dependency to v4.0.0-beta.10. [#203]
* Minimum supported Rust version (MSRV) is now 1.52.

[#195]: https://github.com/actix/actix-extras/pull/195
[#203]: https://github.com/actix/actix-extras/pull/203
[#204]: https://github.com/actix/actix-extras/pull/204


## 0.6.0-beta.2 - 2021-06-27
Expand Down
4 changes: 2 additions & 2 deletions actix-cors/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
[package]
name = "actix-cors"
version = "0.6.0-beta.2"
version = "0.6.0-beta.3"
authors = [
"Nikolay Kim <[email protected]>",
"Rob Ede <[email protected]>",
]
description = "Cross-Origin Resource Sharing (CORS) controls for Actix Web"
keywords = ["actix", "cors", "web", "security", "crossorigin"]
homepage = "https://actix.rs"
repository = "https://github.com/actix/actix-extras"
repository = "https://github.com/actix/actix-extras.git"
license = "MIT OR Apache-2.0"
edition = "2018"

Expand Down
4 changes: 2 additions & 2 deletions actix-cors/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
> Cross-origin resource sharing (CORS) for Actix Web.
[![crates.io](https://img.shields.io/crates/v/actix-cors?label=latest)](https://crates.io/crates/actix-cors)
[![Documentation](https://docs.rs/actix-cors/badge.svg?version=0.6.0-beta.2)](https://docs.rs/actix-cors/0.6.0-beta.2)
[![Documentation](https://docs.rs/actix-cors/badge.svg?version=0.6.0-beta.3)](https://docs.rs/actix-cors/0.6.0-beta.3)
![Apache 2.0 or MIT licensed](https://img.shields.io/crates/l/actix-cors)
[![Dependency Status](https://deps.rs/crate/actix-cors/0.6.0-beta.2/status.svg)](https://deps.rs/crate/actix-cors/0.6.0-beta.2)
[![Dependency Status](https://deps.rs/crate/actix-cors/0.6.0-beta.3/status.svg)](https://deps.rs/crate/actix-cors/0.6.0-beta.3)

## Documentation & Resources

Expand Down
10 changes: 8 additions & 2 deletions actix-cors/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ impl Cors {

expose_headers: AllOrSome::All,
expose_headers_baked: None,

max_age: Some(3600),
preflight: true,
send_wildcard: false,
Expand Down Expand Up @@ -544,13 +545,18 @@ where
}

/// Only call when values are guaranteed to be valid header values and set is not empty.
fn intersperse_header_values<T>(val_set: &HashSet<T>) -> HeaderValue
pub(crate) fn intersperse_header_values<T>(val_set: &HashSet<T>) -> HeaderValue
where
T: AsRef<str>,
{
debug_assert!(
!val_set.is_empty(),
"only call `intersperse_header_values` when set is not empty"
);

val_set
.iter()
.fold(String::with_capacity(32), |mut acc, val| {
.fold(String::with_capacity(64), |mut acc, val| {
acc.push_str(", ");
acc.push_str(val.as_ref());
acc
Expand Down
30 changes: 28 additions & 2 deletions actix-cors/src/middleware.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{convert::TryInto, error::Error as StdError, rc::Rc};
use std::{collections::HashSet, convert::TryInto, error::Error as StdError, rc::Rc};

use actix_web::{
body::{AnyBody, MessageBody},
Expand All @@ -13,7 +13,7 @@ use actix_web::{
use futures_util::future::{ok, Either, FutureExt as _, LocalBoxFuture, Ready, TryFutureExt as _};
use log::debug;

use crate::Inner;
use crate::{builder::intersperse_header_values, AllOrSome, Inner};

/// Service wrapper for Cross-Origin Resource Sharing support.
///
Expand Down Expand Up @@ -78,8 +78,34 @@ impl<S> CorsMiddleware<S> {
};

if let Some(ref expose) = inner.expose_headers_baked {
log::trace!("exposing selected headers: {:?}", expose);

res.headers_mut()
.insert(header::ACCESS_CONTROL_EXPOSE_HEADERS, expose.clone());
} else if matches!(inner.expose_headers, AllOrSome::All) {
// intersperse_header_values requires that argument is non-empty
if !res.request().headers().is_empty() {
// extract header names from request
let expose_all_request_headers = res
.request()
.headers()
.keys()
.into_iter()
.map(|name| name.as_str())
.collect::<HashSet<_>>();

// create comma separated string of header names
let expose_headers_value = intersperse_header_values(&expose_all_request_headers);

log::trace!(
"exposing all headers from request: {:?}",
expose_headers_value
);

// add header names to expose response header
res.headers_mut()
.insert(header::ACCESS_CONTROL_EXPOSE_HEADERS, expose_headers_value);
}
}

if inner.supports_credentials {
Expand Down
29 changes: 29 additions & 0 deletions actix-cors/tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -416,3 +416,32 @@ async fn test_allow_any_origin_any_method_any_header() {
let resp = test::call_service(&cors, req).await;
assert_eq!(resp.status(), StatusCode::OK);
}

#[actix_web::test]
async fn expose_all_request_header_values() {
let cors = Cors::permissive()
.new_transform(test::ok_service())
.await
.unwrap();

let req = TestRequest::default()
.insert_header((header::ORIGIN, "https://www.example.com"))
.insert_header((header::ACCESS_CONTROL_REQUEST_METHOD, "POST"))
.insert_header((header::ACCESS_CONTROL_REQUEST_HEADERS, "content-type"))
.insert_header(("X-XSRF-TOKEN", "xsrf-token"))
.to_srv_request();

let resp = test::call_service(&cors, req).await;

assert!(resp
.headers()
.contains_key(header::ACCESS_CONTROL_EXPOSE_HEADERS));

assert!(resp
.headers()
.get(header::ACCESS_CONTROL_EXPOSE_HEADERS)
.unwrap()
.to_str()
.unwrap()
.contains("xsrf-token"));
}
2 changes: 1 addition & 1 deletion actix-web-httpauth/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,5 @@ base64 = "0.13"
futures-util = { version = "0.3.7", default-features = false }

[dev-dependencies]
actix-cors = "0.6.0-beta.2"
actix-cors = "0.6.0-beta.3"
actix-rt = "2"

0 comments on commit 45643d4

Please sign in to comment.