From b2c93812fb2149ce56678948cbb3e482e595ca6a Mon Sep 17 00:00:00 2001 From: Tim Ramlot <42113979+inteon@users.noreply.github.com> Date: Sun, 3 Dec 2023 10:16:52 +0100 Subject: [PATCH] add missing crashhandler Signed-off-by: Tim Ramlot <42113979+inteon@users.noreply.github.com> --- pkg/webhook/admission/http.go | 5 +++++ pkg/webhook/admission/http_test.go | 27 +++++++++++++++++++++++++ pkg/webhook/authentication/http.go | 5 +++++ pkg/webhook/authentication/http_test.go | 27 +++++++++++++++++++++++++ 4 files changed, 64 insertions(+) diff --git a/pkg/webhook/admission/http.go b/pkg/webhook/admission/http.go index 4735800195..deea112a6d 100644 --- a/pkg/webhook/admission/http.go +++ b/pkg/webhook/admission/http.go @@ -42,6 +42,11 @@ func init() { var _ http.Handler = &Webhook{} func (wh *Webhook) ServeHTTP(w http.ResponseWriter, r *http.Request) { + defer utilruntime.HandleCrash(func(_ interface{}) { + // Assume the crash happened before the response was written. + http.Error(w, "internal server error", http.StatusInternalServerError) + }) + ctx := r.Context() if wh.WithContextFunc != nil { ctx = wh.WithContextFunc(ctx, r) diff --git a/pkg/webhook/admission/http_test.go b/pkg/webhook/admission/http_test.go index be10aea459..d3cd21d81d 100644 --- a/pkg/webhook/admission/http_test.go +++ b/pkg/webhook/admission/http_test.go @@ -198,6 +198,33 @@ var _ = Describe("Admission Webhooks", func() { return respRecorder.Body.Len() }, time.Second*3).Should(Equal(0)) }) + + It("should handle crashes", func() { + req := &http.Request{ + Header: http.Header{"Content-Type": []string{"application/json"}}, + Method: http.MethodPost, + Body: nopCloser{Reader: bytes.NewBufferString(`{"spec":{"token":"foobar"}}`)}, + } + webhook := &Webhook{ + Handler: &fakeHandler{ + fn: func(ctx context.Context, req Request) Response { + panic("boom") + }, + }, + } + + expected := `internal server error +` + (func() { + defer func() { + if r := recover(); r != nil { + Expect(r).To(Equal("boom")) + } + }() + webhook.ServeHTTP(respRecorder, req) + })() + Expect(respRecorder.Body.String()).To(Equal(expected)) + }) }) }) diff --git a/pkg/webhook/authentication/http.go b/pkg/webhook/authentication/http.go index 3b0d5c4959..74611c0ac5 100644 --- a/pkg/webhook/authentication/http.go +++ b/pkg/webhook/authentication/http.go @@ -42,6 +42,11 @@ func init() { var _ http.Handler = &Webhook{} func (wh *Webhook) ServeHTTP(w http.ResponseWriter, r *http.Request) { + defer utilruntime.HandleCrash(func(_ interface{}) { + // Assume the crash happened before the response was written. + http.Error(w, "internal server error", http.StatusInternalServerError) + }) + ctx := r.Context() if wh.WithContextFunc != nil { ctx = wh.WithContextFunc(ctx, r) diff --git a/pkg/webhook/authentication/http_test.go b/pkg/webhook/authentication/http_test.go index 86bd5d0153..215008b4eb 100644 --- a/pkg/webhook/authentication/http_test.go +++ b/pkg/webhook/authentication/http_test.go @@ -181,6 +181,33 @@ var _ = Describe("Authentication Webhooks", func() { webhook.ServeHTTP(respRecorder, req.WithContext(ctx)) Expect(respRecorder.Body.String()).To(Equal(expected)) }) + + It("should handle crashes", func() { + req := &http.Request{ + Header: http.Header{"Content-Type": []string{"application/json"}}, + Method: http.MethodPost, + Body: nopCloser{Reader: bytes.NewBufferString(`{"spec":{"token":"foobar"}}`)}, + } + webhook := &Webhook{ + Handler: &fakeHandler{ + fn: func(ctx context.Context, req Request) Response { + panic("boom") + }, + }, + } + + expected := `internal server error +` + (func() { + defer func() { + if r := recover(); r != nil { + Expect(r).To(Equal("boom")) + } + }() + webhook.ServeHTTP(respRecorder, req) + })() + Expect(respRecorder.Body.String()).To(Equal(expected)) + }) }) })