Documentation ¶
Overview ¶
Package lh enables http.Handlers to be served in the AWS Lambda Go runtime.
ServeHTTP(h) should be called from a main package. If h is nil, http.DefaultServeMux will be used.
Note this package is intended for Lambda functions as API Gateway endpoints; other payloads will have undefined behavior. Also note API Gateway must be configured so all media types are treated as binary. That is, "Binary Media Types" under "Settings" includes:
*/*
API Gateway can remap hostnames and paths. For example using an API Gateway domain (not a custom domain), the stage component of the request URL is elided from the path provided to Lambda handlers. This package inspects for Location headers that would be otherwise incorrect and attempts to correct them if FixRelativeRedirect is left at its default of true.
The Lambda environment can be inspected by asserting http.Responsewriter to the Lambda interface. The ResponseWriter may not be asserted to an http.Hijacker nor Flusher, as the Lambda environment does not support any form of streaming (including but not limited to websockets and EventSources).
Example ¶
package main import ( "fmt" "net/http" "github.com/cloudinterfaces/lh" ) func main() { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { _, ok := w.(lh.Lambda) switch ok { case true: fmt.Fprintf(w, "Hello from the Lambda environment! via %s\n", r.Host) default: fmt.Fprintln(w, "Not running in Lambda environment") } }) lh.ServeHTTP(nil) }
Output:
Example (Complicated) ¶
package main import ( "fmt" "math" "net/http" "github.com/cloudinterfaces/lh" "github.com/gin-gonic/gin" "github.com/gorilla/rpc" "github.com/gorilla/rpc/json" ) type Math struct{} func (m *Math) Add(_ *http.Request, args *[]float64, sum *float64) error { for _, a := range *args { *sum += a } return nil } func (m *Math) Multiply(_ *http.Request, args *[]float64, product *float64) error { for i, a := range *args { if a == 0 { *product = 0 return nil } if i == 0 { *product = a continue } *product *= a } return nil } func (m *Math) Divide(_ *http.Request, args *[]float64, div *float64) error { if len(*args) < 2 { return fmt.Errorf("At least 2 arguments required") } for _, f := range (*args)[1:] { if math.Abs(f) == 0 { return fmt.Errorf("Args includes a division by zero") } } *div = (*args)[0] / (*args)[1] for _, f := range (*args)[2:] { *div /= f } return nil } func main() { server := rpc.NewServer() // github.com/gorilla/rpc server.RegisterCodec(json.NewCodec(), "application/json") server.RegisterService(&Math{}, "Math") http.Handle("/rpc", server) g := gin.Default() g.GET("/ping", func(c *gin.Context) { c.JSON(200, gin.H{ "message": "pong", }) }) http.Handle("/", g) http.HandleFunc("/redirect", func(w http.ResponseWriter, r *http.Request) { http.Redirect(w, r, "../error", 307) }) http.HandleFunc("/error", func(w http.ResponseWriter, r *http.Request) { http.Error(w, "This is an error", 500) }) lh.ServeHTTP(nil) }
Output:
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var Demangle = map[string]struct{}{
"X-Amzn-Remapped-Accept": {},
"X-Amzn-Remapped-Accept-Charset": {},
"X-Amzn-Remapped-Accept-Encoding": {},
"X-Amzn-Remapped-Age": {},
"X-Amzn-Remapped-Authorization": {},
"X-Amzn-Remapped-Connection": {},
"X-Amzn-Remapped-Content-Encoding": {},
"X-Amzn-Remapped-Content-Length": {},
"X-Amzn-Remapped-Content-MD5": {},
"X-Amzn-Remapped-Content-Type": {},
"X-Amzn-Remapped-Date": {},
"X-Amzn-Remapped-Expect": {},
"X-Amzn-Remapped-Host": {},
"X-Amzn-Remapped-Max-Forwards": {},
"X-Amzn-Remapped-Pragma": {},
"X-Amzn-Remapped-Proxy-Authenticate": {},
"X-Amzn-Remapped-Range": {},
"X-Amzn-Remapped-Referer": {},
"X-Amzn-Remapped-Server": {},
"X-Amzn-Remapped-TE": {},
"X-Amzn-Remapped-Trailer": {},
"X-Amzn-Remapped-Transfer-Encoding": {},
"X-Amzn-Remapped-Upgrade": {},
"X-Amzn-Remapped-User-Agent": {},
"X-Amzn-Remapped-Via": {},
"X-Amzn-Remapped-WWW-Authenticate": {},
"X-Amzn-Remapped-Warn": {},
}
Demangle is the set of possible X-Amzn-Remapped headers. It is a good practice to reduce this to a set of concern prior to calling ServeHTTP if DemangleInputHeaders is true.
var DemangleInputHeaders = false
DemangleInputHeaders controls the attempt to replace X-Amzn-Remapped-* headers with non-remapped equivalents. If true, the X-Amzn-Remapped header is deleted if it can be unremapped. If the non-remapped header exists and is not empty, the X-Amzn-Remapped header will not be deleted. For example, the Via header will generally be supplied by API Gateway, therefore X-Amzn-Remapped-Via may still be present if the client sent a Via header. This should be set (if needed) prior to calling ServeHTTP.
var FixRelativeRedirect = true
FixRelativeRedirect attemtps to "fix" relative redirects when API gateway is not configured with a custom domain. Setting this to false prevents modification of Location headers.
var Mangle = map[string]struct{}{
"Accept": {},
"Accept-Charset": {},
"Accept-Encoding": {},
"Age": {},
"Authorization": {},
"Connection": {},
"Content-Encoding": {},
"Content-Length": {},
"Content-MD5": {},
"Content-Type": {},
"Date": {},
"Expect": {},
"Host": {},
"Max-Forwards": {},
"Pragma": {},
"Proxy-Authenticate": {},
"Range": {},
"Referer": {},
"Server": {},
"TE": {},
"Trailer": {},
"Transfer-Encoding": {},
"Upgrade": {},
"User-Agent": {},
"Via": {},
"WWW-Authenticate": {},
"Warn": {},
}
Mangle is the set of headers API Gateway may prefer as X-Amzn-Remapped headers. It's a good practice to reduce this to a set of concern prior to calling ServeHTTP if MangleOutputHeaders is true.
var MangleOutputHeaders = false
MangleOutputHeaders controls replacing output headers with X-Amzn-Remapped headers. If set, headers that need to be remapped have an additional X-Amzn-Remapped header created with the same value. This should be set (if needed) prior to calling ServeHTTP.
var PanicMessage = "Function panic"
PanicMessage is returned as the body of the 500 HTTP response when unrecovered panics occur.
Functions ¶
Types ¶
type Lambda ¶
type Lambda interface { InvokeRequest() messages.InvokeRequest ClientContext() lambdacontext.ClientContext GatewayRequest() events.APIGatewayProxyRequest }
Lambda is an interface to retrieve Lambda-specific types. A Lambda http.ResponseWriter supports this type assertion.