title: Get gorilla/mux router current route name from middleware
body: <p><strong>Problem:</strong>
  Unable to access mux.CurrentRoute(r).GetName() from middleware. (Although I had been able to access it from my middleware, I had to change the way my middleware works due to it's previous inability to access the request).  So I've mucked something up and I'm not sure how to get back to a working state where I can access the route name.</p>
  
  <p>Any help would be much appreciated!</p>
  
  <p><strong>Error:</strong></p>
  
  <pre><code>runtime error: invalid memory address or nil pointer dereference 
  </code></pre>
  
  <p><strong>Code:</strong></p>
  
  <pre><code>func main() {
      var (
          err          error
          r            *mux.Router
          devRouter    *mux.Router
          usersRouter  *mux.Router
          brandsRouter *mux.Router
      )
      defer db.Close()
      defer store.Close()
  
      r = mux.NewRouter()
      devRouter = r.PathPrefix("/api/v1/dev").Subrouter()
      usersRouter = r.PathPrefix("/api/v1/users").Subrouter()
      brandsRouter = r.PathPrefix("/api/v1/brands").Subrouter()
  
      // development endpoints
      devRouter.HandleFunc("/db/seed", devDbSeed)
      ...
  
      // users
      usersRouter.HandleFunc("/create", usersCreateHandlerFunc).Methods("POST").Name("USERS_CREATE")
      ...
  
      // brands
      brandsRouter.HandleFunc("/create", brandsCreateHandlerFunc).Methods("POST").Name("BRANDS_CREATE")
      ...
  
      // products
      brandsRouter.HandleFunc("/{brand_id:[0-9]+}/products", brandsProductsListHandlerFunc).Methods("GET").Name("BRANDS_PRODUCTS_LIST")
      ...
  
      // mwAuthorize and mwAuthenticate basically work the same
      mw := []func(http.Handler) http.Handler{mwAuthenticate, mwAuthorize}
      http.Handle("/", use(r, mw...))
      err = http.ListenAndServe(":9000", nil)
      if err != nil {
           logIt(err)
      }
  }
  
  func use(h http.Handler, mw ...func(http.Handler) http.Handler) http.Handler {
      // exec order: mw[0],mw[1],mw[N]...
      for i := len(mw) - 1; i &gt;= 0; i-- {
          h = mw[i](h)
      }
      return h
  }
  
  func mwAuthorize(next http.Handler) http.Handler {
      return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
           if true != authorize(r) {
              w.WriteHeader(http.StatusForbidden)
              return
           } else {
              next.ServeHTTP(w, r)
           }
       })
  }
  
  func authorize(r *http.Request) (isAuthorized bool) {
      isAuthorized = false
      /**
         This is where it's failing!
      */
      routeName := mux.CurrentRoute(r).GetName()
      switch routeName {
      case "USERS_CREATE":
          // route-specific authorization
          break
      ...
      default:
          break
      }
      return
  }
  </code></pre>
  
  <p>Update (2015-01-04 @ 4:49PM EST):
  So after removing the middleware (or at least commenting out the section that's trying to read mux.CurrentRoute) I am able to retrieve the route name from the destination handlerfunc (ex: usersCreateHandlerFunc or brandsCreateHandlerFunc).  This doesn't solve my problem (I'd still like to perform authentication/authorization in middleware as opposed to every handlerfunc), I have a hunch it's letting me know *mux.Router isn't available in my middleware until after the final .ServeHTTP call.  (Or something along those lines...)</p>
  
  <p>Update (2015-01-04 @ 5:41PM EST):
  Tried a different (albeit less-preferred) direction of using Negroni as the middleware component.  Still getting nil-pointer error when I try to get mux.CurrentRoute.</p>
  
  <p>Update (2015-01-04 @ 6:17PM EST):
  I am able to access the request (ex: r.URL) from the middleware func's, but still no luck on accessing the mux.Route (ex: mux.CurrentRoute(r)). After looking a bit more at the mux source, I think it's because the current mux context isn't getting set because the router hasn't executed the matcher yet (and therefore it doesn't know what route it's currently on until AFTER the middleware is complete).  However, I'm still not sure how to either resolve this, or re-structure my code to handle this.</p>