diff --git a/actix-http/src/h1/encoder.rs b/actix-http/src/h1/encoder.rs index 8f98fe67e..177661b5b 100644 --- a/actix-http/src/h1/encoder.rs +++ b/actix-http/src/h1/encoder.rs @@ -43,6 +43,10 @@ pub(crate) trait MessageType: Sized { fn headers(&self) -> &HeaderMap; + fn upper_camel_case(&self) -> bool { + false + } + fn chunked(&self) -> bool; fn encode_status(&mut self, dst: &mut BytesMut) -> io::Result<()>; @@ -221,6 +225,10 @@ impl MessageType for RequestHead { self.chunked() } + fn upper_camel_case(&self) -> bool { + self.upper_camel_case_headers() + } + fn headers(&self) -> &HeaderMap { &self.headers } @@ -418,6 +426,34 @@ impl<'a> io::Write for Writer<'a> { } } +fn write_upper_camel_case(value: &[u8], buffer: &mut [u8]) { + let mut index = 0; + let key = value; + let mut key_iter = key.iter(); + + if let Some(c) = key_iter.next() { + if *c >= b'a' && *c <= b'z' { + buffer[index] = *c ^ b' '; + index += 1; + } + } else { + return; + } + + while let Some(c) = key_iter.next() { + buffer[index] = *c; + index += 1; + if *c == b'-' { + if let Some(c) = key_iter.next() { + if *c >= b'a' && *c <= b'z' { + buffer[index] = *c ^ b' '; + index += 1; + } + } + } + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/actix-http/src/message.rs b/actix-http/src/message.rs index 7f2dc603f..f3129c758 100644 --- a/actix-http/src/message.rs +++ b/actix-http/src/message.rs @@ -27,6 +27,7 @@ bitflags! { const UPGRADE = 0b0000_0100; const EXPECT = 0b0000_1000; const NO_CHUNKING = 0b0001_0000; + const CAMEL_CASE = 0b0010_0000; } } @@ -97,6 +98,23 @@ impl RequestHead { &mut self.headers } + /// Is to uppercase headers with Camel-Case. + /// Befault is `false` + #[inline] + pub fn upper_camel_case_headers(&self) -> bool { + self.flags.contains(Flags::CAMEL_CASE) + } + + /// Set `true` to send headers which are uppercased with Camel-Case. + #[inline] + pub fn set_upper_camel_case_headers(&mut self, val: bool) { + if val { + self.flags.insert(Flags::CAMEL_CASE); + } else { + self.flags.remove(Flags::CAMEL_CASE); + } + } + #[inline] /// Set connection type of the message pub fn set_connection_type(&mut self, ctype: ConnectionType) { diff --git a/awc/src/request.rs b/awc/src/request.rs index 2e6032649..d99a9418e 100644 --- a/awc/src/request.rs +++ b/awc/src/request.rs @@ -235,6 +235,20 @@ impl ClientRequest { self } + /// Is to uppercase headers with Camel-Case. + /// Befault is `false` + #[inline] + pub fn upper_camel_case_headers(&self) -> bool { + self.head.upper_camel_case_headers() + } + + /// Set `true` to send headers which are uppercased with Camel-Case. + #[inline] + pub fn set_upper_camel_case_headers(&mut self, value: bool) -> &mut Self { + self.head.set_upper_camel_case_headers(value); + self + } + /// Force close connection instead of returning it back to connections pool. /// This setting affect only http/1 connections. #[inline]