1
1
use futures_lite:: { io, prelude:: * , ready} ;
2
2
use serde:: { de:: DeserializeOwned , Serialize } ;
3
3
4
+ use std:: convert:: TryFrom ;
4
5
use std:: fmt:: { self , Debug } ;
5
6
use std:: pin:: Pin ;
6
7
use std:: task:: { Context , Poll } ;
@@ -55,8 +56,8 @@ pin_project_lite::pin_project! {
55
56
#[ pin]
56
57
reader: Box <dyn AsyncBufRead + Unpin + Send + Sync + ' static >,
57
58
mime: Mime ,
58
- length: Option <usize >,
59
- bytes_read: usize
59
+ length: Option <u64 >,
60
+ bytes_read: u64 ,
60
61
}
61
62
}
62
63
@@ -104,12 +105,12 @@ impl Body {
104
105
/// ```
105
106
pub fn from_reader (
106
107
reader : impl AsyncBufRead + Unpin + Send + Sync + ' static ,
107
- len : Option < usize > ,
108
+ length : Option < u64 > ,
108
109
) -> Self {
109
110
Self {
110
111
reader : Box :: new ( reader) ,
111
112
mime : mime:: BYTE_STREAM ,
112
- length : len ,
113
+ length,
113
114
bytes_read : 0 ,
114
115
}
115
116
}
@@ -152,7 +153,7 @@ impl Body {
152
153
pub fn from_bytes ( bytes : Vec < u8 > ) -> Self {
153
154
Self {
154
155
mime : mime:: BYTE_STREAM ,
155
- length : Some ( bytes. len ( ) ) ,
156
+ length : Some ( bytes. len ( ) as u64 ) ,
156
157
reader : Box :: new ( io:: Cursor :: new ( bytes) ) ,
157
158
bytes_read : 0 ,
158
159
}
@@ -202,7 +203,7 @@ impl Body {
202
203
pub fn from_string ( s : String ) -> Self {
203
204
Self {
204
205
mime : mime:: PLAIN ,
205
- length : Some ( s. len ( ) ) ,
206
+ length : Some ( s. len ( ) as u64 ) ,
206
207
reader : Box :: new ( io:: Cursor :: new ( s. into_bytes ( ) ) ) ,
207
208
bytes_read : 0 ,
208
209
}
@@ -223,7 +224,8 @@ impl Body {
223
224
/// # Ok(()) }) }
224
225
/// ```
225
226
pub async fn into_string ( mut self ) -> crate :: Result < String > {
226
- let mut result = String :: with_capacity ( self . len ( ) . unwrap_or ( 0 ) ) ;
227
+ let len = usize:: try_from ( self . len ( ) . unwrap_or ( 0 ) ) . status ( StatusCode :: PayloadTooLarge ) ?;
228
+ let mut result = String :: with_capacity ( len) ;
227
229
self . read_to_string ( & mut result)
228
230
. await
229
231
. status ( StatusCode :: UnprocessableEntity ) ?;
@@ -247,7 +249,7 @@ impl Body {
247
249
pub fn from_json ( json : & impl Serialize ) -> crate :: Result < Self > {
248
250
let bytes = serde_json:: to_vec ( & json) ?;
249
251
let body = Self {
250
- length : Some ( bytes. len ( ) ) ,
252
+ length : Some ( bytes. len ( ) as u64 ) ,
251
253
reader : Box :: new ( io:: Cursor :: new ( bytes) ) ,
252
254
mime : mime:: JSON ,
253
255
bytes_read : 0 ,
@@ -312,7 +314,7 @@ impl Body {
312
314
let bytes = query. into_bytes ( ) ;
313
315
314
316
let body = Self {
315
- length : Some ( bytes. len ( ) ) ,
317
+ length : Some ( bytes. len ( ) as u64 ) ,
316
318
reader : Box :: new ( io:: Cursor :: new ( bytes) ) ,
317
319
mime : mime:: FORM ,
318
320
bytes_read : 0 ,
@@ -382,7 +384,7 @@ impl Body {
382
384
383
385
Ok ( Self {
384
386
mime,
385
- length : Some ( len as usize ) ,
387
+ length : Some ( len) ,
386
388
reader : Box :: new ( io:: BufReader :: new ( file) ) ,
387
389
bytes_read : 0 ,
388
390
} )
@@ -401,7 +403,7 @@ impl Body {
401
403
/// let body = Body::from_reader(cursor, Some(len));
402
404
/// assert_eq!(body.len(), Some(10));
403
405
/// ```
404
- pub fn len ( & self ) -> Option < usize > {
406
+ pub fn len ( & self ) -> Option < u64 > {
405
407
self . length
406
408
}
407
409
@@ -472,13 +474,15 @@ impl AsyncRead for Body {
472
474
None => buf,
473
475
Some ( length) if length == self . bytes_read => return Poll :: Ready ( Ok ( 0 ) ) ,
474
476
Some ( length) => {
475
- let max_len = ( length - self . bytes_read ) . min ( buf. len ( ) ) ;
477
+ // Compute `min` using u64, then truncate back to usize. Since
478
+ // buf.len() is a usize, this can never overflow.
479
+ let max_len = ( length - self . bytes_read ) . min ( buf. len ( ) as u64 ) as usize ;
476
480
& mut buf[ 0 ..max_len]
477
481
}
478
482
} ;
479
483
480
484
let bytes = ready ! ( Pin :: new( & mut self . reader) . poll_read( cx, & mut buf) ) ?;
481
- self . bytes_read += bytes;
485
+ self . bytes_read += bytes as u64 ;
482
486
Poll :: Ready ( Ok ( bytes) )
483
487
}
484
488
}
0 commit comments