Fix jsonp ignoring custom json encoder (#2658)

* add unit test to trigger the bug #2675

* implement solution
pull/2660/head^2
Tiago Peczenyj 2023-10-05 10:09:29 +02:00 committed by GitHub
parent 5171f6b505
commit 9230be3649
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 69 additions and 3 deletions

5
ctx.go
View File

@ -8,7 +8,6 @@ import (
"bytes"
"context"
"crypto/tls"
"encoding/json"
"encoding/xml"
"errors"
"fmt"
@ -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

View File

@ -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
@ -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
@ -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