diff --git a/lambda-http/Cargo.toml b/lambda-http/Cargo.toml index 7ce1fdaf..3bbe9d26 100644 --- a/lambda-http/Cargo.toml +++ b/lambda-http/Cargo.toml @@ -18,7 +18,9 @@ maintenance = { status = "actively-developed" } [dependencies] base64 = "0.13.0" +bytes = "1" http = "0.2" +http-body = "0.4" lambda_runtime = { path = "../lambda-runtime", version = "0.4.1" } serde = { version = "^1", features = ["derive"] } serde_json = "^1" diff --git a/lambda-http/src/body.rs b/lambda-http/src/body.rs index c5dfdcf5..7ac31ce7 100644 --- a/lambda-http/src/body.rs +++ b/lambda-http/src/body.rs @@ -1,9 +1,11 @@ //! Provides an ALB / API Gateway oriented request and response body entity interface -use std::{borrow::Cow, ops::Deref}; - +use crate::Error; use base64::display::Base64Display; +use bytes::Bytes; +use http_body::{Body as HttpBody, SizeHint}; use serde::ser::{Error as SerError, Serialize, Serializer}; +use std::{borrow::Cow, mem::take, ops::Deref, pin::Pin, task::Poll}; /// Representation of http request and response bodies as supported /// by API Gateway and ALBs. @@ -175,6 +177,45 @@ impl<'a> Serialize for Body { } } +impl HttpBody for Body { + type Data = Bytes; + type Error = Error; + + fn poll_data( + self: Pin<&mut Self>, + _cx: &mut std::task::Context<'_>, + ) -> Poll>> { + let body = take(self.get_mut()); + Poll::Ready(match body { + Body::Empty => None, + Body::Text(s) => Some(Ok(s.into())), + Body::Binary(b) => Some(Ok(b.into())), + }) + } + + fn poll_trailers( + self: Pin<&mut Self>, + _cx: &mut std::task::Context<'_>, + ) -> Poll, Self::Error>> { + Poll::Ready(Ok(None)) + } + + fn is_end_stream(&self) -> bool { + match self { + Body::Empty => true, + _ => false, + } + } + + fn size_hint(&self) -> SizeHint { + match self { + Body::Empty => SizeHint::default(), + Body::Text(ref s) => SizeHint::with_exact(s.len() as u64), + Body::Binary(ref b) => SizeHint::with_exact(b.len() as u64), + } + } +} + #[cfg(test)] mod tests { use super::*;