Skip to content

Commit e1e3232

Browse files
change implementation and add size hint
Co-authored-by: neoeinstein <[email protected]>
1 parent 60419ac commit e1e3232

File tree

1 file changed

+33
-15
lines changed

1 file changed

+33
-15
lines changed

src/limited.rs

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! Body types.
22
3-
use crate::Body;
3+
use crate::{Body, SizeHint};
44
use bytes::Buf;
55
use pin_project_lite::pin_project;
66
use std::{
@@ -16,8 +16,7 @@ pin_project! {
1616
pub struct Limited<B> {
1717
#[pin]
1818
inner: B,
19-
limit: usize,
20-
read: usize,
19+
remaining: usize,
2120
}
2221
}
2322

@@ -26,8 +25,7 @@ impl<B> Limited<B> {
2625
pub fn new(inner: B, limit: usize) -> Self {
2726
Self {
2827
inner,
29-
limit,
30-
read: 0,
28+
remaining: limit,
3129
}
3230
}
3331
}
@@ -46,20 +44,22 @@ where
4644
) -> Poll<Option<Result<Self::Data, Self::Error>>> {
4745
let this = self.project();
4846

49-
match this.inner.poll_data(cx) {
47+
let res = match this.inner.poll_data(cx) {
5048
Poll::Ready(Some(Ok(data))) => {
51-
*this.read += data.remaining();
52-
53-
if this.read <= this.limit {
54-
Poll::Ready(Some(Ok(data)))
49+
if data.remaining() > *this.remaining {
50+
*this.remaining = 0;
51+
Some(Err("length limit exceeded".into()))
5552
} else {
56-
Poll::Ready(Some(Err("body limit exceeded".into())))
53+
*this.remaining -= data.remaining();
54+
Some(Ok(data))
5755
}
5856
}
59-
Poll::Ready(Some(Err(e))) => Poll::Ready(Some(Err(e.into()))),
60-
Poll::Ready(None) => Poll::Ready(None),
61-
Poll::Pending => Poll::Pending,
62-
}
57+
Poll::Ready(Some(Err(e))) => Some(Err(e.into())),
58+
Poll::Ready(None) => None,
59+
Poll::Pending => return Poll::Pending,
60+
};
61+
62+
Poll::Ready(res)
6363
}
6464

6565
fn poll_trailers(
@@ -72,6 +72,24 @@ where
7272
fn is_end_stream(&self) -> bool {
7373
self.inner.is_end_stream()
7474
}
75+
76+
fn size_hint(&self) -> SizeHint {
77+
use std::convert::TryFrom;
78+
match u64::try_from(self.remaining) {
79+
Ok(n) => {
80+
let mut hint = self.inner.size_hint();
81+
if hint.lower() >= n {
82+
hint.set_exact(n)
83+
} else if let Some(max) = hint.upper() {
84+
hint.set_upper(n.min(max))
85+
} else {
86+
hint.set_upper(n)
87+
}
88+
hint
89+
}
90+
Err(_) => self.inner.size_hint(),
91+
}
92+
}
7593
}
7694

7795
#[cfg(test)]

0 commit comments

Comments
 (0)