Make Codec max frame length configurable (#57)

This commit is contained in:
Eliza Weisman
2017-09-11 14:56:40 -05:00
committed by Carl Lerche
parent 460afa41c8
commit 11de86b34e
3 changed files with 67 additions and 3 deletions

View File

@@ -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>

View File

@@ -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()

View File

@@ -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");
}