Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

upgrade to lambda_http v0.5.1 #21

Merged
merged 3 commits into from
Mar 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
712 changes: 426 additions & 286 deletions Cargo.lock

Large diffs are not rendered by default.

16 changes: 7 additions & 9 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
[package]
name = "aws-lambda-adapter"
version = "0.1.2"
version = "0.3.0"
authors = ["Harold Sun <sunhua@amazon.com>"]
edition = "2018"

[dependencies]
log = "0.4.14"
env_logger = "0.8.3"
tokio = { version = "1.4", features = ["macros", "io-util", "sync", "rt-multi-thread", "process"] }
tokio-retry = "0.3"
lambda_http = {git = "https://github.com/bnusunny/aws-lambda-rust-runtime", branch = "extensions"}
reqwest = { version = "0.11", default-features = false, features = ["blocking", "json"] }
http = "0.2.4"
lambda-extension = "0.5.0"
lambda_http = "0.5.1"
log = "0.4.14"
once_cell = "1.7.2"
futures = "0.3.16"
url = "2.1.1"
serde_json = "1.0"
reqwest = { version = "0.11", default-features = false, features = ["blocking", "json"] }
tokio = { version = "1.0", features = ["macros", "io-util", "sync", "rt-multi-thread"] }
tokio-retry = "0.3"

[[bin]]
name = "lambda-adapter"
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile.mac
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
FROM scratch
ARG ARCH=x86_64
COPY target/${ARCH}-unknown-linux-musl/release/bootstrap /opt/bootstrap
COPY target/${ARCH}-unknown-linux-musl/release/lambda-adapter /opt/extensions/lambda-adapter
2 changes: 1 addition & 1 deletion examples/expressjs-zip/hello-world/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const app = express()
const port = process.env['PORT'] || 8080


