From ae0fb98c6b8282cfc8ccb1449b548e898f320c2c Mon Sep 17 00:00:00 2001 From: James Rasell Date: Tue, 19 May 2020 15:46:31 +0200 Subject: [PATCH] api: return custom error if API attempts to decode empty body. --- command/agent/http.go | 6 ++++++ command/agent/http_test.go | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/command/agent/http.go b/command/agent/http.go index 3993bdc63..a6723e71a 100644 --- a/command/agent/http.go +++ b/command/agent/http.go @@ -4,6 +4,7 @@ import ( "bytes" "crypto/tls" "encoding/json" + "errors" "fmt" "net" "net/http" @@ -548,6 +549,11 @@ func isAPIClientError(code int) bool { // decodeBody is used to decode a JSON request body func decodeBody(req *http.Request, out interface{}) error { + + if req.Body == http.NoBody { + return errors.New("Request body is empty") + } + dec := json.NewDecoder(req.Body) return dec.Decode(&out) } diff --git a/command/agent/http_test.go b/command/agent/http_test.go index 1b0570659..afa06edb9 100644 --- a/command/agent/http_test.go +++ b/command/agent/http_test.go @@ -5,6 +5,7 @@ import ( "crypto/tls" "crypto/x509" "encoding/json" + "errors" "fmt" "io" "io/ioutil" @@ -12,6 +13,7 @@ import ( "net/http" "net/http/httptest" "net/url" + "strings" "testing" "time" @@ -1094,6 +1096,42 @@ func Test_IsAPIClientError(t *testing.T) { } } +func Test_decodeBody(t *testing.T) { + + testCases := []struct { + inputReq *http.Request + inputOut interface{} + expectedOut interface{} + expectedError error + name string + }{ + { + inputReq: &http.Request{Body: http.NoBody}, + expectedError: errors.New("Request body is empty"), + name: "empty input request body", + }, + { + inputReq: &http.Request{Body: ioutil.NopCloser(strings.NewReader(`{"foo":"bar"}`))}, + inputOut: &struct { + Foo string `json:"foo"` + }{}, + expectedOut: &struct { + Foo string `json:"foo"` + }{Foo: "bar"}, + expectedError: nil, + name: "populated request body and correct out", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + actualError := decodeBody(tc.inputReq, tc.inputOut) + assert.Equal(t, tc.expectedError, actualError, tc.name) + assert.Equal(t, tc.expectedOut, tc.inputOut, tc.name) + }) + } +} + func httpTest(t testing.TB, cb func(c *Config), f func(srv *TestAgent)) { s := makeHTTPServer(t, cb) defer s.Shutdown()