diff --git a/middleware/extractor.go b/middleware/extractor.go index a57ed4e13..afdfd8195 100644 --- a/middleware/extractor.go +++ b/middleware/extractor.go @@ -168,8 +168,8 @@ func valuesFromCookie(name string) ValuesExtractor { // valuesFromForm returns a function that extracts values from the form field. func valuesFromForm(name string) ValuesExtractor { return func(c echo.Context) ([]string, error) { - if parseErr := c.Request().ParseForm(); parseErr != nil { - return nil, fmt.Errorf("valuesFromForm parse form failed: %w", parseErr) + if c.Request().Form == nil { + _ = c.Request().ParseMultipartForm(32 << 20) // same what `c.Request().FormValue(name)` does } values := c.Request().Form[name] if len(values) == 0 { diff --git a/middleware/extractor_test.go b/middleware/extractor_test.go index ae4b30a8a..2e898f541 100644 --- a/middleware/extractor_test.go +++ b/middleware/extractor_test.go @@ -1,9 +1,11 @@ package middleware import ( + "bytes" "fmt" "github.com/labstack/echo/v4" "github.com/stretchr/testify/assert" + "mime/multipart" "net/http" "net/http/httptest" "net/url" @@ -499,6 +501,25 @@ func TestValuesFromForm(t *testing.T) { return req } + exampleMultiPartFormRequest := func(mod func(w *multipart.Writer)) *http.Request { + var b bytes.Buffer + w := multipart.NewWriter(&b) + w.WriteField("name", "Jon Snow") + w.WriteField("emails[]", "jon@labstack.com") + if mod != nil { + mod(w) + } + + fw, _ := w.CreateFormFile("upload", "my.file") + fw.Write([]byte(`
hi
`)) + w.Close() + + req := httptest.NewRequest(http.MethodPost, "/", strings.NewReader(b.String())) + req.Header.Add(echo.HeaderContentType, w.FormDataContentType()) + + return req + } + var testCases = []struct { name string givenRequest *http.Request @@ -520,6 +541,14 @@ func TestValuesFromForm(t *testing.T) { whenName: "emails[]", expectValues: []string{"jon@labstack.com", "snow@labstack.com"}, }, + { + name: "ok, POST multipart/form, multiple value", + givenRequest: exampleMultiPartFormRequest(func(w *multipart.Writer) { + w.WriteField("emails[]", "snow@labstack.com") + }), + whenName: "emails[]", + expectValues: []string{"jon@labstack.com", "snow@labstack.com"}, + }, { name: "ok, GET form, single value", givenRequest: exampleGetFormRequest(nil), @@ -540,16 +569,6 @@ func TestValuesFromForm(t *testing.T) { whenName: "nope", expectError: errFormExtractorValueMissing.Error(), }, - { - name: "nok, POST form, form parsing error", - givenRequest: func() *http.Request { - req := httptest.NewRequest(http.MethodPost, "/", nil) - req.Body = nil - return req - }(), - whenName: "name", - expectError: "valuesFromForm parse form failed: missing form body", - }, { name: "ok, cut values over extractorLimit", givenRequest: examplePostFormRequest(func(v *url.Values) {