From 00328e252c3794795970e9b06dbd1c052e5789ec Mon Sep 17 00:00:00 2001 From: Kevin Franklin Kim Date: Fri, 7 Mar 2025 16:36:03 +0100 Subject: [PATCH] feat: add cancel middleware --- net/http/middleware/cancel.go | 60 +++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 net/http/middleware/cancel.go diff --git a/net/http/middleware/cancel.go b/net/http/middleware/cancel.go new file mode 100644 index 0000000..026eeeb --- /dev/null +++ b/net/http/middleware/cancel.go @@ -0,0 +1,60 @@ +package middleware + +import ( + "net/http" + + httputils "github.com/foomo/keel/utils/net/http" + "go.uber.org/zap" +) + +type ( + CancelOptions struct { + Code int + } + CancelOption func(*CancelOptions) +) + +// GetDefaultCancelOptions returns the default options +func GetDefaultCancelOptions() CancelOptions { + return CancelOptions{ + Code: 499, + } +} + +// CancelWithCode middleware option +func CancelWithCode(v int) CancelOption { + return func(o *CancelOptions) { + o.Code = v + } +} + +// Cancel middleware +func Cancel(opts ...CancelOption) Middleware { + options := GetDefaultCancelOptions() + for _, opt := range opts { + if opt != nil { + opt(&options) + } + } + return CancelWithOptions(options) +} + +// CancelWithOptions middleware +func CancelWithOptions(opts CancelOptions) Middleware { + return func(l *zap.Logger, name string, next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + done := make(chan struct{}) + go func() { + next.ServeHTTP(w, r) + close(done) + }() + + select { + case <-r.Context().Done(): + httputils.ServerError(l, w, r, opts.Code, r.Context().Err()) + case <-done: + // If handler completes normally + } + }) + } +}