From 5206e9ca22864d33f2e971c35297cbfc5fb58a4a Mon Sep 17 00:00:00 2001 From: lbenedar Date: Tue, 17 Mar 2026 12:44:59 +0300 Subject: [PATCH] ch4.3\ --- cmd/api/helpers.go | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/cmd/api/helpers.go b/cmd/api/helpers.go index 29b5785..4848e90 100644 --- a/cmd/api/helpers.go +++ b/cmd/api/helpers.go @@ -7,6 +7,7 @@ import ( "io" "net/http" "strconv" + "strings" "github.com/julienschmidt/httprouter" ) @@ -41,11 +42,17 @@ func (app *application) writeJSON(w http.ResponseWriter, status int, data envelo } func (app *application) readJSON(w http.ResponseWriter, r *http.Request, dst any) error { - err := json.NewDecoder(r.Body).Decode(dst) + maxBytes := 1_048_576 + r.Body = http.MaxBytesReader(w, r.Body, int64(maxBytes)) + dec := json.NewDecoder(r.Body) + dec.DisallowUnknownFields() + + err := dec.Decode(dst) if err != nil { var syntaxError *json.SyntaxError var unmarshalTypeError *json.UnmarshalTypeError var invalidMarshallError *json.InvalidUnmarshalError + var maxBytesError *http.MaxBytesError switch { case errors.As(err, &syntaxError): @@ -59,11 +66,20 @@ func (app *application) readJSON(w http.ResponseWriter, r *http.Request, dst any return fmt.Errorf("body contains incorrect JSON type for field (at character %d)", unmarshalTypeError.Offset) case errors.Is(err, io.EOF): return errors.New("body must be not empty") + case strings.HasPrefix(err.Error(), "json: unknown field"): + fieldName := strings.TrimPrefix(err.Error(), "json: unknown field") + return fmt.Errorf("body contains unknown key %s", fieldName) + case errors.As(err, &maxBytesError): + return fmt.Errorf("body must not be larger than %d bytes", maxBytesError.Limit) case errors.As(err, &invalidMarshallError): panic(err) default: return err } } + err = dec.Decode(&struct{}{}) + if err != io.EOF { + return errors.New("body must only contain a single JSON value") + } return nil }