Decode debug_data in GOAWAY frames
This commit is contained in:
		| @@ -1,11 +1,15 @@ | |||||||
|  | use std::fmt; | ||||||
|  |  | ||||||
|  | use bytes::{BufMut, Bytes}; | ||||||
|  |  | ||||||
| use crate::frame::{self, Error, Head, Kind, Reason, StreamId}; | use crate::frame::{self, Error, Head, Kind, Reason, StreamId}; | ||||||
|  |  | ||||||
| use bytes::BufMut; | #[derive(Clone, Eq, PartialEq)] | ||||||
|  |  | ||||||
| #[derive(Debug, Clone, Copy, Eq, PartialEq)] |  | ||||||
| pub struct GoAway { | pub struct GoAway { | ||||||
|     last_stream_id: StreamId, |     last_stream_id: StreamId, | ||||||
|     error_code: Reason, |     error_code: Reason, | ||||||
|  |     #[allow(unused)] | ||||||
|  |     debug_data: Bytes, | ||||||
| } | } | ||||||
|  |  | ||||||
| impl GoAway { | impl GoAway { | ||||||
| @@ -13,6 +17,7 @@ impl GoAway { | |||||||
|         GoAway { |         GoAway { | ||||||
|             last_stream_id, |             last_stream_id, | ||||||
|             error_code: reason, |             error_code: reason, | ||||||
|  |             debug_data: Bytes::new(), | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -24,6 +29,11 @@ impl GoAway { | |||||||
|         self.error_code |         self.error_code | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     #[cfg(feature = "unstable")] | ||||||
|  |     pub fn debug_data(&self) -> &[u8] { | ||||||
|  |         &self.debug_data | ||||||
|  |     } | ||||||
|  |  | ||||||
|     pub fn load(payload: &[u8]) -> Result<GoAway, Error> { |     pub fn load(payload: &[u8]) -> Result<GoAway, Error> { | ||||||
|         if payload.len() < 8 { |         if payload.len() < 8 { | ||||||
|             return Err(Error::BadFrameSize); |             return Err(Error::BadFrameSize); | ||||||
| @@ -31,10 +41,12 @@ impl GoAway { | |||||||
|  |  | ||||||
|         let (last_stream_id, _) = StreamId::parse(&payload[..4]); |         let (last_stream_id, _) = StreamId::parse(&payload[..4]); | ||||||
|         let error_code = unpack_octets_4!(payload, 4, u32); |         let error_code = unpack_octets_4!(payload, 4, u32); | ||||||
|  |         let debug_data = Bytes::from(&payload[8..]); | ||||||
|  |  | ||||||
|         Ok(GoAway { |         Ok(GoAway { | ||||||
|             last_stream_id, |             last_stream_id, | ||||||
|             error_code: error_code.into(), |             error_code: error_code.into(), | ||||||
|  |             debug_data, | ||||||
|         }) |         }) | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -52,3 +64,17 @@ impl<B> From<GoAway> for frame::Frame<B> { | |||||||
|         frame::Frame::GoAway(src) |         frame::Frame::GoAway(src) | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | impl fmt::Debug for GoAway { | ||||||
|  |     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||||||
|  |         let mut builder = f.debug_struct("GoAway"); | ||||||
|  |         builder.field("error_code", &self.error_code); | ||||||
|  |         builder.field("last_stream_id", &self.last_stream_id); | ||||||
|  |  | ||||||
|  |         if !self.debug_data.is_empty() { | ||||||
|  |             builder.field("debug_data", &self.debug_data); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         builder.finish() | ||||||
|  |     } | ||||||
|  | } | ||||||
|   | |||||||
| @@ -214,3 +214,26 @@ async fn update_max_frame_len_at_rest() { | |||||||
|         "frame with invalid size" |         "frame with invalid size" | ||||||
|     ); |     ); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #[tokio::test] | ||||||
|  | async fn read_goaway_with_debug_data() { | ||||||
|  |     let mut codec = raw_codec! { | ||||||
|  |         read => [ | ||||||
|  |             // head | ||||||
|  |             0, 0, 22, 7, 0, 0, 0, 0, 0, | ||||||
|  |             // last_stream_id | ||||||
|  |             0, 0, 0, 1, | ||||||
|  |             // error_code | ||||||
|  |             0, 0, 0, 11, | ||||||
|  |             // debug_data | ||||||
|  |             "too_many_pings", | ||||||
|  |         ]; | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |     let data = poll_frame!(GoAway, codec); | ||||||
|  |     assert_eq!(data.reason(), Reason::ENHANCE_YOUR_CALM); | ||||||
|  |     assert_eq!(data.last_stream_id(), 1); | ||||||
|  |     assert_eq!(data.debug_data(), b"too_many_pings"); | ||||||
|  |  | ||||||
|  |     assert_closed!(codec); | ||||||
|  | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user