package util import ( "fmt" "strconv" "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/session" "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer" sessionsdk "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/session" ) // maxLocalTTL is maximum TTL for an operation to be considered local. const maxLocalTTL = 1 type CommonPrm struct { local bool netmapEpoch, netmapLookupDepth uint64 token *sessionsdk.Object bearer *bearer.Token ttl uint32 xhdrs []string } // TTL returns TTL for new requests. func (p *CommonPrm) TTL() uint32 { if p != nil { return p.ttl } return 1 } // XHeaders returns X-Headers for new requests. func (p *CommonPrm) XHeaders() []string { if p != nil { return p.xhdrs } return nil } func (p *CommonPrm) WithLocalOnly(v bool) *CommonPrm { if p != nil { p.local = v } return p } func (p *CommonPrm) LocalOnly() bool { if p != nil { return p.local } return false } func (p *CommonPrm) SessionToken() *sessionsdk.Object { if p != nil { return p.token } return nil } func (p *CommonPrm) BearerToken() *bearer.Token { if p != nil { return p.bearer } return nil } func (p *CommonPrm) NetmapEpoch() uint64 { if p != nil { return p.netmapEpoch } return 0 } func (p *CommonPrm) NetmapLookupDepth() uint64 { if p != nil { return p.netmapLookupDepth } return 0 } func (p *CommonPrm) SetNetmapLookupDepth(v uint64) { if p != nil { p.netmapLookupDepth = v } } // ForgetTokens forgets all the tokens read from the request's // meta information before. func (p *CommonPrm) ForgetTokens() func() { if p != nil { tk := p.token br := p.bearer p.token = nil p.bearer = nil return func() { p.token = tk p.bearer = br } } return func() {} } func CommonPrmFromV2(req interface { GetMetaHeader() *session.RequestMetaHeader }, ) (*CommonPrm, error) { meta := req.GetMetaHeader() ttl := meta.GetTTL() // unwrap meta header to get original request meta information for meta.GetOrigin() != nil { meta = meta.GetOrigin() } var tokenSession *sessionsdk.Object var err error if tokenSessionV2 := meta.GetSessionToken(); tokenSessionV2 != nil { tokenSession = new(sessionsdk.Object) err = tokenSession.ReadFromV2(*tokenSessionV2) if err != nil { return nil, fmt.Errorf("invalid session token: %w", err) } } xHdrs := meta.GetXHeaders() prm := &CommonPrm{ local: ttl <= maxLocalTTL, token: tokenSession, ttl: ttl - 1, // decrease TTL for new requests xhdrs: make([]string, 0, 2*len(xHdrs)), } if tok := meta.GetBearerToken(); tok != nil { prm.bearer = new(bearer.Token) err = prm.bearer.ReadFromV2(*tok) if err != nil { return nil, fmt.Errorf("invalid bearer token: %w", err) } } for i := range xHdrs { switch key := xHdrs[i].GetKey(); key { case session.XHeaderNetmapEpoch: var err error prm.netmapEpoch, err = strconv.ParseUint(xHdrs[i].GetValue(), 10, 64) if err != nil { return nil, err } case session.XHeaderNetmapLookupDepth: var err error prm.netmapLookupDepth, err = strconv.ParseUint(xHdrs[i].GetValue(), 10, 64) if err != nil { return nil, err } default: prm.xhdrs = append(prm.xhdrs, key, xHdrs[i].GetValue()) } } return prm, nil }