blob: 9c76651bd351273465ada90896a9054bb5da9014 [file] [log] [blame]
package web
import (
"encoding/json"
"net/http"
"go.skia.org/infra/go/httputils"
"go.skia.org/infra/go/util"
)
// TODO(stephana): Simplify
// the ResponseEnvelope and use it solely to wrap JSON arrays.
// Remove sendResponse and sendErrorResponse in favor of sendJsonResponse
// and httputils.ReportError.
// ResponseEnvelope wraps all responses. Some fields might be empty depending
// on context or whether there was an error or not.
type ResponseEnvelope struct {
Data *interface{} `json:"data"`
Err *string `json:"err"`
Status int `json:"status"`
Pagination *httputils.ResponsePagination `json:"pagination"`
}
// setJSONHeaders sets secure headers for JSON responses.
func setJSONHeaders(w http.ResponseWriter) {
h := w.Header()
h.Set("Access-Control-Allow-Origin", "*")
h.Set("Content-Type", "application/json")
h.Set("X-Content-Type-Options", "nosniff")
}
// sendResponse wraps the data of a successful response in a response envelope
// and sends it to the client.
func sendResponse(w http.ResponseWriter, data interface{}, status int, pagination *httputils.ResponsePagination) {
resp := ResponseEnvelope{&data, nil, status, pagination}
setJSONHeaders(w)
w.WriteHeader(status)
if err := json.NewEncoder(w).Encode(resp); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
}
// sendJsonResponse serializes resp to JSON. If an error occurs
// a text based error code is send to the client.
func sendJsonResponse(w http.ResponseWriter, resp interface{}) {
setJSONHeaders(w)
if err := json.NewEncoder(w).Encode(resp); err != nil {
httputils.ReportError(w, nil, err, "Failed to encode JSON response.")
}
}
// parseJson extracts the body from the request and parses it into the
// provided interface.
func parseJson(r *http.Request, v interface{}) error {
// TODO (stephana): validate the JSON against a schema. Might not be necessary !
defer util.Close(r.Body)
decoder := json.NewDecoder(r.Body)
return decoder.Decode(v)
}