[#87] Allow canonical X-Attribute-Neofs-* headers

Signed-off-by: Denis Kirillov <denis@nspcc.ru>
This commit is contained in:
Denis Kirillov 2021-09-08 09:15:42 +03:00 committed by Alex Vanin
parent d2b0532929
commit 0597c0c143
3 changed files with 46 additions and 11 deletions

View file

@ -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

View file

@ -9,14 +9,14 @@ import (
const (
userAttributeHeaderPrefix = "X-Attribute-"
neofsAttributeHeaderPrefix = "NEOFS-"
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
for _, system := range neofsAttributeHeaderPrefixes {
if bytes.HasPrefix(key, system) {
key = systemTranslator(key)
key = systemTranslator(key, system)
break
}
}
// checks that attribute key not empty

32
uploader/filter_test.go Normal file
View file

@ -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)
}