Make Codec max frame length configurable (#57)
This commit is contained in:
		
				
					committed by
					
						 Carl Lerche
						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