github.com/getong/docker@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  }