Skip to content

Commit

Permalink
Add echo.OnAddRouteHandler field. As name says - this handler is call…
Browse files Browse the repository at this point in the history
…ed when new route is registered.
  • Loading branch information
aldas committed Dec 25, 2022
1 parent f1cf1ec commit 45402bb
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 11 deletions.
39 changes: 28 additions & 11 deletions echo.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,20 +61,28 @@ import (

type (
// Echo is the top-level framework instance.
//
// Goroutine safety: Do not mutate Echo instance fields after server has started. Accessing these
// fields from handlers/middlewares and changing field values at the same time leads to data-races.
// Same rule applies to adding new routes after server has been started - Adding a route is not Goroutine safe action.
Echo struct {
filesystem
common
// startupMutex is mutex to lock Echo instance access during server configuration and startup. Useful for to get
// listener address info (on which interface/port was listener binded) without having data races.
startupMutex sync.RWMutex
startupMutex sync.RWMutex
colorer *color.Color

// premiddleware are middlewares that are run before routing is done. In case pre-middleware returns an error router
// will not be called at all and execution ends up in global error handler.
premiddleware []MiddlewareFunc
middleware []MiddlewareFunc
maxParam *int
router *Router
routers map[string]*Router
pool sync.Pool

StdLogger *stdLog.Logger
colorer *color.Color
premiddleware []MiddlewareFunc
middleware []MiddlewareFunc
maxParam *int
router *Router
routers map[string]*Router
pool sync.Pool
Server *http.Server
TLSServer *http.Server
Listener net.Listener
Expand All @@ -92,6 +100,9 @@ type (
Logger Logger
IPExtractor IPExtractor
ListenerNetwork string

// OnAddRouteHandler is called when Echo adds new route to specific host router.
OnAddRouteHandler func(host string, route Route, handler HandlerFunc, middleware []MiddlewareFunc)
}

// Route contains a handler and information for matching against requests.
Expand Down Expand Up @@ -526,14 +537,20 @@ func (e *Echo) File(path, file string, m ...MiddlewareFunc) *Route {
return e.file(path, file, e.GET, m...)
}

func (e *Echo) add(host, method, path string, handler HandlerFunc, middleware ...MiddlewareFunc) *Route {
func (e *Echo) add(host, method, path string, handler HandlerFunc, middlewares ...MiddlewareFunc) *Route {
router := e.findRouter(host)
//FIXME: when handler+middleware are both nil ... make it behave like handler removal
name := handlerName(handler)
return router.add(method, path, name, func(c Context) error {
h := applyMiddleware(handler, middleware...)
route := router.add(method, path, name, func(c Context) error {
h := applyMiddleware(handler, middlewares...)
return h(c)
})

if e.OnAddRouteHandler != nil {
e.OnAddRouteHandler(host, *route, handler, middlewares)
}

return route
}

// Add registers a new route for an HTTP method and path with matching handler
Expand Down
38 changes: 38 additions & 0 deletions echo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1478,6 +1478,44 @@ func TestEchoListenerNetworkInvalid(t *testing.T) {
assert.Equal(t, ErrInvalidListenerNetwork, e.Start(":1323"))
}

func TestEcho_OnAddRouteHandler(t *testing.T) {
type rr struct {
host string
route Route
handler HandlerFunc
middleware []MiddlewareFunc
}
dummyHandler := func(Context) error { return nil }
e := New()

added := make([]rr, 0)
e.OnAddRouteHandler = func(host string, route Route, handler HandlerFunc, middleware []MiddlewareFunc) {
added = append(added, rr{
host: host,
route: route,
handler: handler,
middleware: middleware,
})
}

e.GET("/static", NotFoundHandler)
e.Host("domain.site").GET("/static/*", dummyHandler, func(next HandlerFunc) HandlerFunc {
return func(c Context) error {
return next(c)
}
})

assert.Len(t, added, 2)

assert.Equal(t, "", added[0].host)
assert.Equal(t, Route{Method: http.MethodGet, Path: "/static", Name: "github.com/labstack/echo/v4.glob..func1"}, added[0].route)
assert.Len(t, added[0].middleware, 0)

assert.Equal(t, "domain.site", added[1].host)
assert.Equal(t, Route{Method: http.MethodGet, Path: "/static/*", Name: "github.com/labstack/echo/v4.TestEcho_OnAddRouteHandler.func1"}, added[1].route)
assert.Len(t, added[1].middleware, 1)
}

func TestEchoReverse(t *testing.T) {
e := New()
dummyHandler := func(Context) error { return nil }
Expand Down

0 comments on commit 45402bb

Please sign in to comment.