use std::pin::Pin; use std::task::{Context, Poll}; use tokio::io::AsyncRead; use tokio_util::codec::FramedRead as InnerFramedRead; use tokio_util::codec::{LengthDelimitedCodec, LengthDelimitedCodecError};
// 16 MB "sane default" taken from golang http2 const DEFAULT_SETTINGS_MAX_HEADER_LIST_SIZE: usize = 16 << 20;
pubfn get_mut(&mutself) -> &mut T { self.inner.get_mut()
}
/// Returns the current max frame size setting #[cfg(feature = "unstable")] #[inline] pubfn max_frame_size(&self) -> usize { self.inner.decoder().max_frame_length()
}
/// Updates the max frame size setting. /// /// Must be within 16,384 and 16,777,215. #[inline] pubfn set_max_frame_size(&mutself, 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)
}
/// Update the max header list size setting. #[inline] pubfn set_max_header_list_size(&mutself, val: usize) { self.max_header_list_size = val;
}
/// Decodes a frame. /// /// This method is intentionally de-generified and outlined because it is very large. fn decode_frame(
hpack: &mut hpack::Decoder,
max_header_list_size: usize,
partial_inout: &mut Option<Partial>, mut bytes: BytesMut,
) -> Result<Option<Frame>, Error> { let span = tracing::trace_span!("FramedRead::decode_frame", offset = bytes.len()); let _e = span.enter();
tracing::trace!("decoding frame from {}B", bytes.len());
// Parse the head let head = frame::Head::parse(&bytes);
// The stream identifiers must match if partial.frame.stream_id() != head.stream_id() {
proto_err!(conn: "CONTINUATION frame stream ID does not match previous frame stream ID"); return Err(Error::library_go_away(Reason::PROTOCOL_ERROR));
}
// Extend the buf if partial.buf.is_empty() {
partial.buf = bytes.split_off(frame::HEADER_LEN);
} else { if partial.frame.is_over_size() { // If there was left over bytes previously, they may be // needed to continue decoding, even though we will // be ignoring this frame. This is done to keep the HPACK // decoder state up-to-date. // // Still, we need to be careful, because if a malicious // attacker were to try to send a gigantic string, such // that it fits over multiple header blocks, we could // grow memory uncontrollably again, and that'd be a shame. // // Instead, we use a simple heuristic to determine if // we should continue to ignore decoding, or to tell // the attacker to go away. if partial.buf.len() + bytes.len() > max_header_list_size {
proto_err!(conn: "CONTINUATION frame header block size over ignorable limit"); return Err(Error::library_go_away(Reason::COMPRESSION_ERROR));
}
}
partial.buf.extend_from_slice(&bytes[frame::HEADER_LEN..]);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.