Skip to content

Commit 1b6acc9

Browse files
committed
Deprecated "Sanitize JSON" related implementation is dropped. Instead, for scalars (e.g. strings) and containers (e.g. slices) use omitempty tag, and structs are to be pointers.
1 parent 77fcf80 commit 1b6acc9

8 files changed

Lines changed: 38 additions & 125 deletions

File tree

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
.vscode/
2-
vendor/
2+
vendor/
3+
coverage.out

client.go

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,6 @@ type Client struct {
125125
// Changing its value does not change client kind.
126126
Kind string
127127
httpsCfg *HTTPSConfig
128-
sanitizeJSON bool
129128
rootURL string
130129
userAgent string
131130
username string
@@ -405,14 +404,6 @@ func (c *Client) Timeout(timeout time.Duration) *Client {
405404
return c
406405
}
407406

408-
// SanitizeJSON enables JSON sanitization.
409-
// See details at SanitizeJSONString.
410-
// Deprecated.
411-
func (c *Client) SanitizeJSON() *Client {
412-
c.sanitizeJSON = true
413-
return c
414-
}
415-
416407
// SetBasicAuth sets Authorization header for each request sent by the client.
417408
// String username:password sent in HTTP header.
418409
//
@@ -767,9 +758,6 @@ func (c *Client) makeBodyBytes(data any) ([]byte, error) {
767758
return nil, err
768759
}
769760

770-
if c.sanitizeJSON {
771-
body = SanitizeJSONBytes(body)
772-
}
773761
if len(body) <= len("{}") {
774762
return nil, nil
775763
}

client_test.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,14 @@ type strType struct {
3333

3434
type innerStruct struct {
3535
String string `json:"string,omitempty"`
36-
Array []byte `json:"array"`
37-
Map map[string]string `json:"map"`
36+
Array []byte `json:"array,omitempty"`
37+
Map map[string]string `json:"map,omitempty"`
3838
Number int `json:"number,omitempty"`
3939
}
4040

4141
type structType struct {
42-
Str string `json:"str,omitempty"`
43-
Struct innerStruct `json:"struct"`
42+
Str string `json:"str,omitempty"`
43+
Struct *innerStruct `json:"struct,omitempty"`
4444
}
4545

4646
func testMsgPackDiscoveryAccepted(t testing.TB, iters int) {
@@ -68,16 +68,16 @@ func testMsgPackDiscoveryAccepted(t testing.TB, iters int) {
6868
assert.True(acceptsMsgPack(r))
6969

7070
// Answer
71-
sendResponse(w, r, data, false)
71+
sendResponse(w, r, data)
7272
requestCount++
7373
}))
7474
defer srv.Close()
7575

7676
respData := structType{}
7777
ctx := context.Background()
7878
client := NewClient().Root(srv.URL).MsgPack(true)
79-
reqData1 := structType{Str: "a", Struct: innerStruct{Number: 1, Array: []byte{1, 2, 3}}}
80-
reqData2 := structType{Str: "b", Struct: innerStruct{Number: 2, Array: []byte{4, 5, 6}}}
79+
reqData1 := structType{Str: "a", Struct: &innerStruct{Number: 1, Array: []byte{1, 2, 3}}}
80+
reqData2 := structType{Str: "b", Struct: &innerStruct{Number: 2, Array: []byte{4, 5, 6}}}
8181

8282
for i := 0; i < iters; i++ {
8383
_, err := client.Post(ctx, "/", &reqData1, &respData)
@@ -122,16 +122,16 @@ func testMsgPackDiscoveryRejected(t testing.TB, iters int) {
122122
}
123123

124124
// Answer
125-
sendResponse(w, r, data, false)
125+
sendResponse(w, r, data)
126126
requestCount++
127127
}))
128128
defer srv.Close()
129129

130130
respData := structType{}
131131
ctx := context.Background()
132132
client := NewClient().Root(srv.URL).MsgPack(true)
133-
reqData1 := structType{Str: "a", Struct: innerStruct{Number: 1, Array: []byte{1, 2, 3}}}
134-
reqData2 := structType{Str: "b", Struct: innerStruct{Number: 2, Array: []byte{4, 5, 6}}}
133+
reqData1 := structType{Str: "a", Struct: &innerStruct{Number: 1, Array: []byte{1, 2, 3}}}
134+
reqData2 := structType{Str: "b", Struct: &innerStruct{Number: 2, Array: []byte{4, 5, 6}}}
135135

