From 3aae495dd2053818e2ea916b520484d0246ed747 Mon Sep 17 00:00:00 2001 From: Tom Clegg Date: Tue, 23 Jul 2024 08:06:43 -0400 Subject: [PATCH] 22005: Add Etag to s3 response header. Arvados-DCO-1.1-Signed-off-by: Tom Clegg --- services/keep-web/s3.go | 3 +++ services/keep-web/s3_test.go | 17 +++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/services/keep-web/s3.go b/services/keep-web/s3.go index 614cf200f7..75dc8f98e5 100644 --- a/services/keep-web/s3.go +++ b/services/keep-web/s3.go @@ -717,6 +717,9 @@ func setFileInfoHeaders(header http.Header, fs arvados.CustomFileSystem, path st switch src := fi.Sys().(type) { case *arvados.Collection: props = src.Properties + if src.PortableDataHash != "" { + header.Set("Etag", fmt.Sprintf(`"%s"`, src.PortableDataHash)) + } case *arvados.Group: props = src.Properties default: diff --git a/services/keep-web/s3_test.go b/services/keep-web/s3_test.go index 7f021a5d3b..f8dc8add94 100644 --- a/services/keep-web/s3_test.go +++ b/services/keep-web/s3_test.go @@ -774,6 +774,7 @@ func (s *IntegrationSuite) TestS3VirtualHostStyleRequests(c *check.C) { body string responseCode int responseRegexp []string + checkEtag bool }{ { url: "https://" + stage.collbucket.Name + ".example.com/", @@ -798,6 +799,7 @@ func (s *IntegrationSuite) TestS3VirtualHostStyleRequests(c *check.C) { method: "GET", responseCode: http.StatusOK, responseRegexp: []string{`⛵\n`}, + checkEtag: true, }, { url: "https://" + stage.projbucket.Name + ".example.com/" + stage.coll.Name + "/beep", @@ -810,6 +812,7 @@ func (s *IntegrationSuite) TestS3VirtualHostStyleRequests(c *check.C) { method: "GET", responseCode: http.StatusOK, responseRegexp: []string{`boop`}, + checkEtag: true, }, { url: "https://" + stage.projbucket.Name + ".example.com/" + stage.coll.Name + "//boop", @@ -827,6 +830,7 @@ func (s *IntegrationSuite) TestS3VirtualHostStyleRequests(c *check.C) { method: "GET", responseCode: http.StatusOK, responseRegexp: []string{`boop`}, + checkEtag: true, }, } { url, err := url.Parse(trial.url) @@ -843,6 +847,9 @@ func (s *IntegrationSuite) TestS3VirtualHostStyleRequests(c *check.C) { for _, re := range trial.responseRegexp { c.Check(string(body), check.Matches, re) } + if trial.checkEtag { + c.Check(resp.Header.Get("Etag"), check.Matches, `"[\da-f]{32}\+\d+"`) + } } } @@ -1482,6 +1489,16 @@ func (s *IntegrationSuite) TestS3cmd(c *check.C) { // started catching the NoSuchKey error code and replacing it // with "Source object '%s' does not exist.". c.Check(string(buf), check.Matches, `(?ms).*(NoSuchKey|Source object.*does not exist).*\n`) + + tmpfile = c.MkDir() + "/foo" + cmd = exec.Command("s3cmd", "--no-ssl", "--host="+s.testServer.URL[7:], "--host-bucket="+s.testServer.URL[7:], "--access_key="+arvadostest.ActiveTokenUUID, "--secret_key="+arvadostest.ActiveToken, "get", "s3://"+arvadostest.FooCollection+"/foo", tmpfile) + buf, err = cmd.CombinedOutput() + c.Logf("%s", buf) + if c.Check(err, check.IsNil) { + checkcontent, err := os.ReadFile(tmpfile) + c.Check(err, check.IsNil) + c.Check(string(checkcontent), check.Equals, "foo") + } } func (s *IntegrationSuite) TestS3BucketInHost(c *check.C) { -- 2.30.2