@@ -61,20 +61,28 @@ import (
6161
6262type (
6363 // Echo is the top-level framework instance.
64+ //
65+ // Goroutine safety: Do not mutate Echo instance fields after server has started. Accessing these
66+ // fields from handlers/middlewares and changing field values at the same time leads to data-races.
67+ // Same rule applies to adding new routes after server has been started - Adding a route is not Goroutine safe action.
6468 Echo struct {
6569 filesystem
6670 common
6771 // startupMutex is mutex to lock Echo instance access during server configuration and startup. Useful for to get
6872 // listener address info (on which interface/port was listener binded) without having data races.
69- startupMutex sync.RWMutex
73+ startupMutex sync.RWMutex
74+ colorer * color.Color
75+
76+ // premiddleware are middlewares that are run before routing is done. In case pre-middleware returns an error router
77+ // will not be called at all and execution ends up in global error handler.
78+ premiddleware []MiddlewareFunc
79+ middleware []MiddlewareFunc
80+ maxParam * int
81+ router * Router
82+ routers map [string ]* Router
83+ pool sync.Pool
84+
7085 StdLogger * stdLog.Logger
71- colorer * color.Color
72- premiddleware []MiddlewareFunc
73- middleware []MiddlewareFunc
74- maxParam * int
75- router * Router
76- routers map [string ]* Router
77- pool sync.Pool
7886 Server * http.Server
7987 TLSServer * http.Server
8088 Listener net.Listener
@@ -92,6 +100,9 @@ type (
92100 Logger Logger
93101 IPExtractor IPExtractor
94102 ListenerNetwork string
103+
104+ // OnAddRouteHandler is called when Echo adds new route to specific host router.
105+ OnAddRouteHandler func (host string , route Route , handler HandlerFunc , middleware []MiddlewareFunc )
95106 }
96107
97108 // Route contains a handler and information for matching against requests.
@@ -526,14 +537,20 @@ func (e *Echo) File(path, file string, m ...MiddlewareFunc) *Route {
526537 return e .file (path , file , e .GET , m ... )
527538}
528539
529- func (e * Echo ) add (host , method , path string , handler HandlerFunc , middleware ... MiddlewareFunc ) * Route {
540+ func (e * Echo ) add (host , method , path string , handler HandlerFunc , middlewares ... MiddlewareFunc ) * Route {
530541 router := e .findRouter (host )
531542 //FIXME: when handler+middleware are both nil ... make it behave like handler removal
532543 name := handlerName (handler )
533- return router .add (method , path , name , func (c Context ) error {
534- h := applyMiddleware (handler , middleware ... )
544+ route := router .add (method , path , name , func (c Context ) error {
545+ h := applyMiddleware (handler , middlewares ... )
535546 return h (c )
536547 })
548+
549+ if e .OnAddRouteHandler != nil {
550+ e .OnAddRouteHandler (host , * route , handler , middlewares )
551+ }
552+
553+ return route
537554}
538555
539556// Add registers a new route for an HTTP method and path with matching handler
0 commit comments