mirror of
https://github.com/zeromicro/go-zero.git
synced 2026-05-07 15:10:01 +08:00
fix: ignore empty form values in http request (#4542)
This commit is contained in:
@@ -47,6 +47,21 @@ func TestParseForm(t *testing.T) {
|
||||
assert.Nil(t, Parse(r, &v))
|
||||
assert.Equal(t, 0, len(v.NoValue))
|
||||
})
|
||||
|
||||
t.Run("slice with one value on array format", func(t *testing.T) {
|
||||
var v struct {
|
||||
Names string `form:"names"`
|
||||
}
|
||||
|
||||
r, err := http.NewRequest(
|
||||
http.MethodGet,
|
||||
"/a?names=1,2,3",
|
||||
http.NoBody)
|
||||
assert.NoError(t, err)
|
||||
if assert.NoError(t, Parse(r, &v)) {
|
||||
assert.Equal(t, "1,2,3", v.Names)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestParseFormArray(t *testing.T) {
|
||||
@@ -114,7 +129,7 @@ func TestParseFormArray(t *testing.T) {
|
||||
http.NoBody)
|
||||
assert.NoError(t, err)
|
||||
if assert.NoError(t, Parse(r, &v)) {
|
||||
assert.ElementsMatch(t, []string{""}, v.Name)
|
||||
assert.Empty(t, v.Name)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -129,7 +144,7 @@ func TestParseFormArray(t *testing.T) {
|
||||
http.NoBody)
|
||||
assert.NoError(t, err)
|
||||
if assert.NoError(t, Parse(r, &v)) {
|
||||
assert.ElementsMatch(t, []string{"", "1"}, v.Name)
|
||||
assert.ElementsMatch(t, []string{"1"}, v.Name)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -192,6 +207,66 @@ func TestParseFormArray(t *testing.T) {
|
||||
assert.ElementsMatch(t, []string{"1", "2", "3"}, v.Names)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("slice with one empty value on integer array format", func(t *testing.T) {
|
||||
var v struct {
|
||||
Numbers []int `form:"numbers,optional"`
|
||||
}
|
||||
|
||||
r, err := http.NewRequest(
|
||||
http.MethodGet,
|
||||
"/a?numbers=",
|
||||
http.NoBody)
|
||||
assert.NoError(t, err)
|
||||
if assert.NoError(t, Parse(r, &v)) {
|
||||
assert.Empty(t, v.Numbers)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("slice with one value on integer array format", func(t *testing.T) {
|
||||
var v struct {
|
||||
Numbers []int `form:"numbers,optional"`
|
||||
}
|
||||
|
||||
r, err := http.NewRequest(
|
||||
http.MethodGet,
|
||||
"/a?numbers=&numbers=2",
|
||||
http.NoBody)
|
||||
assert.NoError(t, err)
|
||||
if assert.NoError(t, Parse(r, &v)) {
|
||||
assert.ElementsMatch(t, []int{2}, v.Numbers)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("slice with one empty value on float64 array format", func(t *testing.T) {
|
||||
var v struct {
|
||||
Numbers []float64 `form:"numbers,optional"`
|
||||
}
|
||||
|
||||
r, err := http.NewRequest(
|
||||
http.MethodGet,
|
||||
"/a?numbers=",
|
||||
http.NoBody)
|
||||
assert.NoError(t, err)
|
||||
if assert.NoError(t, Parse(r, &v)) {
|
||||
assert.Empty(t, v.Numbers)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("slice with one value on float64 array format", func(t *testing.T) {
|
||||
var v struct {
|
||||
Numbers []float64 `form:"numbers,optional"`
|
||||
}
|
||||
|
||||
r, err := http.NewRequest(
|
||||
http.MethodGet,
|
||||
"/a?numbers=&numbers=2",
|
||||
http.NoBody)
|
||||
assert.NoError(t, err)
|
||||
if assert.NoError(t, Parse(r, &v)) {
|
||||
assert.ElementsMatch(t, []float64{2}, v.Numbers)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestParseForm_Error(t *testing.T) {
|
||||
|
||||
@@ -35,6 +35,16 @@ func GetFormValues(r *http.Request) (map[string]any, error) {
|
||||
for name, values := range r.Form {
|
||||
filtered := make([]string, 0, len(values))
|
||||
for _, v := range values {
|
||||
// ignore empty values, especially for optional int parameters
|
||||
// e.g. /api?ids=
|
||||
// e.g. /api
|
||||
// type Req struct {
|
||||
// IDs []int `form:"ids,optional"`
|
||||
// }
|
||||
if len(v) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
if n < maxFormParamCount {
|
||||
filtered = append(filtered, v)
|
||||
n++
|
||||
|
||||
Reference in New Issue
Block a user