From: Tom Clegg Date: Mon, 27 Jun 2022 19:05:58 +0000 (-0400) Subject: 19088: base64-encode non-ascii property values in response headers. X-Git-Tag: 2.5.0~126^2~1 X-Git-Url: https://git.arvados.org/arvados.git/commitdiff_plain/9568d12b9bb5db7f39c9627d0059c72cfc6f2eb1 19088: base64-encode non-ascii property values in response headers. Arvados-DCO-1.1-Signed-off-by: Tom Clegg --- diff --git a/services/keep-web/s3.go b/services/keep-web/s3.go index d92828e066..90b75f8a30 100644 --- a/services/keep-web/s3.go +++ b/services/keep-web/s3.go @@ -14,6 +14,7 @@ import ( "fmt" "hash" "io" + "mime" "net/http" "net/textproto" "net/url" @@ -604,6 +605,14 @@ func (h *handler) serveS3(w http.ResponseWriter, r *http.Request) bool { } func setFileInfoHeaders(header http.Header, fs arvados.CustomFileSystem, path string) error { + maybeEncode := func(s string) string { + for _, c := range s { + if c > '\u007f' { + return mime.BEncoding.Encode("UTF-8", s) + } + } + return s + } path = strings.TrimSuffix(path, "/") var props map[string]interface{} for { @@ -636,9 +645,9 @@ func setFileInfoHeaders(header http.Header, fs arvados.CustomFileSystem, path st } k = "x-amz-meta-" + k if s, ok := v.(string); ok { - header.Set(k, s) + header.Set(k, maybeEncode(s)) } else if j, err := json.Marshal(v); err == nil { - header.Set(k, string(j)) + header.Set(k, maybeEncode(string(j))) } } return nil diff --git a/services/keep-web/s3_test.go b/services/keep-web/s3_test.go index b25ef972dc..a99f3c278f 100644 --- a/services/keep-web/s3_test.go +++ b/services/keep-web/s3_test.go @@ -11,6 +11,7 @@ import ( "crypto/sha256" "fmt" "io/ioutil" + "mime" "net/http" "net/http/httptest" "net/url" @@ -77,9 +78,10 @@ func (s *IntegrationSuite) s3setup(c *check.C) s3stage { "name": "keep-web s3 test collection", "manifest_text": ". d41d8cd98f00b204e9800998ecf8427e+0 0:0:emptyfile\n./emptydir d41d8cd98f00b204e9800998ecf8427e+0 0:0:.\n", "properties": map[string]interface{}{ - "string": "string value", - "array": []string{"element1", "element2"}, - "object": map[string]interface{}{"key": map[string]interface{}{"key2": "value"}}, + "string": "string value", + "array": []string{"element1", "element2"}, + "object": map[string]interface{}{"key": map[string]interface{}{"key2": "value⛵"}}, + "nonascii": "⛵", }, }}) c.Assert(err, check.IsNil) @@ -252,9 +254,10 @@ func (s *IntegrationSuite) TestS3PropertiesAsMetadata(c *check.C) { defer stage.teardown(c) expectCollectionTags := map[string]string{ - "String": "string value", - "Array": `["element1","element2"]`, - "Object": `{"key":{"key2":"value"}}`, + "String": "string value", + "Array": `["element1","element2"]`, + "Object": mime.BEncoding.Encode("UTF-8", `{"key":{"key2":"value⛵"}}`), + "Nonascii": "=?UTF-8?b?4pu1?=", } expectSubprojectTags := map[string]string{ "Subproject_properties_key": "subproject properties value",