feat(body): add body::aggregate and body::to_bytes functions

Adds utility functions to `hyper::body` to help asynchronously
collecting all the buffers of some `HttpBody` into one.

- `aggregate` will collect all into an `impl Buf` without copying the
  contents. This is ideal if you don't need a contiguous buffer.
- `to_bytes` will copy all the data into a single contiguous `Bytes`
  buffer.
This commit is contained in:
Sean McArthur
2019-12-05 17:51:37 -08:00
parent 5a59875742
commit 8ba9a8d2c4
15 changed files with 282 additions and 128 deletions

View File

@@ -11,12 +11,12 @@ use std::task::{Context, Poll};
use std::thread;
use std::time::Duration;
use hyper::body::to_bytes as concat;
use hyper::{Body, Client, Method, Request, StatusCode};
use futures_channel::oneshot;
use futures_core::{Future, Stream, TryFuture};
use futures_util::future::{self, FutureExt, TryFutureExt};
use futures_util::StreamExt;
use tokio::net::TcpStream;
use tokio::runtime::Runtime;
@@ -28,14 +28,6 @@ fn tcp_connect(addr: &SocketAddr) -> impl Future<Output = std::io::Result<TcpStr
TcpStream::connect(*addr)
}
async fn concat(mut body: Body) -> Result<bytes::Bytes, hyper::Error> {
let mut vec = Vec::new();
while let Some(chunk) = body.next().await {
vec.extend_from_slice(&chunk?);
}
Ok(vec.into())
}
macro_rules! test {
(
name: $name:ident,

View File

@@ -355,7 +355,7 @@ async fn async_test(cfg: __TestConfig) {
func(&req.headers());
}
let sbody = sreq.body;
concat(req.into_body()).map_ok(move |body| {
hyper::body::to_bytes(req.into_body()).map_ok(move |body| {
assert_eq!(body.as_ref(), sbody.as_slice(), "client body");
let mut res = Response::builder()
@@ -410,7 +410,7 @@ async fn async_test(cfg: __TestConfig) {
for func in &cheaders {
func(&res.headers());
}
concat(res.into_body())
hyper::body::to_bytes(res.into_body())
})
.map_ok(move |body| {
assert_eq!(body.as_ref(), cbody.as_slice(), "server body");
@@ -473,11 +473,3 @@ fn naive_proxy(cfg: ProxyConfig) -> (SocketAddr, impl Future<Output = ()>) {
let proxy_addr = srv.local_addr();
(proxy_addr, srv.map(|res| res.expect("proxy error")))
}
async fn concat(mut body: Body) -> Result<bytes::Bytes, hyper::Error> {
let mut vec = Vec::new();
while let Some(chunk) = body.next().await {
vec.extend_from_slice(&chunk?);
}
Ok(vec.into())
}