Skip to content

Commit

Permalink
Fix jsonp ignoring custom json encoder (#2658)
Browse files Browse the repository at this point in the history
* add unit test to trigger the bug #2675

* implement solution
  • Loading branch information
peczenyj authored Oct 5, 2023
1 parent 5171f6b commit 9230be3
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 3 deletions.
5 changes: 2 additions & 3 deletions ctx.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"bytes"
"context"
"crypto/tls"
"encoding/json"
"encoding/xml"
"errors"
"fmt"
Expand Down Expand Up @@ -863,9 +862,9 @@ func (c *Ctx) JSON(data interface{}) error {
// This method is identical to JSON, except that it opts-in to JSONP callback support.
// By default, the callback name is simply callback.
func (c *Ctx) JSONP(data interface{}, callback ...string) error {
raw, err := json.Marshal(data)
raw, err := c.app.config.JSONEncoder(data)
if err != nil {
return fmt.Errorf("failed to marshal: %w", err)
return err
}

var result, cb string
Expand Down
67 changes: 67 additions & 0 deletions ctx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2771,6 +2771,26 @@ func Test_Ctx_JSON(t *testing.T) {
testEmpty("", `""`)
testEmpty(0, "0")
testEmpty([]int{}, "[]")

t.Run("custom json encoder", func(t *testing.T) {
t.Parallel()

app := New(Config{
JSONEncoder: func(v interface{}) ([]byte, error) {
return []byte(`["custom","json"]`), nil
},
})
c := app.AcquireCtx(&fasthttp.RequestCtx{})
defer app.ReleaseCtx(c)

err := c.JSON(Map{ // map has no order
"Name": "Grame",
"Age": 20,
})
utils.AssertEqual(t, nil, err)
utils.AssertEqual(t, `["custom","json"]`, string(c.Response().Body()))
utils.AssertEqual(t, "application/json", string(c.Response().Header.Peek("content-type")))
})
}

// go test -run=^$ -bench=Benchmark_Ctx_JSON -benchmem -count=4
Expand Down Expand Up @@ -2820,6 +2840,26 @@ func Test_Ctx_JSONP(t *testing.T) {
utils.AssertEqual(t, nil, err)
utils.AssertEqual(t, `john({"Age":20,"Name":"Grame"});`, string(c.Response().Body()))
utils.AssertEqual(t, "text/javascript; charset=utf-8", string(c.Response().Header.Peek("content-type")))

t.Run("custom json encoder", func(t *testing.T) {
t.Parallel()

app := New(Config{
JSONEncoder: func(v interface{}) ([]byte, error) {
return []byte(`["custom","json"]`), nil
},
})
c := app.AcquireCtx(&fasthttp.RequestCtx{})
defer app.ReleaseCtx(c)

err := c.JSONP(Map{ // map has no order
"Name": "Grame",
"Age": 20,
})
utils.AssertEqual(t, nil, err)
utils.AssertEqual(t, `callback(["custom","json"]);`, string(c.Response().Body()))
utils.AssertEqual(t, "text/javascript; charset=utf-8", string(c.Response().Header.Peek("content-type")))
})
}

// go test -v -run=^$ -bench=Benchmark_Ctx_JSONP -benchmem -count=4
Expand Down Expand Up @@ -2879,6 +2919,33 @@ func Test_Ctx_XML(t *testing.T) {
testEmpty("", `<string></string>`)
testEmpty(0, "<int>0</int>")
testEmpty([]int{}, "")

t.Run("custom xml encoder", func(t *testing.T) {
t.Parallel()

app := New(Config{
XMLEncoder: func(v interface{}) ([]byte, error) {
return []byte(`<custom>xml</custom>`), nil
},
})
c := app.AcquireCtx(&fasthttp.RequestCtx{})
defer app.ReleaseCtx(c)

type xmlResult struct {
XMLName xml.Name `xml:"Users"`
Names []string `xml:"Names"`
Ages []int `xml:"Ages"`
}

err := c.XML(xmlResult{
Names: []string{"Grame", "John"},
Ages: []int{1, 12, 20},
})

utils.AssertEqual(t, nil, err)
utils.AssertEqual(t, `<custom>xml</custom>`, string(c.Response().Body()))
utils.AssertEqual(t, "application/xml", string(c.Response().Header.Peek("content-type")))
})
}

// go test -run=^$ -bench=Benchmark_Ctx_XML -benchmem -count=4
Expand Down

0 comments on commit 9230be3

Please sign in to comment.