1
1
//! Body types.
2
2
3
- use crate :: Body ;
3
+ use crate :: { Body , SizeHint } ;
4
4
use bytes:: Buf ;
5
5
use pin_project_lite:: pin_project;
6
6
use std:: {
@@ -16,8 +16,7 @@ pin_project! {
16
16
pub struct Limited <B > {
17
17
#[ pin]
18
18
inner: B ,
19
- limit: usize ,
20
- read: usize ,
19
+ remaining: usize ,
21
20
}
22
21
}
23
22
@@ -26,8 +25,7 @@ impl<B> Limited<B> {
26
25
pub fn new ( inner : B , limit : usize ) -> Self {
27
26
Self {
28
27
inner,
29
- limit,
30
- read : 0 ,
28
+ remaining : limit,
31
29
}
32
30
}
33
31
}
@@ -46,20 +44,22 @@ where
46
44
) -> Poll < Option < Result < Self :: Data , Self :: Error > > > {
47
45
let this = self . project ( ) ;
48
46
49
- match this. inner . poll_data ( cx) {
47
+ let res = match this. inner . poll_data ( cx) {
50
48
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 ( ) ) )
55
52
} else {
56
- Poll :: Ready ( Some ( Err ( "body limit exceeded" . into ( ) ) ) )
53
+ * this. remaining -= data. remaining ( ) ;
54
+ Some ( Ok ( data) )
57
55
}
58
56
}
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)
63
63
}
64
64
65
65
fn poll_trailers (
72
72
fn is_end_stream ( & self ) -> bool {
73
73
self . inner . is_end_stream ( )
74
74
}
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
+ }
75
93
}
76
94
77
95
#[ cfg( test) ]
0 commit comments