Skip to content

Commit d6f16af

Browse files
Fishrock123joshtriplett
authored andcommitted
Body: make len() and related use u64 rather than usize.
Breaking change. Closes #164
1 parent 482106b commit d6f16af

File tree

3 files changed

+19
-15
lines changed

3 files changed

+19
-15
lines changed

src/body.rs

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use futures_lite::{io, prelude::*, ready};
22
use serde::{de::DeserializeOwned, Serialize};
33

4+
use std::convert::TryFrom;
45
use std::fmt::{self, Debug};
56
use std::pin::Pin;
67
use std::task::{Context, Poll};
@@ -55,8 +56,8 @@ pin_project_lite::pin_project! {
5556
#[pin]
5657
reader: Box<dyn AsyncBufRead + Unpin + Send + Sync + 'static>,
5758
mime: Mime,
58-
length: Option<usize>,
59-
bytes_read: usize
59+
length: Option<u64>,
60+
bytes_read: u64,
6061
}
6162
}
6263

@@ -104,12 +105,12 @@ impl Body {
104105
/// ```
105106
pub fn from_reader(
106107
reader: impl AsyncBufRead + Unpin + Send + Sync + 'static,
107-
len: Option<usize>,
108+
length: Option<u64>,
108109
) -> Self {
109110
Self {
110111
reader: Box::new(reader),
111112
mime: mime::BYTE_STREAM,
112-
length: len,
113+
length,
113114
bytes_read: 0,
114115
}
115116
}
@@ -152,7 +153,7 @@ impl Body {
152153
pub fn from_bytes(bytes: Vec<u8>) -> Self {
153154
Self {
154155
mime: mime::BYTE_STREAM,
155-
length: Some(bytes.len()),
156+
length: Some(bytes.len() as u64),
156157
reader: Box::new(io::Cursor::new(bytes)),
157158
bytes_read: 0,
158159
}
@@ -202,7 +203,7 @@ impl Body {
202203
pub fn from_string(s: String) -> Self {
203204
Self {
204205
mime: mime::PLAIN,
205-
length: Some(s.len()),
206+
length: Some(s.len() as u64),
206207
reader: Box::new(io::Cursor::new(s.into_bytes())),
207208
bytes_read: 0,
208209
}
@@ -223,7 +224,8 @@ impl Body {
223224
/// # Ok(()) }) }
224225
/// ```
225226
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);
227229
self.read_to_string(&mut result)
228230
.await
229231
.status(StatusCode::UnprocessableEntity)?;
@@ -247,7 +249,7 @@ impl Body {
247249
pub fn from_json(json: &impl Serialize) -> crate::Result<Self> {
248250
let bytes = serde_json::to_vec(&json)?;
249251
let body = Self {
250-
length: Some(bytes.len()),
252+
length: Some(bytes.len() as u64),
251253
reader: Box::new(io::Cursor::new(bytes)),
252254
mime: mime::JSON,
253255
bytes_read: 0,
@@ -312,7 +314,7 @@ impl Body {
312314
let bytes = query.into_bytes();
313315

314316
let body = Self {
315-
length: Some(bytes.len()),
317+
length: Some(bytes.len() as u64),
316318
reader: Box::new(io::Cursor::new(bytes)),
317319
mime: mime::FORM,
318320
bytes_read: 0,
@@ -382,7 +384,7 @@ impl Body {
382384

383385
Ok(Self {
384386
mime,
385-
length: Some(len as usize),
387+
length: Some(len),
386388
reader: Box::new(io::BufReader::new(file)),
387389
bytes_read: 0,
388390
})
@@ -401,7 +403,7 @@ impl Body {
401403
/// let body = Body::from_reader(cursor, Some(len));
402404
/// assert_eq!(body.len(), Some(10));
403405
/// ```
404-
pub fn len(&self) -> Option<usize> {
406+
pub fn len(&self) -> Option<u64> {
405407
self.length
406408
}
407409

@@ -472,13 +474,15 @@ impl AsyncRead for Body {
472474
None => buf,
473475
Some(length) if length == self.bytes_read => return Poll::Ready(Ok(0)),
474476
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;
476480
&mut buf[0..max_len]
477481
}
478482
};
479483

480484
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;
482486
Poll::Ready(Ok(bytes))
483487
}
484488
}

src/request.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -488,7 +488,7 @@ impl Request {
488488
/// E.g. a string, or a buffer. Consumers of this API should check this
489489
/// value to decide whether to use `Chunked` encoding, or set the
490490
/// response length.
491-
pub fn len(&self) -> Option<usize> {
491+
pub fn len(&self) -> Option<u64> {
492492
self.body.len()
493493
}
494494

src/response.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ impl Response {
392392
/// E.g. a string, or a buffer. Consumers of this API should check this
393393
/// value to decide whether to use `Chunked` encoding, or set the
394394
/// response length.
395-
pub fn len(&self) -> Option<usize> {
395+
pub fn len(&self) -> Option<u64> {
396396
self.body.len()
397397
}
398398

0 commit comments

Comments
 (0)