Skip to content

Commit e221846

Browse files
committed
feat: Add option in client builder to ignore content length
1 parent e2168de commit e221846

File tree

5 files changed

+30
-4
lines changed

5 files changed

+30
-4
lines changed

src/client.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,9 @@ pub struct Builder {
344344
///
345345
/// When this gets exceeded, we issue GOAWAYs.
346346
local_max_error_reset_streams: Option<usize>,
347+
348+
/// Ignore content length and only stop receiving when peer close stream
349+
ignore_content_length: bool,
347350
}
348351

349352
#[derive(Debug)]
@@ -654,6 +657,7 @@ impl Builder {
654657
settings: Default::default(),
655658
stream_id: 1.into(),
656659
local_max_error_reset_streams: Some(proto::DEFAULT_LOCAL_RESET_COUNT_MAX),
660+
ignore_content_length: false,
657661
}
658662
}
659663

@@ -1136,6 +1140,16 @@ impl Builder {
11361140
self
11371141
}
11381142

1143+
/// Setup whether to ignore the content length when receiving
1144+
///
1145+
/// If content length is ignored, receiving only stops when server closes stream
1146+
pub fn ignore_content_length(&mut self, ignore: bool) -> &mut Self {
1147+
self.ignore_content_length = ignore;
1148+
self
1149+
}
1150+
1151+
1152+
11391153
/// Sets the first stream ID to something other than 1.
11401154
#[cfg(feature = "unstable")]
11411155
pub fn initial_stream_id(&mut self, stream_id: u32) -> &mut Self {
@@ -1326,6 +1340,7 @@ where
13261340
remote_reset_stream_max: builder.pending_accept_reset_stream_max,
13271341
local_error_reset_streams_max: builder.local_max_error_reset_streams,
13281342
settings: builder.settings.clone(),
1343+
ignore_content_length: builder.ignore_content_length,
13291344
},
13301345
);
13311346
let send_request = SendRequest {

src/proto/connection.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ pub(crate) struct Config {
8383
pub remote_reset_stream_max: usize,
8484
pub local_error_reset_streams_max: Option<usize>,
8585
pub settings: frame::Settings,
86+
pub ignore_content_length: bool,
8687
}
8788

8889
#[derive(Debug)]
@@ -123,6 +124,7 @@ where
123124
.max_concurrent_streams()
124125
.map(|max| max as usize),
125126
local_max_error_reset_streams: config.local_error_reset_streams_max,
127+
ignore_content_length: config.ignore_content_length,
126128
}
127129
}
128130
let streams = Streams::new(streams_config(&config));

src/proto/streams/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,4 +72,7 @@ pub struct Config {
7272
///
7373
/// When this gets exceeded, we issue GOAWAYs.
7474
pub local_max_error_reset_streams: Option<usize>,
75+
76+
/// Ignore the content length header and only stop receiving when peer close stream
77+
pub ignore_content_length: bool,
7578
}

src/proto/streams/recv.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ pub(super) struct Recv {
5959

6060
/// If extended connect protocol is enabled.
6161
is_extended_connect_protocol_enabled: bool,
62+
63+
/// Ignore the content length header and only stop when peer close stream
64+
ignore_content_length: bool,
6265
}
6366

6467
#[derive(Debug)]
@@ -107,6 +110,7 @@ impl Recv {
107110
refused: None,
108111
is_push_enabled: config.local_push_enabled,
109112
is_extended_connect_protocol_enabled: config.extended_connect_protocol_enabled,
113+
ignore_content_length: config.ignore_content_length,
110114
}
111115
}
112116

@@ -171,7 +175,7 @@ impl Recv {
171175
counts.inc_num_recv_streams(stream);
172176
}
173177

174-
if !stream.content_length.is_head() {
178+
if !self.ignore_content_length && !stream.content_length.is_head() {
175179
use super::stream::ContentLength;
176180
use http::header;
177181

@@ -341,7 +345,7 @@ impl Recv {
341345
// Transition the state
342346
stream.state.recv_close()?;
343347

344-
if stream.ensure_content_length_zero().is_err() {
348+
if !self.ignore_content_length && stream.ensure_content_length_zero().is_err() {
345349
proto_err!(stream: "recv_trailers: content-length is not zero; stream={:?};", stream.id);
346350
return Err(Error::library_reset(stream.id, Reason::PROTOCOL_ERROR));
347351
}
@@ -616,7 +620,8 @@ impl Recv {
616620
return Err(Error::library_reset(stream.id, Reason::FLOW_CONTROL_ERROR));
617621
}
618622

619-
if stream.dec_content_length(frame.payload().len()).is_err() {
623+
if !self.ignore_content_length && stream.dec_content_length(frame.payload().len()).is_err()
624+
{
620625
proto_err!(stream:
621626
"recv_data: content-length overflow; stream={:?}; len={:?}",
622627
stream.id,
@@ -626,7 +631,7 @@ impl Recv {
626631
}
627632

628633
if frame.is_end_stream() {
629-
if stream.ensure_content_length_zero().is_err() {
634+
if !self.ignore_content_length && stream.ensure_content_length_zero().is_err() {
630635
proto_err!(stream:
631636
"recv_data: content-length underflow; stream={:?}; len={:?}",
632637
stream.id,

src/server.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1385,6 +1385,7 @@ where
13851385
.builder
13861386
.local_max_error_reset_streams,
13871387
settings: self.builder.settings.clone(),
1388+
ignore_content_length: false,
13881389
},
13891390
);
13901391

0 commit comments

Comments
 (0)