api: return custom error if API attempts to decode empty body.

This commit is contained in:
James Rasell 2020-05-19 15:46:31 +02:00
parent c60b987729
commit ae0fb98c6b
No known key found for this signature in database
GPG key ID: AA7D460F5C8377AA
2 changed files with 44 additions and 0 deletions

View file

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

View file

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