mirror of
				https://github.com/moby/moby.git
				synced 2022-11-09 12:21:53 -05:00 
			
		
		
		
	
		
			
				
	
	
		
			104 lines
		
	
	
	
		
			3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			104 lines
		
	
	
	
		
			3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package router
 | 
						|
 | 
						|
import (
 | 
						|
	"net/http"
 | 
						|
 | 
						|
	"github.com/docker/docker/api/server/httputils"
 | 
						|
	"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 {
 | 
						|
	method  string
 | 
						|
	path    string
 | 
						|
	handler httputils.APIFunc
 | 
						|
}
 | 
						|
 | 
						|
// Handler returns the APIFunc to let the server wrap it in middlewares.
 | 
						|
func (l localRoute) Handler() httputils.APIFunc {
 | 
						|
	return l.handler
 | 
						|
}
 | 
						|
 | 
						|
// Method returns the http method that the route responds to.
 | 
						|
func (l localRoute) Method() string {
 | 
						|
	return l.method
 | 
						|
}
 | 
						|
 | 
						|
// Path returns the subpath where the route responds to.
 | 
						|
func (l localRoute) Path() string {
 | 
						|
	return l.path
 | 
						|
}
 | 
						|
 | 
						|
// NewRoute initializes a new local route for the router.
 | 
						|
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, 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, 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, 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, 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, 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, opts ...RouteWrapper) Route {
 | 
						|
	return NewRoute("HEAD", path, handler, opts...)
 | 
						|
}
 | 
						|
 | 
						|
func cancellableHandler(h httputils.APIFunc) httputils.APIFunc {
 | 
						|
	return func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
 | 
						|
		if notifier, ok := w.(http.CloseNotifier); ok {
 | 
						|
			notify := notifier.CloseNotify()
 | 
						|
			notifyCtx, cancel := context.WithCancel(ctx)
 | 
						|
			finished := make(chan struct{})
 | 
						|
			defer close(finished)
 | 
						|
			ctx = notifyCtx
 | 
						|
			go func() {
 | 
						|
				select {
 | 
						|
				case <-notify:
 | 
						|
					cancel()
 | 
						|
				case <-finished:
 | 
						|
				}
 | 
						|
			}()
 | 
						|
		}
 | 
						|
		return h(ctx, w, r, vars)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
// WithCancel makes new route which embeds http.CloseNotifier feature to
 | 
						|
// context.Context of handler.
 | 
						|
func WithCancel(r Route) Route {
 | 
						|
	return localRoute{
 | 
						|
		method:  r.Method(),
 | 
						|
		path:    r.Path(),
 | 
						|
		handler: cancellableHandler(r.Handler()),
 | 
						|
	}
 | 
						|
}
 |