added eagerRequestDataCache middleware
This commit is contained in:
parent
177230a765
commit
6127350e91
|
@ -121,6 +121,10 @@ func InitApi(app core.App) (*echo.Echo, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// note: it is after the OnBeforeServe hook to ensure that the implicit
|
||||||
|
// cache is after any user custom defined middlewares
|
||||||
|
e.Use(eagerRequestDataCache(app))
|
||||||
|
|
||||||
// catch all any route
|
// catch all any route
|
||||||
api.Any("/*", func(c echo.Context) error {
|
api.Any("/*", func(c echo.Context) error {
|
||||||
return echo.ErrNotFound
|
return echo.ErrNotFound
|
||||||
|
|
|
@ -2,12 +2,15 @@ package apis_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/labstack/echo/v5"
|
"github.com/labstack/echo/v5"
|
||||||
"github.com/pocketbase/pocketbase/apis"
|
"github.com/pocketbase/pocketbase/apis"
|
||||||
"github.com/pocketbase/pocketbase/tests"
|
"github.com/pocketbase/pocketbase/tests"
|
||||||
|
"github.com/spf13/cast"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test404(t *testing.T) {
|
func Test404(t *testing.T) {
|
||||||
|
@ -209,3 +212,83 @@ func TestRemoveTrailingSlashMiddleware(t *testing.T) {
|
||||||
scenario.Test(t)
|
scenario.Test(t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestEagerRequestDataCache(t *testing.T) {
|
||||||
|
scenarios := []tests.ApiScenario{
|
||||||
|
{
|
||||||
|
Name: "[UNKNOWN] unsupported eager cached request method",
|
||||||
|
Method: "UNKNOWN",
|
||||||
|
Url: "/custom",
|
||||||
|
Body: strings.NewReader(`{"name":"test123"}`),
|
||||||
|
BeforeTestFunc: func(t *testing.T, app *tests.TestApp, e *echo.Echo) {
|
||||||
|
e.AddRoute(echo.Route{
|
||||||
|
Method: "UNKNOWN",
|
||||||
|
Path: "/custom",
|
||||||
|
Handler: func(c echo.Context) error {
|
||||||
|
data := &struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
}{}
|
||||||
|
|
||||||
|
if err := c.Bind(data); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// since the unknown method is not eager cache support
|
||||||
|
// it should fail reading the json body twice
|
||||||
|
r := apis.RequestData(c)
|
||||||
|
if v := cast.ToString(r.Data["name"]); v != "" {
|
||||||
|
t.Fatalf("Expected empty request data body, got, %v", r.Data)
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.String(200, data.Name)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
},
|
||||||
|
ExpectedStatus: 200,
|
||||||
|
ExpectedContent: []string{"test123"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// supported eager cache request methods
|
||||||
|
supportedMethods := []string{"POST", "PUT", "PATCH", "DELETE"}
|
||||||
|
for _, m := range supportedMethods {
|
||||||
|
scenarios = append(
|
||||||
|
scenarios,
|
||||||
|
tests.ApiScenario{
|
||||||
|
Name: fmt.Sprintf("[%s] valid cached json body request", m),
|
||||||
|
Method: http.MethodPost,
|
||||||
|
Url: "/custom",
|
||||||
|
Body: strings.NewReader(`{"name":"test123"}`),
|
||||||
|
BeforeTestFunc: func(t *testing.T, app *tests.TestApp, e *echo.Echo) {
|
||||||
|
e.AddRoute(echo.Route{
|
||||||
|
Method: http.MethodPost,
|
||||||
|
Path: "/custom",
|
||||||
|
Handler: func(c echo.Context) error {
|
||||||
|
data := &struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
}{}
|
||||||
|
|
||||||
|
if err := c.Bind(data); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// try to read the body again
|
||||||
|
r := apis.RequestData(c)
|
||||||
|
if v := cast.ToString(r.Data["name"]); v != "test123" {
|
||||||
|
t.Fatalf("Expected request data with name %q, got, %q", "test123", v)
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.String(200, data.Name)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
},
|
||||||
|
ExpectedStatus: 200,
|
||||||
|
ExpectedContent: []string{"test123"},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, scenario := range scenarios {
|
||||||
|
scenario.Test(t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -385,3 +385,19 @@ func realUserIp(r *http.Request, fallbackIp string) string {
|
||||||
|
|
||||||
return fallbackIp
|
return fallbackIp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// eagerRequestDataCache ensures that the request data is cached in the request
|
||||||
|
// context to allow reading for example the json request body data more than once.
|
||||||
|
func eagerRequestDataCache(app core.App) echo.MiddlewareFunc {
|
||||||
|
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||||
|
return func(c echo.Context) error {
|
||||||
|
switch c.Request().Method {
|
||||||
|
// currently we are eagerly caching only the requests with body
|
||||||
|
case "POST", "PUT", "PATCH", "DELETE":
|
||||||
|
RequestData(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
return next(c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue