Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add option in client builder to ignore content length #768

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,9 @@ pub struct Builder {
///
/// When this gets exceeded, we issue GOAWAYs.
local_max_error_reset_streams: Option<usize>,

/// Ignore content length and only stop receiving when peer close stream
ignore_content_length: bool,
}

#[derive(Debug)]
Expand Down Expand Up @@ -654,6 +657,7 @@ impl Builder {
settings: Default::default(),
stream_id: 1.into(),
local_max_error_reset_streams: Some(proto::DEFAULT_LOCAL_RESET_COUNT_MAX),
ignore_content_length: false,
}
}

Expand Down Expand Up @@ -1136,6 +1140,14 @@ impl Builder {
self
}

/// Setup whether to ignore the content length when receiving
///
/// If content length is ignored, receiving only stops when server closes stream
pub fn ignore_content_length(&mut self, ignore: bool) -> &mut Self {
self.ignore_content_length = ignore;
self
}

/// Sets the first stream ID to something other than 1.
#[cfg(feature = "unstable")]
pub fn initial_stream_id(&mut self, stream_id: u32) -> &mut Self {
Expand Down Expand Up @@ -1326,6 +1338,7 @@ where
remote_reset_stream_max: builder.pending_accept_reset_stream_max,
local_error_reset_streams_max: builder.local_max_error_reset_streams,
settings: builder.settings.clone(),
ignore_content_length: builder.ignore_content_length,
},
);
let send_request = SendRequest {
Expand Down
2 changes: 2 additions & 0 deletions src/proto/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ pub(crate) struct Config {
pub remote_reset_stream_max: usize,
pub local_error_reset_streams_max: Option<usize>,
pub settings: frame::Settings,
pub ignore_content_length: bool,
}

#[derive(Debug)]
Expand Down Expand Up @@ -123,6 +124,7 @@ where
.max_concurrent_streams()
.map(|max| max as usize),
local_max_error_reset_streams: config.local_error_reset_streams_max,
ignore_content_length: config.ignore_content_length,
}
}
let streams = Streams::new(streams_config(&config));
Expand Down
3 changes: 3 additions & 0 deletions src/proto/streams/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,7 @@ pub struct Config {
///
/// When this gets exceeded, we issue GOAWAYs.
pub local_max_error_reset_streams: Option<usize>,

/// Ignore the content length header and only stop receiving when peer close stream
pub ignore_content_length: bool,
}
13 changes: 9 additions & 4 deletions src/proto/streams/recv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ pub(super) struct Recv {

/// If extended connect protocol is enabled.
is_extended_connect_protocol_enabled: bool,

/// Ignore the content length header and only stop when peer close stream
ignore_content_length: bool,
}

#[derive(Debug)]
Expand Down Expand Up @@ -107,6 +110,7 @@ impl Recv {
refused: None,
is_push_enabled: config.local_push_enabled,
is_extended_connect_protocol_enabled: config.extended_connect_protocol_enabled,
ignore_content_length: config.ignore_content_length,
}
}

Expand Down Expand Up @@ -171,7 +175,7 @@ impl Recv {
counts.inc_num_recv_streams(stream);
}

if !stream.content_length.is_head() {
if !self.ignore_content_length && !stream.content_length.is_head() {
use super::stream::ContentLength;
use http::header;

Expand Down Expand Up @@ -341,7 +345,7 @@ impl Recv {
// Transition the state
stream.state.recv_close()?;

if stream.ensure_content_length_zero().is_err() {
if !self.ignore_content_length && stream.ensure_content_length_zero().is_err() {
proto_err!(stream: "recv_trailers: content-length is not zero; stream={:?};", stream.id);
return Err(Error::library_reset(stream.id, Reason::PROTOCOL_ERROR));
}
Expand Down Expand Up @@ -616,7 +620,8 @@ impl Recv {
return Err(Error::library_reset(stream.id, Reason::FLOW_CONTROL_ERROR));
}

if stream.dec_content_length(frame.payload().len()).is_err() {
if !self.ignore_content_length && stream.dec_content_length(frame.payload().len()).is_err()
{
proto_err!(stream:
"recv_data: content-length overflow; stream={:?}; len={:?}",
stream.id,
Expand All @@ -626,7 +631,7 @@ impl Recv {
}

if frame.is_end_stream() {
if stream.ensure_content_length_zero().is_err() {
if !self.ignore_content_length && stream.ensure_content_length_zero().is_err() {
proto_err!(stream:
"recv_data: content-length underflow; stream={:?}; len={:?}",
stream.id,
Expand Down
1 change: 1 addition & 0 deletions src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1385,6 +1385,7 @@ where
.builder
.local_max_error_reset_streams,
settings: self.builder.settings.clone(),
ignore_content_length: false,
},
);

Expand Down