From 6017cdbdbbb9d4f9b4984dc0a06bd0c04dd732e3 Mon Sep 17 00:00:00 2001 From: drakejin Date: Fri, 4 Feb 2022 02:31:42 +0900 Subject: [PATCH 1/3] fix: gofiber adapter to inject about request and response header logic. --- fiber/adapter.go | 17 ++- fiber/fiberlambda_test.go | 254 +++++++++++++++++++++++++++++++++++++- 2 files changed, 264 insertions(+), 7 deletions(-) diff --git a/fiber/adapter.go b/fiber/adapter.go index 0bcb635..a65e328 100644 --- a/fiber/adapter.go +++ b/fiber/adapter.go @@ -10,10 +10,11 @@ import ( "net/http" "github.com/aws/aws-lambda-go/events" - "github.com/awslabs/aws-lambda-go-api-proxy/core" "github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2/utils" "github.com/valyala/fasthttp" + + "github.com/awslabs/aws-lambda-go-api-proxy/core" ) // FiberLambda makes it easy to send API Gateway proxy events to a fiber.App. @@ -115,7 +116,17 @@ func (f *FiberLambda) adaptor(w http.ResponseWriter, r *http.Request) { req.SetHost(r.Host) for key, val := range r.Header { for _, v := range val { - req.Header.Add(key, v) + switch key { + // NOTI: fiber.HeaderTransferEncoding is no need to add case statements + case fiber.HeaderHost, + fiber.HeaderContentType, + fiber.HeaderUserAgent, + fiber.HeaderContentLength, + fiber.HeaderConnection: + req.Header.Set(key, v) + default: + req.Header.Add(key, v) + } } } @@ -134,7 +145,7 @@ func (f *FiberLambda) adaptor(w http.ResponseWriter, r *http.Request) { // Set response headers fctx.Response.Header.VisitAll(func(k, v []byte) { - w.Header().Set(utils.UnsafeString(k), utils.UnsafeString(v)) + w.Header().Add(utils.UnsafeString(k), utils.UnsafeString(v)) }) // Set response statuscode diff --git a/fiber/fiberlambda_test.go b/fiber/fiberlambda_test.go index 3bd8ff6..eb94293 100644 --- a/fiber/fiberlambda_test.go +++ b/fiber/fiberlambda_test.go @@ -2,12 +2,12 @@ package fiberadapter_test import ( "context" - "log" "github.com/aws/aws-lambda-go/events" - fiberadaptor "github.com/awslabs/aws-lambda-go-api-proxy/fiber" "github.com/gofiber/fiber/v2" + fiberadaptor "github.com/awslabs/aws-lambda-go-api-proxy/fiber" + . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) @@ -15,10 +15,8 @@ import ( var _ = Describe("FiberLambda tests", func() { Context("Simple ping request", func() { It("Proxies the event correctly", func() { - log.Println("Starting test") app := fiber.New() app.Get("/ping", func(c *fiber.Ctx) error { - log.Println("Handler!!") return c.SendString("pong") }) @@ -40,4 +38,252 @@ var _ = Describe("FiberLambda tests", func() { Expect(resp.StatusCode).To(Equal(200)) }) }) + + Context("request header", func() { + It("check pass canonical header to fiber", func() { + app := fiber.New() + app.Post("/canonical_header", func(c *fiber.Ctx) error { + Expect(c.Get(fiber.HeaderHost)).To(Equal("localhost")) + Expect(c.Get(fiber.HeaderContentType)).To(Equal(fiber.MIMEApplicationJSONCharsetUTF8)) + Expect(c.Get(fiber.HeaderUserAgent)).To(Equal("fiber")) + + Expect(c.Cookies("a")).To(Equal("b")) + Expect(c.Cookies("b")).To(Equal("c")) + Expect(c.Cookies("c")).To(Equal("d")) + + Expect(c.Get(fiber.HeaderContentLength)).To(Equal("77")) + Expect(c.Get(fiber.HeaderConnection)).To(Equal("Keep-Alive")) + Expect(c.Get(fiber.HeaderKeepAlive)).To(Equal("timeout=5, max=1000")) + Expect(c.Get(fiber.HeaderTransferEncoding)).To(Equal("gzip")) + + return c.Status(fiber.StatusNoContent).Send(nil) + }) + + adapter := fiberadaptor.New(app) + + req := events.APIGatewayProxyRequest{ + Path: "/canonical_header", + HTTPMethod: "POST", + MultiValueHeaders: map[string][]string{ + fiber.HeaderHost: {"localhost"}, + fiber.HeaderContentType: {fiber.MIMEApplicationJSONCharsetUTF8}, + fiber.HeaderUserAgent: {"fiber"}, + + "cookie": {"a=b", "b=c;c=d"}, + + fiber.HeaderContentLength: {"77"}, + fiber.HeaderConnection: {"Keep-Alive"}, + fiber.HeaderKeepAlive: {"timeout=5, max=1000"}, + fiber.HeaderTransferEncoding: {"gzip"}, + }, + } + + resp, err := adapter.ProxyWithContext(context.Background(), req) + + Expect(err).To(BeNil()) + Expect(resp.StatusCode).To(Equal(fiber.StatusNoContent)) + Expect(resp.Body).To(Equal("")) + }) + + It("check pass non canonical header to fiber", func() { + app := fiber.New() + app.Post("/header", func(c *fiber.Ctx) error { + Expect(c.Get(fiber.HeaderReferer)).To(Equal("https://github.com/gofiber/fiber")) + Expect(c.Get(fiber.HeaderAuthorization)).To(Equal("Bearer drink_beer_not_coffee")) + + c.Context().Request.Header.VisitAll(func(key, value []byte) { + if string(key) == "K1" { + Expect(Expect(c.Get("K1")).To(Or(Equal("v1"), Equal("v2")))) + } + }) + + return c.Status(fiber.StatusNoContent).Send(nil) + }) + + adapter := fiberadaptor.New(app) + + req := events.APIGatewayProxyRequest{ + Path: "/header", + HTTPMethod: "POST", + MultiValueHeaders: map[string][]string{ + fiber.HeaderReferer: {"https://github.com/gofiber/fiber"}, + fiber.HeaderAuthorization: {"Bearer drink_beer_not_coffee"}, + + "k1": {"v1", "v2"}, + }, + } + + resp, err := adapter.ProxyWithContext(context.Background(), req) + + Expect(err).To(BeNil()) + Expect(resp.StatusCode).To(Equal(fiber.StatusNoContent)) + Expect(resp.Body).To(Equal("")) + }) + }) + + Context("response header", func() { + It("check pass canonical header to fiber", func() { + app := fiber.New() + app.Post("/canonical_header", func(c *fiber.Ctx) error { + c.Set(fiber.HeaderContentType, fiber.MIMEApplicationJSONCharsetUTF8) + c.Set(fiber.HeaderServer, "localhost") + + c.Cookie(&fiber.Cookie{ + Name: "a", + Value: "b", + HTTPOnly: true, + }) + c.Cookie(&fiber.Cookie{ + Name: "b", + Value: "c", + HTTPOnly: true, + }) + c.Cookie(&fiber.Cookie{ + Name: "c", + Value: "d", + HTTPOnly: true, + }) + + c.Set(fiber.HeaderContentLength, "77") + c.Set(fiber.HeaderConnection, "keep-alive") + + return c.Status(fiber.StatusNoContent).Send(nil) + }) + + adapter := fiberadaptor.New(app) + + req := events.APIGatewayProxyRequest{ + Path: "/canonical_header", + HTTPMethod: "POST", + } + + resp, err := adapter.ProxyWithContext(context.Background(), req) + + Expect(err).To(BeNil()) + Expect(resp.StatusCode).To(Equal(fiber.StatusNoContent)) + // NOTI: core.NewProxyResponseWriter().GetProxyResponse() => Doesn't use `resp.Header` + Expect(resp.MultiValueHeaders[fiber.HeaderContentType]).To(Equal([]string{fiber.MIMEApplicationJSONCharsetUTF8})) + Expect(resp.MultiValueHeaders[fiber.HeaderServer]).To(Equal([]string{"localhost"})) + Expect(resp.MultiValueHeaders[fiber.HeaderSetCookie]).To(Equal([]string{"a=b; path=/; HttpOnly; SameSite=Lax", "b=c; path=/; HttpOnly; SameSite=Lax", "c=d; path=/; HttpOnly; SameSite=Lax"})) + Expect(resp.MultiValueHeaders[fiber.HeaderContentLength]).To(Equal([]string{"77"})) + Expect(resp.MultiValueHeaders[fiber.HeaderConnection]).To(Equal([]string{"keep-alive"})) + Expect(resp.Body).To(Equal("")) + }) + It("check pass non canonical header to fiber", func() { + app := fiber.New() + app.Post("/header", func(c *fiber.Ctx) error { + c.Links("http://api.example.com/users?page=2", "next", "http://api.example.com/users?page=5", "last") + return c.Redirect("https://github.com/gofiber/fiber") + }) + + adapter := fiberadaptor.New(app) + + req := events.APIGatewayProxyRequest{ + Path: "/header", + HTTPMethod: "POST", + } + + resp, err := adapter.ProxyWithContext(context.Background(), req) + + Expect(err).To(BeNil()) + Expect(resp.StatusCode).To(Equal(fiber.StatusFound)) + Expect(resp.MultiValueHeaders[fiber.HeaderLocation]).To(Equal([]string{"https://github.com/gofiber/fiber"})) + Expect(resp.MultiValueHeaders[fiber.HeaderLink]).To(Equal([]string{"; rel=\"next\",; rel=\"last\""})) + Expect(resp.Body).To(Equal("")) + }) + }) + + Context("next pattern", func() { + It("request header", func() { + app := fiber.New() + app.Post("/next", func(c *fiber.Ctx) error { + c.Next() + Expect(c.Get(fiber.HeaderHost)).To(Equal("localhost")) + Expect(c.Get(fiber.HeaderContentType)).To(Equal(fiber.MIMEApplicationJSONCharsetUTF8)) + Expect(c.Get(fiber.HeaderUserAgent)).To(Equal("fiber")) + + Expect(c.Cookies("a")).To(Equal("b")) + Expect(c.Cookies("b")).To(Equal("c")) + Expect(c.Cookies("c")).To(Equal("d")) + + Expect(c.Get(fiber.HeaderContentLength)).To(Equal("77")) + Expect(c.Get(fiber.HeaderConnection)).To(Equal("Keep-Alive")) + Expect(c.Get(fiber.HeaderKeepAlive)).To(Equal("timeout=5, max=1000")) + Expect(c.Get(fiber.HeaderTransferEncoding)).To(Equal("gzip")) + + return c.Status(fiber.StatusNoContent).Send(nil) + }) + adapter := fiberadaptor.New(app) + + req := events.APIGatewayProxyRequest{ + Path: "/next", + HTTPMethod: "POST", + MultiValueHeaders: map[string][]string{ + fiber.HeaderHost: {"localhost"}, + fiber.HeaderContentType: {fiber.MIMEApplicationJSONCharsetUTF8}, + fiber.HeaderUserAgent: {"fiber"}, + + "cookie": {"a=b", "b=c;c=d"}, + + fiber.HeaderContentLength: {"77"}, + fiber.HeaderConnection: {"Keep-Alive"}, + fiber.HeaderKeepAlive: {"timeout=5, max=1000"}, + fiber.HeaderTransferEncoding: {"gzip"}, + }, + } + + resp, err := adapter.ProxyWithContext(context.Background(), req) + + Expect(err).To(BeNil()) + Expect(resp.StatusCode).To(Equal(fiber.StatusNoContent)) + Expect(resp.Body).To(Equal("")) + }) + + It("response header", func() { + app := fiber.New() + app.Post("/next", func(c *fiber.Ctx) error { + c.Set(fiber.HeaderContentType, fiber.MIMEApplicationJSONCharsetUTF8) + c.Set(fiber.HeaderServer, "localhost") + + c.Cookie(&fiber.Cookie{ + Name: "a", + Value: "b", + HTTPOnly: true, + }) + c.Cookie(&fiber.Cookie{ + Name: "b", + Value: "c", + HTTPOnly: true, + }) + c.Cookie(&fiber.Cookie{ + Name: "c", + Value: "d", + HTTPOnly: true, + }) + + c.Set(fiber.HeaderContentLength, "77") + c.Set(fiber.HeaderConnection, "keep-alive") + + c.Next() + return c.Status(fiber.StatusNoContent).Send(nil) + }) + adapter := fiberadaptor.New(app) + + req := events.APIGatewayProxyRequest{ + Path: "/next", + HTTPMethod: "POST", + } + + resp, err := adapter.ProxyWithContext(context.Background(), req) + + Expect(err).To(BeNil()) + Expect(resp.StatusCode).To(Equal(fiber.StatusNoContent)) + Expect(resp.MultiValueHeaders[fiber.HeaderContentType]).To(Equal([]string{fiber.MIMEApplicationJSONCharsetUTF8})) + Expect(resp.MultiValueHeaders[fiber.HeaderServer]).To(Equal([]string{"localhost"})) + Expect(resp.MultiValueHeaders[fiber.HeaderSetCookie]).To(Equal([]string{"a=b; path=/; HttpOnly; SameSite=Lax", "b=c; path=/; HttpOnly; SameSite=Lax", "c=d; path=/; HttpOnly; SameSite=Lax"})) + Expect(resp.MultiValueHeaders[fiber.HeaderContentLength]).To(Equal([]string{"77"})) + Expect(resp.MultiValueHeaders[fiber.HeaderConnection]).To(Equal([]string{"keep-alive"})) + Expect(resp.Body).To(Equal("")) + }) + }) }) From b9fe6abab3be519b3cacb86460826c4441ed66ab Mon Sep 17 00:00:00 2001 From: drakejin Date: Fri, 4 Feb 2022 02:43:27 +0900 Subject: [PATCH 2/3] fix: remove comment --- fiber/adapter.go | 1 - 1 file changed, 1 deletion(-) diff --git a/fiber/adapter.go b/fiber/adapter.go index a65e328..6da955f 100644 --- a/fiber/adapter.go +++ b/fiber/adapter.go @@ -117,7 +117,6 @@ func (f *FiberLambda) adaptor(w http.ResponseWriter, r *http.Request) { for key, val := range r.Header { for _, v := range val { switch key { - // NOTI: fiber.HeaderTransferEncoding is no need to add case statements case fiber.HeaderHost, fiber.HeaderContentType, fiber.HeaderUserAgent, From a5340e807158993ff61507cafafcc35036b640be Mon Sep 17 00:00:00 2001 From: drakejin Date: Fri, 4 Feb 2022 02:46:12 +0900 Subject: [PATCH 3/3] fix: test case statements --- fiber/fiberlambda_test.go | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/fiber/fiberlambda_test.go b/fiber/fiberlambda_test.go index eb94293..6ea2199 100644 --- a/fiber/fiberlambda_test.go +++ b/fiber/fiberlambda_test.go @@ -39,8 +39,8 @@ var _ = Describe("FiberLambda tests", func() { }) }) - Context("request header", func() { - It("check pass canonical header to fiber", func() { + Context("Request header", func() { + It("Check pass canonical header to fiber", func() { app := fiber.New() app.Post("/canonical_header", func(c *fiber.Ctx) error { Expect(c.Get(fiber.HeaderHost)).To(Equal("localhost")) @@ -85,7 +85,7 @@ var _ = Describe("FiberLambda tests", func() { Expect(resp.Body).To(Equal("")) }) - It("check pass non canonical header to fiber", func() { + It("Check pass non canonical header to fiber", func() { app := fiber.New() app.Post("/header", func(c *fiber.Ctx) error { Expect(c.Get(fiber.HeaderReferer)).To(Equal("https://github.com/gofiber/fiber")) @@ -121,8 +121,8 @@ var _ = Describe("FiberLambda tests", func() { }) }) - Context("response header", func() { - It("check pass canonical header to fiber", func() { + Context("Response header", func() { + It("Check pass canonical header to fiber", func() { app := fiber.New() app.Post("/canonical_header", func(c *fiber.Ctx) error { c.Set(fiber.HeaderContentType, fiber.MIMEApplicationJSONCharsetUTF8) @@ -169,7 +169,7 @@ var _ = Describe("FiberLambda tests", func() { Expect(resp.MultiValueHeaders[fiber.HeaderConnection]).To(Equal([]string{"keep-alive"})) Expect(resp.Body).To(Equal("")) }) - It("check pass non canonical header to fiber", func() { + It("Check pass non canonical header to fiber", func() { app := fiber.New() app.Post("/header", func(c *fiber.Ctx) error { c.Links("http://api.example.com/users?page=2", "next", "http://api.example.com/users?page=5", "last") @@ -193,8 +193,8 @@ var _ = Describe("FiberLambda tests", func() { }) }) - Context("next pattern", func() { - It("request header", func() { + Context("Next method", func() { + It("Check missing values in request header", func() { app := fiber.New() app.Post("/next", func(c *fiber.Ctx) error { c.Next() @@ -239,7 +239,7 @@ var _ = Describe("FiberLambda tests", func() { Expect(resp.Body).To(Equal("")) }) - It("response header", func() { + It("Check missing values in response header", func() { app := fiber.New() app.Post("/next", func(c *fiber.Ctx) error { c.Set(fiber.HeaderContentType, fiber.MIMEApplicationJSONCharsetUTF8)