| // Copyright 2024 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| package main |
| |
| import ( |
| "encoding/json" |
| "fmt" |
| "mime" |
| "net/http" |
| ) |
| |
| // readRequestJSON expects req to have a JSON content type with a body that |
| // contains a JSON-encoded value complying with the underlying type of target. |
| // It populates target, or returns an error. |
| func readRequestJSON(target any, req *http.Request) error { |
| contentType := req.Header.Get("Content-Type") |
| mediaType, _, err := mime.ParseMediaType(contentType) |
| if err != nil { |
| return err |
| } |
| if mediaType != "application/json" { |
| return fmt.Errorf("expect application/json Content-Type, got %s", mediaType) |
| } |
| |
| dec := json.NewDecoder(req.Body) |
| dec.DisallowUnknownFields() |
| if err := dec.Decode(target); err != nil { |
| return err |
| } |
| return nil |
| } |
| |
| // renderJSON renders 'v' as JSON and writes it as a response into w. |
| func renderJSON(w http.ResponseWriter, v interface{}) { |
| js, err := json.Marshal(v) |
| if err != nil { |
| http.Error(w, err.Error(), http.StatusInternalServerError) |
| return |
| } |
| w.Header().Set("Content-Type", "application/json") |
| w.Write(js) |
| } |