[#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.
type PrmBalanceGet struct {
prmCommonMeta
ownerSet bool
ownerID owner.ID
}
@ -82,6 +84,7 @@ func (c *Client) BalanceGet(ctx context.Context, prm PrmBalanceGet) (*ResBalance
)
c.initCallContext(&cc)
cc.meta = prm.prmCommonMeta
cc.req = &req
cc.statusRes = &res
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.
const (
panicMsgMissingContext = "missing context"
@ -82,6 +116,9 @@ type contextCall struct {
// NeoFS network magic
netMagic uint64
// Meta parameters
meta prmCommonMeta
// ==================================================
// custom call parameters
@ -128,6 +165,8 @@ func (x contextCall) prepareRequest() {
}
meta.SetNetworkMagic(x.netMagic)
x.meta.writeToMetaHeader(meta)
}
// prepares, signs and writes the request. Result means success.

View file

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

View file

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

View file

@ -65,6 +65,18 @@ func (x *PrmObjectDelete) UseKey(key ecdsa.PrivateKey) {
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.
type ResObjectDelete struct {
statusRes

View file

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

View file

@ -97,6 +97,18 @@ func (x *PrmObjectHash) UseSalt(salt []byte) {
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.
type ResObjectHash struct {
statusRes

View file

@ -84,6 +84,18 @@ func (x *ObjectWriter) MarkLocal() {
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.
// Failure reason can be received via Close.
func (x *ObjectWriter) WriteHeader(hdr object.Object) bool {

View file

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

View file

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

View file

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