1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
use crate::{
body::SizeHint,
http::header::{CONTENT_LENGTH, HeaderMap},
};
use super::frame::headers;
pub(crate) trait BodySize {
/// Parse content-length from headers.
/// Returns `Err(())` if the header is present but malformed (RFC 7540 ยง8.1.2.6).
fn from_header(headers: &HeaderMap, is_end_stream: bool) -> Result<Self, ()>
where
Self: Sized;
/// Subtract `len` bytes received in a DATA frame.
/// Returns `Err(())` if this would underflow (overflow: more data than declared).
fn dec(&mut self, len: usize) -> Result<(), ()>;
/// Returns `Err` if remaining != 0 at END_STREAM (underflow: less data than declared).
fn ensure_zero(&self) -> Result<(), ()>;
}
impl BodySize for SizeHint {
fn from_header(headers: &HeaderMap, is_end_stream: bool) -> Result<Self, ()> {
let res = match headers.get(CONTENT_LENGTH) {
Some(v) => {
let s = v.to_str().map_err(|_| ())?;
match headers::parse_u64(s.as_bytes())? {
0 if is_end_stream => Self::None,
_ if is_end_stream => return Err(()),
n => Self::Exact(n),
}
}
None if is_end_stream => Self::None,
None => Self::Unknown,
};
Ok(res)
}
/// Subtract `len` bytes received in a DATA frame.
/// Returns `Err(())` if this would underflow (overflow: more data than declared).
fn dec(&mut self, len: usize) -> Result<(), ()> {
match self {
Self::Unknown => Ok(()),
Self::None => Err(()),
Self::Exact(rem) => {
*rem = rem.checked_sub(len as u64).ok_or(())?;
Ok(())
}
}
}
/// Returns `Err` if remaining != 0 at END_STREAM (underflow: less data than declared).
fn ensure_zero(&self) -> Result<(), ()> {
match self {
Self::Unknown | Self::None | Self::Exact(0) => Ok(()),
Self::Exact(_) => Err(()),
}
}
}