Skip to content

Commit

Permalink
middleware: add method override
Browse files Browse the repository at this point in the history
  • Loading branch information
haoxin committed Apr 24, 2016
1 parent c830734 commit 592790b
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 0 deletions.
39 changes: 39 additions & 0 deletions middleware/method_override.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package middleware

import (
"github.com/labstack/echo"
)

const (
HttpMethodOverrideHeader = "X-HTTP-Method-Override"
)

func OverrideMethod() echo.MiddlewareFunc {
return Override()
}

// Override checks for the X-HTTP-Method-Override header
// or the body for parameter, `_method`
// and uses the http method instead of Request.Method.
// It isn't secure to override e.g a GET to a POST,
// so only Request.Method which are POSTs are considered.
func Override() echo.MiddlewareFunc {
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
originalMethod := c.Request().Method()

if originalMethod == "POST" {
m := c.FormValue("_method")
if m != "" {
c.Request().SetMethod(m)
}
m = c.Request().Header().Get(HttpMethodOverrideHeader)
if m != "" {
c.Request().SetMethod(m)
}
}

return next(c)
}
}
}
43 changes: 43 additions & 0 deletions middleware/method_override_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package middleware

import (
"bytes"
"net/http"
"testing"

"github.com/labstack/echo"
"github.com/labstack/echo/test"
"github.com/stretchr/testify/assert"
)

func TestOverrideMtrhod(t *testing.T) {
e := echo.New()
methodOverride := OverrideMethod()
h := methodOverride(func(c echo.Context) error {
return c.String(http.StatusOK, c.Request().Method())
})

// Override with http header
rq := test.NewRequest(echo.POST, "/", nil)
rq.Header().Set(HttpMethodOverrideHeader, "DELETE")
rc := test.NewResponseRecorder()
c := e.NewContext(rq, rc)
h(c)
assert.Equal(t, "DELETE", rc.Body.String())

// Override with body parameter
rq = test.NewRequest(echo.POST, "/", bytes.NewReader([]byte("_method=DELETE")))
rq.Header().Set(echo.HeaderContentType, echo.MIMEApplicationForm)
rc = test.NewResponseRecorder()
c = e.NewContext(rq, rc)
h(c)
assert.Equal(t, "DELETE", rc.Body.String())

// Ignore GET
rq = test.NewRequest(echo.GET, "/", nil)
rq.Header().Set(HttpMethodOverrideHeader, "DELETE")
rc = test.NewResponseRecorder()
c = e.NewContext(rq, rc)
h(c)
assert.Equal(t, "GET", rc.Body.String())
}

0 comments on commit 592790b

Please sign in to comment.