[arvados] created: 2.6.0-277-gc18d038b8
git repository hosting
git at public.arvados.org
Fri Jun 16 06:10:31 UTC 2023
at c18d038b87786aee25da9aac751193219e316c3a (commit)
commit c18d038b87786aee25da9aac751193219e316c3a
Author: Tom Clegg <tom at curii.com>
Date: Fri Jun 16 02:06:35 2023 -0400
20647: Test CORS preflight request routing.
Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom at curii.com>
diff --git a/lib/controller/router/router_test.go b/lib/controller/router/router_test.go
index 0a85dcbf6..a8359a440 100644
--- a/lib/controller/router/router_test.go
+++ b/lib/controller/router/router_test.go
@@ -47,14 +47,15 @@ func (s *RouterSuite) SetUpTest(c *check.C) {
func (s *RouterSuite) TestOptions(c *check.C) {
token := arvadostest.ActiveToken
for _, trial := range []struct {
- comment string // unparsed -- only used to help match test failures to trials
- method string
- path string
- header http.Header
- body string
- shouldStatus int // zero value means 200
- shouldCall string
- withOptions interface{}
+ comment string // unparsed -- only used to help match test failures to trials
+ method string
+ path string
+ header http.Header
+ body string
+ unauthenticated bool
+ shouldStatus int // zero value means 200
+ shouldCall string
+ withOptions interface{}
}{
{
method: "GET",
@@ -222,6 +223,22 @@ func (s *RouterSuite) TestOptions(c *check.C) {
Header: http.Header{"Authorization": {"Bearer " + arvadostest.ActiveToken}},
Path: "/" + arvadostest.CompletedContainerUUID}},
},
+ {
+ comment: "container log webdav OPTIONS for CORS",
+ unauthenticated: true,
+ method: "OPTIONS",
+ path: "/arvados/v1/container_requests/" + arvadostest.CompletedContainerRequestUUID + "/log/" + arvadostest.CompletedContainerUUID + "/",
+ header: http.Header{"Access-Control-Request-Method": {"POST"}},
+ shouldCall: "ContainerRequestLog",
+ withOptions: arvados.ContainerLogOptions{
+ UUID: arvadostest.CompletedContainerRequestUUID,
+ WebDAVOptions: arvados.WebDAVOptions{
+ Method: "OPTIONS",
+ Header: http.Header{
+ "Access-Control-Request-Method": {"POST"},
+ },
+ Path: "/" + arvadostest.CompletedContainerUUID + "/"}},
+ },
{
comment: "container log webdav PROPFIND root",
method: "PROPFIND",
@@ -273,7 +290,7 @@ func (s *RouterSuite) TestOptions(c *check.C) {
c.Logf("trial: %+v", trial)
comment := check.Commentf("trial comment: %s", trial.comment)
- _, rr := doRequest(c, s.rtr, token, trial.method, trial.path, trial.header, bytes.NewBufferString(trial.body), nil)
+ _, rr := doRequest(c, s.rtr, token, trial.method, trial.path, !trial.unauthenticated, trial.header, bytes.NewBufferString(trial.body), nil)
if trial.shouldStatus == 0 {
c.Check(rr.Code, check.Equals, http.StatusOK, comment)
} else {
@@ -315,7 +332,7 @@ func (s *RouterIntegrationSuite) TestCollectionResponses(c *check.C) {
// Check "get collection" response has "kind" key
jresp := map[string]interface{}{}
- _, rr := doRequest(c, s.rtr, token, "GET", `/arvados/v1/collections`, nil, bytes.NewBufferString(`{"include_trash":true}`), jresp)
+ _, rr := doRequest(c, s.rtr, token, "GET", `/arvados/v1/collections`, true, nil, bytes.NewBufferString(`{"include_trash":true}`), jresp)
c.Check(rr.Code, check.Equals, http.StatusOK)
c.Check(jresp["items"], check.FitsTypeOf, []interface{}{})
c.Check(jresp["kind"], check.Equals, "arvados#collectionList")
@@ -330,7 +347,7 @@ func (s *RouterIntegrationSuite) TestCollectionResponses(c *check.C) {
`,"select":["uuid"]`,
} {
jresp := map[string]interface{}{}
- _, rr = doRequest(c, s.rtr, token, "GET", `/arvados/v1/collections`, nil, bytes.NewBufferString(`{"where":{"uuid":["`+arvadostest.FooCollection+`"]}`+selectj+`}`), jresp)
+ _, rr = doRequest(c, s.rtr, token, "GET", `/arvados/v1/collections`, true, nil, bytes.NewBufferString(`{"where":{"uuid":["`+arvadostest.FooCollection+`"]}`+selectj+`}`), jresp)
c.Check(rr.Code, check.Equals, http.StatusOK)
c.Check(jresp["items"], check.FitsTypeOf, []interface{}{})
c.Check(jresp["items_available"], check.FitsTypeOf, float64(0))
@@ -356,7 +373,7 @@ func (s *RouterIntegrationSuite) TestCollectionResponses(c *check.C) {
// Check "create collection" response has "kind" key
jresp = map[string]interface{}{}
- _, rr = doRequest(c, s.rtr, token, "POST", `/arvados/v1/collections`, http.Header{"Content-Type": {"application/x-www-form-urlencoded"}}, bytes.NewBufferString(`ensure_unique_name=true`), jresp)
+ _, rr = doRequest(c, s.rtr, token, "POST", `/arvados/v1/collections`, true, http.Header{"Content-Type": {"application/x-www-form-urlencoded"}}, bytes.NewBufferString(`ensure_unique_name=true`), jresp)
c.Check(rr.Code, check.Equals, http.StatusOK)
c.Check(jresp["uuid"], check.FitsTypeOf, "")
c.Check(jresp["kind"], check.Equals, "arvados#collection")
@@ -381,11 +398,11 @@ func (s *RouterIntegrationSuite) TestMaxRequestSize(c *check.C) {
hdr := http.Header{"Content-Type": {"application/x-www-form-urlencoded"}}
body := bytes.NewBufferString(url.Values{"foo_bar": {okstr}}.Encode())
- _, rr := doRequest(c, s.rtr, token, "POST", `/arvados/v1/collections`, hdr, body, nil)
+ _, rr := doRequest(c, s.rtr, token, "POST", `/arvados/v1/collections`, true, hdr, body, nil)
c.Check(rr.Code, check.Equals, http.StatusOK)
body = bytes.NewBufferString(url.Values{"foo_bar": {okstr + okstr}}.Encode())
- _, rr = doRequest(c, s.rtr, token, "POST", `/arvados/v1/collections`, hdr, body, nil)
+ _, rr = doRequest(c, s.rtr, token, "POST", `/arvados/v1/collections`, true, hdr, body, nil)
c.Check(rr.Code, check.Equals, http.StatusRequestEntityTooLarge)
}
}
@@ -394,7 +411,7 @@ func (s *RouterIntegrationSuite) TestContainerList(c *check.C) {
token := arvadostest.ActiveTokenV2
jresp := map[string]interface{}{}
- _, rr := doRequest(c, s.rtr, token, "GET", `/arvados/v1/containers?limit=0`, nil, nil, jresp)
+ _, rr := doRequest(c, s.rtr, token, "GET", `/arvados/v1/containers?limit=0`, true, nil, nil, jresp)
c.Check(rr.Code, check.Equals, http.StatusOK)
c.Check(jresp["items_available"], check.FitsTypeOf, float64(0))
c.Check(jresp["items_available"].(float64) > 2, check.Equals, true)
@@ -402,14 +419,14 @@ func (s *RouterIntegrationSuite) TestContainerList(c *check.C) {
c.Check(jresp["items"], check.HasLen, 0)
jresp = map[string]interface{}{}
- _, rr = doRequest(c, s.rtr, token, "GET", `/arvados/v1/containers?filters=[["uuid","in",[]]]`, nil, nil, jresp)
+ _, rr = doRequest(c, s.rtr, token, "GET", `/arvados/v1/containers?filters=[["uuid","in",[]]]`, true, nil, nil, jresp)
c.Check(rr.Code, check.Equals, http.StatusOK)
c.Check(jresp["items_available"], check.Equals, float64(0))
c.Check(jresp["items"], check.NotNil)
c.Check(jresp["items"], check.HasLen, 0)
jresp = map[string]interface{}{}
- _, rr = doRequest(c, s.rtr, token, "GET", `/arvados/v1/containers?limit=2&select=["uuid","command"]`, nil, nil, jresp)
+ _, rr = doRequest(c, s.rtr, token, "GET", `/arvados/v1/containers?limit=2&select=["uuid","command"]`, true, nil, nil, jresp)
c.Check(rr.Code, check.Equals, http.StatusOK)
c.Check(jresp["items_available"], check.FitsTypeOf, float64(0))
c.Check(jresp["items_available"].(float64) > 2, check.Equals, true)
@@ -421,7 +438,7 @@ func (s *RouterIntegrationSuite) TestContainerList(c *check.C) {
c.Check(item0["mounts"], check.IsNil)
jresp = map[string]interface{}{}
- _, rr = doRequest(c, s.rtr, token, "GET", `/arvados/v1/containers`, nil, nil, jresp)
+ _, rr = doRequest(c, s.rtr, token, "GET", `/arvados/v1/containers`, true, nil, nil, jresp)
c.Check(rr.Code, check.Equals, http.StatusOK)
c.Check(jresp["items_available"], check.FitsTypeOf, float64(0))
c.Check(jresp["items_available"].(float64) > 2, check.Equals, true)
@@ -439,31 +456,31 @@ func (s *RouterIntegrationSuite) TestContainerLock(c *check.C) {
token := arvadostest.AdminToken
jresp := map[string]interface{}{}
- _, rr := doRequest(c, s.rtr, token, "POST", "/arvados/v1/containers/"+uuid+"/lock", nil, nil, jresp)
+ _, rr := doRequest(c, s.rtr, token, "POST", "/arvados/v1/containers/"+uuid+"/lock", true, nil, nil, jresp)
c.Check(rr.Code, check.Equals, http.StatusOK)
c.Check(jresp["uuid"], check.HasLen, 27)
c.Check(jresp["state"], check.Equals, "Locked")
- _, rr = doRequest(c, s.rtr, token, "POST", "/arvados/v1/containers/"+uuid+"/lock", nil, nil, nil)
+ _, rr = doRequest(c, s.rtr, token, "POST", "/arvados/v1/containers/"+uuid+"/lock", true, nil, nil, nil)
c.Check(rr.Code, check.Equals, http.StatusUnprocessableEntity)
c.Check(rr.Body.String(), check.Not(check.Matches), `.*"uuid":.*`)
jresp = map[string]interface{}{}
- _, rr = doRequest(c, s.rtr, token, "POST", "/arvados/v1/containers/"+uuid+"/unlock", nil, nil, jresp)
+ _, rr = doRequest(c, s.rtr, token, "POST", "/arvados/v1/containers/"+uuid+"/unlock", true, nil, nil, jresp)
c.Check(rr.Code, check.Equals, http.StatusOK)
c.Check(jresp["uuid"], check.HasLen, 27)
c.Check(jresp["state"], check.Equals, "Queued")
c.Check(jresp["environment"], check.IsNil)
jresp = map[string]interface{}{}
- _, rr = doRequest(c, s.rtr, token, "POST", "/arvados/v1/containers/"+uuid+"/unlock", nil, nil, jresp)
+ _, rr = doRequest(c, s.rtr, token, "POST", "/arvados/v1/containers/"+uuid+"/unlock", true, nil, nil, jresp)
c.Check(rr.Code, check.Equals, http.StatusUnprocessableEntity)
c.Check(jresp["uuid"], check.IsNil)
}
func (s *RouterIntegrationSuite) TestWritableBy(c *check.C) {
jresp := map[string]interface{}{}
- _, rr := doRequest(c, s.rtr, arvadostest.ActiveTokenV2, "GET", `/arvados/v1/users/`+arvadostest.ActiveUserUUID, nil, nil, jresp)
+ _, rr := doRequest(c, s.rtr, arvadostest.ActiveTokenV2, "GET", `/arvados/v1/users/`+arvadostest.ActiveUserUUID, true, nil, nil, jresp)
c.Check(rr.Code, check.Equals, http.StatusOK)
c.Check(jresp["writable_by"], check.DeepEquals, []interface{}{"zzzzz-tpzed-000000000000000", "zzzzz-tpzed-xurymjxw79nv3jz", "zzzzz-j7d0g-48foin4vonvc2at"})
}
@@ -473,7 +490,7 @@ func (s *RouterIntegrationSuite) TestFullTimestampsInResponse(c *check.C) {
token := arvadostest.ActiveTokenV2
jresp := map[string]interface{}{}
- _, rr := doRequest(c, s.rtr, token, "GET", `/arvados/v1/collections/`+uuid, nil, nil, jresp)
+ _, rr := doRequest(c, s.rtr, token, "GET", `/arvados/v1/collections/`+uuid, true, nil, nil, jresp)
c.Check(rr.Code, check.Equals, http.StatusOK)
c.Check(jresp["uuid"], check.Equals, uuid)
expectNS := map[string]int{
@@ -501,7 +518,7 @@ func (s *RouterIntegrationSuite) TestSelectParam(c *check.C) {
j, err := json.Marshal(sel)
c.Assert(err, check.IsNil)
jresp := map[string]interface{}{}
- _, rr := doRequest(c, s.rtr, token, "GET", "/arvados/v1/containers/"+uuid+"?select="+string(j), nil, nil, jresp)
+ _, rr := doRequest(c, s.rtr, token, "GET", "/arvados/v1/containers/"+uuid+"?select="+string(j), true, nil, nil, jresp)
c.Check(rr.Code, check.Equals, http.StatusOK)
c.Check(jresp["kind"], check.Equals, "arvados#container")
@@ -521,9 +538,9 @@ func (s *RouterIntegrationSuite) TestSelectParam(c *check.C) {
jresp := map[string]interface{}{}
var rr *httptest.ResponseRecorder
if method == "PUT" {
- _, rr = doRequest(c, s.rtr, token, method, "/arvados/v1/collections/"+uuid+"?select="+string(j), nil, bytes.NewReader([]byte(reqBody)), jresp)
+ _, rr = doRequest(c, s.rtr, token, method, "/arvados/v1/collections/"+uuid+"?select="+string(j), true, nil, bytes.NewReader([]byte(reqBody)), jresp)
} else {
- _, rr = doRequest(c, s.rtr, token, method, "/arvados/v1/collections?select="+string(j), nil, bytes.NewReader([]byte(reqBody)), jresp)
+ _, rr = doRequest(c, s.rtr, token, method, "/arvados/v1/collections?select="+string(j), true, nil, bytes.NewReader([]byte(reqBody)), jresp)
}
c.Check(rr.Code, check.Equals, http.StatusOK)
c.Check(jresp["kind"], check.Equals, "arvados#collection")
@@ -534,7 +551,7 @@ 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, nil)
+ _, rr := doRequest(c, s.rtr, arvadostest.ActiveTokenV2, "HEAD", "/arvados/v1/containers/"+arvadostest.QueuedContainerUUID, true, nil, nil, nil)
c.Check(rr.Code, check.Equals, http.StatusOK)
}
@@ -606,15 +623,21 @@ func (s *RouterIntegrationSuite) TestCORS(c *check.C) {
}
}
-func doRequest(c *check.C, rtr http.Handler, token, method, path string, hdrs http.Header, body io.Reader, jresp map[string]interface{}) (*http.Request, *httptest.ResponseRecorder) {
+func doRequest(c *check.C, rtr http.Handler, token, method, path string, auth bool, hdrs http.Header, body io.Reader, jresp map[string]interface{}) (*http.Request, *httptest.ResponseRecorder) {
req := httptest.NewRequest(method, path, body)
for k, v := range hdrs {
req.Header[k] = v
}
- req.Header.Set("Authorization", "Bearer "+token)
+ if auth {
+ req.Header.Set("Authorization", "Bearer "+token)
+ }
rr := httptest.NewRecorder()
rtr.ServeHTTP(rr, req)
- c.Logf("response body: %s", rr.Body.String())
+ respbody := rr.Body.String()
+ if len(respbody) > 10000 {
+ respbody = respbody[:10000] + "[...]"
+ }
+ c.Logf("response body: %s", respbody)
if jresp != nil {
err := json.Unmarshal(rr.Body.Bytes(), &jresp)
c.Check(err, check.IsNil)
commit e7c3a477fc4f75321671a6f601cc07a9180e4646
Author: Tom Clegg <tom at curii.com>
Date: Fri Jun 16 02:05:59 2023 -0400
20647: Fix CORS preflight request handling.
Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tom at curii.com>
diff --git a/lib/controller/localdb/container_gateway.go b/lib/controller/localdb/container_gateway.go
index d17f2e10d..9526c01f8 100644
--- a/lib/controller/localdb/container_gateway.go
+++ b/lib/controller/localdb/container_gateway.go
@@ -31,6 +31,7 @@ import (
"git.arvados.org/arvados.git/sdk/go/auth"
"git.arvados.org/arvados.git/sdk/go/ctxlog"
"git.arvados.org/arvados.git/sdk/go/httpserver"
+ keepweb "git.arvados.org/arvados.git/services/keep-web"
"github.com/hashicorp/yamux"
"golang.org/x/net/webdav"
)
@@ -78,6 +79,16 @@ var (
// ...or the request may be handled locally using an empty-collection
// stub.
func (conn *Conn) ContainerRequestLog(ctx context.Context, opts arvados.ContainerLogOptions) (http.Handler, error) {
+ if opts.Method == "OPTIONS" && opts.Header.Get("Access-Control-Request-Method") != "" {
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ if !keepweb.ServeCORSPreflight(w, opts.Header) {
+ // Inconceivable. We already checked
+ // for the only condition where
+ // ServeCORSPreflight returns false.
+ httpserver.Error(w, "unhandled CORS preflight request", http.StatusInternalServerError)
+ }
+ }), nil
+ }
cr, err := conn.railsProxy.ContainerRequestGet(ctx, arvados.GetOptions{UUID: opts.UUID, Select: []string{"uuid", "container_uuid", "log_uuid"}})
if err != nil {
if se := httpserver.HTTPStatusError(nil); errors.As(err, &se) && se.HTTPStatus() == http.StatusUnauthorized {
diff --git a/lib/controller/localdb/container_gateway_test.go b/lib/controller/localdb/container_gateway_test.go
index dc8a8cea0..f7310e8de 100644
--- a/lib/controller/localdb/container_gateway_test.go
+++ b/lib/controller/localdb/container_gateway_test.go
@@ -6,6 +6,7 @@ package localdb
import (
"bytes"
+ "context"
"crypto/hmac"
"crypto/sha256"
"fmt"
@@ -28,6 +29,7 @@ import (
"git.arvados.org/arvados.git/sdk/go/arvados"
"git.arvados.org/arvados.git/sdk/go/arvadosclient"
"git.arvados.org/arvados.git/sdk/go/arvadostest"
+ "git.arvados.org/arvados.git/sdk/go/auth"
"git.arvados.org/arvados.git/sdk/go/ctxlog"
"git.arvados.org/arvados.git/sdk/go/httpserver"
"git.arvados.org/arvados.git/sdk/go/keepclient"
@@ -298,9 +300,16 @@ func (s *ContainerGatewaySuite) TestContainerRequestLogViaTunnel(c *check.C) {
defer delete(s.cluster.Services.Controller.InternalURLs, *forceInternalURLForTest)
}
+ r, err := http.NewRequestWithContext(s.userctx, "GET", "https://controller.example/arvados/v1/container_requests/"+s.reqUUID+"/log/"+s.ctrUUID+"/stderr.txt", nil)
+ c.Assert(err, check.IsNil)
+ r.Header.Set("Authorization", "Bearer "+arvadostest.ActiveTokenV2)
handler, err := s.localdb.ContainerRequestLog(s.userctx, arvados.ContainerLogOptions{
- UUID: s.reqUUID,
- WebDAVOptions: arvados.WebDAVOptions{Path: "/" + s.ctrUUID + "/stderr.txt"},
+ UUID: s.reqUUID,
+ WebDAVOptions: arvados.WebDAVOptions{
+ Method: "GET",
+ Header: r.Header,
+ Path: "/" + s.ctrUUID + "/stderr.txt",
+ },
})
if broken {
c.Check(err, check.ErrorMatches, `.*tunnel endpoint is invalid.*`)
@@ -308,9 +317,6 @@ func (s *ContainerGatewaySuite) TestContainerRequestLogViaTunnel(c *check.C) {
}
c.Check(err, check.IsNil)
c.Assert(handler, check.NotNil)
- r, err := http.NewRequestWithContext(s.userctx, "GET", "https://controller.example/arvados/v1/container_requests/"+s.reqUUID+"/log/"+s.ctrUUID+"/stderr.txt", nil)
- c.Assert(err, check.IsNil)
- r.Header.Set("Authorization", "Bearer "+arvadostest.ActiveTokenV2)
rec := httptest.NewRecorder()
handler.ServeHTTP(rec, r)
resp := rec.Result()
@@ -334,12 +340,13 @@ func (s *ContainerGatewaySuite) TestContainerRequestLogViaKeepWeb(c *check.C) {
func (s *ContainerGatewaySuite) testContainerRequestLog(c *check.C) {
for _, trial := range []struct {
- method string
- path string
- header http.Header
- expectStatus int
- expectBodyRe string
- expectHeader http.Header
+ method string
+ path string
+ header http.Header
+ unauthenticated bool
+ expectStatus int
+ expectBodyRe string
+ expectHeader http.Header
}{
{
method: "GET",
@@ -373,6 +380,22 @@ func (s *ContainerGatewaySuite) testContainerRequestLog(c *check.C) {
"Allow": {"OPTIONS, LOCK, GET, HEAD, POST, DELETE, PROPPATCH, COPY, MOVE, UNLOCK, PROPFIND, PUT"},
},
},
+ {
+ method: "OPTIONS",
+ path: s.ctrUUID + "/stderr.txt",
+ unauthenticated: true,
+ header: http.Header{
+ "Access-Control-Request-Method": {"POST"},
+ },
+ expectStatus: http.StatusOK,
+ expectBodyRe: "",
+ expectHeader: http.Header{
+ "Access-Control-Allow-Headers": {"Authorization, Content-Type, Range, Depth, Destination, If, Lock-Token, Overwrite, Timeout, Cache-Control"},
+ "Access-Control-Allow-Methods": {"COPY, DELETE, GET, LOCK, MKCOL, MOVE, OPTIONS, POST, PROPFIND, PROPPATCH, PUT, RMCOL, UNLOCK"},
+ "Access-Control-Allow-Origin": {"*"},
+ "Access-Control-Max-Age": {"86400"},
+ },
+ },
{
method: "PROPFIND",
path: s.ctrUUID + "/",
@@ -411,17 +434,25 @@ func (s *ContainerGatewaySuite) testContainerRequestLog(c *check.C) {
},
} {
c.Logf("trial %#v", trial)
- handler, err := s.localdb.ContainerRequestLog(s.userctx, arvados.ContainerLogOptions{
- UUID: s.reqUUID,
- WebDAVOptions: arvados.WebDAVOptions{Path: "/" + trial.path},
- })
- c.Assert(err, check.IsNil)
- c.Assert(handler, check.NotNil)
- r, err := http.NewRequestWithContext(s.userctx, trial.method, "https://controller.example/arvados/v1/container_requests/"+s.reqUUID+"/log/"+trial.path, nil)
+ ctx := s.userctx
+ if trial.unauthenticated {
+ ctx = auth.NewContext(context.Background(), auth.CredentialsFromRequest(&http.Request{URL: &url.URL{}, Header: http.Header{}}))
+ }
+ r, err := http.NewRequestWithContext(ctx, trial.method, "https://controller.example/arvados/v1/container_requests/"+s.reqUUID+"/log/"+trial.path, nil)
c.Assert(err, check.IsNil)
for k := range trial.header {
r.Header.Set(k, trial.header.Get(k))
}
+ handler, err := s.localdb.ContainerRequestLog(ctx, arvados.ContainerLogOptions{
+ UUID: s.reqUUID,
+ WebDAVOptions: arvados.WebDAVOptions{
+ Method: trial.method,
+ Header: r.Header,
+ Path: "/" + trial.path,
+ },
+ })
+ c.Assert(err, check.IsNil)
+ c.Assert(handler, check.NotNil)
rec := httptest.NewRecorder()
handler.ServeHTTP(rec, r)
resp := rec.Result()
diff --git a/services/keep-web/handler.go b/services/keep-web/handler.go
index 27981c487..3cdaf5d2b 100644
--- a/services/keep-web/handler.go
+++ b/services/keep-web/handler.go
@@ -182,15 +182,7 @@ func (h *handler) ServeHTTP(wOrig http.ResponseWriter, r *http.Request) {
w := httpserver.WrapResponseWriter(wOrig)
- if method := r.Header.Get("Access-Control-Request-Method"); method != "" && r.Method == "OPTIONS" {
- if !browserMethod[method] && !webdavMethod[method] {
- w.WriteHeader(http.StatusMethodNotAllowed)
- return
- }
- w.Header().Set("Access-Control-Allow-Headers", corsAllowHeadersHeader)
- w.Header().Set("Access-Control-Allow-Methods", "COPY, DELETE, GET, LOCK, MKCOL, MOVE, OPTIONS, POST, PROPFIND, PROPPATCH, PUT, RMCOL, UNLOCK")
- w.Header().Set("Access-Control-Allow-Origin", "*")
- w.Header().Set("Access-Control-Max-Age", "86400")
+ if r.Method == "OPTIONS" && ServeCORSPreflight(w, r.Header) {
return
}
@@ -949,3 +941,19 @@ func (h *handler) determineCollection(fs arvados.CustomFileSystem, path string)
}
return nil, ""
}
+
+func ServeCORSPreflight(w http.ResponseWriter, header http.Header) bool {
+ method := header.Get("Access-Control-Request-Method")
+ if method == "" {
+ return false
+ }
+ if !browserMethod[method] && !webdavMethod[method] {
+ w.WriteHeader(http.StatusMethodNotAllowed)
+ return true
+ }
+ w.Header().Set("Access-Control-Allow-Headers", corsAllowHeadersHeader)
+ w.Header().Set("Access-Control-Allow-Methods", "COPY, DELETE, GET, LOCK, MKCOL, MOVE, OPTIONS, POST, PROPFIND, PROPPATCH, PUT, RMCOL, UNLOCK")
+ w.Header().Set("Access-Control-Allow-Origin", "*")
+ w.Header().Set("Access-Control-Max-Age", "86400")
+ return true
+}
-----------------------------------------------------------------------
hooks/post-receive
--
More information about the arvados-commits
mailing list