diff --git a/context.go b/context.go index 5d3b6a4e..df001a40 100644 --- a/context.go +++ b/context.go @@ -230,13 +230,29 @@ func (c *Context) DefaultQuery(key, defaultValue string) string { // ("", false) == c.GetQuery("id") // ("", true) == c.GetQuery("lastname") func (c *Context) GetQuery(key string) (string, bool) { - req := c.Request - if values, ok := req.URL.Query()[key]; ok && len(values) > 0 { - return values[0], true + if values, ok := c.GetQueryArray(key); ok { + return values[0], ok } return "", false } +// QueryArray returns a slice of strings for a given query key. +// The length of the slice depends on the number of params with the given key. +func (c *Context) QueryArray(key string) []string { + values, _ := c.GetQueryArray(key) + return values +} + +// GetQueryArray returns a slice of strings for a given query key, plus +// a boolean value whether at least one value exists for the given key. +func (c *Context) GetQueryArray(key string) ([]string, bool) { + req := c.Request + if values, ok := req.URL.Query()[key]; ok && len(values) > 0 { + return values, true + } + return []string{}, false +} + // PostForm returns the specified key from a POST urlencoded form or multipart form // when it exists, otherwise it returns an empty string `("")`. func (c *Context) PostForm(key string) string { @@ -262,17 +278,34 @@ func (c *Context) DefaultPostForm(key, defaultValue string) string { // email= --> ("", true) := GetPostForm("email") // set email to "" // --> ("", false) := GetPostForm("email") // do nothing with email func (c *Context) GetPostForm(key string) (string, bool) { + if values, ok := c.GetPostFormArray(key); ok { + return values[0], ok + } + return "", false +} + +// PostFormArray returns a slice of strings for a given form key. +// The length of the slice depends on the number of params with the given key. +func (c *Context) PostFormArray(key string) []string { + values, _ := c.GetPostFormArray(key) + return values +} + +// GetPostFormArray returns a slice of strings for a given form key, plus +// a boolean value whether at least one value exists for the given key. +func (c *Context) GetPostFormArray(key string) ([]string, bool) { req := c.Request + req.ParseForm() req.ParseMultipartForm(32 << 20) // 32 MB if values := req.PostForm[key]; len(values) > 0 { - return values[0], true + return values, true } if req.MultipartForm != nil && req.MultipartForm.File != nil { if values := req.MultipartForm.Value[key]; len(values) > 0 { - return values[0], true + return values, true } } - return "", false + return []string{}, false } // Bind checks the Content-Type to select a binding engine automatically, diff --git a/context_test.go b/context_test.go index 97d4957c..01ee6b83 100644 --- a/context_test.go +++ b/context_test.go @@ -251,6 +251,22 @@ func TestContextQueryAndPostForm(t *testing.T) { assert.Equal(t, obj.Page, 11) assert.Equal(t, obj.Both, "") assert.Equal(t, obj.Array, []string{"first", "second"}) + + values, ok := c.GetQueryArray("array[]") + assert.True(t, ok) + assert.Equal(t, "first", values[0]) + assert.Equal(t, "second", values[1]) + + values = c.QueryArray("array[]") + assert.Equal(t, "first", values[0]) + assert.Equal(t, "second", values[1]) + + values = c.QueryArray("nokey") + assert.Equal(t, 0, len(values)) + + values = c.QueryArray("both") + assert.Equal(t, 1, len(values)) + assert.Equal(t, "GET", values[0]) } func TestContextPostFormMultipart(t *testing.T) { @@ -299,6 +315,22 @@ func TestContextPostFormMultipart(t *testing.T) { assert.False(t, ok) assert.Empty(t, value) assert.Equal(t, c.DefaultPostForm("nokey", "nothing"), "nothing") + + values, ok := c.GetPostFormArray("array") + assert.True(t, ok) + assert.Equal(t, "first", values[0]) + assert.Equal(t, "second", values[1]) + + values = c.PostFormArray("array") + assert.Equal(t, "first", values[0]) + assert.Equal(t, "second", values[1]) + + values = c.PostFormArray("nokey") + assert.Equal(t, 0, len(values)) + + values = c.PostFormArray("foo") + assert.Equal(t, 1, len(values)) + assert.Equal(t, "bar", values[0]) } func TestContextSetCookie(t *testing.T) {