diff --git a/actix-http/CHANGES.md b/actix-http/CHANGES.md index 0c5da36d7..9edd7b6f0 100644 --- a/actix-http/CHANGES.md +++ b/actix-http/CHANGES.md @@ -2,6 +2,10 @@ ## Unreleased +- Encode the HTTP/1 `Connection: Upgrade` header in Camel-Case when camel-case header formatting is enabled.[#3953] + +[#3953]: https://github.com/actix/actix-web/pull/3953 + ## 3.12.0 - Minimum supported Rust version (MSRV) is now 1.88. diff --git a/actix-http/src/h1/encoder.rs b/actix-http/src/h1/encoder.rs index 81af7868b..1853843c3 100644 --- a/actix-http/src/h1/encoder.rs +++ b/actix-http/src/h1/encoder.rs @@ -111,7 +111,13 @@ pub(crate) trait MessageType: Sized { // Connection match conn_type { - ConnectionType::Upgrade => dst.put_slice(b"connection: upgrade\r\n"), + ConnectionType::Upgrade => { + if camel_case { + dst.put_slice(b"Connection: Upgrade\r\n") + } else { + dst.put_slice(b"connection: upgrade\r\n") + } + } ConnectionType::KeepAlive if version < Version::HTTP_11 => { if camel_case { dst.put_slice(b"Connection: keep-alive\r\n") @@ -580,6 +586,16 @@ mod tests { assert!(data.contains("Date: date\r\n")); assert!(data.contains("Upgrade-Insecure-Requests: 1\r\n")); + let _ = head.encode_headers( + &mut bytes, + Version::HTTP_11, + BodySize::None, + ConnectionType::Upgrade, + &ServiceConfig::default(), + ); + let data = String::from_utf8(Vec::from(bytes.split().freeze().as_ref())).unwrap(); + assert!(data.contains("Connection: Upgrade\r\n")); + let _ = head.encode_headers( &mut bytes, Version::HTTP_11, diff --git a/actix-http/src/requests/head.rs b/actix-http/src/requests/head.rs index 9ceb2a20c..ddc9dd98f 100644 --- a/actix-http/src/requests/head.rs +++ b/actix-http/src/requests/head.rs @@ -61,14 +61,15 @@ impl RequestHead { &mut self.headers } - /// Is to uppercase headers with Camel-Case. - /// Default is `false` + /// Returns whether headers should be sent in Camel-Case. + /// + /// Default is `false`. #[inline] pub fn camel_case_headers(&self) -> bool { self.flags.contains(Flags::CAMEL_CASE) } - /// Set `true` to send headers which are formatted as Camel-Case. + /// Sets whether to send headers formatted as Camel-Case. #[inline] pub fn set_camel_case_headers(&mut self, val: bool) { if val { diff --git a/awc/CHANGES.md b/awc/CHANGES.md index 49159b18d..38a9f8b09 100644 --- a/awc/CHANGES.md +++ b/awc/CHANGES.md @@ -2,6 +2,10 @@ ## Unreleased +- Add camel-case header controls to `WebsocketsRequest` via `camel_case_headers()` and `set_camel_case_headers()`. [#3953] + +[#3953]: https://github.com/actix/actix-web/pull/3953 + ## 3.8.2 - Minimum supported Rust version (MSRV) is now 1.88. diff --git a/awc/src/ws.rs b/awc/src/ws.rs index c33531d41..de8ed2d14 100644 --- a/awc/src/ws.rs +++ b/awc/src/ws.rs @@ -245,6 +245,21 @@ impl WebsocketsRequest { self.header(AUTHORIZATION, format!("Bearer {}", token)) } + /// Returns whether headers should be sent in Camel-Case. + /// + /// Default is `false`. + #[inline] + pub fn camel_case_headers(&self) -> bool { + self.head.camel_case_headers() + } + + /// Sets whether to send headers formatted as Camel-Case. + #[inline] + pub fn set_camel_case_headers(mut self, val: bool) -> Self { + self.head.set_camel_case_headers(val); + self + } + /// Complete request construction and connect to a WebSocket server. pub async fn connect( mut self, @@ -529,6 +544,12 @@ mod tests { let _ = req.connect(); } + #[actix_rt::test] + async fn camel_case_headers() { + let req = Client::new().ws("/").set_camel_case_headers(true); + assert!(req.camel_case_headers()); + } + #[actix_rt::test] async fn basics() { let req = Client::new()