136136
for i := 0; i < iters; i++ {
137137
_, err := client.Post(ctx, "/", &reqData1, &respData)
@@ -188,7 +188,7 @@ func TestMethods(t *testing.T) {
188188
reqData := strType{Str: "b"}
189189
respData := strType{}
190190
ctx := context.Background()
191-
client := NewClient().Root(srv.URL).SanitizeJSON().HTTPS(&HTTPSConfig{AllowLocalhostHTTP: true})
191+
client := NewClient().Root(srv.URL).HTTPS(&HTTPSConfig{AllowLocalhostHTTP: true})
192192
location, err := client.Post(ctx, "/users", &reqData, &respData)
193193
assert.Nil(err)
194194
locationStr := location.String()
@@ -414,7 +414,7 @@ func TestMethodsError(t *testing.T) {
414414
reqData := strType{Str: "b"}
415415
respData := strType{}
416416
ctx := context.Background()
417-
client := NewClient().Root(srv.URL).SanitizeJSON()
417+
client := NewClient().Root(srv.URL)
418418
client.SetMaxBytesToParse(100000)
419419
location, err := client.Post(ctx, "/users", &reqData, &respData)
420420
assert.NotNil(err)

json.go

Lines changed: 0 additions & 42 deletions
This file was deleted.

json_test.go

Lines changed: 0 additions & 34 deletions
This file was deleted.

mux_lambda_wrapper.go

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,6 @@ import (
1818
// You may want to set it to a smaller value, such as 4KiB, to prevent DoS attacks.
1919
var LambdaMaxBytesToParse = 64 * 1024 * 1024
2020

21-
// LambdaSanitizeJSON defines whether to sanitize JSON of Lambda return or SendResp.
22-
// See SanitizeJSONString for details.
23-
// Deprecated.
24-
var LambdaSanitizeJSON = false
25-
2621
// LambdaValidator tells if incoming request is to be validated.
2722
// Validation is done by https://github.com/go-playground/validator.
2823
// See its documentation for details.

server_response.go

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import (
1313
log "github.com/sirupsen/logrus"
1414
)
1515

16-
func getJSONBody(data any, sanitizeJSON bool) ([]byte, error) {
16+
func getJSONBody(data any) ([]byte, error) {
1717
if data == nil {
1818
return nil, nil // Otherwise "null" (4 bytes) would be returned.
1919
}
@@ -22,20 +22,17 @@ func getJSONBody(data any, sanitizeJSON bool) ([]byte, error) {
2222
if err != nil {
2323
return nil, err
2424
}
25-
if sanitizeJSON {
26-
body = SanitizeJSONBytes(body)
27-
if len(body) == 2 && body[0] == '{' && body[1] == '}' {
28-
return nil, nil
29-
}
30-
}
3125

3226
return body, nil
3327
}
3428

35-
// SendJSONResponse sends an HTTP response with an optionally sanitized JSON data.
29+
// SendJSONResponse sends an HTTP response with a JSON data.
3630
// Caller may set additional headers like `w.Header().Set("Location", "https://me")` before calling this function.
37-
func SendJSONResponse(w http.ResponseWriter, statusCode int, data any, sanitizeJSON bool) (err error) {
38-
body, err := getJSONBody(data, sanitizeJSON)
31+
//
32+
// Warning: The last boolean parameter is ignored. It is there for temporary backward compatibility only.
33+
// It will be removed in the near-future.
34+
func SendJSONResponse(w http.ResponseWriter, statusCode int, data any, _ ...bool) (err error) {
35+
body, err := getJSONBody(data)
3936
if body != nil {
4037
w.Header().Set(ContentTypeHeader, ContentTypeApplicationJSON)
4138
w.WriteHeader(statusCode)
@@ -46,7 +43,7 @@ func SendJSONResponse(w http.ResponseWriter, statusCode int, data any, sanitizeJ
4643
return err
4744
}
4845

49-
func sendResponse(w http.ResponseWriter, r *http.Request, data any, sanitizeJSON bool) (err error) {
46+
func sendResponse(w http.ResponseWriter, r *http.Request, data any) (err error) {
5047
okStatus := getOkStatus(w, r, data)
5148

5249
if data == nil {
@@ -74,13 +71,16 @@ func sendResponse(w http.ResponseWriter, r *http.Request, data any, sanitizeJSON
7471
return err
7572
}
7673

77-
return SendJSONResponse(w, okStatus, data, sanitizeJSON)
74+
return SendJSONResponse(w, okStatus, data)
7875
}
7976

8077
// SendResponse sends an HTTP response with a JSON data.
8178
// Caller may set additional headers like `w.Header().Set("Location", "https://me")` before calling this function.
79+
//
80+
// Same as SendJSONResponse. It will be removed in the near-future.
81+
// Deprecated.
8282
func SendResponse(w http.ResponseWriter, statusCode int, data any) error {
83-
return SendJSONResponse(w, statusCode, data, false)
83+
return SendJSONResponse(w, statusCode, data)
8484
}
8585

8686
func getOkStatus(w http.ResponseWriter, r *http.Request, data any) int {
@@ -95,19 +95,19 @@ func getOkStatus(w http.ResponseWriter, r *http.Request, data any) int {
9595
}
9696

9797
// SendResp sends an HTTP response with data.
98-
// On no error 200/201/204 sent according to the request.
99-
// On error send response depending on whether the error is created by NewError and the client supports RFC 7807.
98+
// If the supplied err is nil, 200/201/204 is sent according to the request and if response data is supplied.
99+
// If err is not nil, a response is sent depending on whether the supplied error is created by NewError and the client supports RFC 7807.
100100
// Caller may set additional headers like `w.Header().Set("Location", "https://me")` before calling this function.
101101
func SendResp(w http.ResponseWriter, r *http.Request, err error, data any) error {
102102
if err == nil {
103-
return sendResponse(w, r, data, LambdaSanitizeJSON)
103+
return sendResponse(w, r, data)
104104
}
105105

106106
if errStr := err.Error(); errStr != "" { // In some cases status like 404 does not indicate error, just a plain result. E.g. on a distributed cache query.
107107
log.Error(errStr)
108108
}
109109

110-
body, _ := getJSONBody(data, LambdaSanitizeJSON)
110+
body, _ := getJSONBody(data)
111111
if body == nil {
112112
return SendProblemDetails(w, r, err)
113113
}
@@ -124,6 +124,11 @@ func SendEmptyResponse(w http.ResponseWriter, statusCode int) {
124124
}
125125

126126
// SendLocationResponse sends an empty "201 Created" HTTP response with Location header.
127+
//
128+
// Looking at the APIs of various bodies, it seems that 201 Created responses usually send back the JSON description of the created resource.
129+
// So, this function is practically never used. Thus, it will be removed in the near-future.
130+
// One can use SendEmptyResponse instead.
131+
// Deprecated.
127132
func SendLocationResponse(w http.ResponseWriter, location string) {
128133
w.Header().Set("Location", location)
129134
SendEmptyResponse(w, http.StatusCreated)
@@ -201,7 +206,7 @@ func sendCustomResponse(r *http.Request, w http.ResponseWriter, body []byte, sta
201206
return nil
202207
}
203208

204-
// SendProblemDetails adds detailed problem description to JSON body, if available. See RFC 7807.
209+
// SendProblemDetails sends a response adding detailed problem description to JSON body, if available. See RFC 7807.
205210
func SendProblemDetails(w http.ResponseWriter, r *http.Request, err error) error {
206211
if restErr, ok := err.(*restError); ok {
207212
if len(restErr.body) != 0 {

server_response_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ func TestSendResponse(t *testing.T) {
2323
w.Header().Set("Location", "https://me/path")
2424
var a structType
2525
a.Str = "hello"
26-
SendJSONResponse(w, 201, &a, true)
26+
SendJSONResponse(w, 201, &a)
2727
})))
2828
defer srv.Close()
2929

0 commit comments

Comments
 (0)