853e2e92d8
(*App).context, called in the HTTP handler on each request, creates a URLBuilder, which involves calling Router(). This shows up in profiles a hot spot because it involves compiling the regexps which define all the routes. For efficiency, cache the router and return the same object each time. It appears to be safe to reuse the router because GetRoute is the only method ever called on the returned router object. Signed-off-by: Aaron Lehmann <alehmann@netflix.com>
52 lines
1.2 KiB
Go
52 lines
1.2 KiB
Go
package v2
|
|
|
|
import (
|
|
"sync"
|
|
|
|
"github.com/gorilla/mux"
|
|
)
|
|
|
|
// The following are definitions of the name under which all V2 routes are
|
|
// registered. These symbols can be used to look up a route based on the name.
|
|
const (
|
|
RouteNameBase = "base"
|
|
RouteNameManifest = "manifest"
|
|
RouteNameTags = "tags"
|
|
RouteNameBlob = "blob"
|
|
RouteNameBlobUpload = "blob-upload"
|
|
RouteNameBlobUploadChunk = "blob-upload-chunk"
|
|
RouteNameCatalog = "catalog"
|
|
)
|
|
|
|
var (
|
|
baseRouter *mux.Router
|
|
createBaseRouterOnce sync.Once
|
|
)
|
|
|
|
// Router builds a gorilla router with named routes for the various API
|
|
// methods. This can be used directly by both server implementations and
|
|
// clients.
|
|
func Router() *mux.Router {
|
|
createBaseRouterOnce.Do(func() {
|
|
baseRouter = RouterWithPrefix("")
|
|
})
|
|
return baseRouter
|
|
}
|
|
|
|
// RouterWithPrefix builds a gorilla router with a configured prefix
|
|
// on all routes.
|
|
func RouterWithPrefix(prefix string) *mux.Router {
|
|
rootRouter := mux.NewRouter()
|
|
router := rootRouter
|
|
if prefix != "" {
|
|
router = router.PathPrefix(prefix).Subrouter()
|
|
}
|
|
|
|
router.StrictSlash(true)
|
|
|
|
for _, descriptor := range routeDescriptors {
|
|
router.Path(descriptor.Path).Name(descriptor.Name)
|
|
}
|
|
|
|
return rootRouter
|
|
}
|