feat(http1): add options to preserve header casing (#2480)

Decouple preserving header case from FFI:

The feature is now supported in both the server and the client
and can be combined with the title case feature, for headers
which don't have entries in the header case map.

Closes #2313
This commit is contained in:
Anthony Ramine
2021-04-21 18:50:35 +02:00
committed by GitHub
parent 117cc492a6
commit dbea7716f1
12 changed files with 656 additions and 181 deletions

View File

@@ -88,6 +88,7 @@ pub struct Http<E = Exec> {
exec: E,
h1_half_close: bool,
h1_keep_alive: bool,
h1_title_case_headers: bool,
#[cfg(feature = "http2")]
h2_builder: proto::h2::server::Config,
mode: ConnectionMode,
@@ -234,6 +235,7 @@ impl Http {
exec: Exec::Default,
h1_half_close: false,
h1_keep_alive: true,
h1_title_case_headers: false,
#[cfg(feature = "http2")]
h2_builder: Default::default(),
mode: ConnectionMode::default(),
@@ -286,6 +288,19 @@ impl<E> Http<E> {
self
}
/// Set whether HTTP/1 connections will write header names as title case at
/// the socket level.
///
/// Note that this setting does not affect HTTP/2.
///
/// Default is false.
#[cfg(feature = "http1")]
#[cfg_attr(docsrs, doc(cfg(feature = "http1")))]
pub fn http1_title_case_headers(&mut self, enabled: bool) -> &mut Self {
self.h1_title_case_headers = enabled;
self
}
/// Sets whether HTTP2 is required.
///
/// Default is false
@@ -459,6 +474,7 @@ impl<E> Http<E> {
exec,
h1_half_close: self.h1_half_close,
h1_keep_alive: self.h1_keep_alive,
h1_title_case_headers: self.h1_title_case_headers,
#[cfg(feature = "http2")]
h2_builder: self.h2_builder,
mode: self.mode,
@@ -514,6 +530,9 @@ impl<E> Http<E> {
if self.h1_half_close {
conn.set_allow_half_close();
}
if self.h1_title_case_headers {
conn.set_title_case_headers();
}
conn.set_flush_pipeline(self.pipeline_flush);
if let Some(max) = self.max_buf_size {
conn.set_max_buf_size(max);

View File

@@ -231,6 +231,19 @@ impl<I, E> Builder<I, E> {
self
}
/// Set whether HTTP/1 connections will write header names as title case at
/// the socket level.
///
/// Note that this setting does not affect HTTP/2.
///
/// Default is false.
#[cfg(feature = "http1")]
#[cfg_attr(docsrs, doc(cfg(feature = "http1")))]
pub fn http1_title_case_headers(&mut self, val: bool) -> &mut Self {
self.protocol.http1_title_case_headers(val);
self
}
/// Sets whether HTTP/1 is required.
///
/// Default is `false`.