diff --git a/Cargo.toml b/Cargo.toml index 805e2ca3..c795348b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,12 +25,14 @@ rustdoc-args = ["--cfg", "feature=\"docs\""] [features] default = ["h1-server", "cookies", "logger", "sessions"] +docs = ["unstable"] +unstable = [] + cookies = ["http-types/cookies"] h1-server = ["async-h1"] +lambda = ["lambda_http", "http", "http-types/hyperium_http"] logger = ["femme"] -docs = ["unstable"] sessions = ["async-session", "cookies"] -unstable = [] [dependencies] async-h1 = { version = "2.3.0", optional = true } @@ -49,6 +51,10 @@ route-recognizer = "0.2.0" serde = "1.0.117" serde_json = "1.0.59" +# feature = lambda +lambda_http = { version = "0.3.0", optional = true } +http = { version = "0.2.4", optional = true } + [dev-dependencies] async-std = { version = "1.6.5", features = ["unstable", "attributes"] } criterion = "0.3.3" diff --git a/src/lambda.rs b/src/lambda.rs new file mode 100644 index 00000000..788e98a8 --- /dev/null +++ b/src/lambda.rs @@ -0,0 +1,39 @@ +use std::convert::TryInto; +use std::future::Future; +use std::pin::Pin; + +use crate::http::Error; +use crate::{Body, Server}; + +impl lambda_http::Handler for Server +where + State: Clone + Send + Sync + 'static, +{ + type Error = Error; + type Response = lambda_http::Response; + type Fut = Pin> + Send + 'static>>; + + fn call(&self, event: lambda_http::Request, context: lambda_http::Context) -> Self::Fut { + let server = self.clone(); + Box::pin(async move { + let (parts, body) = event.into_parts(); + let body = match body { + lambda_http::Body::Empty => Body::empty(), + lambda_http::Body::Text(text) => Body::from_string(text), + lambda_http::Body::Binary(bytes) => Body::from_bytes(bytes), + }; + let mut req: http_types::Request = http::Request::from_parts(parts, body).try_into()?; + + req.ext_mut().insert(context); + let res: http_types::Response = server.respond(req).await?; + + let res: http::Response = res.try_into()?; + let (parts, body) = res.into_parts(); + let body = match body.is_empty() { + Some(true) => lambda_http::Body::Empty, + _ => lambda_http::Body::Binary(body.into_bytes().await?), + }; + Ok(http::Response::from_parts(parts, body)) + }) + } +} diff --git a/src/lib.rs b/src/lib.rs index 718184c6..e4be047d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -75,6 +75,9 @@ mod route; mod router; mod server; +#[cfg(feature = "lambda")] +mod lambda; + pub mod convert; pub mod listener; pub mod log;