app.get('/', (req, res) => {
app.get('/Prod', (req, res) => {
res.send('Hi there!')
})

Expand Down
2 changes: 1 addition & 1 deletion examples/expressjs/app/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
FROM public.ecr.aws/docker/library/node:16.13.2-stretch-slim
COPY --from=public.ecr.aws/awsguru/aws-lambda-adapter:0.2.0 /opt/extensions/lambda-adapter /opt/extensions/lambda-adapter
COPY --from=public.ecr.aws/awsguru/aws-lambda-adapter:0.3.0 /opt/extensions/lambda-adapter /opt/extensions/lambda-adapter
EXPOSE 8080
WORKDIR "/var/task"
ADD src/package.json /var/task/package.json
Expand Down
2 changes: 1 addition & 1 deletion examples/flask/app/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
FROM public.ecr.aws/docker/library/python:3.8.12-slim-buster
COPY --from=public.ecr.aws/awsguru/aws-lambda-adapter:0.2.0 /opt/extensions/lambda-adapter /opt/extensions/lambda-adapter
COPY --from=public.ecr.aws/awsguru/aws-lambda-adapter:0.3.0 /opt/extensions/lambda-adapter /opt/extensions/lambda-adapter
WORKDIR /var/task
COPY app.py requirements.txt ./
RUN python -m pip install -r requirements.txt
Expand Down
2 changes: 1 addition & 1 deletion examples/nginx/app/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
FROM public.ecr.aws/docker/library/nginx:1.21.6
COPY --from=public.ecr.aws/awsguru/aws-lambda-adapter:0.2.0 /opt/extensions/lambda-adapter /opt/extensions/lambda-adapter
COPY --from=public.ecr.aws/awsguru/aws-lambda-adapter:0.3.0 /opt/extensions/lambda-adapter /opt/extensions/lambda-adapter
WORKDIR "/tmp"
ADD config/ /etc/nginx/
ADD images/ /usr/share/nginx/html/images
Expand Down
2 changes: 1 addition & 1 deletion examples/php/docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
FROM public.ecr.aws/amazonlinux/amazonlinux:2.0.20220121.0

COPY --from=public.ecr.aws/awsguru/aws-lambda-adapter:0.2.0 /opt/extensions/lambda-adapter /opt/extensions/lambda-adapter
COPY --from=public.ecr.aws/awsguru/aws-lambda-adapter:0.3.0 /opt/extensions/lambda-adapter /opt/extensions/lambda-adapter

RUN amazon-linux-extras install -y nginx1 php7.4 && yum clean all && rm -rf /var/cache/yum

Expand Down
2 changes: 1 addition & 1 deletion examples/springboot/app/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ COPY pom.xml ./
RUN mvn -q clean package

FROM public.ecr.aws/docker/library/amazoncorretto:8u322-al2
COPY --from=public.ecr.aws/awsguru/aws-lambda-adapter:0.2.0 /opt/extensions/lambda-adapter /opt/extensions/lambda-adapter
COPY --from=public.ecr.aws/awsguru/aws-lambda-adapter:0.3.0 /opt/extensions/lambda-adapter /opt/extensions/lambda-adapter
EXPOSE 8080
WORKDIR /opt
COPY --from=build-image /task/target/petstore-0.0.1-SNAPSHOT.jar /opt
Expand Down
74 changes: 22 additions & 52 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

use lambda_http::{
handler,
lambda_runtime::{self, Context},
Body, IntoResponse, Request, RequestExt, Response,
};
use lambda_extension::{service_fn as extension_handler, Extension};
use lambda_http::{service_fn as http_handler, Body, IntoResponse, Request, Response};
use log::*;
use once_cell::sync::OnceCell;
use reqwest::{redirect, Client};
use serde_json::json;
use std::{env, mem, thread};
use tokio_retry::strategy::FixedInterval;
use tokio_retry::Retry;
use url::form_urlencoded::Serializer;
use std::{env, mem};
use tokio::runtime::Handle;
use tokio_retry::{strategy::FixedInterval, Retry};

type Error = Box<dyn std::error::Error + Send + Sync + 'static>;
static HTTP_CLIENT: OnceCell<Client> = OnceCell::new();
Expand All @@ -23,25 +18,16 @@ async fn main() -> Result<(), Error> {
env_logger::init();

// register as an external extension
let aws_lambda_runtime_api = env::var("AWS_LAMBDA_RUNTIME_API").unwrap();
let extension_next_url = format!("http://{}/2020-01-01/extension/event/next", aws_lambda_runtime_api);
let extension_register_url = format!("http://{}/2020-01-01/extension/register", aws_lambda_runtime_api);
let executable_name = env::current_exe().unwrap().file_name().unwrap().to_string_lossy().to_string();
let client = reqwest::blocking::ClientBuilder::new().timeout(None).build().unwrap();
let resp = client
.post(extension_register_url)
.header("Lambda-Extension-Name", executable_name)
.json(&json!({"events": []}))
.send()?;
let extension_id = resp.headers().get("Lambda-Extension-Identifier").unwrap().clone();
thread::spawn(move || {
let extension_id_str = extension_id.to_str().unwrap();
debug!("[extension] enter event loop for extension id: '{}'", extension_id_str);
client
.get(extension_next_url)
.header("Lambda-Extension-Identifier", extension_id_str)
.send()
.unwrap();
let handle = Handle::current();
tokio::task::spawn_blocking(move || {
handle.spawn(async {
Extension::new()
.with_events(&[])
.with_events_processor(extension_handler(|_| async { Ok::<(), Error>(()) }))
.run()
.await
.expect("extension thread error");
})
});

// check if the application is ready every 10 milliseconds
Expand All @@ -57,30 +43,15 @@ async fn main() -> Result<(), Error> {

// start lambda runtime
HTTP_CLIENT.set(Client::builder().redirect(redirect::Policy::none()).build().unwrap()).unwrap();
lambda_runtime::run(handler(http_proxy_handler)).await?;
lambda_http::run(http_handler(http_proxy_handler)).await?;
Ok(())
}

async fn http_proxy_handler(event: Request, _: Context) -> Result<impl IntoResponse, Error> {
async fn http_proxy_handler(event: Request) -> Result<impl IntoResponse, Error> {
let port = env::var("PORT").unwrap_or_else(|_| "8080".to_string());
let app_host = format!("http://127.0.0.1:{}", port);
let query_params = event.query_string_parameters();
debug!("query_params are {:#?}", query_params);

let (parts, body) = event.into_parts();
let mut app_url = app_host + parts.uri.path();

// append query parameters to app_url
if !query_params.is_empty() {
app_url.push('?');
let mut serializer = Serializer::new(&mut app_url);
for (key, _) in query_params.iter() {
for value in query_params.get_all(key).unwrap().iter() {
serializer.append_pair(key, value);
}
}
serializer.finish();
}
let app_url = app_host + parts.uri.path_and_query().unwrap().as_str();
debug!("app_url is {:#?}", app_url);
debug!("request headers are {:#?}", parts.headers);

Expand All @@ -102,7 +73,6 @@ async fn http_proxy_handler(event: Request, _: Context) -> Result<impl IntoRespo
}

async fn convert_body(app_response: reqwest::Response) -> Result<Body, Error> {
let content_type;
debug!("app response headers are {:#?}", app_response.headers());

if app_response.headers().get(http::header::CONTENT_ENCODING).is_some() {
Expand All @@ -111,11 +81,11 @@ async fn convert_body(app_response: reqwest::Response) -> Result<Body, Error> {
return Ok(Body::Binary(content.to_vec()));
}

if let Some(value) = app_response.headers().get(http::header::CONTENT_TYPE) {
content_type = value.to_str().unwrap_or_default();
let content_type = if let Some(value) = app_response.headers().get(http::header::CONTENT_TYPE) {
value.to_str().unwrap_or_default()
} else {
content_type = "";
}
""
};
debug!("content_type is {:?}", content_type);

if content_type.starts_with("text")
Expand Down