Make Codec max frame length configurable (#57)
This commit is contained in:
committed by
Carl Lerche
parent
460afa41c8
commit
11de86b34e
@@ -219,6 +219,18 @@ impl<T> FramedRead<T> {
|
||||
pub fn get_mut(&mut self) -> &mut T {
|
||||
self.inner.get_mut()
|
||||
}
|
||||
|
||||
/// Returns the current max frame size setting
|
||||
#[inline]
|
||||
pub fn max_frame_size(&self) -> usize {
|
||||
self.inner.max_frame_length()
|
||||
}
|
||||
|
||||
/// Updates the max frame size setting.
|
||||
#[inline]
|
||||
pub fn set_max_frame_size(&mut self, val: usize) {
|
||||
self.inner.set_max_frame_length(val)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Stream for FramedRead<T>
|
||||
|
||||
@@ -27,7 +27,17 @@ impl<T, B> Codec<T, B>
|
||||
where T: AsyncRead + AsyncWrite,
|
||||
B: Buf,
|
||||
{
|
||||
/// Returns a new `Codec` with the default max frame size
|
||||
#[inline]
|
||||
pub fn new(io: T) -> Self {
|
||||
Self::with_max_recv_frame_size(
|
||||
io,
|
||||
frame::DEFAULT_MAX_FRAME_SIZE as usize
|
||||
)
|
||||
}
|
||||
|
||||
/// Returns a new `Codec` with the given maximum frame size
|
||||
pub fn with_max_recv_frame_size(io: T, max_frame_size: usize) -> Self {
|
||||
// Wrap with writer
|
||||
let framed_write = FramedWrite::new(io);
|
||||
|
||||
@@ -37,9 +47,7 @@ impl<T, B> Codec<T, B>
|
||||
.length_field_length(3)
|
||||
.length_adjustment(9)
|
||||
.num_skip(0) // Don't skip the header
|
||||
// TODO: make this configurable and allow it to be changed during
|
||||
// runtime.
|
||||
.max_frame_length(frame::DEFAULT_MAX_FRAME_SIZE as usize)
|
||||
.max_frame_length(max_frame_size)
|
||||
.new_read(framed_write);
|
||||
|
||||
let inner = FramedRead::new(delimited);
|
||||
@@ -49,6 +57,29 @@ impl<T, B> Codec<T, B>
|
||||
}
|
||||
|
||||
impl<T, B> Codec<T, B> {
|
||||
|
||||
/// Updates the max received frame size.
|
||||
///
|
||||
/// The change takes effect the next time a frame is decoded. In other
|
||||
/// words, if a frame is currently in process of being decoded with a frame
|
||||
/// size greater than `val` but less than the max frame size in effect
|
||||
/// before calling this function, then the frame will be allowed.
|
||||
#[inline]
|
||||
pub fn set_max_recv_frame_size(&mut self, val: usize) {
|
||||
// TODO: should probably make some assertions about max frame size...
|
||||
self.inner.set_max_frame_size(val)
|
||||
|
||||
}
|
||||
|
||||
/// Returns the current max received frame size setting.
|
||||
///
|
||||
/// This is the largest size this codec will accept from the wire. Larger
|
||||
/// frames will be rejected.
|
||||
#[inline]
|
||||
pub fn max_recv_frame_size(&self) -> usize {
|
||||
self.inner.max_frame_size()
|
||||
}
|
||||
|
||||
/// Returns the max frame size that can be sent to the peer.
|
||||
pub fn max_send_frame_size(&self) -> usize {
|
||||
self.inner.get_ref().max_frame_size()
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
extern crate h2_test_support;
|
||||
use h2_test_support::prelude::*;
|
||||
|
||||
use std::error::Error;
|
||||
|
||||
#[test]
|
||||
fn read_none() {
|
||||
let mut codec = Codec::from(
|
||||
@@ -111,3 +113,22 @@ fn read_headers_with_pseudo() {
|
||||
#[test]
|
||||
fn read_headers_empty_payload() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn update_max_frame_len_at_rest() {
|
||||
// TODO: add test for updating max frame length in flight as well?
|
||||
let mut codec = raw_codec! {
|
||||
read => [
|
||||
0, 0, 5, 0, 0, 0, 0, 0, 1,
|
||||
"hello",
|
||||
"world",
|
||||
];
|
||||
};
|
||||
|
||||
assert_eq!(poll_data!(codec).payload(), &b"hello"[..]);
|
||||
|
||||
codec.set_max_recv_frame_size(2);
|
||||
|
||||
assert_eq!(codec.max_recv_frame_size(), 2);
|
||||
assert_eq!(codec.poll().unwrap_err().description(), "frame size too big");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user