diff --git a/CHANGES.md b/CHANGES.md index f7e663d6..d0488c55 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -15,7 +15,6 @@ * Allow TestServer to open a websocket on any URL (TestServer::ws_at()) #433 - ### Fixed * Fixed failure 0.1.2 compatibility @@ -26,6 +25,8 @@ * HttpRequest::url_for is not working with scopes #429 +* Fixed headers' formating for CORS Middleware `Access-Control-Expose-Headers` header value to HTTP/1.1 & HTTP/2 spec-compliant format #436 + ## [0.7.2] - 2018-07-26 diff --git a/src/middleware/cors.rs b/src/middleware/cors.rs index 052e4da2..a6172740 100644 --- a/src/middleware/cors.rs +++ b/src/middleware/cors.rs @@ -838,10 +838,9 @@ impl CorsBuilder { 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| format!("{}, {}", s, v.as_str()))[2..] + .to_owned() ); } Cors { @@ -1073,12 +1072,14 @@ mod tests { #[test] fn test_response() { + let exposed_headers = vec![header::AUTHORIZATION, header::ACCEPT]; let cors = Cors::build() .send_wildcard() .disable_preflight() .max_age(3600) .allowed_methods(vec![Method::GET, Method::OPTIONS, Method::POST]) - .allowed_headers(vec![header::AUTHORIZATION, header::ACCEPT]) + .allowed_headers(exposed_headers.clone()) + .expose_headers(exposed_headers.clone()) .allowed_header(header::CONTENT_TYPE) .finish(); @@ -1100,6 +1101,21 @@ mod tests { resp.headers().get(header::VARY).unwrap().as_bytes() ); + { + let headers = resp.headers() + .get(header::ACCESS_CONTROL_EXPOSE_HEADERS) + .unwrap() + .to_str() + .unwrap() + .split(',') + .map(|s| s.trim()) + .collect::>(); + + for h in exposed_headers { + assert!(headers.contains(&h.as_str())); + } + } + let resp: HttpResponse = HttpResponse::Ok().header(header::VARY, "Accept").finish(); let resp = cors.response(&req, resp).unwrap().response();