#[cfg(feature = "http1")] use bytes::BytesMut; use http::header::CONTENT_LENGTH; use http::header::{HeaderValue, ValueIter}; use http::HeaderMap; #[cfg(all(feature = "http2", feature = "client"))] use http::Method;
pub(super) fn content_length_parse_all_values(values: ValueIter<'_, HeaderValue>) -> Option<u64> { // If multiple Content-Length headers were sent, everything can still // be alright if they all contain the same value, and all parse // correctly. If not, then it's an error.
letmut content_length: Option<u64> = None; for h in values { iflet Ok(line) = h.to_str() { for v in line.split(',') { iflet Some(n) = from_digits(v.trim().as_bytes()) { if content_length.is_none() {
content_length = Some(n)
} elseif content_length != Some(n) { return None;
}
} else { return None
}
}
} else { return None
}
}
return content_length
}
fn from_digits(bytes: &[u8]) -> Option<u64> { // cannot use FromStr for u64, since it allows a signed prefix letmut result = 0u64; const RADIX: u64 = 10;
if bytes.is_empty() { return None;
}
for &b in bytes { // can't use char::to_digit, since we haven't verified these bytes // are utf-8. match b {
b'0'..=b'9' => {
result = result.checked_mul(RADIX)?;
result = result.checked_add((b - b'0') as u64)?;
},
_ => { // not a DIGIT, get outta here! return None;
}
}
}
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.