From 134837b3ced4714f9a291b924ad028a1f7ef76dd Mon Sep 17 00:00:00 2001 From: Mariano Sosto Date: Fri, 15 Oct 2021 19:34:11 -0300 Subject: [PATCH 1/5] Create new helper method for creating middlewares from a closure/anonymous function --- middleware.go | 21 +++++++++++++++++++++ middleware_test.go | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/middleware.go b/middleware.go index cb51c56..03a9d9b 100644 --- a/middleware.go +++ b/middleware.go @@ -20,6 +20,27 @@ func (mw MiddlewareFunc) Middleware(handler http.Handler) http.Handler { return mw(handler) } +// NewMiddleware helper method which allows creating a middleware from a function which receives the response and request. +// The typical case would be passing a closure +func NewMiddleware(mw func(http.ResponseWriter, *http.Request)) MiddlewareFunc { + return func(handler http.Handler) http.Handler { + return &genericMW{ + process: func(w http.ResponseWriter, r *http.Request) { + mw(w, r) + handler.ServeHTTP(w, r) + }, + } + } +} + +// genericMW is for creating a middleware from a closure, it's used in the public method NewMiddleware +type genericMW struct { + process func(http.ResponseWriter, *http.Request) +} +func (instance *genericMW) ServeHTTP(w http.ResponseWriter, req *http.Request) { + instance.process(w, req) +} + // Use appends a MiddlewareFunc to the chain. Middleware can be used to intercept or otherwise modify requests and/or responses, and are executed in the order that they are applied to the Router. func (r *Router) Use(mwf ...MiddlewareFunc) { for _, fn := range mwf { diff --git a/middleware_test.go b/middleware_test.go index e9f0ef5..47730e3 100644 --- a/middleware_test.go +++ b/middleware_test.go @@ -3,6 +3,7 @@ package mux import ( "bytes" "net/http" + "net/http/httptest" "testing" ) @@ -563,3 +564,36 @@ func TestMiddlewareOnMultiSubrouter(t *testing.T) { } }) } + +func TestNewMiddleware(t *testing.T) { + + mwFuncCalls := 0 + + handler := &mockHandler{ + serverHttp: func(w http.ResponseWriter, r *http.Request) { + if mwFuncCalls != 1 { + t.Fatalf("Expected Handler to be called after mw run. However, the middleware run {%d} times before the handler.", mwFuncCalls) + } + mwFuncCalls++ + }, + } + + newHandler := NewMiddleware(func(http.ResponseWriter, *http.Request) { + mwFuncCalls++ + }).Middleware(handler) + + newHandler.ServeHTTP(&httptest.ResponseRecorder{}, &http.Request{}) + + if mwFuncCalls != 2 { + t.Fatalf("Expected mwFuncCalls to be 2, but got {%d}", mwFuncCalls) + } + +} + +type mockHandler struct { + serverHttp func(writer http.ResponseWriter, request *http.Request) +} + +func (d *mockHandler) ServeHTTP(writer http.ResponseWriter, request *http.Request) { + d.serverHttp(writer, request) +} From 6815336c0a13f6fca7718f810888b5f27e16acd0 Mon Sep 17 00:00:00 2001 From: Mariano Sosto Date: Fri, 15 Oct 2021 19:47:08 -0300 Subject: [PATCH 2/5] run gofmt on edited files --- middleware.go | 1 + 1 file changed, 1 insertion(+) diff --git a/middleware.go b/middleware.go index 03a9d9b..f3f7ce2 100644 --- a/middleware.go +++ b/middleware.go @@ -37,6 +37,7 @@ func NewMiddleware(mw func(http.ResponseWriter, *http.Request)) MiddlewareFunc { type genericMW struct { process func(http.ResponseWriter, *http.Request) } + func (instance *genericMW) ServeHTTP(w http.ResponseWriter, req *http.Request) { instance.process(w, req) } From a967d77672f5e4ae093334449fdce5e454888ab7 Mon Sep 17 00:00:00 2001 From: Mariano Sosto Date: Sat, 16 Oct 2021 15:28:03 -0300 Subject: [PATCH 3/5] fix golint warning: middleware_test.go:594:2: struct field serverHttp should be serverHTTP --- middleware_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/middleware_test.go b/middleware_test.go index 47730e3..189e572 100644 --- a/middleware_test.go +++ b/middleware_test.go @@ -570,7 +570,7 @@ func TestNewMiddleware(t *testing.T) { mwFuncCalls := 0 handler := &mockHandler{ - serverHttp: func(w http.ResponseWriter, r *http.Request) { + serverHTTP: func(w http.ResponseWriter, r *http.Request) { if mwFuncCalls != 1 { t.Fatalf("Expected Handler to be called after mw run. However, the middleware run {%d} times before the handler.", mwFuncCalls) } @@ -591,9 +591,9 @@ func TestNewMiddleware(t *testing.T) { } type mockHandler struct { - serverHttp func(writer http.ResponseWriter, request *http.Request) + serverHTTP func(writer http.ResponseWriter, request *http.Request) } func (d *mockHandler) ServeHTTP(writer http.ResponseWriter, request *http.Request) { - d.serverHttp(writer, request) + d.serverHTTP(writer, request) } From 7dc66a2eb45f4258461e28e4d7b5140ce985d747 Mon Sep 17 00:00:00 2001 From: Mariano Sosto Date: Sat, 16 Oct 2021 15:31:27 -0300 Subject: [PATCH 4/5] fix golint warnings --- mux.go | 6 +++--- mux_test.go | 2 +- regexp_test.go | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/mux.go b/mux.go index f126a60..30f1672 100644 --- a/mux.go +++ b/mux.go @@ -363,9 +363,9 @@ func (r *Router) Walk(walkFn WalkFunc) error { return r.walk(walkFn, []*Route{}) } -// SkipRouter is used as a return value from WalkFuncs to indicate that the +// ErrSkipRouter is used as a return value from WalkFuncs to indicate that the // router that walk is about to descend down to should be skipped. -var SkipRouter = errors.New("skip this router") +var ErrSkipRouter = errors.New("skip this router") // WalkFunc is the type of the function called for each route visited by Walk. // At every invocation, it is given the current route, and the current router, @@ -375,7 +375,7 @@ type WalkFunc func(route *Route, router *Router, ancestors []*Route) error func (r *Router) walk(walkFn WalkFunc, ancestors []*Route) error { for _, t := range r.routes { err := walkFn(t, r, ancestors) - if err == SkipRouter { + if err == ErrSkipRouter { continue } if err != nil { diff --git a/mux_test.go b/mux_test.go index 2d8d2b3..4c88a2f 100644 --- a/mux_test.go +++ b/mux_test.go @@ -1600,7 +1600,7 @@ func TestWalkSingleDepth(t *testing.T) { err := r0.Walk(func(route *Route, router *Router, ancestors []*Route) error { matcher := route.matchers[0].(*routeRegexp) if matcher.template == "/d" { - return SkipRouter + return ErrSkipRouter } if len(ancestors) != depths[i] { t.Errorf(`Expected depth of %d at i = %d; got "%d"`, depths[i], i, len(ancestors)) diff --git a/regexp_test.go b/regexp_test.go index 0d80e6a..d7518f3 100644 --- a/regexp_test.go +++ b/regexp_test.go @@ -54,7 +54,7 @@ func Benchmark_findQueryKey(b *testing.B) { b.ReportAllocs() b.ResetTimer() for i := 0; i < b.N; i++ { - for key, _ := range all { + for key := range all { _, _ = findFirstQueryKey(query, key) } } @@ -79,7 +79,7 @@ func Benchmark_findQueryKeyGoLib(b *testing.B) { b.ReportAllocs() b.ResetTimer() for i := 0; i < b.N; i++ { - for key, _ := range all { + for key := range all { v := u.Query()[key] if len(v) > 0 { _ = v[0] From 21f221575c917f722beeab1651e2a86abe907921 Mon Sep 17 00:00:00 2001 From: Mariano Sosto Date: Sat, 16 Oct 2021 15:35:25 -0300 Subject: [PATCH 5/5] remove build comment in file mux_httpserver_test.go --- mux_httpserver_test.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/mux_httpserver_test.go b/mux_httpserver_test.go index 5d2f4d3..db3f7c5 100644 --- a/mux_httpserver_test.go +++ b/mux_httpserver_test.go @@ -1,5 +1,3 @@ -// +build go1.9 - package mux import (