From e1527a6e697541c6621aafa1eec927134a3560d7 Mon Sep 17 00:00:00 2001 From: "Daniel G. Taylor" Date: Tue, 13 Sep 2022 16:19:21 -0700 Subject: [PATCH] fix: panic on put without body --- patch.go | 2 +- patch_test.go | 30 ++++++++++++++++++++++++++++++ resolver.go | 2 +- 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/patch.go b/patch.go index 731568af..e8c88be3 100644 --- a/patch.go +++ b/patch.go @@ -81,7 +81,7 @@ func (r *Router) AutoPatch() { case http.MethodPut: put = op _, reqDef := put.requestForContentType("application/json") - if reqDef.model != nil { + if reqDef != nil && reqDef.model != nil { kind = reqDef.model.Kind() if kind == reflect.Ptr { kind = reqDef.model.Elem().Kind() diff --git a/patch_test.go b/patch_test.go index fe978b69..c7c3edc6 100644 --- a/patch_test.go +++ b/patch_test.go @@ -170,3 +170,33 @@ func TestPatch(t *testing.T) { app.ServeHTTP(w, req) assert.Equal(t, http.StatusUnsupportedMediaType, w.Code, w.Body.String()) } + +func TestPatchPutNoBody(t *testing.T) { + app := newTestRouter() + + things := app.Resource("/things/{thing-id}") + + things.Get("get-thing", "docs", + NewResponse(http.StatusOK, "OK").Model(&ThingModel{}), + ).Run(func(ctx Context, input struct { + ThingIDParam + }) { + ctx.WriteModel(http.StatusOK, &ThingModel{}) + }) + + things.Put("put-thing", "docs", + NewResponse(http.StatusNoContent, "No Content"), + ).Run(func(ctx Context, input struct { + ThingIDParam + // Note: no body! + }) { + ctx.WriteHeader(http.StatusNoContent) + }) + + // There should be no generated PATCH since there is nothing to + // write in the PUT! + w := httptest.NewRecorder() + req, _ := http.NewRequest(http.MethodPatch, "/things/test", nil) + app.ServeHTTP(w, req) + assert.Equal(t, http.StatusMethodNotAllowed, w.Code, w.Body.String()) +} diff --git a/resolver.go b/resolver.go index 0cc3d2b1..f821cf81 100644 --- a/resolver.go +++ b/resolver.go @@ -237,7 +237,7 @@ func setFields(ctx *hcontext, req *http.Request, input reflect.Value, t reflect. continue } - if reqDef.schema != nil && reqDef.schema.HasValidation() { + if reqDef != nil && reqDef.schema != nil && reqDef.schema.HasValidation() { if !validAgainstSchema(ctx, locationBody+".", reqDef.schema, data) { continue }