1
0
Fork 0
mirror of https://github.com/actix/actix-web.git synced 2024-06-13 02:39:32 +00:00

Support to set header names of ClientRequest as Camel-Case (#713)

* Support to set header names of `ClientRequest` as Camel-Case

This is the case for supporting to request for servers which don't
perfectly implement the `RFC 7230`. It is important for an app
which uses `ClientRequest` as core part.

* Add field `upper_camel_case_headers` to `ClientRequest`.

* Add function `set_upper_camel_case_headers` to `ClientRequest`
  and `ClientRequestBuilder` to set field `upper_camel_case_headers`.

* Add trait `client::writer::UpperCamelCaseHeader` for
  `http::header::HeaderName`, let it can be converted to Camel-Case
  then writed to buffer.

* Add test `test_client::test_upper_camel_case_headers`.

* Support upper Camel-Case headers

* [actix-http] Add field `upper_camel_case_headers` for `RequestHead`
* [actix-http] Add code for `MessageType` to support upper camel case
* [awc] Add functions for `ClientRequest` to set upper camel case

* Use `Flags::CAMEL_CASE` for upper camel case of headers
This commit is contained in:
Peter Ding 2019-04-25 01:48:49 +08:00 committed by Nikolay Kim
parent 679d1cd513
commit 64f603b076
3 changed files with 68 additions and 0 deletions

View file

@ -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::*;

View file

@ -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) {

View file

@ -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]