Skip to content

Commit

Permalink
HTTP unmarshal a number into an interface{} as a Number instead of as…
Browse files Browse the repository at this point in the history
  • Loading branch information
aniketnk committed Jan 12, 2025
1 parent 61085e1 commit f6f32ef
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 8 deletions.
14 changes: 6 additions & 8 deletions internal/server/httpws/redisCmdAdapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,17 +86,15 @@ func ParseHTTPRequest(r *http.Request) (*cmd.DiceDBCmd, error) {
}
// Step 1: Handle JSON body if present
if r.Body != nil {
body, err := io.ReadAll(r.Body)
if err != nil {
return nil, err
}
decoder := json.NewDecoder(r.Body)
decoder.UseNumber() // avoids converting numbers to float64

if len(body) > 0 {
var jsonBody map[string]interface{}
if err := json.Unmarshal(body, &jsonBody); err != nil {
var jsonBody map[string]interface{}
if err := decoder.Decode(&jsonBody); err != nil {
if err != io.EOF { // ignore EOF error
return nil, err
}

} else {
if len(jsonBody) == 0 && command != ABORT {
return nil, fmt.Errorf("empty JSON object")
}
Expand Down
59 changes: 59 additions & 0 deletions internal/server/httpws/redisCmdAdapter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package httpws

import (
"io"
"net/http/httptest"
"strings"
"testing"
Expand Down Expand Up @@ -82,6 +83,14 @@ func TestParseHTTPRequest(t *testing.T) {
expectedCmd: "SET",
expectedArgs: []string{"k1", `[{"subKey1":"value1"},{"subKey2":"value2"}]`, "nx"},
},
{
name: "Test SET command with int64",
method: "POST",
url: "/set",
body: `{"key": "k1", "value": -9223372036854775808}`,
expectedCmd: "SET",
expectedArgs: []string{"k1", "-9223372036854775808"},
},
{
name: "Test GET command",
method: "POST",
Expand Down Expand Up @@ -226,6 +235,14 @@ func TestParseHTTPRequest(t *testing.T) {
expectedCmd: "JSON.ARRPOP",
expectedArgs: []string{"k1", "$", "1"},
},
{
name: "Test ABORT command",
method: "POST",
url: "/abort",
body: `{}`,
expectedCmd: "ABORT",
expectedArgs: []string{},
},
}

for _, tc := range commands {
Expand All @@ -251,6 +268,48 @@ func TestParseHTTPRequest(t *testing.T) {
}
}

func TestParseHTTPRequestError(t *testing.T) {
commands := []struct {
name string
method string
url string
body string
expectedErr string
}{
{
name: "Unexpected EOF",
method: "POST",
url: "/set",
body: `{"key": "malformed json}"`,
expectedErr: io.ErrUnexpectedEOF.Error(),
},
{
name: "Empty body",
method: "POST",
url: "/set",
body: `{}`,
expectedErr: "empty JSON object",
},
{
name: "Syntax error",
method: "POST",
url: "/set",
body: `{'key': "k1"}`,
expectedErr: "invalid character '\\'' looking for beginning of object key string",
},
}
for _, tc := range commands {
t.Run(tc.name, func(t *testing.T) {
req := httptest.NewRequest(tc.method, tc.url, strings.NewReader(tc.body))
req.Header.Set("Content-Type", "application/json")

_, err := ParseHTTPRequest(req)
assert.Error(t, err)
assert.EqualError(t, err, tc.expectedErr)
})
}
}

func TestParseWebsocketMessage(t *testing.T) {
commands := []struct {
name string
Expand Down

0 comments on commit f6f32ef

Please sign in to comment.