forked from TrueCloudLab/frostfs-api-go
291 lines
6.3 KiB
Go
291 lines
6.3 KiB
Go
|
package acl
|
||
|
|
||
|
import (
|
||
|
"strconv"
|
||
|
|
||
|
"github.com/nspcc-dev/neofs-api-go/object"
|
||
|
"github.com/nspcc-dev/neofs-api-go/service"
|
||
|
)
|
||
|
|
||
|
type objectHeaderSource struct {
|
||
|
obj *object.Object
|
||
|
}
|
||
|
|
||
|
type typedHeader struct {
|
||
|
n string
|
||
|
v string
|
||
|
t HeaderType
|
||
|
}
|
||
|
|
||
|
type extendedHeadersWrapper struct {
|
||
|
hdrSrc service.ExtendedHeadersSource
|
||
|
}
|
||
|
|
||
|
type typedExtendedHeader struct {
|
||
|
hdr service.ExtendedHeader
|
||
|
}
|
||
|
|
||
|
const (
|
||
|
_ HeaderType = iota
|
||
|
|
||
|
// HdrTypeRequest is a HeaderType for request header.
|
||
|
HdrTypeRequest
|
||
|
|
||
|
// HdrTypeObjSys is a HeaderType for system headers of object.
|
||
|
HdrTypeObjSys
|
||
|
|
||
|
// HdrTypeObjUsr is a HeaderType for user headers of object.
|
||
|
HdrTypeObjUsr
|
||
|
)
|
||
|
|
||
|
const (
|
||
|
// HdrObjSysNameID is a name of ID field in system header of object.
|
||
|
HdrObjSysNameID = "ID"
|
||
|
|
||
|
// HdrObjSysNameCID is a name of CID field in system header of object.
|
||
|
HdrObjSysNameCID = "CID"
|
||
|
|
||
|
// HdrObjSysNameOwnerID is a name of OwnerID field in system header of object.
|
||
|
HdrObjSysNameOwnerID = "OWNER_ID"
|
||
|
|
||
|
// HdrObjSysNameVersion is a name of Version field in system header of object.
|
||
|
HdrObjSysNameVersion = "VERSION"
|
||
|
|
||
|
// HdrObjSysNamePayloadLength is a name of PayloadLength field in system header of object.
|
||
|
HdrObjSysNamePayloadLength = "PAYLOAD_LENGTH"
|
||
|
|
||
|
// HdrObjSysNameCreatedUnix is a name of CreatedAt.UnitTime field in system header of object.
|
||
|
HdrObjSysNameCreatedUnix = "CREATED_UNIX"
|
||
|
|
||
|
// HdrObjSysNameCreatedEpoch is a name of CreatedAt.Epoch field in system header of object.
|
||
|
HdrObjSysNameCreatedEpoch = "CREATED_EPOCH"
|
||
|
|
||
|
// HdrObjSysLinkPrev is a name of previous link header in extended headers of object.
|
||
|
HdrObjSysLinkPrev = "LINK_PREV"
|
||
|
|
||
|
// HdrObjSysLinkNext is a name of next link header in extended headers of object.
|
||
|
HdrObjSysLinkNext = "LINK_NEXT"
|
||
|
|
||
|
// HdrObjSysLinkChild is a name of child link header in extended headers of object.
|
||
|
HdrObjSysLinkChild = "LINK_CHILD"
|
||
|
|
||
|
// HdrObjSysLinkPar is a name of parent link header in extended headers of object.
|
||
|
HdrObjSysLinkPar = "LINK_PAR"
|
||
|
|
||
|
// HdrObjSysLinkSG is a name of storage group link header in extended headers of object.
|
||
|
HdrObjSysLinkSG = "LINK_SG"
|
||
|
)
|
||
|
|
||
|
func newTypedHeader(name, value string, typ HeaderType) TypedHeader {
|
||
|
return &typedHeader{
|
||
|
n: name,
|
||
|
v: value,
|
||
|
t: typ,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Name is a name field getter.
|
||
|
func (s typedHeader) Name() string {
|
||
|
return s.n
|
||
|
}
|
||
|
|
||
|
// Value is a value field getter.
|
||
|
func (s typedHeader) Value() string {
|
||
|
return s.v
|
||
|
}
|
||
|
|
||
|
// HeaderType is a type field getter.
|
||
|
func (s typedHeader) HeaderType() HeaderType {
|
||
|
return s.t
|
||
|
}
|
||
|
|
||
|
// TypedHeaderSourceFromObject wraps passed object and returns TypedHeaderSource interface.
|
||
|
func TypedHeaderSourceFromObject(obj *object.Object) TypedHeaderSource {
|
||
|
return &objectHeaderSource{
|
||
|
obj: obj,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// HeaderOfType gathers object headers of passed type and returns Header list.
|
||
|
//
|
||
|
// If value of some header can not be calculated (e.g. nil extended header), it does not appear in list.
|
||
|
//
|
||
|
// Always returns true.
|
||
|
func (s objectHeaderSource) HeadersOfType(typ HeaderType) ([]Header, bool) {
|
||
|
if s.obj == nil {
|
||
|
return nil, true
|
||
|
}
|
||
|
|
||
|
var res []Header
|
||
|
|
||
|
switch typ {
|
||
|
case HdrTypeObjUsr:
|
||
|
objHeaders := s.obj.GetHeaders()
|
||
|
|
||
|
res = make([]Header, 0, len(objHeaders)) // 7 system header fields
|
||
|
|
||
|
for _, extHdr := range objHeaders {
|
||
|
if h := newTypedObjectExtendedHeader(extHdr); h != nil {
|
||
|
res = append(res, h)
|
||
|
}
|
||
|
}
|
||
|
case HdrTypeObjSys:
|
||
|
res = make([]Header, 0, 7)
|
||
|
|
||
|
sysHdr := s.obj.GetSystemHeader()
|
||
|
|
||
|
// ID
|
||
|
res = append(res, newTypedHeader(
|
||
|
HdrObjSysNameID,
|
||
|
sysHdr.ID.String(),
|
||
|
HdrTypeObjSys),
|
||
|
)
|
||
|
|
||
|
// CID
|
||
|
res = append(res, newTypedHeader(
|
||
|
HdrObjSysNameCID,
|
||
|
sysHdr.CID.String(),
|
||
|
HdrTypeObjSys),
|
||
|
)
|
||
|
|
||
|
// OwnerID
|
||
|
res = append(res, newTypedHeader(
|
||
|
HdrObjSysNameOwnerID,
|
||
|
sysHdr.OwnerID.String(),
|
||
|
HdrTypeObjSys),
|
||
|
)
|
||
|
|
||
|
// Version
|
||
|
res = append(res, newTypedHeader(
|
||
|
HdrObjSysNameVersion,
|
||
|
strconv.FormatUint(sysHdr.GetVersion(), 10),
|
||
|
HdrTypeObjSys),
|
||
|
)
|
||
|
|
||
|
// PayloadLength
|
||
|
res = append(res, newTypedHeader(
|
||
|
HdrObjSysNamePayloadLength,
|
||
|
strconv.FormatUint(sysHdr.GetPayloadLength(), 10),
|
||
|
HdrTypeObjSys),
|
||
|
)
|
||
|
|
||
|
created := sysHdr.GetCreatedAt()
|
||
|
|
||
|
// CreatedAt.UnitTime
|
||
|
res = append(res, newTypedHeader(
|
||
|
HdrObjSysNameCreatedUnix,
|
||
|
strconv.FormatUint(uint64(created.GetUnixTime()), 10),
|
||
|
HdrTypeObjSys),
|
||
|
)
|
||
|
|
||
|
// CreatedAt.Epoch
|
||
|
res = append(res, newTypedHeader(
|
||
|
HdrObjSysNameCreatedEpoch,
|
||
|
strconv.FormatUint(created.GetEpoch(), 10),
|
||
|
HdrTypeObjSys),
|
||
|
)
|
||
|
}
|
||
|
|
||
|
return res, true
|
||
|
}
|
||
|
|
||
|
func newTypedObjectExtendedHeader(h object.Header) TypedHeader {
|
||
|
val := h.GetValue()
|
||
|
if val == nil {
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
res := new(typedHeader)
|
||
|
res.t = HdrTypeObjSys
|
||
|
|
||
|
switch hdr := val.(type) {
|
||
|
case *object.Header_UserHeader:
|
||
|
if hdr.UserHeader == nil {
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
res.t = HdrTypeObjUsr
|
||
|
res.n = hdr.UserHeader.GetKey()
|
||
|
res.v = hdr.UserHeader.GetValue()
|
||
|
case *object.Header_Link:
|
||
|
if hdr.Link == nil {
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
switch hdr.Link.GetType() {
|
||
|
case object.Link_Previous:
|
||
|
res.n = HdrObjSysLinkPrev
|
||
|
case object.Link_Next:
|
||
|
res.n = HdrObjSysLinkNext
|
||
|
case object.Link_Child:
|
||
|
res.n = HdrObjSysLinkChild
|
||
|
case object.Link_Parent:
|
||
|
res.n = HdrObjSysLinkPar
|
||
|
case object.Link_StorageGroup:
|
||
|
res.n = HdrObjSysLinkSG
|
||
|
default:
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
res.v = hdr.Link.ID.String()
|
||
|
default:
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
return res
|
||
|
}
|
||
|
|
||
|
// TypedHeaderSourceFromExtendedHeaders wraps passed ExtendedHeadersSource and returns TypedHeaderSource interface.
|
||
|
func TypedHeaderSourceFromExtendedHeaders(hdrSrc service.ExtendedHeadersSource) TypedHeaderSource {
|
||
|
return &extendedHeadersWrapper{
|
||
|
hdrSrc: hdrSrc,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Name returns the result of Key method.
|
||
|
func (s typedExtendedHeader) Name() string {
|
||
|
return s.hdr.Key()
|
||
|
}
|
||
|
|
||
|
// Value returns the result of Value method.
|
||
|
func (s typedExtendedHeader) Value() string {
|
||
|
return s.hdr.Value()
|
||
|
}
|
||
|
|
||
|
// HeaderType always returns HdrTypeRequest.
|
||
|
func (s typedExtendedHeader) HeaderType() HeaderType {
|
||
|
return HdrTypeRequest
|
||
|
}
|
||
|
|
||
|
// TypedHeaders gathers extended request headers and returns TypedHeader list.
|
||
|
//
|
||
|
// Nil headers are ignored.
|
||
|
//
|
||
|
// Always returns true.
|
||
|
func (s extendedHeadersWrapper) HeadersOfType(typ HeaderType) ([]Header, bool) {
|
||
|
if s.hdrSrc == nil {
|
||
|
return nil, true
|
||
|
}
|
||
|
|
||
|
var res []Header
|
||
|
|
||
|
switch typ {
|
||
|
case HdrTypeRequest:
|
||
|
hs := s.hdrSrc.ExtendedHeaders()
|
||
|
|
||
|
res = make([]Header, 0, len(hs))
|
||
|
|
||
|
for i := range hs {
|
||
|
if hs[i] == nil {
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
res = append(res, &typedExtendedHeader{
|
||
|
hdr: hs[i],
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return res, true
|
||
|
}
|