15922: Accept HEAD method on all GET routes.
authorTom Clegg <tom@tomclegg.ca>
Mon, 9 Dec 2019 14:51:55 +0000 (09:51 -0500)
committerTom Clegg <tom@tomclegg.ca>
Thu, 12 Dec 2019 14:59:58 +0000 (09:59 -0500)
Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom@tomclegg.ca>

lib/controller/router/router.go
lib/controller/router/router_test.go
services/keepproxy/keepproxy_test.go

index bc70963dab1f4c1bb68f791719b1ff1b1d2a5a4d..c41f103dc464be41be43002b24e11a59a9968c8c 100644 (file)
@@ -298,12 +298,6 @@ func (rtr *router) addRoutes() {
                },
        } {
                rtr.addRoute(route.endpoint, route.defaultOpts, route.exec)
-               if route.endpoint.Method == "PATCH" {
-                       // Accept PUT as a synonym for PATCH.
-                       endpointPUT := route.endpoint
-                       endpointPUT.Method = "PUT"
-                       rtr.addRoute(endpointPUT, route.defaultOpts, route.exec)
-               }
        }
        rtr.mux.NotFoundHandler = http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
                httpserver.Errors(w, []string{"API endpoint not found"}, http.StatusNotFound)
@@ -313,8 +307,17 @@ func (rtr *router) addRoutes() {
        })
 }
 
+var altMethod = map[string]string{
+       "PATCH": "PUT",  // Accept PUT as a synonym for PATCH
+       "GET":   "HEAD", // Accept HEAD at any GET route
+}
+
 func (rtr *router) addRoute(endpoint arvados.APIEndpoint, defaultOpts func() interface{}, exec routableFunc) {
-       rtr.mux.Methods(endpoint.Method).Path("/" + endpoint.Path).HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
+       methods := []string{endpoint.Method}
+       if alt, ok := altMethod[endpoint.Method]; ok {
+               methods = append(methods, alt)
+       }
+       rtr.mux.Methods(methods...).Path("/" + endpoint.Path).HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
                logger := ctxlog.FromContext(req.Context())
                params, err := rtr.loadRequestParams(req, endpoint.AttrsKey)
                if err != nil {
index 7a7e3dd6fcfb90857480521c4b9931ac92c6a401..a17bd3bd8b8f43daf6cf52dc61d3cf00ca132f2a 100644 (file)
@@ -329,6 +329,11 @@ func (s *RouterIntegrationSuite) TestSelectParam(c *check.C) {
        }
 }
 
+func (s *RouterIntegrationSuite) TestHEAD(c *check.C) {
+       _, rr, _ := doRequest(c, s.rtr, arvadostest.ActiveTokenV2, "HEAD", "/arvados/v1/containers/"+arvadostest.QueuedContainerUUID, nil, nil)
+       c.Check(rr.Code, check.Equals, http.StatusOK)
+}
+
 func (s *RouterIntegrationSuite) TestRouteNotFound(c *check.C) {
        token := arvadostest.ActiveTokenV2
        req := (&testReq{
index 1c86a461aaf14da4c5801f617d20e364d3c11e2d..aa32356806abdb32e73ea0de9534e76567e5e83e 100644 (file)
@@ -142,6 +142,7 @@ func (s *ServerRequiredSuite) TestResponseViaHeader(c *C) {
        resp, err := (&http.Client{}).Do(req)
        c.Assert(err, Equals, nil)
        c.Check(resp.Header.Get("Via"), Equals, "HTTP/1.1 keepproxy")
+       c.Assert(resp.StatusCode, Equals, http.StatusOK)
        locator, err := ioutil.ReadAll(resp.Body)
        c.Assert(err, Equals, nil)
        resp.Body.Close()