Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🔥 add config to enable splitting by comma in parsers #2560

Merged
merged 3 commits into from
Aug 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions app.go
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,13 @@ type Config struct {
//
// Optional. Default: DefaultMethods
RequestMethods []string

// EnableSplittingOnParsers splits the query/body/header parameters by comma when it's true.
// For example, you can use it to parse multiple values from a query parameter like this:
// /api?foo=bar,baz == foo[]=bar&foo[]=baz
//
// Optional. Default: false
EnableSplittingOnParsers bool `json:"enable_splitting_on_parsers"`
}

// Static defines configuration options when defining static assets.
Expand Down
6 changes: 3 additions & 3 deletions ctx.go
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ func (c *Ctx) BodyParser(out interface{}) error {
k, err = parseParamSquareBrackets(k)
}

if strings.Contains(v, ",") && equalFieldType(out, reflect.Slice, k) {
if c.app.config.EnableSplittingOnParsers && strings.Contains(v, ",") && equalFieldType(out, reflect.Slice, k) {
values := strings.Split(v, ",")
for i := 0; i < len(values); i++ {
data[k] = append(data[k], values[i])
Expand Down Expand Up @@ -1159,7 +1159,7 @@ func (c *Ctx) QueryParser(out interface{}) error {
k, err = parseParamSquareBrackets(k)
}

if strings.Contains(v, ",") && equalFieldType(out, reflect.Slice, k) {
if c.app.config.EnableSplittingOnParsers && strings.Contains(v, ",") && equalFieldType(out, reflect.Slice, k) {
values := strings.Split(v, ",")
for i := 0; i < len(values); i++ {
data[k] = append(data[k], values[i])
Expand Down Expand Up @@ -1208,7 +1208,7 @@ func (c *Ctx) ReqHeaderParser(out interface{}) error {
k := c.app.getString(key)
v := c.app.getString(val)

if strings.Contains(v, ",") && equalFieldType(out, reflect.Slice, k) {
if c.app.config.EnableSplittingOnParsers && strings.Contains(v, ",") && equalFieldType(out, reflect.Slice, k) {
values := strings.Split(v, ",")
for i := 0; i < len(values); i++ {
data[k] = append(data[k], values[i])
Expand Down
59 changes: 55 additions & 4 deletions ctx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3917,7 +3917,7 @@ func Benchmark_Ctx_Queries(b *testing.B) {
// go test -run Test_Ctx_QueryParser -v
func Test_Ctx_QueryParser(t *testing.T) {
t.Parallel()
app := New()
app := New(Config{EnableSplittingOnParsers: true})
c := app.AcquireCtx(&fasthttp.RequestCtx{})
defer app.ReleaseCtx(c)
type Query struct {
Expand Down Expand Up @@ -3988,6 +3988,29 @@ func Test_Ctx_QueryParser(t *testing.T) {
utils.AssertEqual(t, 2, len(aq.Data))
}

// go test -run Test_Ctx_QueryParser -v
func Test_Ctx_QueryParser_WithoutSplitting(t *testing.T) {
t.Parallel()
app := New()
c := app.AcquireCtx(&fasthttp.RequestCtx{})
defer app.ReleaseCtx(c)
type Query struct {
ID int
Name string
Hobby []string
}

c.Request().URI().SetQueryString("id=1&name=tom&hobby=basketball,football")
q := new(Query)
utils.AssertEqual(t, nil, c.QueryParser(q))
utils.AssertEqual(t, 1, len(q.Hobby))

c.Request().URI().SetQueryString("id=1&name=tom&hobby=scoccer&hobby=basketball,football")
q = new(Query)
utils.AssertEqual(t, nil, c.QueryParser(q))
utils.AssertEqual(t, 2, len(q.Hobby))
}

// go test -run Test_Ctx_QueryParser_WithSetParserDecoder -v
func Test_Ctx_QueryParser_WithSetParserDecoder(t *testing.T) {
t.Parallel()
Expand Down Expand Up @@ -4146,7 +4169,7 @@ func Test_Ctx_QueryParser_Schema(t *testing.T) {
// go test -run Test_Ctx_ReqHeaderParser -v
func Test_Ctx_ReqHeaderParser(t *testing.T) {
t.Parallel()
app := New()
app := New(Config{EnableSplittingOnParsers: true})
c := app.AcquireCtx(&fasthttp.RequestCtx{})
defer app.ReleaseCtx(c)
type Header struct {
Expand Down Expand Up @@ -4215,6 +4238,34 @@ func Test_Ctx_ReqHeaderParser(t *testing.T) {
utils.AssertEqual(t, "failed to decode: name is empty", c.ReqHeaderParser(rh).Error())
}

// go test -run Test_Ctx_ReqHeaderParser -v
func Test_Ctx_ReqHeaderParser_WithoutSplitting(t *testing.T) {
t.Parallel()
app := New()
c := app.AcquireCtx(&fasthttp.RequestCtx{})
defer app.ReleaseCtx(c)
type Header struct {
ID int
Name string
Hobby []string
}
c.Request().SetBody([]byte(``))
c.Request().Header.SetContentType("")

c.Request().Header.Add("id", "1")
c.Request().Header.Add("Name", "John Doe")
c.Request().Header.Add("Hobby", "golang,fiber")
q := new(Header)
utils.AssertEqual(t, nil, c.ReqHeaderParser(q))
utils.AssertEqual(t, 1, len(q.Hobby))

c.Request().Header.Del("hobby")
c.Request().Header.Add("Hobby", "golang,fiber,go")
q = new(Header)
utils.AssertEqual(t, nil, c.ReqHeaderParser(q))
utils.AssertEqual(t, 1, len(q.Hobby))
}

// go test -run Test_Ctx_ReqHeaderParser_WithSetParserDecoder -v
func Test_Ctx_ReqHeaderParser_WithSetParserDecoder(t *testing.T) {
t.Parallel()
Expand Down Expand Up @@ -4439,7 +4490,7 @@ func Benchmark_Ctx_parseQuery(b *testing.B) {

// go test -v -run=^$ -bench=Benchmark_Ctx_QueryParser_Comma -benchmem -count=4
func Benchmark_Ctx_QueryParser_Comma(b *testing.B) {
app := New()
app := New(Config{EnableSplittingOnParsers: true})
c := app.AcquireCtx(&fasthttp.RequestCtx{})
defer app.ReleaseCtx(c)
type Query struct {
Expand All @@ -4465,7 +4516,7 @@ func Benchmark_Ctx_QueryParser_Comma(b *testing.B) {

// go test -v -run=^$ -bench=Benchmark_Ctx_ReqHeaderParser -benchmem -count=4
func Benchmark_Ctx_ReqHeaderParser(b *testing.B) {
app := New()
app := New(Config{EnableSplittingOnParsers: true})
c := app.AcquireCtx(&fasthttp.RequestCtx{})
defer app.ReleaseCtx(c)
type ReqHeader struct {
Expand Down
Loading
Loading