Skip to content

Commit

Permalink
feat: default response content type to json if not specified (#859)
Browse files Browse the repository at this point in the history
Fixes #855
  • Loading branch information
wesbillman authored Jan 31, 2024
1 parent 5b6e674 commit d6204e2
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 8 deletions.
1 change: 1 addition & 0 deletions backend/controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ func (s *Service) ServeHTTP(w http.ResponseWriter, r *http.Request) {
return
}

ingress.SetDefaultContentType(response.Headers)
responseBody, err = ingress.ResponseBodyForContentType(response.Headers, response.Body)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
Expand Down
23 changes: 15 additions & 8 deletions backend/controller/ingress/ingress.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,17 +61,24 @@ func matchSegments(pattern, urlPath string, onMatch func(segment, value string))
return true
}

func ResponseBodyForContentType(headers map[string][]string, body []byte) ([]byte, error) {
contentType, hasContentType := headers["Content-Type"]
if !hasContentType || len(contentType) == 0 || contentType[0] == "" || !strings.HasPrefix(contentType[0], "text/") {
return body, nil
func SetDefaultContentType(headers map[string][]string) {
if _, hasContentType := headers["Content-Type"]; !hasContentType {
headers["Content-Type"] = []string{"application/json"}
}
}

var htmlContent string
if err := json.Unmarshal(body, &htmlContent); err != nil {
return nil, err
func ResponseBodyForContentType(headers map[string][]string, body []byte) ([]byte, error) {
if contentType, hasContentType := headers["Content-Type"]; hasContentType {
if strings.HasPrefix(contentType[0], "text/") {
var textContent string
if err := json.Unmarshal(body, &textContent); err != nil {
return nil, err
}
return []byte(textContent), nil
}
}
return []byte(htmlContent), nil

return body, nil
}

func ValidateCallBody(body []byte, verbRef *schema.VerbRef, sch *schema.Schema) error {
Expand Down
46 changes: 46 additions & 0 deletions backend/controller/ingress/ingress_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,3 +140,49 @@ func TestParseQueryJson(t *testing.T) {
assert.Equal(t, test.request, actual, test.query)
}
}

func TestSetDefaultContentType(t *testing.T) {
headers := map[string][]string{}
SetDefaultContentType(headers)
assert.Equal(t, map[string][]string{"Content-Type": {"application/json"}}, headers)

headers = map[string][]string{"Content-Type": {"text/html"}}
SetDefaultContentType(headers)
assert.Equal(t, map[string][]string{"Content-Type": {"text/html"}}, headers)
}

func TestResponseBodyForContentType(t *testing.T) {
tests := []struct {
name string
headers map[string][]string
body []byte
expectedBody []byte
}{
{
name: "application/json",
headers: map[string][]string{"Content-Type": {"application/json"}},
body: []byte(`{"message": "Hello, World!"}`),
expectedBody: []byte(`{"message": "Hello, World!"}`),
},
{
name: "text/html",
headers: map[string][]string{"Content-Type": {"text/html"}},
body: []byte(`"<html><body>Hello, World!</body></html>"`),
expectedBody: []byte("<html><body>Hello, World!</body></html>"),
},
{
name: "Default to application/json",
headers: map[string][]string{},
body: []byte(`{"message": "Default to JSON"}`),
expectedBody: []byte(`{"message": "Default to JSON"}`),
},
}

for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
result, err := ResponseBodyForContentType(tc.headers, tc.body)
assert.NoError(t, err)
assert.Equal(t, tc.expectedBody, result)
})
}
}

0 comments on commit d6204e2

Please sign in to comment.