Skip to content

Commit

Permalink
Merge pull request #98 from tsawler/development
Browse files Browse the repository at this point in the history
Add check for Content-Type header; simplify error checking; improve t…
  • Loading branch information
tsawler committed Apr 10, 2023
2 parents 4c50bb0 + 146130e commit 58967c4
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 6 deletions.
15 changes: 11 additions & 4 deletions tools.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,16 @@ type XMLResponse struct {

// ReadJSON tries to read the body of a request and converts it from JSON to a variable.
func (t *Tools) ReadJSON(w http.ResponseWriter, r *http.Request, data interface{}) error {

// check content-type header; it should be application/json. If it's not specified, try to decode the body anyway.
if r.Header.Get("Content-Type") != "" {
contentType := r.Header.Get("Content-Type")
if strings.ToLower(contentType) != "application/json" {
return errors.New("the Content-Type header is not application/json")
}
}

// set a sensible default for the maximum payload size.
maxBytes := 1024 * 1024 // one megabyte

// if MaxJSONSize is set, use that value instead of default.
Expand Down Expand Up @@ -75,10 +85,7 @@ func (t *Tools) ReadJSON(w http.ResponseWriter, r *http.Request, data interface{
return errors.New("body contains badly-formed JSON")

case errors.As(err, &unmarshalTypeError):
if unmarshalTypeError.Field != "" {
return fmt.Errorf("body contains incorrect JSON type for field %q", unmarshalTypeError.Field)
}
return fmt.Errorf("body contains incorrect JSON type (at character %d)", unmarshalTypeError.Offset)
return fmt.Errorf("body contains incorrect JSON type for field %q at offset %d", unmarshalTypeError.Field, unmarshalTypeError.Offset)

case errors.Is(err, io.EOF):
return errors.New("body must not be empty")
Expand Down
10 changes: 8 additions & 2 deletions tools_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ var jsonTests = []struct {
errorExpected bool
maxSize int
allowUnknown bool
contentType string
}{
{name: "good json", json: `{"foo": "bar"}`, errorExpected: false, maxSize: 1024, allowUnknown: false},
{name: "badly formatted json", json: `{"foo":"}`, errorExpected: true, maxSize: 1024, allowUnknown: false},
Expand All @@ -101,6 +102,7 @@ var jsonTests = []struct {
{name: "missing field name", json: `{jack: "bar"}`, errorExpected: true, maxSize: 1024, allowUnknown: false},
{name: "file too large", json: `{"foo": "bar"}`, errorExpected: true, maxSize: 5, allowUnknown: false},
{name: "not json", json: `Hello, world`, errorExpected: true, maxSize: 1024, allowUnknown: false},
{name: "wrong header", json: `{"foo": "bar"}`, errorExpected: true, maxSize: 1024, allowUnknown: false, contentType: "application/xml"},
}

func TestTools_ReadJSON(t *testing.T) {
Expand All @@ -114,15 +116,19 @@ func TestTools_ReadJSON(t *testing.T) {

// declare a variable to read the decoded json into.
var decodedJSON struct {
Foo string `json:"foo"`
Chan chan int `json:"chan"`
Foo string `json:"foo"`
}

// create a request with the body.
req, err := http.NewRequest("POST", "/", bytes.NewReader([]byte(e.json)))
if err != nil {
t.Log("Error", err)
}
if e.contentType != "" {
req.Header.Add("Content-Type", e.contentType)
} else {
req.Header.Add("Content-Type", "application/json")
}

// create a test response recorder, which satisfies the requirements
// for a ResponseWriter.
Expand Down

0 comments on commit 58967c4

Please sign in to comment.