[#131] client: Re-implement Object.Head method

Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
Leonard Lyubich 2022-02-11 19:13:53 +03:00 committed by LeL
parent 8d734d1020
commit caf31a928c
5 changed files with 216 additions and 251 deletions

View file

@ -32,14 +32,6 @@ type DeleteObjectParams struct {
tombTgt ObjectAddressWriter
}
type ObjectHeaderParams struct {
addr *address.Address
raw bool
short bool
}
type RangeDataParams struct {
addr *address.Address
@ -251,190 +243,6 @@ func writeUnexpectedMessageTypeErr(res resCommon, val interface{}) {
res.setStatus(st)
}
func (p *ObjectHeaderParams) WithAddress(v *address.Address) *ObjectHeaderParams {
if p != nil {
p.addr = v
}
return p
}
func (p *ObjectHeaderParams) Address() *address.Address {
if p != nil {
return p.addr
}
return nil
}
func (p *ObjectHeaderParams) WithAllFields() *ObjectHeaderParams {
if p != nil {
p.short = false
}
return p
}
// AllFields return true if parameter set to return all header fields, returns
// false if parameter set to return only main fields of header.
func (p *ObjectHeaderParams) AllFields() bool {
if p != nil {
return !p.short
}
return false
}
func (p *ObjectHeaderParams) WithMainFields() *ObjectHeaderParams {
if p != nil {
p.short = true
}
return p
}
func (p *ObjectHeaderParams) WithRawFlag(v bool) *ObjectHeaderParams {
if p != nil {
p.raw = v
}
return p
}
func (p *ObjectHeaderParams) RawFlag() bool {
if p != nil {
return p.raw
}
return false
}
type ObjectHeadRes struct {
statusRes
objectRes
}
// HeadObject receives object's header through NeoFS API call.
//
// Any client's internal or transport errors are returned as `error`.
// If WithNeoFSErrorParsing option has been provided, unsuccessful
// NeoFS status codes are returned as `error`, otherwise, are included
// in the returned result structure.
func (c *Client) HeadObject(ctx context.Context, p *ObjectHeaderParams, opts ...CallOption) (*ObjectHeadRes, error) {
callOpts := c.defaultCallOptions()
for i := range opts {
if opts[i] != nil {
opts[i](callOpts)
}
}
// create request
req := new(v2object.HeadRequest)
// initialize request body
body := new(v2object.HeadRequestBody)
req.SetBody(body)
// set meta header
meta := v2MetaHeaderFromOpts(callOpts)
if err := c.attachV2SessionToken(callOpts, meta, v2SessionReqInfo{
addr: p.addr.ToV2(),
verb: v2session.ObjectVerbHead,
}); err != nil {
return nil, fmt.Errorf("could not attach session token: %w", err)
}
req.SetMetaHeader(meta)
// fill body fields
body.SetAddress(p.addr.ToV2())
body.SetMainOnly(p.short)
body.SetRaw(p.raw)
// sign the request
if err := signature.SignServiceMessage(callOpts.key, req); err != nil {
return nil, fmt.Errorf("signing the request failed: %w", err)
}
// send Head request
resp, err := rpcapi.HeadObject(c.Raw(), req, client.WithContext(ctx))
if err != nil {
return nil, fmt.Errorf("sending the request failed: %w", err)
}
var (
res = new(ObjectHeadRes)
procPrm processResponseV2Prm
procRes processResponseV2Res
)
procPrm.callOpts = callOpts
procPrm.resp = resp
procRes.statusRes = res
// process response in general
if c.processResponseV2(&procRes, procPrm) {
if procRes.cliErr != nil {
return nil, procRes.cliErr
}
return res, nil
}
var (
hdr *v2object.Header
idSig *v2refs.Signature
)
switch v := resp.GetBody().GetHeaderPart().(type) {
case nil:
writeUnexpectedMessageTypeErr(res, v)
return res, nil
case *v2object.ShortHeader:
if !p.short {
writeUnexpectedMessageTypeErr(res, v)
return res, nil
}
h := v
hdr = new(v2object.Header)
hdr.SetPayloadLength(h.GetPayloadLength())
hdr.SetVersion(h.GetVersion())
hdr.SetOwnerID(h.GetOwnerID())
hdr.SetObjectType(h.GetObjectType())
hdr.SetCreationEpoch(h.GetCreationEpoch())
hdr.SetPayloadHash(h.GetPayloadHash())
hdr.SetHomomorphicHash(h.GetHomomorphicHash())
case *v2object.HeaderWithSignature:
if p.short {
writeUnexpectedMessageTypeErr(res, v)
return res, nil
}
hdr = v.GetHeader()
idSig = v.GetSignature()
case *v2object.SplitInfo:
si := object.NewSplitInfoFromV2(v)
return nil, object.NewSplitInfoError(si)
}
obj := new(v2object.Object)
obj.SetHeader(hdr)
obj.SetSignature(idSig)
raw := object.NewRawFromV2(obj)
raw.SetID(p.addr.ObjectID())
res.setObject(raw.Object())
return res, nil
}
func (p *RangeDataParams) WithAddress(v *address.Address) *RangeDataParams {
if p != nil {
p.addr = v