From d63880c5ee029a51888aad31f78e1533f6789017 Mon Sep 17 00:00:00 2001 From: grqphical07 <95062977+grqphical07@users.noreply.github.com> Date: Tue, 2 Jul 2024 19:00:10 -0700 Subject: [PATCH 1/4] added allow content type middleware --- middleware/allow_content_type.go | 24 ++++++++++++++++++++++ middleware/allow_content_type_test.go | 29 +++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 middleware/allow_content_type.go create mode 100644 middleware/allow_content_type_test.go diff --git a/middleware/allow_content_type.go b/middleware/allow_content_type.go new file mode 100644 index 000000000..794beacbb --- /dev/null +++ b/middleware/allow_content_type.go @@ -0,0 +1,24 @@ +package middleware + +import ( + "mime" + "net/http" + "slices" + + "github.com/labstack/echo/v4" +) + +func AllowContentType(contentTypes ...string) echo.MiddlewareFunc { + return func(next echo.HandlerFunc) echo.HandlerFunc { + return func(c echo.Context) error { + mediaType, _, err := mime.ParseMediaType(c.Request().Header.Get("Content-Type")) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, "invalid content-type value") + } + if slices.Contains(contentTypes, mediaType) { + return next(c) + } + return echo.NewHTTPError(http.StatusUnsupportedMediaType) + } + } +} diff --git a/middleware/allow_content_type_test.go b/middleware/allow_content_type_test.go new file mode 100644 index 000000000..2673dd2df --- /dev/null +++ b/middleware/allow_content_type_test.go @@ -0,0 +1,29 @@ +package middleware + +import ( + "net/http" + "net/http/httptest" + "testing" + + "github.com/labstack/echo/v4" + "github.com/stretchr/testify/assert" +) + +func TestAllowContentType(t *testing.T) { + e := echo.New() + req := httptest.NewRequest(http.MethodGet, "/", nil) + res := httptest.NewRecorder() + c := e.NewContext(req, res) + + h := AllowContentType("application/json")(func(c echo.Context) error { + return c.String(http.StatusOK, "test") + }) + + // Test valid content type + req.Header.Add("Content-Type", "application/json") + assert.NoError(t, h(c)) + + // Test invalid content type + req.Header.Add("Content-Type", "text/plain") + assert.NoError(t, h(c)) +} From 10142e48ad20d2009d444b183fd65f4313330612 Mon Sep 17 00:00:00 2001 From: grqphical07 <95062977+grqphical07@users.noreply.github.com> Date: Tue, 2 Jul 2024 19:07:44 -0700 Subject: [PATCH 2/4] made test look for more specific conditions --- middleware/allow_content_type_test.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/middleware/allow_content_type_test.go b/middleware/allow_content_type_test.go index 2673dd2df..03c8d78b0 100644 --- a/middleware/allow_content_type_test.go +++ b/middleware/allow_content_type_test.go @@ -13,7 +13,6 @@ func TestAllowContentType(t *testing.T) { e := echo.New() req := httptest.NewRequest(http.MethodGet, "/", nil) res := httptest.NewRecorder() - c := e.NewContext(req, res) h := AllowContentType("application/json")(func(c echo.Context) error { return c.String(http.StatusOK, "test") @@ -21,9 +20,12 @@ func TestAllowContentType(t *testing.T) { // Test valid content type req.Header.Add("Content-Type", "application/json") + c := e.NewContext(req, res) assert.NoError(t, h(c)) // Test invalid content type - req.Header.Add("Content-Type", "text/plain") - assert.NoError(t, h(c)) + req.Header.Set("Content-Type", "text/plain") + c = e.NewContext(req, res) + he := h(c).(*echo.HTTPError) + assert.Equal(t, http.StatusUnsupportedMediaType, he.Code) } From 357f8709dc25b7f8db1ca4d1e06d310e8e752d4d Mon Sep 17 00:00:00 2001 From: grqphical07 <95062977+grqphical07@users.noreply.github.com> Date: Tue, 2 Jul 2024 19:37:30 -0700 Subject: [PATCH 3/4] added setting of accept header in response --- middleware/allow_content_type.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/middleware/allow_content_type.go b/middleware/allow_content_type.go index 794beacbb..630390c7b 100644 --- a/middleware/allow_content_type.go +++ b/middleware/allow_content_type.go @@ -11,6 +11,16 @@ import ( func AllowContentType(contentTypes ...string) echo.MiddlewareFunc { return func(next echo.HandlerFunc) echo.HandlerFunc { return func(c echo.Context) error { + var acceptTypes = "" + for i, contentType := range contentTypes { + acceptTypes += contentType + + if i != len(contentTypes)-1 { + acceptTypes += "," + } + } + c.Response().Header().Set("Accept", acceptTypes) + mediaType, _, err := mime.ParseMediaType(c.Request().Header.Get("Content-Type")) if err != nil { return echo.NewHTTPError(http.StatusBadRequest, "invalid content-type value") From d8dc88b0b53eca3f3d92ed6ee6028646e0dedfda Mon Sep 17 00:00:00 2001 From: grqphical07 <95062977+grqphical07@users.noreply.github.com> Date: Tue, 2 Jul 2024 19:39:58 -0700 Subject: [PATCH 4/4] added tests for Accept header --- middleware/allow_content_type_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/middleware/allow_content_type_test.go b/middleware/allow_content_type_test.go index 03c8d78b0..8c84bb0f5 100644 --- a/middleware/allow_content_type_test.go +++ b/middleware/allow_content_type_test.go @@ -22,6 +22,7 @@ func TestAllowContentType(t *testing.T) { req.Header.Add("Content-Type", "application/json") c := e.NewContext(req, res) assert.NoError(t, h(c)) + assert.Equal(t, "application/json", res.Header().Get("Accept")) // Test invalid content type req.Header.Set("Content-Type", "text/plain")