The current LengthDelimitedCodec implementation has a bug (tokio-rs/tokio#4815) where length adjustment is not applied before checking overflow. And the PR that tries to fix the bug (tokio-rs/tokio#4816) currently has failed h2_connect_large_body test with hyper because of the way LengthDelimitedCodec is used in h2 right now.
Suspected cause
The cause of the problem is that FramedRead internally uses a LengthDelimitedCodec while FramedWrite uses a custom encoder. Though the LengthDelimitedCodec in FramedRead has a length_adjustment of 9, the encoder doesn't seem to make adjustment to the encoded length. For a length adjustment of 9 and a real max_frame_length of N, the LengthDelimitedCodec would expect an encoded length of N-9 (ie. if the encodec length is N-9, the codec would read N-9+9=N bytes). Thus if the encoded length is N, the codec would try to read N+9 which exceeds the max_frame_length and would cause an error.
One of the newly added unit test for the above mentioned PR is attached below as an example
This can be circumvented if an additional 9 is added when setting the decoders max_frame_length ie.
/// Updates the max frame size setting.
///
/// Must be within 16,384 and 16,777,215.
#[inline]
pub fn set_max_frame_size(&mut self, val: usize) {
assert!(DEFAULT_MAX_FRAME_SIZE as usize <= val && val <= MAX_MAX_FRAME_SIZE as usize);
self.inner.decoder_mut().set_max_frame_length(val + 9)
}
Description
The current
LengthDelimitedCodec
implementation has a bug (tokio-rs/tokio#4815) where length adjustment is not applied before checking overflow. And the PR that tries to fix the bug (tokio-rs/tokio#4816) currently has failedh2_connect_large_body
test withhyper
because of the wayLengthDelimitedCodec
is used inh2
right now.Suspected cause
The cause of the problem is that
FramedRead
internally uses aLengthDelimitedCodec
whileFramedWrite
uses a custom encoder. Though theLengthDelimitedCodec
inFramedRead
has alength_adjustment
of9
, the encoder doesn't seem to make adjustment to the encoded length. For a length adjustment of 9 and a realmax_frame_length
ofN
, theLengthDelimitedCodec
would expect an encoded length ofN-9
(ie. if the encodec length isN-9
, the codec would readN-9+9=N
bytes). Thus if the encoded length isN
, the codec would try to readN+9
which exceeds themax_frame_length
and would cause an error.One of the newly added unit test for the above mentioned PR is attached below as an example
Workaround (a sketchy one)
This can be circumvented if an additional
9
is added when setting the decodersmax_frame_length
ie.