feat(http1): Add http1_writev(bool) to client and server Builders
Restore a way to force queue writing strategy. Closes #2676
This commit is contained in:
@@ -1022,6 +1022,23 @@ impl Builder {
|
||||
self
|
||||
}
|
||||
|
||||
/// Set whether HTTP/1 connections should try to use vectored writes,
|
||||
/// or always flatten into a single buffer.
|
||||
///
|
||||
/// Note that setting this to false may mean more copies of body data,
|
||||
/// but may also improve performance when an IO transport doesn't
|
||||
/// support vectored writes well, such as most TLS implementations.
|
||||
///
|
||||
/// Setting this to true will force hyper to use queued strategy
|
||||
/// which may eliminate unnecessary cloning on some TLS backends
|
||||
///
|
||||
/// Default is `auto`. In this mode hyper will try to guess which
|
||||
/// mode to use
|
||||
pub fn http1_writev(&mut self, enabled: bool) -> &mut Builder {
|
||||
self.conn_builder.http1_writev(enabled);
|
||||
self
|
||||
}
|
||||
|
||||
/// Set whether HTTP/1 connections will write header names as title case at
|
||||
/// the socket level.
|
||||
///
|
||||
|
||||
@@ -153,6 +153,7 @@ pub struct Builder {
|
||||
pub(super) exec: Exec,
|
||||
h09_responses: bool,
|
||||
h1_parser_config: ParserConfig,
|
||||
h1_writev: Option<bool>,
|
||||
h1_title_case_headers: bool,
|
||||
h1_preserve_header_case: bool,
|
||||
h1_read_buf_exact_size: Option<usize>,
|
||||
@@ -535,6 +536,7 @@ impl Builder {
|
||||
Builder {
|
||||
exec: Exec::Default,
|
||||
h09_responses: false,
|
||||
h1_writev: None,
|
||||
h1_read_buf_exact_size: None,
|
||||
h1_parser_config: Default::default(),
|
||||
h1_title_case_headers: false,
|
||||
@@ -596,6 +598,23 @@ impl Builder {
|
||||
self
|
||||
}
|
||||
|
||||
/// Set whether HTTP/1 connections should try to use vectored writes,
|
||||
/// or always flatten into a single buffer.
|
||||
///
|
||||
/// Note that setting this to false may mean more copies of body data,
|
||||
/// but may also improve performance when an IO transport doesn't
|
||||
/// support vectored writes well, such as most TLS implementations.
|
||||
///
|
||||
/// Setting this to true will force hyper to use queued strategy
|
||||
/// which may eliminate unnecessary cloning on some TLS backends
|
||||
///
|
||||
/// Default is `auto`. In this mode hyper will try to guess which
|
||||
/// mode to use
|
||||
pub fn http1_writev(&mut self, enabled: bool) -> &mut Builder {
|
||||
self.h1_writev = Some(enabled);
|
||||
self
|
||||
}
|
||||
|
||||
/// Set whether HTTP/1 connections will write header names as title case at
|
||||
/// the socket level.
|
||||
///
|
||||
@@ -837,6 +856,13 @@ impl Builder {
|
||||
Proto::Http1 => {
|
||||
let mut conn = proto::Conn::new(io);
|
||||
conn.set_h1_parser_config(opts.h1_parser_config);
|
||||
if let Some(writev) = opts.h1_writev {
|
||||
if writev {
|
||||
conn.set_write_strategy_queue();
|
||||
} else {
|
||||
conn.set_write_strategy_flatten();
|
||||
}
|
||||
}
|
||||
if opts.h1_title_case_headers {
|
||||
conn.set_title_case_headers();
|
||||
}
|
||||
|
||||
@@ -71,7 +71,6 @@ where
|
||||
self.io.set_flush_pipeline(enabled);
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) fn set_write_strategy_queue(&mut self) {
|
||||
self.io.set_write_strategy_queue();
|
||||
}
|
||||
@@ -85,6 +84,10 @@ where
|
||||
self.io.set_read_buf_exact_size(sz);
|
||||
}
|
||||
|
||||
pub(crate) fn set_write_strategy_flatten(&mut self) {
|
||||
self.io.set_write_strategy_flatten();
|
||||
}
|
||||
|
||||
#[cfg(feature = "client")]
|
||||
pub(crate) fn set_h1_parser_config(&mut self, parser_config: ParserConfig) {
|
||||
self.state.h1_parser_config = parser_config;
|
||||
|
||||
@@ -97,16 +97,17 @@ where
|
||||
self.read_buf_strategy = ReadStrategy::Exact(sz);
|
||||
}
|
||||
|
||||
#[cfg(feature = "server")]
|
||||
fn set_write_strategy_flatten(&mut self) {
|
||||
pub(crate) fn set_write_strategy_flatten(&mut self) {
|
||||
// this should always be called only at construction time,
|
||||
// so this assert is here to catch myself
|
||||
debug_assert!(self.write_buf.queue.bufs_cnt() == 0);
|
||||
self.write_buf.set_strategy(WriteStrategy::Flatten);
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) fn set_write_strategy_queue(&mut self) {
|
||||
// this should always be called only at construction time,
|
||||
// so this assert is here to catch myself
|
||||
debug_assert!(self.write_buf.queue.bufs_cnt() == 0);
|
||||
self.write_buf.set_strategy(WriteStrategy::Queue);
|
||||
}
|
||||
|
||||
@@ -520,7 +521,6 @@ impl<B> WriteBuf<B>
|
||||
where
|
||||
B: Buf,
|
||||
{
|
||||
#[cfg(feature = "server")]
|
||||
fn set_strategy(&mut self, strategy: WriteStrategy) {
|
||||
self.strategy = strategy;
|
||||
}
|
||||
|
||||
@@ -103,6 +103,7 @@ pub struct Http<E = Exec> {
|
||||
h1_keep_alive: bool,
|
||||
h1_title_case_headers: bool,
|
||||
h1_preserve_header_case: bool,
|
||||
h1_writev: Option<bool>,
|
||||
#[cfg(feature = "http2")]
|
||||
h2_builder: proto::h2::server::Config,
|
||||
mode: ConnectionMode,
|
||||
@@ -284,6 +285,7 @@ impl Http {
|
||||
h1_keep_alive: true,
|
||||
h1_title_case_headers: false,
|
||||
h1_preserve_header_case: false,
|
||||
h1_writev: None,
|
||||
#[cfg(feature = "http2")]
|
||||
h2_builder: Default::default(),
|
||||
mode: ConnectionMode::default(),
|
||||
@@ -363,6 +365,26 @@ impl<E> Http<E> {
|
||||
self
|
||||
}
|
||||
|
||||
/// Set whether HTTP/1 connections should try to use vectored writes,
|
||||
/// or always flatten into a single buffer.
|
||||
///
|
||||
/// Note that setting this to false may mean more copies of body data,
|
||||
/// but may also improve performance when an IO transport doesn't
|
||||
/// support vectored writes well, such as most TLS implementations.
|
||||
///
|
||||
/// Setting this to true will force hyper to use queued strategy
|
||||
/// which may eliminate unnecessary cloning on some TLS backends
|
||||
///
|
||||
/// Default is `auto`. In this mode hyper will try to guess which
|
||||
/// mode to use
|
||||
#[inline]
|
||||
#[cfg(feature = "http1")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "http1")))]
|
||||
pub fn http1_writev(&mut self, val: bool) -> &mut Self {
|
||||
self.h1_writev = Some(val);
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets whether HTTP2 is required.
|
||||
///
|
||||
/// Default is false
|
||||
@@ -538,6 +560,7 @@ impl<E> Http<E> {
|
||||
h1_keep_alive: self.h1_keep_alive,
|
||||
h1_title_case_headers: self.h1_title_case_headers,
|
||||
h1_preserve_header_case: self.h1_preserve_header_case,
|
||||
h1_writev: self.h1_writev,
|
||||
#[cfg(feature = "http2")]
|
||||
h2_builder: self.h2_builder,
|
||||
mode: self.mode,
|
||||
@@ -599,6 +622,13 @@ impl<E> Http<E> {
|
||||
if self.h1_preserve_header_case {
|
||||
conn.set_preserve_header_case();
|
||||
}
|
||||
if let Some(writev) = self.h1_writev {
|
||||
if writev {
|
||||
conn.set_write_strategy_queue();
|
||||
} else {
|
||||
conn.set_write_strategy_flatten();
|
||||
}
|
||||
}
|
||||
conn.set_flush_pipeline(self.pipeline_flush);
|
||||
if let Some(max) = self.max_buf_size {
|
||||
conn.set_max_buf_size(max);
|
||||
|
||||
@@ -258,6 +258,24 @@ impl<I, E> Builder<I, E> {
|
||||
self
|
||||
}
|
||||
|
||||
/// Set whether HTTP/1 connections should try to use vectored writes,
|
||||
/// or always flatten into a single buffer.
|
||||
///
|
||||
/// Note that setting this to false may mean more copies of body data,
|
||||
/// but may also improve performance when an IO transport doesn't
|
||||
/// support vectored writes well, such as most TLS implementations.
|
||||
///
|
||||
/// Setting this to true will force hyper to use queued strategy
|
||||
/// which may eliminate unnecessary cloning on some TLS backends
|
||||
///
|
||||
/// Default is `auto`. In this mode hyper will try to guess which
|
||||
/// mode to use
|
||||
#[cfg(feature = "http1")]
|
||||
pub fn http1_writev(mut self, enabled: bool) -> Self {
|
||||
self.protocol.http1_writev(enabled);
|
||||
self
|
||||
}
|
||||
|
||||
/// Set whether HTTP/1 connections will write header names as title case at
|
||||
/// the socket level.
|
||||
///
|
||||
|
||||
Reference in New Issue
Block a user