1
0
mirror of https://github.com/actix/actix-extras.git synced 2025-06-26 10:27:42 +02:00

fix cors expose_any_header behavior (#204)

This commit is contained in:
Rob Ede
2021-10-21 15:47:56 +01:00
committed by GitHub
parent 545873b5b2
commit 45643d4035
7 changed files with 75 additions and 9 deletions

View File

@ -95,6 +95,7 @@ impl Cors {
expose_headers: AllOrSome::All,
expose_headers_baked: None,
max_age: Some(3600),
preflight: true,
send_wildcard: false,
@ -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

View File

@ -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},
@ -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.
///
@ -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 {