Skip to content

Commit c9eb0db

Browse files
authored
teach checking for limits on request bodies (#80)
1 parent 08c4c66 commit c9eb0db

File tree

2 files changed

+27
-3
lines changed

2 files changed

+27
-3
lines changed

_legacy/server/echo.md

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,16 +170,29 @@ collect the full body.
170170
In this case, we can't really generate a `Response` immediately. Instead, we
171171
must wait for the full request body to be received.
172172

173-
We want to concatenate the request body, and map the result into our `reverse` function, and return the eventual result. We can make use of the `hyper::body::to_bytes` utility function to make this easy.
173+
We want to concatenate the request body, and map the result into our `reverse`
174+
function, and return the eventual result. We can make use of the
175+
`hyper::body::to_bytes` utility function to make this easy.
176+
177+
> Note: You must always be careful not to buffer without a max bounds. We'll
178+
> set a 64kb maximum here.
174179
175180
```rust
176181
# extern crate hyper;
177-
# use hyper::{Body, Method, Request, Response};
182+
# use hyper::{body::HttpBody, Body, Method, Request, Response};
178183
# async fn echo(req: Request<Body>) -> Result<Response<Body>, hyper::Error> {
179184
# let mut response = Response::default();
180185
# match (req.method(), req.uri().path()) {
181186
// Yet another route inside our match block...
182187
(&Method::POST, "/echo/reverse") => {
188+
// Protect our server from massive bodies.
189+
let upper = req.body().size_hint().upper().unwrap_or(u64::MAX);
190+
if upper > 1024 * 64 {
191+
let mut resp = Response::new(Body::from("Body too big"));
192+
*resp.status_mut() = hyper::StatusCode::PAYLOAD_TOO_LARGE;
193+
return Ok(resp);
194+
}
195+
183196
// Await the full body to be concatenated into a single `Bytes`...
184197
let full_body = hyper::body::to_bytes(req.into_body()).await?;
185198

_stable/server/echo.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,18 +191,29 @@ stream to completion, collecting all the data and trailer frames into a `Collect
191191
We can easily turn the `Collected` body into a single `Bytes` by calling its `into_bytes`
192192
method.
193193

194+
> Note: You must always be careful not to buffer without a max bounds. We'll
195+
> set a 64kb maximum here.
196+
194197
```rust
195198
# extern crate hyper;
196199
# extern crate http_body_util;
197200
# use hyper::body::Bytes;
198201
# use http_body_util::{combinators::BoxBody, BodyExt, Empty, Full};
199-
# use hyper::{Method, Request, Response, StatusCode};
202+
# use hyper::{body::Body, Method, Request, Response, StatusCode};
200203
# async fn echo(
201204
# req: Request<hyper::body::Incoming>,
202205
# ) -> Result<Response<BoxBody<Bytes, hyper::Error>>, hyper::Error> {
203206
# match (req.method(), req.uri().path()) {
204207
// Yet another route inside our match block...
205208
(&Method::POST, "/echo/reversed") => {
209+
// Protect our server from massive bodies.
210+
let upper = req.body().size_hint().upper().unwrap_or(u64::MAX);
211+
if upper > 1024 * 64 {
212+
let mut resp = Response::new(full("Body too big"));
213+
*resp.status_mut() = hyper::StatusCode::PAYLOAD_TOO_LARGE;
214+
return Ok(resp);
215+
}
216+
206217
// Await the whole body to be collected into a single `Bytes`...
207218
let whole_body = req.collect().await?.to_bytes();
208219

0 commit comments

Comments
 (0)