From f2afcd9ea4587129923cb67a92555baa8d3e6c71 Mon Sep 17 00:00:00 2001 From: Tatiana Nesterenko Date: Fri, 2 Feb 2024 12:55:06 +0000 Subject: [PATCH] api: fix `upload` to handle attributes `FilePath`, `FileName` When we receive headers, they are automatically formatted from any case to only the first letter being uppercase. For example, `FilePath` transforms into `Filepath`. However, NEOFS is case-sensitive for these attributes, which is why we intentionally change them to CamelCase style. We hope this is a temporary workaround and will be removed asap. Connected to https://github.com/nspcc-dev/neofs-http-gw/issues/255. Signed-off-by: Tatiana Nesterenko --- handlers/objects.go | 3 +++ handlers/util.go | 15 +++++++++++++++ handlers/util_test.go | 14 +++++++++++--- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/handlers/objects.go b/handlers/objects.go index 72c50ad..133c861 100644 --- a/handlers/objects.go +++ b/handlers/objects.go @@ -42,6 +42,9 @@ const ( attributeFilePath = "FilePath" sizeToDetectType = 512 userAttributeHeaderPrefix = "X-Attribute-" + + attributeFilepathHTTP = "Filepath" + attributeFilenameHTTP = "Filename" ) type readCloser struct { diff --git a/handlers/util.go b/handlers/util.go index e5f6757..e45d992 100644 --- a/handlers/util.go +++ b/handlers/util.go @@ -291,6 +291,7 @@ func filterHeaders(l *zap.Logger, header http.Header) (map[string]string, error) continue } + clearKey = formatSpecialAttribute(clearKey) result[clearKey] = value l.Debug("add attribute to result object", @@ -299,3 +300,17 @@ func filterHeaders(l *zap.Logger, header http.Header) (map[string]string, error) } return result, nil } + +// formatSpecialAttribute checks if a key-string is one of the special NEOFS +// attributes and returns the string in the correct case. +// For example: "Filepath" -> "FilePath". +func formatSpecialAttribute(s string) string { + switch s { + case attributeFilepathHTTP: + return attributeFilePath + case attributeFilenameHTTP: + return object.AttributeFileName + default: + return s + } +} diff --git a/handlers/util_test.go b/handlers/util_test.go index acd9560..1b693f8 100644 --- a/handlers/util_test.go +++ b/handlers/util_test.go @@ -191,16 +191,24 @@ func TestFilter(t *testing.T) { req.Set("X-Attribute-Neofs-Expiration-Epoch1", "101") req.Set("X-Attribute-NEOFS-Expiration-Epoch2", "102") req.Set("X-Attribute-neofs-Expiration-Epoch3", "103") + req.Set("X-Attribute-FileName", "FileName") // This one will be overridden. + req.Set("X-Attribute-filename", "filename") + req.Set("X-Attribute-fIlePaTh", "fIlePaTh/") // This one will be overridden. + req.Set("X-Attribute-Filepath", "Filepath/") + req.Set("X-Attribute-FilePath1", "FilePath/1") req.Set("X-Attribute-My-Attribute", "value") req.Set("X-Attribute-MyAttribute", "value2") - req.Set("X-Attribute-Empty-Value", "") - req.Set("X-Attribute-", "prefix only") - req.Set("No-Prefix", "value") + req.Set("X-Attribute-Empty-Value", "") // This one will be skipped. + req.Set("X-Attribute-", "prefix only") // This one will be skipped. + req.Set("No-Prefix", "value") // This one will be skipped. expected := map[string]string{ "__NEOFS__EXPIRATION_EPOCH1": "101", "__NEOFS__EXPIRATION_EPOCH2": "102", "__NEOFS__EXPIRATION_EPOCH3": "103", + "FileName": "filename", + "FilePath": "Filepath/", + "Filepath1": "FilePath/1", "My-Attribute": "value", "Myattribute": "value2", }