diff --git a/chi/adapterALB.go b/chi/adapterALB.go new file mode 100644 index 0000000..455946e --- /dev/null +++ b/chi/adapterALB.go @@ -0,0 +1,59 @@ +package chiadapter + +import ( + "context" + "net/http" + + "github.com/aws/aws-lambda-go/events" + "github.com/awslabs/aws-lambda-go-api-proxy/core" + "github.com/go-chi/chi/v5" +) + +// ChiLambdaALB makes it easy to send ALB proxy events to a chi.Mux. +// The library transforms the proxy event into an HTTP request and then +// creates a proxy response object from the http.ResponseWriter +type ChiLambdaALB struct { + core.RequestAccessorALB + + Chi *chi.Mux +} + +// NewALB creates a new instance of the ChiLambdaALB object. +// Receives an initialized *chi.Mux object - normally created with chi.New(). +// It returns the initialized instance of the ChiLambdaALB object. +func NewALB(chi *chi.Mux) *ChiLambdaALB { + return &ChiLambdaALB{Chi: chi} +} + +// Proxy receives an ALB proxy event, transforms it into an http.Request +// object, and sends it to the chi.Mux for routing. +// It returns a proxy response object generated from the http.ResponseWriter. +func (c *ChiLambdaALB) Proxy(req events.ALBTargetGroupRequest) (events.ALBTargetGroupResponse, error) { + chiRequest, err := c.ProxyEventToHTTPRequest(req) + return c.proxyInternal(chiRequest, err) +} + +// ProxyWithContext receives an ALB proxy event, transforms it into an http.Request +// object, and sends it to the chi.Mux for routing. +// It returns a proxy response object generated from the http.ResponseWriter. +func (c *ChiLambdaALB) ProxyWithContext(ctx context.Context, req events.ALBTargetGroupRequest) (events.ALBTargetGroupResponse, error) { + chiRequest, err := c.EventToRequestWithContext(ctx, req) + return c.proxyInternal(chiRequest, err) +} + +func (c *ChiLambdaALB) proxyInternal(req *http.Request, err error) (events.ALBTargetGroupResponse, error) { + + if err != nil { + return core.GatewayTimeoutALB(), core.NewLoggedError("Could not convert proxy event to request: %v", err) + } + + respWriter := core.NewProxyResponseWriterALB() + c.Chi.ServeHTTP(http.ResponseWriter(respWriter), req) + + proxyResponse, err := respWriter.GetProxyResponse() + if err != nil { + return core.GatewayTimeoutALB(), core.NewLoggedError("Error while generating proxy response: %v", err) + } + + return proxyResponse, nil +} diff --git a/chi/chilambda_test.go b/chi/chilambda_test.go index 0589d52..d46d5b2 100644 --- a/chi/chilambda_test.go +++ b/chi/chilambda_test.go @@ -41,3 +41,30 @@ var _ = Describe("ChiLambda tests", func() { }) }) }) + +var _ = Describe("ChiLambdaALB tests", func() { + Context("Simple ping request", func() { + It("Proxies the event correctly", func() { + log.Println("Starting test") + + r := chi.NewRouter() + r.Get("/ping", func(w http.ResponseWriter, r *http.Request) { + w.Write([]byte("pong")) + }) + + adapter := chiadapter.NewALB(r) + + req := events.ALBTargetGroupRequest{ + HTTPMethod: "GET", + Path: "/ping", + RequestContext: events.ALBTargetGroupRequestContext{ + ELB: events.ELBContext{TargetGroupArn: " ad"}, + }} + + resp, err := adapter.Proxy(req) + + Expect(err).To(BeNil()) + Expect(resp.StatusCode).To(Equal(200)) + }) + }) +}) diff --git a/core/requestALB.go b/core/requestALB.go index 69eb023..df91b36 100644 --- a/core/requestALB.go +++ b/core/requestALB.go @@ -115,7 +115,15 @@ func (r *RequestAccessorALB) EventToRequest(req events.ALBTargetGroupRequest) (* if !strings.HasPrefix(path, "/") { path = "/" + path } - serverAddress := "https://" + req.Headers["host"] + + host := req.Headers["host"] + if _, ok := req.Headers["host"]; !ok { + if req.MultiValueHeaders["host"] != nil && len(req.MultiValueHeaders["host"]) > 0 { + host = req.MultiValueHeaders["host"][0] + } + } + + serverAddress := "https://" + host // if customAddress, ok := os.LookupEnv(CustomHostVariable); ok { // serverAddress = customAddress // }