diff --git a/api/server/router/build/build.go b/api/server/router/build/build.go index 959498e0f1..8c9137015a 100644 --- a/api/server/router/build/build.go +++ b/api/server/router/build/build.go @@ -24,6 +24,6 @@ func (r *buildRouter) Routes() []router.Route { func (r *buildRouter) initRoutes() { r.routes = []router.Route{ - router.Cancellable(router.NewPostRoute("/build", r.postBuild)), + router.NewPostRoute("/build", r.postBuild, router.WithCancel), } } diff --git a/api/server/router/checkpoint/checkpoint.go b/api/server/router/checkpoint/checkpoint.go index c1e93926f5..b169718232 100644 --- a/api/server/router/checkpoint/checkpoint.go +++ b/api/server/router/checkpoint/checkpoint.go @@ -29,8 +29,8 @@ func (r *checkpointRouter) Routes() []router.Route { func (r *checkpointRouter) initRoutes() { r.routes = []router.Route{ - router.Experimental(router.NewGetRoute("/containers/{name:.*}/checkpoints", r.getContainerCheckpoints)), - router.Experimental(router.NewPostRoute("/containers/{name:.*}/checkpoints", r.postContainerCheckpoint)), - router.Experimental(router.NewDeleteRoute("/containers/{name}/checkpoints/{checkpoint}", r.deleteContainerCheckpoint)), + router.NewGetRoute("/containers/{name:.*}/checkpoints", r.getContainerCheckpoints, router.Experimental), + router.NewPostRoute("/containers/{name:.*}/checkpoints", r.postContainerCheckpoint, router.Experimental), + router.NewDeleteRoute("/containers/{name}/checkpoints/{checkpoint}", r.deleteContainerCheckpoint, router.Experimental), } } diff --git a/api/server/router/container/container.go b/api/server/router/container/container.go index bbed7e9944..bba5b3e8b7 100644 --- a/api/server/router/container/container.go +++ b/api/server/router/container/container.go @@ -46,8 +46,8 @@ func (r *containerRouter) initRoutes() { router.NewGetRoute("/containers/{name:.*}/changes", r.getContainersChanges), router.NewGetRoute("/containers/{name:.*}/json", r.getContainersByName), router.NewGetRoute("/containers/{name:.*}/top", r.getContainersTop), - router.Cancellable(router.NewGetRoute("/containers/{name:.*}/logs", r.getContainersLogs)), - router.Cancellable(router.NewGetRoute("/containers/{name:.*}/stats", r.getContainersStats)), + router.NewGetRoute("/containers/{name:.*}/logs", r.getContainersLogs, router.WithCancel), + router.NewGetRoute("/containers/{name:.*}/stats", r.getContainersStats, router.WithCancel), router.NewGetRoute("/containers/{name:.*}/attach/ws", r.wsContainersAttach), router.NewGetRoute("/exec/{id:.*}/json", r.getExecByID), router.NewGetRoute("/containers/{name:.*}/archive", r.getContainersArchive), diff --git a/api/server/router/image/image.go b/api/server/router/image/image.go index 54a4d51482..de6b059ce1 100644 --- a/api/server/router/image/image.go +++ b/api/server/router/image/image.go @@ -40,8 +40,8 @@ func (r *imageRouter) initRoutes() { // POST router.NewPostRoute("/commit", r.postCommit), router.NewPostRoute("/images/load", r.postImagesLoad), - router.Cancellable(router.NewPostRoute("/images/create", r.postImagesCreate)), - router.Cancellable(router.NewPostRoute("/images/{name:.*}/push", r.postImagesPush)), + router.NewPostRoute("/images/create", r.postImagesCreate, router.WithCancel), + router.NewPostRoute("/images/{name:.*}/push", r.postImagesPush, router.WithCancel), router.NewPostRoute("/images/{name:.*}/tag", r.postImagesTag), router.NewPostRoute("/images/prune", r.postImagesPrune), // DELETE diff --git a/api/server/router/local.go b/api/server/router/local.go index 7cb2a5a2f3..ba70f34132 100644 --- a/api/server/router/local.go +++ b/api/server/router/local.go @@ -7,6 +7,10 @@ import ( "golang.org/x/net/context" ) +// RouteWrapper wraps a route with extra functionality. +// It is passed in when creating a new route. +type RouteWrapper func(r Route) Route + // localRoute defines an individual API route to connect // with the docker daemon. It implements Route. type localRoute struct { @@ -31,38 +35,42 @@ func (l localRoute) Path() string { } // NewRoute initializes a new local route for the router. -func NewRoute(method, path string, handler httputils.APIFunc) Route { - return localRoute{method, path, handler} +func NewRoute(method, path string, handler httputils.APIFunc, opts ...RouteWrapper) Route { + var r Route = localRoute{method, path, handler} + for _, o := range opts { + r = o(r) + } + return r } // NewGetRoute initializes a new route with the http method GET. -func NewGetRoute(path string, handler httputils.APIFunc) Route { - return NewRoute("GET", path, handler) +func NewGetRoute(path string, handler httputils.APIFunc, opts ...RouteWrapper) Route { + return NewRoute("GET", path, handler, opts...) } // NewPostRoute initializes a new route with the http method POST. -func NewPostRoute(path string, handler httputils.APIFunc) Route { - return NewRoute("POST", path, handler) +func NewPostRoute(path string, handler httputils.APIFunc, opts ...RouteWrapper) Route { + return NewRoute("POST", path, handler, opts...) } // NewPutRoute initializes a new route with the http method PUT. -func NewPutRoute(path string, handler httputils.APIFunc) Route { - return NewRoute("PUT", path, handler) +func NewPutRoute(path string, handler httputils.APIFunc, opts ...RouteWrapper) Route { + return NewRoute("PUT", path, handler, opts...) } // NewDeleteRoute initializes a new route with the http method DELETE. -func NewDeleteRoute(path string, handler httputils.APIFunc) Route { - return NewRoute("DELETE", path, handler) +func NewDeleteRoute(path string, handler httputils.APIFunc, opts ...RouteWrapper) Route { + return NewRoute("DELETE", path, handler, opts...) } // NewOptionsRoute initializes a new route with the http method OPTIONS. -func NewOptionsRoute(path string, handler httputils.APIFunc) Route { - return NewRoute("OPTIONS", path, handler) +func NewOptionsRoute(path string, handler httputils.APIFunc, opts ...RouteWrapper) Route { + return NewRoute("OPTIONS", path, handler, opts...) } // NewHeadRoute initializes a new route with the http method HEAD. -func NewHeadRoute(path string, handler httputils.APIFunc) Route { - return NewRoute("HEAD", path, handler) +func NewHeadRoute(path string, handler httputils.APIFunc, opts ...RouteWrapper) Route { + return NewRoute("HEAD", path, handler, opts...) } func cancellableHandler(h httputils.APIFunc) httputils.APIFunc { @@ -85,9 +93,9 @@ func cancellableHandler(h httputils.APIFunc) httputils.APIFunc { } } -// Cancellable makes new route which embeds http.CloseNotifier feature to +// WithCancel makes new route which embeds http.CloseNotifier feature to // context.Context of handler. -func Cancellable(r Route) Route { +func WithCancel(r Route) Route { return localRoute{ method: r.Method(), path: r.Path(), diff --git a/api/server/router/plugin/plugin.go b/api/server/router/plugin/plugin.go index e4ea9e23bf..22819e27a9 100644 --- a/api/server/router/plugin/plugin.go +++ b/api/server/router/plugin/plugin.go @@ -30,9 +30,9 @@ func (r *pluginRouter) initRoutes() { router.NewDeleteRoute("/plugins/{name:.*}", r.removePlugin), router.NewPostRoute("/plugins/{name:.*}/enable", r.enablePlugin), // PATCH? router.NewPostRoute("/plugins/{name:.*}/disable", r.disablePlugin), - router.Cancellable(router.NewPostRoute("/plugins/pull", r.pullPlugin)), - router.Cancellable(router.NewPostRoute("/plugins/{name:.*}/push", r.pushPlugin)), - router.Cancellable(router.NewPostRoute("/plugins/{name:.*}/upgrade", r.upgradePlugin)), + router.NewPostRoute("/plugins/pull", r.pullPlugin, router.WithCancel), + router.NewPostRoute("/plugins/{name:.*}/push", r.pushPlugin, router.WithCancel), + router.NewPostRoute("/plugins/{name:.*}/upgrade", r.upgradePlugin, router.WithCancel), router.NewPostRoute("/plugins/{name:.*}/set", r.setPlugin), router.NewPostRoute("/plugins/create", r.createPlugin), } diff --git a/api/server/router/swarm/cluster.go b/api/server/router/swarm/cluster.go index cda2eb7bdb..61723adb2a 100644 --- a/api/server/router/swarm/cluster.go +++ b/api/server/router/swarm/cluster.go @@ -36,14 +36,14 @@ func (sr *swarmRouter) initRoutes() { router.NewPostRoute("/services/create", sr.createService), router.NewPostRoute("/services/{id}/update", sr.updateService), router.NewDeleteRoute("/services/{id}", sr.removeService), - router.Cancellable(router.NewGetRoute("/services/{id}/logs", sr.getServiceLogs)), + router.NewGetRoute("/services/{id}/logs", sr.getServiceLogs, router.WithCancel), router.NewGetRoute("/nodes", sr.getNodes), router.NewGetRoute("/nodes/{id}", sr.getNode), router.NewDeleteRoute("/nodes/{id}", sr.removeNode), router.NewPostRoute("/nodes/{id}/update", sr.updateNode), router.NewGetRoute("/tasks", sr.getTasks), router.NewGetRoute("/tasks/{id}", sr.getTask), - router.Cancellable(router.NewGetRoute("/tasks/{id}/logs", sr.getTaskLogs)), + router.NewGetRoute("/tasks/{id}/logs", sr.getTaskLogs, router.WithCancel), router.NewGetRoute("/secrets", sr.getSecrets), router.NewPostRoute("/secrets/create", sr.createSecret), router.NewDeleteRoute("/secrets/{id}", sr.removeSecret), diff --git a/api/server/router/system/system.go b/api/server/router/system/system.go index 44231d964c..357bbbe8ee 100644 --- a/api/server/router/system/system.go +++ b/api/server/router/system/system.go @@ -23,7 +23,7 @@ func NewRouter(b Backend, c *cluster.Cluster) router.Router { r.routes = []router.Route{ router.NewOptionsRoute("/{anyroute:.*}", optionsHandler), router.NewGetRoute("/_ping", pingHandler), - router.Cancellable(router.NewGetRoute("/events", r.getEvents)), + router.NewGetRoute("/events", r.getEvents, router.WithCancel), router.NewGetRoute("/info", r.getInfo), router.NewGetRoute("/version", r.getVersion), router.NewGetRoute("/system/df", r.getDiskUsage),