feat(client): add option to allow misplaced spaces in HTTP/1 responses (#2506)
This commit is contained in:
@@ -961,6 +961,31 @@ impl Builder {
|
||||
self
|
||||
}
|
||||
|
||||
/// Set whether HTTP/1 connections will accept spaces between header names
|
||||
/// and the colon that follow them in responses.
|
||||
///
|
||||
/// You probably don't need this, here is what [RFC 7230 Section 3.2.4.] has
|
||||
/// to say about it:
|
||||
///
|
||||
/// > No whitespace is allowed between the header field-name and colon. In
|
||||
/// > the past, differences in the handling of such whitespace have led to
|
||||
/// > security vulnerabilities in request routing and response handling. A
|
||||
/// > server MUST reject any received request message that contains
|
||||
/// > whitespace between a header field-name and colon with a response code
|
||||
/// > of 400 (Bad Request). A proxy MUST remove any such whitespace from a
|
||||
/// > response message before forwarding the message downstream.
|
||||
///
|
||||
/// Note that this setting does not affect HTTP/2.
|
||||
///
|
||||
/// Default is false.
|
||||
///
|
||||
/// [RFC 7230 Section 3.2.4.]: https://tools.ietf.org/html/rfc7230#section-3.2.4
|
||||
pub fn http1_allow_spaces_after_header_name_in_responses(&mut self, val: bool) -> &mut Self {
|
||||
self.conn_builder
|
||||
.h1_allow_spaces_after_header_name_in_responses(val);
|
||||
self
|
||||
}
|
||||
|
||||
/// Set whether HTTP/1 connections will write header names as title case at
|
||||
/// the socket level.
|
||||
///
|
||||
|
||||
@@ -56,6 +56,7 @@ use std::time::Duration;
|
||||
|
||||
use bytes::Bytes;
|
||||
use futures_util::future::{self, Either, FutureExt as _};
|
||||
use httparse::ParserConfig;
|
||||
use pin_project::pin_project;
|
||||
use tokio::io::{AsyncRead, AsyncWrite};
|
||||
use tower_service::Service;
|
||||
@@ -123,6 +124,7 @@ where
|
||||
pub struct Builder {
|
||||
pub(super) exec: Exec,
|
||||
h09_responses: bool,
|
||||
h1_parser_config: ParserConfig,
|
||||
h1_title_case_headers: bool,
|
||||
h1_read_buf_exact_size: Option<usize>,
|
||||
h1_max_buf_size: Option<usize>,
|
||||
@@ -496,6 +498,7 @@ impl Builder {
|
||||
exec: Exec::Default,
|
||||
h09_responses: false,
|
||||
h1_read_buf_exact_size: None,
|
||||
h1_parser_config: Default::default(),
|
||||
h1_title_case_headers: false,
|
||||
h1_max_buf_size: None,
|
||||
#[cfg(feature = "http2")]
|
||||
@@ -521,6 +524,14 @@ impl Builder {
|
||||
self
|
||||
}
|
||||
|
||||
pub(crate) fn h1_allow_spaces_after_header_name_in_responses(
|
||||
&mut self,
|
||||
enabled: bool,
|
||||
) -> &mut Builder {
|
||||
self.h1_parser_config.allow_spaces_after_header_name_in_responses(enabled);
|
||||
self
|
||||
}
|
||||
|
||||
pub(super) fn h1_title_case_headers(&mut self, enabled: bool) -> &mut Builder {
|
||||
self.h1_title_case_headers = enabled;
|
||||
self
|
||||
@@ -704,6 +715,7 @@ impl Builder {
|
||||
#[cfg(feature = "http1")]
|
||||
Proto::Http1 => {
|
||||
let mut conn = proto::Conn::new(io);
|
||||
conn.set_h1_parser_config(opts.h1_parser_config);
|
||||
if opts.h1_title_case_headers {
|
||||
conn.set_title_case_headers();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user