From dbbc9e05cfb01ee66dd5ad08466dcaa1eadf3f99 Mon Sep 17 00:00:00 2001 From: Angira Kekteeva Date: Tue, 30 Nov 2021 10:22:05 +0300 Subject: [PATCH] [#111] Move attributes to a separate file Signed-off-by: Angira Kekteeva --- downloader/download.go | 3 ++- downloader/head.go | 3 ++- uploader/filter.go | 38 +++++++++++++++----------------------- uploader/filter_test.go | 38 +++++++++++++++++++------------------- uploader/upload.go | 7 ++++--- utils/attributes.go | 10 ++++++++++ 6 files changed, 52 insertions(+), 47 deletions(-) create mode 100644 utils/attributes.go diff --git a/downloader/download.go b/downloader/download.go index 13027a3..d37ed32 100644 --- a/downloader/download.go +++ b/downloader/download.go @@ -14,6 +14,7 @@ import ( "github.com/nspcc-dev/neofs-http-gw/response" "github.com/nspcc-dev/neofs-http-gw/tokens" + "github.com/nspcc-dev/neofs-http-gw/utils" "github.com/nspcc-dev/neofs-sdk-go/client" cid "github.com/nspcc-dev/neofs-sdk-go/container/id" "github.com/nspcc-dev/neofs-sdk-go/object" @@ -152,7 +153,7 @@ func (r request) receiveFile(clnt pool.Object, objectAddress *object.Address) { if !isValidToken(key) || !isValidValue(val) { continue } - r.Response.Header.Set("X-Attribute-"+key, val) + r.Response.Header.Set(utils.UserAttributeHeaderPrefix+key, val) switch key { case object.AttributeFileName: filename = val diff --git a/downloader/head.go b/downloader/head.go index 67cc04e..8e113e6 100644 --- a/downloader/head.go +++ b/downloader/head.go @@ -7,6 +7,7 @@ import ( "github.com/nspcc-dev/neofs-http-gw/response" "github.com/nspcc-dev/neofs-http-gw/tokens" + "github.com/nspcc-dev/neofs-http-gw/utils" "github.com/nspcc-dev/neofs-sdk-go/client" "github.com/nspcc-dev/neofs-sdk-go/object" "github.com/nspcc-dev/neofs-sdk-go/pool" @@ -40,7 +41,7 @@ func (r request) headObject(clnt pool.Object, objectAddress *object.Address) { if !isValidToken(key) || !isValidValue(val) { continue } - r.Response.Header.Set("X-Attribute-"+key, val) + r.Response.Header.Set(utils.UserAttributeHeaderPrefix+key, val) switch key { case object.AttributeTimestamp: value, err := strconv.ParseInt(val, 10, 64) diff --git a/uploader/filter.go b/uploader/filter.go index 9e4eca5..98046c4 100644 --- a/uploader/filter.go +++ b/uploader/filter.go @@ -7,24 +7,16 @@ import ( "time" "github.com/nspcc-dev/neofs-api-go/v2/object" + "github.com/nspcc-dev/neofs-http-gw/utils" "github.com/valyala/fasthttp" "go.uber.org/zap" ) -const ( - userAttributeHeaderPrefix = "X-Attribute-" - systemAttributePrefix = "__NEOFS__" - - expirationDurationAttr = systemAttributePrefix + "EXPIRATION_DURATION" - expirationTimestampAttr = systemAttributePrefix + "EXPIRATION_TIMESTAMP" - expirationRFC3339Attr = systemAttributePrefix + "EXPIRATION_RFC3339" -) - 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) + key = bytes.Replace(key, prefix, []byte(utils.SystemAttributePrefix), 1) // replace `-` with `_` key = bytes.ReplaceAll(key, []byte("-"), []byte("_")) @@ -35,7 +27,7 @@ func systemTranslator(key, prefix []byte) []byte { func filterHeaders(l *zap.Logger, header *fasthttp.RequestHeader) map[string]string { result := make(map[string]string) - prefix := []byte(userAttributeHeaderPrefix) + prefix := []byte(utils.UserAttributeHeaderPrefix) header.VisitAll(func(key, val []byte) { // checks that key and val not empty @@ -80,45 +72,45 @@ func filterHeaders(l *zap.Logger, header *fasthttp.RequestHeader) map[string]str func prepareExpirationHeader(headers map[string]string, epochDurations *epochDurations) error { expirationInEpoch := headers[object.SysAttributeExpEpoch] - if timeRFC3339, ok := headers[expirationRFC3339Attr]; ok { + if timeRFC3339, ok := headers[utils.ExpirationRFC3339Attr]; ok { expTime, err := time.Parse(time.RFC3339, timeRFC3339) if err != nil { - return fmt.Errorf("couldn't parse value %s of header %s", timeRFC3339, expirationRFC3339Attr) + return fmt.Errorf("couldn't parse value %s of header %s", timeRFC3339, utils.ExpirationRFC3339Attr) } now := time.Now().UTC() if expTime.Before(now) { - return fmt.Errorf("value %s of header %s must be in the future", timeRFC3339, expirationRFC3339Attr) + return fmt.Errorf("value %s of header %s must be in the future", timeRFC3339, utils.ExpirationRFC3339Attr) } updateExpirationHeader(headers, epochDurations, expTime.Sub(now)) - delete(headers, expirationRFC3339Attr) + delete(headers, utils.ExpirationRFC3339Attr) } - if timestamp, ok := headers[expirationTimestampAttr]; ok { + if timestamp, ok := headers[utils.ExpirationTimestampAttr]; ok { value, err := strconv.ParseInt(timestamp, 10, 64) if err != nil { - return fmt.Errorf("couldn't parse value %s of header %s", timestamp, expirationTimestampAttr) + return fmt.Errorf("couldn't parse value %s of header %s", timestamp, utils.ExpirationTimestampAttr) } expTime := time.Unix(value, 0) now := time.Now() if expTime.Before(now) { - return fmt.Errorf("value %s of header %s must be in the future", timestamp, expirationTimestampAttr) + return fmt.Errorf("value %s of header %s must be in the future", timestamp, utils.ExpirationTimestampAttr) } updateExpirationHeader(headers, epochDurations, expTime.Sub(now)) - delete(headers, expirationTimestampAttr) + delete(headers, utils.ExpirationTimestampAttr) } - if duration, ok := headers[expirationDurationAttr]; ok { + if duration, ok := headers[utils.ExpirationDurationAttr]; ok { expDuration, err := time.ParseDuration(duration) if err != nil { - return fmt.Errorf("couldn't parse value %s of header %s", duration, expirationDurationAttr) + return fmt.Errorf("couldn't parse value %s of header %s", duration, utils.ExpirationDurationAttr) } if expDuration <= 0 { - return fmt.Errorf("value %s of header %s must be positive", expDuration, expirationDurationAttr) + return fmt.Errorf("value %s of header %s must be positive", expDuration, utils.ExpirationDurationAttr) } updateExpirationHeader(headers, epochDurations, expDuration) - delete(headers, expirationDurationAttr) + delete(headers, utils.ExpirationDurationAttr) } if expirationInEpoch != "" { diff --git a/uploader/filter_test.go b/uploader/filter_test.go index a59bcf5..4dc8e0c 100644 --- a/uploader/filter_test.go +++ b/uploader/filter_test.go @@ -6,7 +6,7 @@ import ( "time" "github.com/nspcc-dev/neofs-api-go/v2/object" - + "github.com/nspcc-dev/neofs-http-gw/utils" "github.com/nspcc-dev/neofs-sdk-go/logger" "github.com/stretchr/testify/require" "github.com/valyala/fasthttp" @@ -71,8 +71,8 @@ func TestPrepareExpirationHeader(t *testing.T) { { name: "valid epoch, valid duration", headers: map[string]string{ - object.SysAttributeExpEpoch: epoch, - expirationDurationAttr: duration, + object.SysAttributeExpEpoch: epoch, + utils.ExpirationDurationAttr: duration, }, durations: defaultDurations, expected: map[string]string{object.SysAttributeExpEpoch: epoch}, @@ -81,7 +81,7 @@ func TestPrepareExpirationHeader(t *testing.T) { name: "valid epoch, valid rfc3339", headers: map[string]string{ object.SysAttributeExpEpoch: epoch, - expirationRFC3339Attr: tomorrow.Format(time.RFC3339), + utils.ExpirationRFC3339Attr: tomorrow.Format(time.RFC3339), }, durations: defaultDurations, expected: map[string]string{object.SysAttributeExpEpoch: epoch}, @@ -89,8 +89,8 @@ func TestPrepareExpirationHeader(t *testing.T) { { name: "valid epoch, valid timestamp sec", headers: map[string]string{ - object.SysAttributeExpEpoch: epoch, - expirationTimestampAttr: timestampSec, + object.SysAttributeExpEpoch: epoch, + utils.ExpirationTimestampAttr: timestampSec, }, durations: defaultDurations, expected: map[string]string{object.SysAttributeExpEpoch: epoch}, @@ -98,8 +98,8 @@ func TestPrepareExpirationHeader(t *testing.T) { { name: "valid epoch, valid timestamp milli", headers: map[string]string{ - object.SysAttributeExpEpoch: epoch, - expirationTimestampAttr: timestampMilli, + object.SysAttributeExpEpoch: epoch, + utils.ExpirationTimestampAttr: timestampMilli, }, durations: defaultDurations, expected: map[string]string{object.SysAttributeExpEpoch: epoch}, @@ -107,58 +107,58 @@ func TestPrepareExpirationHeader(t *testing.T) { { name: "valid epoch, valid timestamp nano", headers: map[string]string{ - object.SysAttributeExpEpoch: epoch, - expirationTimestampAttr: timestampNano, + object.SysAttributeExpEpoch: epoch, + utils.ExpirationTimestampAttr: timestampNano, }, durations: defaultDurations, expected: map[string]string{object.SysAttributeExpEpoch: epoch}, }, { name: "valid timestamp sec", - headers: map[string]string{expirationTimestampAttr: timestampSec}, + headers: map[string]string{utils.ExpirationTimestampAttr: timestampSec}, durations: defaultDurations, expected: map[string]string{object.SysAttributeExpEpoch: defaultExpEpoch}, }, { name: "valid duration", - headers: map[string]string{expirationDurationAttr: duration}, + headers: map[string]string{utils.ExpirationDurationAttr: duration}, durations: defaultDurations, expected: map[string]string{object.SysAttributeExpEpoch: defaultExpEpoch}, }, { name: "valid rfc3339", - headers: map[string]string{expirationRFC3339Attr: tomorrow.Format(time.RFC3339)}, + headers: map[string]string{utils.ExpirationRFC3339Attr: tomorrow.Format(time.RFC3339)}, durations: defaultDurations, expected: map[string]string{object.SysAttributeExpEpoch: defaultExpEpoch}, }, { name: "invalid timestamp sec", - headers: map[string]string{expirationTimestampAttr: "abc"}, + headers: map[string]string{utils.ExpirationTimestampAttr: "abc"}, err: true, }, { name: "invalid timestamp sec zero", - headers: map[string]string{expirationTimestampAttr: "0"}, + headers: map[string]string{utils.ExpirationTimestampAttr: "0"}, err: true, }, { name: "invalid duration", - headers: map[string]string{expirationDurationAttr: "1d"}, + headers: map[string]string{utils.ExpirationDurationAttr: "1d"}, err: true, }, { name: "invalid duration negative", - headers: map[string]string{expirationDurationAttr: "-5h"}, + headers: map[string]string{utils.ExpirationDurationAttr: "-5h"}, err: true, }, { name: "invalid rfc3339", - headers: map[string]string{expirationRFC3339Attr: "abc"}, + headers: map[string]string{utils.ExpirationRFC3339Attr: "abc"}, err: true, }, { name: "invalid rfc3339 zero", - headers: map[string]string{expirationRFC3339Attr: time.RFC3339}, + headers: map[string]string{utils.ExpirationRFC3339Attr: time.RFC3339}, err: true, }, } { diff --git a/uploader/upload.go b/uploader/upload.go index 4b81d83..c2d06c4 100644 --- a/uploader/upload.go +++ b/uploader/upload.go @@ -11,6 +11,7 @@ import ( "github.com/nspcc-dev/neofs-http-gw/response" "github.com/nspcc-dev/neofs-http-gw/tokens" + "github.com/nspcc-dev/neofs-http-gw/utils" "github.com/nspcc-dev/neofs-sdk-go/client" cid "github.com/nspcc-dev/neofs-sdk-go/container/id" "github.com/nspcc-dev/neofs-sdk-go/netmap" @@ -220,8 +221,8 @@ func getEpochDurations(ctx context.Context, p pool.Pool) (*epochDurations, error } func needParseExpiration(headers map[string]string) bool { - _, ok1 := headers[expirationDurationAttr] - _, ok2 := headers[expirationRFC3339Attr] - _, ok3 := headers[expirationTimestampAttr] + _, ok1 := headers[utils.ExpirationDurationAttr] + _, ok2 := headers[utils.ExpirationRFC3339Attr] + _, ok3 := headers[utils.ExpirationTimestampAttr] return ok1 || ok2 || ok3 } diff --git a/utils/attributes.go b/utils/attributes.go new file mode 100644 index 0000000..814d7b1 --- /dev/null +++ b/utils/attributes.go @@ -0,0 +1,10 @@ +package utils + +const ( + UserAttributeHeaderPrefix = "X-Attribute-" + SystemAttributePrefix = "__NEOFS__" + + ExpirationDurationAttr = SystemAttributePrefix + "EXPIRATION_DURATION" + ExpirationTimestampAttr = SystemAttributePrefix + "EXPIRATION_TIMESTAMP" + ExpirationRFC3339Attr = SystemAttributePrefix + "EXPIRATION_RFC3339" +)