fs rc: fixes incorrect Content-Type in HTTP API - fixes #7726

This commit is contained in:
Kyle Reynolds 2024-04-05 14:06:41 -06:00 committed by Nick Craig-Wood
parent 5323a21898
commit 47cbddbd27
2 changed files with 54 additions and 1 deletions

View File

@ -200,6 +200,7 @@ func (s *Server) Serve() error {
func writeError(path string, in rc.Params, w http.ResponseWriter, err error, status int) {
fs.Errorf(nil, "rc: %q: error: %v", path, err)
params, status := rc.Error(path, in, err, status)
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(status)
err = rc.WriteJSON(w, params)
if err != nil {
@ -294,6 +295,7 @@ func (s *Server) handlePost(w http.ResponseWriter, r *http.Request, path string)
}
fs.Debugf(nil, "rc: %q: reply %+v: %v", path, out, err)
w.Header().Set("Content-Type", "application/json")
err = rc.WriteJSON(w, out)
if err != nil {
// can't return the error at this point - but have a go anyway

View File

@ -3,6 +3,7 @@ package rcserver
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net/http"
@ -147,7 +148,11 @@ func testServer(t *testing.T, tests []testRun, opt *rc.Options) {
body, err := io.ReadAll(resp.Body)
require.NoError(t, err)
if test.Contains == nil {
if test.ContentType == "application/json" && test.Expected != "" {
expectedNormalized := normalizeJSON(t, test.Expected)
actualNormalized := normalizeJSON(t, string(body))
assert.Equal(t, expectedNormalized, actualNormalized, "Normalized JSON does not match")
} else if test.Contains == nil {
assert.Equal(t, test.Expected, string(body))
} else {
assert.True(t, test.Contains.Match(body), fmt.Sprintf("body didn't match: %v: %v", test.Contains, string(body)))
@ -847,3 +852,49 @@ func TestServeModTime(t *testing.T) {
}}
testServer(t, tests, &opt)
}
func TestContentTypeJSON(t *testing.T) {
tests := []testRun{
{
Name: "Check Content-Type for JSON response",
URL: "rc/noop",
Method: "POST",
Body: `{}`,
ContentType: "application/json",
Status: http.StatusOK,
Expected: "{}\n",
Headers: map[string]string{
"Content-Type": "application/json",
},
},
{
Name: "Check Content-Type for JSON error response",
URL: "rc/error",
Method: "POST",
Body: `{}`,
ContentType: "application/json",
Status: http.StatusInternalServerError,
Expected: `{
"error": "arbitrary error on input map[]",
"input": {},
"path": "rc/error",
"status": 500
}
`,
Headers: map[string]string{
"Content-Type": "application/json",
},
},
}
opt := newTestOpt()
testServer(t, tests, &opt)
}
func normalizeJSON(t *testing.T, jsonStr string) string {
var jsonObj map[string]interface{}
err := json.Unmarshal([]byte(jsonStr), &jsonObj)
require.NoError(t, err, "JSON unmarshalling failed")
normalizedJSON, err := json.Marshal(jsonObj)
require.NoError(t, err, "JSON marshalling failed")
return string(normalizedJSON)
}