From 52e8441f849db503546011aabfbb7c17098718cc Mon Sep 17 00:00:00 2001 From: Dave Hall Date: Sat, 4 Sep 2021 16:17:46 +1000 Subject: [PATCH] Make invocation URL dynamic The API endpoint in Amazon's implementation of Lambda used the path `/2015-03-31/functions/[func]/invocations` to invoke the function. `[func]` the name of the function and is set as the value of the `AWS_LAMBDA_FUNCTION_NAME` environment variable when the function is executing on AWS. The emulator uses a hard coded endpoint of `/2015-03-31/functions/function/invocations`. This is even the case when the `AWS_LAMBDA_FUNCTION_NAME` environment variable is set to another value. This patch changes the endpoint URL when the `AWS_LAMBDA_FUNCTION_NAME` environment variable is set. In this case the invocation URL will be `/2015-03-31/functions/${AWS_LAMBDA_FUNCTION_NAME}/invocations`. When the environment variable isn't set, the current behaviour persists and the function name is set to `function`. The end result is the emulator behaviour is closer to the real environment the functions execute in. This PR fixes #43 I raised a few weeks ago. --- cmd/aws-lambda-rie/http.go | 16 +++++++++++----- cmd/aws-lambda-rie/main.go | 4 +++- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/cmd/aws-lambda-rie/http.go b/cmd/aws-lambda-rie/http.go index 88bd39b..5d6ad8b 100644 --- a/cmd/aws-lambda-rie/http.go +++ b/cmd/aws-lambda-rie/http.go @@ -11,15 +11,21 @@ import ( "go.amzn.com/lambda/rapidcore" ) -func startHTTPServer(ipport string, sandbox *rapidcore.SandboxBuilder, bs interop.Bootstrap) { +func startHTTPServer(ipport string, sandbox *rapidcore.SandboxBuilder, bs interop.Bootstrap, funcName string) { srv := &http.Server{ Addr: ipport, } - // Pass a channel - http.HandleFunc("/2015-03-31/functions/function/invocations", func(w http.ResponseWriter, r *http.Request) { - InvokeHandler(w, r, sandbox.LambdaInvokeAPI(), bs) - }) + var functions = []string{funcName} + if funcName != "function" { + functions = []string{"function", funcName} + } + for _, funcName := range functions { + // Pass a channel + http.HandleFunc("/2015-03-31/functions/"+funcName+"/invocations", func(w http.ResponseWriter, r *http.Request) { + InvokeHandler(w, r, sandbox.LambdaInvokeAPI(), bs) + }) + } // go routine (main thread waits) if err := srv.ListenAndServe(); err != nil { diff --git a/cmd/aws-lambda-rie/main.go b/cmd/aws-lambda-rie/main.go index bd15402..7ff7d7f 100644 --- a/cmd/aws-lambda-rie/main.go +++ b/cmd/aws-lambda-rie/main.go @@ -78,13 +78,15 @@ func main() { sandbox.SetRuntimeAPIAddress(opts.RuntimeAPIAddress) } + funcName := GetenvWithDefault("AWS_LAMBDA_FUNCTION_NAME", "function") + sandboxContext, internalStateFn := sandbox.Create() // Since we have not specified a custom interop server for standalone, we can // directly reference the default interop server, which is a concrete type sandbox.DefaultInteropServer().SetSandboxContext(sandboxContext) sandbox.DefaultInteropServer().SetInternalStateGetter(internalStateFn) - startHTTPServer(opts.RuntimeInterfaceEmulatorAddress, sandbox, bootstrap) + startHTTPServer(opts.RuntimeInterfaceEmulatorAddress, sandbox, bootstrap, funcName) } func getCLIArgs() (options, []string) {