forked from TrueCloudLab/frostfs-http-gw
[#108] Add different expiration header formats
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
This commit is contained in:
parent
06be798111
commit
cd0633cda0
5 changed files with 279 additions and 0 deletions
|
@ -2,7 +2,11 @@ package uploader
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/nspcc-dev/neofs-api-go/v2/object"
|
||||
"github.com/valyala/fasthttp"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
@ -10,6 +14,10 @@ import (
|
|||
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-")}
|
||||
|
@ -68,3 +76,60 @@ func filterHeaders(l *zap.Logger, header *fasthttp.RequestHeader) map[string]str
|
|||
|
||||
return result
|
||||
}
|
||||
|
||||
func prepareExpirationHeader(headers map[string]string, epochDurations *epochDurations) error {
|
||||
expirationInEpoch := headers[object.SysAttributeExpEpoch]
|
||||
|
||||
if timeRFC3339, ok := headers[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)
|
||||
}
|
||||
|
||||
now := time.Now().UTC()
|
||||
if expTime.Before(now) {
|
||||
return fmt.Errorf("value %s of header %s must be in the future", timeRFC3339, expirationRFC3339Attr)
|
||||
}
|
||||
updateExpirationHeader(headers, epochDurations, expTime.Sub(now))
|
||||
delete(headers, expirationRFC3339Attr)
|
||||
}
|
||||
|
||||
if timestamp, ok := headers[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)
|
||||
}
|
||||
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)
|
||||
}
|
||||
updateExpirationHeader(headers, epochDurations, expTime.Sub(now))
|
||||
delete(headers, expirationTimestampAttr)
|
||||
}
|
||||
|
||||
if duration, ok := headers[expirationDurationAttr]; ok {
|
||||
expDuration, err := time.ParseDuration(duration)
|
||||
if err != nil {
|
||||
return fmt.Errorf("couldn't parse value %s of header %s", duration, expirationDurationAttr)
|
||||
}
|
||||
if expDuration <= 0 {
|
||||
return fmt.Errorf("value %s of header %s must be positive", expDuration, expirationDurationAttr)
|
||||
}
|
||||
updateExpirationHeader(headers, epochDurations, expDuration)
|
||||
delete(headers, expirationDurationAttr)
|
||||
}
|
||||
|
||||
if expirationInEpoch != "" {
|
||||
headers[object.SysAttributeExpEpoch] = expirationInEpoch
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func updateExpirationHeader(headers map[string]string, durations *epochDurations, expDuration time.Duration) {
|
||||
epochDuration := durations.msPerBlock * int64(durations.blockPerEpoch)
|
||||
numEpoch := expDuration.Milliseconds() / epochDuration
|
||||
headers[object.SysAttributeExpEpoch] = strconv.FormatInt(int64(durations.currentEpoch)+numEpoch, 10)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue