github.com/hms58/moby@v1.13.1/api/server/router/local.go (about) 1 package router 2 3 import ( 4 "net/http" 5 6 "github.com/docker/docker/api/server/httputils" 7 "golang.org/x/net/context" 8 ) 9 10 // localRoute defines an individual API route to connect 11 // with the docker daemon. It implements Route. 12 type localRoute struct { 13 method string 14 path string 15 handler httputils.APIFunc 16 } 17 18 // Handler returns the APIFunc to let the server wrap it in middlewares. 19 func (l localRoute) Handler() httputils.APIFunc { 20 return l.handler 21 } 22 23 // Method returns the http method that the route responds to. 24 func (l localRoute) Method() string { 25 return l.method 26 } 27 28 // Path returns the subpath where the route responds to. 29 func (l localRoute) Path() string { 30 return l.path 31 } 32 33 // NewRoute initializes a new local route for the router. 34 func NewRoute(method, path string, handler httputils.APIFunc) Route { 35 return localRoute{method, path, handler} 36 } 37 38 // NewGetRoute initializes a new route with the http method GET. 39 func NewGetRoute(path string, handler httputils.APIFunc) Route { 40 return NewRoute("GET", path, handler) 41 } 42 43 // NewPostRoute initializes a new route with the http method POST. 44 func NewPostRoute(path string, handler httputils.APIFunc) Route { 45 return NewRoute("POST", path, handler) 46 } 47 48 // NewPutRoute initializes a new route with the http method PUT. 49 func NewPutRoute(path string, handler httputils.APIFunc) Route { 50 return NewRoute("PUT", path, handler) 51 } 52 53 // NewDeleteRoute initializes a new route with the http method DELETE. 54 func NewDeleteRoute(path string, handler httputils.APIFunc) Route { 55 return NewRoute("DELETE", path, handler) 56 } 57 58 // NewOptionsRoute initializes a new route with the http method OPTIONS. 59 func NewOptionsRoute(path string, handler httputils.APIFunc) Route { 60 return NewRoute("OPTIONS", path, handler) 61 } 62 63 // NewHeadRoute initializes a new route with the http method HEAD. 64 func NewHeadRoute(path string, handler httputils.APIFunc) Route { 65 return NewRoute("HEAD", path, handler) 66 } 67 68 func cancellableHandler(h httputils.APIFunc) httputils.APIFunc { 69 return func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 70 if notifier, ok := w.(http.CloseNotifier); ok { 71 notify := notifier.CloseNotify() 72 notifyCtx, cancel := context.WithCancel(ctx) 73 finished := make(chan struct{}) 74 defer close(finished) 75 ctx = notifyCtx 76 go func() { 77 select { 78 case <-notify: 79 cancel() 80 case <-finished: 81 } 82 }() 83 } 84 return h(ctx, w, r, vars) 85 } 86 } 87 88 // Cancellable makes new route which embeds http.CloseNotifier feature to 89 // context.Context of handler. 90 func Cancellable(r Route) Route { 91 return localRoute{ 92 method: r.Method(), 93 path: r.Path(), 94 handler: cancellableHandler(r.Handler()), 95 } 96 }