From 0597c0c143e8a91997206aa5b938fb41b86e6b3f Mon Sep 17 00:00:00 2001 From: Denis Kirillov Date: Wed, 8 Sep 2021 09:15:42 +0300 Subject: [PATCH] [#87] Allow canonical X-Attribute-Neofs-* headers Signed-off-by: Denis Kirillov --- README.md | 3 ++- uploader/filter.go | 22 ++++++++++++---------- uploader/filter_test.go | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 11 deletions(-) create mode 100644 uploader/filter_test.go diff --git a/README.md b/README.md index 57a1504..d65992a 100644 --- a/README.md +++ b/README.md @@ -357,7 +357,8 @@ You can also add some attributes to your file using the following rules: "X-Attribute-" prefix stripped, that is if you add "X-Attribute-Ololo: 100500" header to your request the resulting object will get "Ololo: 100500" attribute - * "X-Attribute-NEOFS-*" headers are special, they're used to set internal + * "X-Attribute-NEOFS-*" headers are special + (`-NEOFS-` part can also be `-neofs-` or`-Neofs-`), they're used to set internal NeoFS attributes starting with `__NEOFS__` prefix, for these attributes all dashes get converted to underscores and all letters are capitalized. For example, you can use "X-Attribute-NEOFS-Expiration-Epoch" header to set diff --git a/uploader/filter.go b/uploader/filter.go index 47c789a..0fb853f 100644 --- a/uploader/filter.go +++ b/uploader/filter.go @@ -8,15 +8,15 @@ import ( ) const ( - userAttributeHeaderPrefix = "X-Attribute-" - neofsAttributeHeaderPrefix = "NEOFS-" - - systemAttributePrefix = "__NEOFS__" + userAttributeHeaderPrefix = "X-Attribute-" + systemAttributePrefix = "__NEOFS__" ) -func systemTranslator(key []byte) []byte { - // replace `NEOFS-` with `__NEOFS__` - key = bytes.Replace(key, []byte(neofsAttributeHeaderPrefix), []byte(systemAttributePrefix), 1) +var neofsAttributeHeaderPrefixes = [...][]byte{[]byte("Neofs-"), []byte("NEOFS-"), []byte("neofs-")} + +func systemTranslator(key, prefix []byte) []byte { + // replace specified prefix with `__NEOFS__` + key = bytes.Replace(key, prefix, []byte(systemAttributePrefix), 1) // replace `-` with `_` key = bytes.ReplaceAll(key, []byte("-"), []byte("_")) @@ -28,7 +28,6 @@ func systemTranslator(key []byte) []byte { func filterHeaders(l *zap.Logger, header *fasthttp.RequestHeader) map[string]string { result := make(map[string]string) prefix := []byte(userAttributeHeaderPrefix) - system := []byte(neofsAttributeHeaderPrefix) header.VisitAll(func(key, val []byte) { // checks that key and val not empty @@ -45,8 +44,11 @@ func filterHeaders(l *zap.Logger, header *fasthttp.RequestHeader) map[string]str key = bytes.TrimPrefix(key, prefix) // checks that it's a system NeoFS header - if bytes.HasPrefix(key, system) { - key = systemTranslator(key) + for _, system := range neofsAttributeHeaderPrefixes { + if bytes.HasPrefix(key, system) { + key = systemTranslator(key, system) + break + } } // checks that attribute key not empty diff --git a/uploader/filter_test.go b/uploader/filter_test.go new file mode 100644 index 0000000..6e04270 --- /dev/null +++ b/uploader/filter_test.go @@ -0,0 +1,32 @@ +package uploader + +import ( + "testing" + + "github.com/nspcc-dev/neofs-sdk-go/pkg/logger" + "github.com/stretchr/testify/require" + "github.com/valyala/fasthttp" +) + +func TestFilter(t *testing.T) { + log, err := logger.New() + require.NoError(t, err) + + req := &fasthttp.RequestHeader{} + req.DisableNormalizing() + 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-MyAttribute", "value") + + expected := map[string]string{ + "__NEOFS__EXPIRATION_EPOCH1": "101", + "MyAttribute": "value", + "__NEOFS__EXPIRATION_EPOCH3": "103", + "__NEOFS__EXPIRATION_EPOCH2": "102", + } + + result := filterHeaders(log, req) + + require.Equal(t, expected, result) +}