[#160] client: Support request X-Headers

Add `WithXHeaders` method to all `Client` operations.

Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
Leonard Lyubich 2022-03-03 14:04:53 +03:00 committed by LeL
parent 6f1c21da31
commit 529c4d1c2a
11 changed files with 142 additions and 43 deletions

View file

@ -12,6 +12,8 @@ import (
// PrmBalanceGet groups parameters of BalanceGet operation. // PrmBalanceGet groups parameters of BalanceGet operation.
type PrmBalanceGet struct { type PrmBalanceGet struct {
prmCommonMeta
ownerSet bool ownerSet bool
ownerID owner.ID ownerID owner.ID
} }
@ -82,6 +84,7 @@ func (c *Client) BalanceGet(ctx context.Context, prm PrmBalanceGet) (*ResBalance
) )
c.initCallContext(&cc) c.initCallContext(&cc)
cc.meta = prm.prmCommonMeta
cc.req = &req cc.req = &req
cc.statusRes = &res cc.statusRes = &res
cc.call = func() (responseV2, error) { cc.call = func() (responseV2, error) {

View file

@ -50,6 +50,40 @@ func (x prmSession) writeToMetaHeader(meta *v2session.RequestMetaHeader) {
} }
} }
// groups meta parameters shared between all Client operations.
type prmCommonMeta struct {
// NeoFS request X-Headers
xHeaders []string
}
// WithXHeaders specifies list of extended headers (string key-value pairs)
// to be attached to the request. Must have an even length.
//
// Slice must not be mutated until the operation completes.
func (x *prmCommonMeta) WithXHeaders(hs ...string) {
if len(hs)%2 != 0 {
panic("slice of X-Headers with odd length")
}
x.xHeaders = hs
}
func (x prmCommonMeta) writeToMetaHeader(h *v2session.RequestMetaHeader) {
if len(x.xHeaders) > 0 {
hs := make([]*v2session.XHeader, 0, len(x.xHeaders)/2)
for i := 0; i < len(x.xHeaders); i += 2 {
var h v2session.XHeader
h.SetKey(x.xHeaders[i])
h.SetValue(x.xHeaders[i+1])
hs = append(hs, &h)
}
h.SetXHeaders(hs)
}
}
// panic messages. // panic messages.
const ( const (
panicMsgMissingContext = "missing context" panicMsgMissingContext = "missing context"
@ -82,6 +116,9 @@ type contextCall struct {
// NeoFS network magic // NeoFS network magic
netMagic uint64 netMagic uint64
// Meta parameters
meta prmCommonMeta
// ================================================== // ==================================================
// custom call parameters // custom call parameters
@ -128,6 +165,8 @@ func (x contextCall) prepareRequest() {
} }
meta.SetNetworkMagic(x.netMagic) meta.SetNetworkMagic(x.netMagic)
x.meta.writeToMetaHeader(meta)
} }
// prepares, signs and writes the request. Result means success. // prepares, signs and writes the request. Result means success.

View file

