summaryrefslogtreecommitdiffstats
path: root/third_party/rust/h2/src/frame/util.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/h2/src/frame/util.rs')
-rw-r--r--third_party/rust/h2/src/frame/util.rs79
1 files changed, 79 insertions, 0 deletions
diff --git a/third_party/rust/h2/src/frame/util.rs b/third_party/rust/h2/src/frame/util.rs
new file mode 100644
index 0000000000..6bee7bd9bb
--- /dev/null
+++ b/third_party/rust/h2/src/frame/util.rs
@@ -0,0 +1,79 @@
+use std::fmt;
+
+use super::Error;
+use bytes::Bytes;
+
+/// Strip padding from the given payload.
+///
+/// It is assumed that the frame had the padded flag set. This means that the
+/// first byte is the length of the padding with that many
+/// 0 bytes expected to follow the actual payload.
+///
+/// # Returns
+///
+/// A slice of the given payload where the actual one is found and the length
+/// of the padding.
+///
+/// If the padded payload is invalid (e.g. the length of the padding is equal
+/// to the total length), returns `None`.
+pub fn strip_padding(payload: &mut Bytes) -> Result<u8, Error> {
+ let payload_len = payload.len();
+ if payload_len == 0 {
+ // If this is the case, the frame is invalid as no padding length can be
+ // extracted, even though the frame should be padded.
+ return Err(Error::TooMuchPadding);
+ }
+
+ let pad_len = payload[0] as usize;
+
+ if pad_len >= payload_len {
+ // This is invalid: the padding length MUST be less than the
+ // total frame size.
+ return Err(Error::TooMuchPadding);
+ }
+
+ let _ = payload.split_to(1);
+ let _ = payload.split_off(payload_len - pad_len - 1);
+
+ Ok(pad_len as u8)
+}
+
+pub(super) fn debug_flags<'a, 'f: 'a>(
+ fmt: &'a mut fmt::Formatter<'f>,
+ bits: u8,
+) -> DebugFlags<'a, 'f> {
+ let result = write!(fmt, "({:#x}", bits);
+ DebugFlags {
+ fmt,
+ result,
+ started: false,
+ }
+}
+
+pub(super) struct DebugFlags<'a, 'f: 'a> {
+ fmt: &'a mut fmt::Formatter<'f>,
+ result: fmt::Result,
+ started: bool,
+}
+
+impl<'a, 'f: 'a> DebugFlags<'a, 'f> {
+ pub(super) fn flag_if(&mut self, enabled: bool, name: &str) -> &mut Self {
+ if enabled {
+ self.result = self.result.and_then(|()| {
+ let prefix = if self.started {
+ " | "
+ } else {
+ self.started = true;
+ ": "
+ };
+
+ write!(self.fmt, "{}{}", prefix, name)
+ });
+ }
+ self
+ }
+
+ pub(super) fn finish(&mut self) -> fmt::Result {
+ self.result.and_then(|()| write!(self.fmt, ")"))
+ }
+}