@ -19,6 +19,8 @@ import (
// PrmContainerPut groups parameters of ContainerPut operation. // PrmContainerPut groups parameters of ContainerPut operation.
type PrmContainerPut struct { type PrmContainerPut struct {
prmCommonMeta
cnrSet bool cnrSet bool
cnr container.Container cnr container.Container
} }
@ -96,6 +98,7 @@ func (c *Client) ContainerPut(ctx context.Context, prm PrmContainerPut) (*ResCon
// form meta header // form meta header
var meta v2session.RequestMetaHeader var meta v2session.RequestMetaHeader
meta.SetSessionToken(prm.cnr.SessionToken().ToV2()) meta.SetSessionToken(prm.cnr.SessionToken().ToV2())
prm.prmCommonMeta.writeToMetaHeader(&meta)
// form request // form request
var req v2container.PutRequest var req v2container.PutRequest
@ -131,6 +134,8 @@ func (c *Client) ContainerPut(ctx context.Context, prm PrmContainerPut) (*ResCon
// PrmContainerGet groups parameters of ContainerGet operation. // PrmContainerGet groups parameters of ContainerGet operation.
type PrmContainerGet struct { type PrmContainerGet struct {
prmCommonMeta
idSet bool idSet bool
id cid.ID id cid.ID
} }
@ -199,6 +204,7 @@ func (c *Client) ContainerGet(ctx context.Context, prm PrmContainerGet) (*ResCon
) )
c.initCallContext(&cc) c.initCallContext(&cc)
cc.meta = prm.prmCommonMeta
cc.req = &req cc.req = &req
cc.statusRes = &res cc.statusRes = &res
cc.call = func() (responseV2, error) { cc.call = func() (responseV2, error) {
@ -232,6 +238,8 @@ func (c *Client) ContainerGet(ctx context.Context, prm PrmContainerGet) (*ResCon
// PrmContainerList groups parameters of ContainerList operation. // PrmContainerList groups parameters of ContainerList operation.
type PrmContainerList struct { type PrmContainerList struct {
prmCommonMeta
ownerSet bool ownerSet bool
ownerID owner.ID ownerID owner.ID
} }
@ -302,6 +310,7 @@ func (c *Client) ContainerList(ctx context.Context, prm PrmContainerList) (*ResC
) )
c.initCallContext(&cc) c.initCallContext(&cc)
cc.meta = prm.prmCommonMeta
cc.req = &req cc.req = &req
cc.statusRes = &res cc.statusRes = &res
cc.call = func() (responseV2, error) { cc.call = func() (responseV2, error) {
@ -329,6 +338,7 @@ func (c *Client) ContainerList(ctx context.Context, prm PrmContainerList) (*ResC
// PrmContainerDelete groups parameters of ContainerDelete operation. // PrmContainerDelete groups parameters of ContainerDelete operation.
type PrmContainerDelete struct { type PrmContainerDelete struct {
prmCommonMeta
prmSession prmSession
idSet bool idSet bool
@ -408,6 +418,7 @@ func (c *Client) ContainerDelete(ctx context.Context, prm PrmContainerDelete) (*
var meta v2session.RequestMetaHeader var meta v2session.RequestMetaHeader
prm.prmSession.writeToMetaHeader(&meta) prm.prmSession.writeToMetaHeader(&meta)
prm.prmCommonMeta.writeToMetaHeader(&meta)
// form request // form request
var req v2container.DeleteRequest var req v2container.DeleteRequest
@ -439,6 +450,8 @@ func (c *Client) ContainerDelete(ctx context.Context, prm PrmContainerDelete) (*
// PrmContainerEACL groups parameters of ContainerEACL operation. // PrmContainerEACL groups parameters of ContainerEACL operation.
type PrmContainerEACL struct { type PrmContainerEACL struct {
prmCommonMeta
idSet bool idSet bool
id cid.ID id cid.ID
} }
@ -508,6 +521,7 @@ func (c *Client) ContainerEACL(ctx context.Context, prm PrmContainerEACL) (*ResC
) )
c.initCallContext(&cc) c.initCallContext(&cc)
cc.meta = prm.prmCommonMeta
cc.req = &req cc.req = &req
cc.statusRes = &res cc.statusRes = &res
cc.call = func() (responseV2, error) { cc.call = func() (responseV2, error) {
@ -541,6 +555,8 @@ func (c *Client) ContainerEACL(ctx context.Context, prm PrmContainerEACL) (*ResC
// PrmContainerSetEACL groups parameters of ContainerSetEACL operation. // PrmContainerSetEACL groups parameters of ContainerSetEACL operation.
type PrmContainerSetEACL struct { type PrmContainerSetEACL struct {
prmCommonMeta
tableSet bool tableSet bool
table eacl.Table table eacl.Table
} }
@ -601,6 +617,7 @@ func (c *Client) ContainerSetEACL(ctx context.Context, prm PrmContainerSetEACL)
// form meta header // form meta header
var meta v2session.RequestMetaHeader var meta v2session.RequestMetaHeader
meta.SetSessionToken(prm.table.SessionToken().ToV2()) meta.SetSessionToken(prm.table.SessionToken().ToV2())
prm.prmCommonMeta.writeToMetaHeader(&meta)
// form request // form request
var req v2container.SetExtendedACLRequest var req v2container.SetExtendedACLRequest
@ -632,6 +649,8 @@ func (c *Client) ContainerSetEACL(ctx context.Context, prm PrmContainerSetEACL)
// PrmAnnounceSpace groups parameters of ContainerAnnounceUsedSpace operation. // PrmAnnounceSpace groups parameters of ContainerAnnounceUsedSpace operation.
type PrmAnnounceSpace struct { type PrmAnnounceSpace struct {
prmCommonMeta
announcements []container.UsedSpaceAnnouncement announcements []container.UsedSpaceAnnouncement
} }
@ -698,6 +717,7 @@ func (c *Client) ContainerAnnounceUsedSpace(ctx context.Context, prm PrmAnnounce
) )
c.initCallContext(&cc) c.initCallContext(&cc)
cc.meta = prm.prmCommonMeta
cc.req = &req cc.req = &req
cc.statusRes = &res cc.statusRes = &res
cc.call = func() (responseV2, error) { cc.call = func() (responseV2, error) {

View file

@ -11,10 +11,9 @@ import (
) )
// PrmEndpointInfo groups parameters of EndpointInfo operation. // PrmEndpointInfo groups parameters of EndpointInfo operation.
// type PrmEndpointInfo struct {
// At the moment the operation is not parameterized, however, prmCommonMeta
// the structure is still declared for backward compatibility. }
type PrmEndpointInfo struct{}
// ResEndpointInfo group resulting values of EndpointInfo operation. // ResEndpointInfo group resulting values of EndpointInfo operation.
type ResEndpointInfo struct { type ResEndpointInfo struct {
@ -64,7 +63,7 @@ func (x *ResEndpointInfo) setNodeInfo(info *netmap.NodeInfo) {
// //
// Return statuses: // Return statuses:
// - global (see Client docs). // - global (see Client docs).
func (c *Client) EndpointInfo(ctx context.Context, _ PrmEndpointInfo) (*ResEndpointInfo, error) { func (c *Client) EndpointInfo(ctx context.Context, prm PrmEndpointInfo) (*ResEndpointInfo, error) {
// check context // check context
if ctx == nil { if ctx == nil {
panic(panicMsgMissingContext) panic(panicMsgMissingContext)
@ -81,6 +80,7 @@ func (c *Client) EndpointInfo(ctx context.Context, _ PrmEndpointInfo) (*ResEndpo
) )
c.initCallContext(&cc) c.initCallContext(&cc)
cc.meta = prm.prmCommonMeta
cc.req = &req cc.req = &req
cc.statusRes = &res cc.statusRes = &res
cc.call = func() (responseV2, error) { cc.call = func() (responseV2, error) {
@ -104,10 +104,9 @@ func (c *Client) EndpointInfo(ctx context.Context, _ PrmEndpointInfo) (*ResEndpo
} }
// PrmNetworkInfo groups parameters of NetworkInfo operation. // PrmNetworkInfo groups parameters of NetworkInfo operation.
// type PrmNetworkInfo struct {
// At the moment the operation is not parameterized, however, prmCommonMeta
// the structure is still declared for backward compatibility. }
type PrmNetworkInfo struct{}
// ResNetworkInfo groups resulting values of NetworkInfo operation. // ResNetworkInfo groups resulting values of NetworkInfo operation.
type ResNetworkInfo struct { type ResNetworkInfo struct {
@ -142,7 +141,7 @@ func (x *ResNetworkInfo) setInfo(info *netmap.NetworkInfo) {
// //
// Return statuses: // Return statuses:
// - global (see Client docs). // - global (see Client docs).
func (c *Client) NetworkInfo(ctx context.Context, _ PrmNetworkInfo) (*ResNetworkInfo, error) { func (c *Client) NetworkInfo(ctx context.Context, prm PrmNetworkInfo) (*ResNetworkInfo, error) {
// check context // check context
if ctx == nil { if ctx == nil {
panic(panicMsgMissingContext) panic(panicMsgMissingContext)
@ -159,6 +158,7 @@ func (c *Client) NetworkInfo(ctx context.Context, _ PrmNetworkInfo) (*ResNetwork
) )
c.initCallContext(&cc) c.initCallContext(&cc)
cc.meta = prm.prmCommonMeta
cc.req = &req cc.req = &req
cc.statusRes = &res cc.statusRes = &res
cc.call = func() (responseV2, error) { cc.call = func() (responseV2, error) {

View file

@ -65,6 +65,18 @@ func (x *PrmObjectDelete) UseKey(key ecdsa.PrivateKey) {
x.key = key x.key = key
} }
// WithXHeaders specifies list of extended headers (string key-value pairs)
// to be attached to the request. Must have an even length.
//
// Slice must not be mutated until the operation completes.
func (x *PrmObjectDelete) WithXHeaders(hs ...string) {
if len(hs)%2 != 0 {
panic("slice of X-Headers with odd length")
}
prmCommonMeta{xHeaders: hs}.writeToMetaHeader(&x.meta)
}
// ResObjectDelete groups resulting values of ObjectDelete operation. // ResObjectDelete groups resulting values of ObjectDelete operation.
type ResObjectDelete struct { type ResObjectDelete struct {
statusRes statusRes

View file

@ -22,6 +22,8 @@ import (
// shared parameters of GET/HEAD/RANGE. // shared parameters of GET/HEAD/RANGE.
type prmObjectRead struct { type prmObjectRead struct {
prmCommonMeta
raw bool raw bool
local bool local bool
@ -39,6 +41,22 @@ type prmObjectRead struct {
obj oid.ID obj oid.ID
} }
func (x prmObjectRead) writeToMetaHeader(h *v2session.RequestMetaHeader) {
if x.local {
h.SetTTL(1)
}
if x.bearerSet {
h.SetBearerToken(x.bearer.ToV2())
}
if x.sessionSet {
h.SetSessionToken(x.session.ToV2())
}
x.prmCommonMeta.writeToMetaHeader(h)
}
// MarkRaw marks an intent to read physically stored object. // MarkRaw marks an intent to read physically stored object.
func (x *prmObjectRead) MarkRaw() { func (x *prmObjectRead) MarkRaw() {
x.raw = true x.raw = true
@ -311,17 +329,7 @@ func (c *Client) ObjectGetInit(ctx context.Context, prm PrmObjectGet) (*ObjectRe
// form meta header // form meta header
var meta v2session.RequestMetaHeader var meta v2session.RequestMetaHeader
if prm.local { prm.prmObjectRead.writeToMetaHeader(&meta)
meta.SetTTL(1)
}
if prm.bearerSet {
meta.SetBearerToken(prm.bearer.ToV2())
}
if prm.sessionSet {
meta.SetSessionToken(prm.session.ToV2())
}
// form request // form request
var req v2object.GetRequest var req v2object.GetRequest
@ -490,17 +498,7 @@ func (c *Client) ObjectHead(ctx context.Context, prm PrmObjectHead) (*ResObjectH
// form meta header // form meta header
var meta v2session.RequestMetaHeader var meta v2session.RequestMetaHeader
if prm.local { prm.prmObjectRead.writeToMetaHeader(&meta)
meta.SetTTL(1)
}
if prm.bearerSet {
meta.SetBearerToken(prm.bearer.ToV2())
}
if prm.sessionSet {
meta.SetSessionToken(prm.session.ToV2())
}
// form request // form request
var req v2object.HeadRequest var req v2object.HeadRequest
@ -772,17 +770,7 @@ func (c *Client) ObjectRangeInit(ctx context.Context, prm PrmObjectRange) (*Obje
// form meta header // form meta header
var meta v2session.RequestMetaHeader var meta v2session.RequestMetaHeader
if prm.local { prm.prmObjectRead.writeToMetaHeader(&meta)
meta.SetTTL(1)
}
if prm.bearerSet {
meta.SetBearerToken(prm.bearer.ToV2())
}
if prm.sessionSet {
meta.SetSessionToken(prm.session.ToV2())
}
// form request // form request
var req v2object.GetRangeRequest var req v2object.GetRangeRequest

View file

@ -97,6 +97,18 @@ func (x *PrmObjectHash) UseSalt(salt []byte) {
x.body.SetSalt(salt) x.body.SetSalt(salt)
} }
// WithXHeaders specifies list of extended headers (string key-value pairs)
// to be attached to the request. Must have an even length.
//
// Slice must not be mutated until the operation completes.
func (x *PrmObjectHash) WithXHeaders(hs ...string) {
if len(hs)%2 != 0 {
panic("slice of X-Headers with odd length")
}
prmCommonMeta{xHeaders: hs}.writeToMetaHeader(&x.meta)
}
// ResObjectHash groups resulting values of ObjectHash operation. // ResObjectHash groups resulting values of ObjectHash operation.
type ResObjectHash struct { type ResObjectHash struct {
statusRes statusRes

View file

@ -84,6 +84,18 @@ func (x *ObjectWriter) MarkLocal() {
x.metaHdr.SetTTL(1) x.metaHdr.SetTTL(1)
} }
// WithXHeaders specifies list of extended headers (string key-value pairs)
// to be attached to the request. Must have an even length.
//
// Slice must not be mutated until the operation completes.
func (x *ObjectWriter) WithXHeaders(hs ...string) {
if len(hs)%2 != 0 {
panic("slice of X-Headers with odd length")
}
prmCommonMeta{xHeaders: hs}.writeToMetaHeader(&x.metaHdr)
}
// WriteHeader writes header of the object. Result means success. // WriteHeader writes header of the object. Result means success.
// Failure reason can be received via Close. // Failure reason can be received via Close.
func (x *ObjectWriter) WriteHeader(hdr object.Object) bool { func (x *ObjectWriter) WriteHeader(hdr object.Object) bool {

View file

@ -22,6 +22,8 @@ import (
// PrmObjectSearch groups parameters of ObjectSearch operation. // PrmObjectSearch groups parameters of ObjectSearch operation.
type PrmObjectSearch struct { type PrmObjectSearch struct {
prmCommonMeta
local bool local bool
sessionSet bool sessionSet bool
@ -262,6 +264,8 @@ func (c *Client) ObjectSearchInit(ctx context.Context, prm PrmObjectSearch) (*Ob
meta.SetSessionToken(prm.session.ToV2()) meta.SetSessionToken(prm.session.ToV2())
} }
prm.prmCommonMeta.writeToMetaHeader(&meta)
// form request // form request
var req v2object.SearchRequest var req v2object.SearchRequest

View file

@ -11,6 +11,8 @@ import (
// PrmAnnounceLocalTrust groups parameters of AnnounceLocalTrust operation. // PrmAnnounceLocalTrust groups parameters of AnnounceLocalTrust operation.
type PrmAnnounceLocalTrust struct { type PrmAnnounceLocalTrust struct {
prmCommonMeta
epoch uint64 epoch uint64
trusts []reputation.Trust trusts []reputation.Trust
@ -84,6 +86,7 @@ func (c *Client) AnnounceLocalTrust(ctx context.Context, prm PrmAnnounceLocalTru
) )
c.initCallContext(&cc) c.initCallContext(&cc)
cc.meta = prm.prmCommonMeta
cc.req = &req cc.req = &req
cc.statusRes = &res cc.statusRes = &res
cc.call = func() (responseV2, error) { cc.call = func() (responseV2, error) {
@ -100,6 +103,8 @@ func (c *Client) AnnounceLocalTrust(ctx context.Context, prm PrmAnnounceLocalTru
// PrmAnnounceIntermediateTrust groups parameters of AnnounceIntermediateTrust operation. // PrmAnnounceIntermediateTrust groups parameters of AnnounceIntermediateTrust operation.
type PrmAnnounceIntermediateTrust struct { type PrmAnnounceIntermediateTrust struct {
prmCommonMeta
epoch uint64 epoch uint64
iter uint32 iter uint32
@ -176,6 +181,7 @@ func (c *Client) AnnounceIntermediateTrust(ctx context.Context, prm PrmAnnounceI
) )
c.initCallContext(&cc) c.initCallContext(&cc)
cc.meta = prm.prmCommonMeta
cc.req = &req cc.req = &req
cc.statusRes = &res cc.statusRes = &res
cc.call = func() (responseV2, error) { cc.call = func() (responseV2, error) {

View file

@ -11,6 +11,8 @@ import (
// PrmSessionCreate groups parameters of SessionCreate operation. // PrmSessionCreate groups parameters of SessionCreate operation.
type PrmSessionCreate struct { type PrmSessionCreate struct {
prmCommonMeta
exp uint64 exp uint64
} }
@ -89,6 +91,7 @@ func (c *Client) SessionCreate(ctx context.Context, prm PrmSessionCreate) (*ResS
) )
c.initCallContext(&cc) c.initCallContext(&cc)
cc.meta = prm.prmCommonMeta
cc.req = &req cc.req = &req
cc.statusRes = &res cc.statusRes = &res
cc.call = func() (responseV2, error) { cc.call = func() (responseV2, error) {