diff --git a/pkg/services/object/get/v2/util.go b/pkg/services/object/get/v2/util.go index e35cece36..a871714a1 100644 --- a/pkg/services/object/get/v2/util.go +++ b/pkg/services/object/get/v2/util.go @@ -426,7 +426,7 @@ func (w *headResponseWriter) WriteHeader(_ context.Context, hdr *object.Object) return nil } -// nolint: funlen, gocognit +// nolint: funlen func (s *Service) toHeadPrm(ctx context.Context, req *objectV2.HeadRequest, resp *objectV2.HeadResponse) (*getsvc.HeadPrm, error) { body := req.GetBody() @@ -459,138 +459,140 @@ func (s *Service) toHeadPrm(ctx context.Context, req *objectV2.HeadRequest, resp body: resp.GetBody(), }) - if !commonPrm.LocalOnly() { - var onceResign sync.Once - - p.SetRequestForwarder(groupAddressRequestForwarder(func(addr network.Address, c client.MultiAddressClient, pubkey []byte) (*object.Object, error) { - var err error - - key, err := s.keyStorage.GetKey(nil) - if err != nil { - return nil, err - } - - // once compose and resign forwarding request - onceResign.Do(func() { - // compose meta header of the local server - metaHdr := new(session.RequestMetaHeader) - metaHdr.SetTTL(meta.GetTTL() - 1) - // TODO: #1165 think how to set the other fields - metaHdr.SetOrigin(meta) - writeCurrentVersion(metaHdr) - - req.SetMetaHeader(metaHdr) - - err = signature.SignServiceMessage(key, req) - }) - - if err != nil { - return nil, err - } - - // code below is copy-pasted from c.GetObjectHeader implementation, - // perhaps it is worth highlighting the utility function in frostfs-api-go - - // send Head request - var headResp *objectV2.HeadResponse - err = c.RawForAddress(addr, func(cli *rpcclient.Client) error { - headResp, err = rpc.HeadObject(cli, req, rpcclient.WithContext(ctx)) - return err - }) - if err != nil { - return nil, fmt.Errorf("sending the request failed: %w", err) - } - - // verify response key - if err = internal.VerifyResponseKeyV2(pubkey, headResp); err != nil { - return nil, err - } - - // verify response structure - if err := signature.VerifyServiceMessage(headResp); err != nil { - return nil, fmt.Errorf("response verification failed: %w", err) - } - - if err = checkStatus(resp.GetMetaHeader().GetStatus()); err != nil { - return nil, err - } - - var ( - hdr *objectV2.Header - idSig *refs.Signature - ) - - switch v := headResp.GetBody().GetHeaderPart().(type) { - case nil: - return nil, fmt.Errorf("unexpected header type %T", v) - case *objectV2.ShortHeader: - if !body.GetMainOnly() { - return nil, fmt.Errorf("wrong header part type: expected %T, received %T", - (*objectV2.ShortHeader)(nil), (*objectV2.HeaderWithSignature)(nil), - ) - } - - h := v - - hdr = new(objectV2.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 *objectV2.HeaderWithSignature: - if body.GetMainOnly() { - return nil, fmt.Errorf("wrong header part type: expected %T, received %T", - (*objectV2.HeaderWithSignature)(nil), (*objectV2.ShortHeader)(nil), - ) - } - - hdrWithSig := v - if hdrWithSig == nil { - return nil, errors.New("nil object part") - } - - hdr = hdrWithSig.GetHeader() - idSig = hdrWithSig.GetSignature() - - if idSig == nil { - // TODO(@cthulhu-rider): #1387 use "const" error - return nil, errors.New("missing signature") - } - - binID, err := objAddr.Object().Marshal() - if err != nil { - return nil, fmt.Errorf("marshal ID: %w", err) - } - - var sig frostfscrypto.Signature - if err := sig.ReadFromV2(*idSig); err != nil { - return nil, fmt.Errorf("can't read signature: %w", err) - } - - if !sig.Verify(binID) { - return nil, errors.New("invalid object ID signature") - } - case *objectV2.SplitInfo: - si := object.NewSplitInfoFromV2(v) - - return nil, object.NewSplitInfoError(si) - } - - objv2 := new(objectV2.Object) - objv2.SetHeader(hdr) - objv2.SetSignature(idSig) - - obj := object.NewFromV2(objv2) - obj.SetID(objAddr.Object()) - - // convert the object - return obj, nil - })) + if commonPrm.LocalOnly() { + return p, nil } + var onceResign sync.Once + + p.SetRequestForwarder(groupAddressRequestForwarder(func(addr network.Address, c client.MultiAddressClient, pubkey []byte) (*object.Object, error) { + var err error + + key, err := s.keyStorage.GetKey(nil) + if err != nil { + return nil, err + } + + // once compose and resign forwarding request + onceResign.Do(func() { + // compose meta header of the local server + metaHdr := new(session.RequestMetaHeader) + metaHdr.SetTTL(meta.GetTTL() - 1) + // TODO: #1165 think how to set the other fields + metaHdr.SetOrigin(meta) + writeCurrentVersion(metaHdr) + + req.SetMetaHeader(metaHdr) + + err = signature.SignServiceMessage(key, req) + }) + + if err != nil { + return nil, err + } + + // code below is copy-pasted from c.GetObjectHeader implementation, + // perhaps it is worth highlighting the utility function in frostfs-api-go + + // send Head request + var headResp *objectV2.HeadResponse + err = c.RawForAddress(addr, func(cli *rpcclient.Client) error { + headResp, err = rpc.HeadObject(cli, req, rpcclient.WithContext(ctx)) + return err + }) + if err != nil { + return nil, fmt.Errorf("sending the request failed: %w", err) + } + + // verify response key + if err = internal.VerifyResponseKeyV2(pubkey, headResp); err != nil { + return nil, err + } + + // verify response structure + if err := signature.VerifyServiceMessage(headResp); err != nil { + return nil, fmt.Errorf("response verification failed: %w", err) + } + + if err = checkStatus(resp.GetMetaHeader().GetStatus()); err != nil { + return nil, err + } + + var ( + hdr *objectV2.Header + idSig *refs.Signature + ) + + switch v := headResp.GetBody().GetHeaderPart().(type) { + case nil: + return nil, fmt.Errorf("unexpected header type %T", v) + case *objectV2.ShortHeader: + if !body.GetMainOnly() { + return nil, fmt.Errorf("wrong header part type: expected %T, received %T", + (*objectV2.ShortHeader)(nil), (*objectV2.HeaderWithSignature)(nil), + ) + } + + h := v + + hdr = new(objectV2.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 *objectV2.HeaderWithSignature: + if body.GetMainOnly() { + return nil, fmt.Errorf("wrong header part type: expected %T, received %T", + (*objectV2.HeaderWithSignature)(nil), (*objectV2.ShortHeader)(nil), + ) + } + + hdrWithSig := v + if hdrWithSig == nil { + return nil, errors.New("nil object part") + } + + hdr = hdrWithSig.GetHeader() + idSig = hdrWithSig.GetSignature() + + if idSig == nil { + // TODO(@cthulhu-rider): #1387 use "const" error + return nil, errors.New("missing signature") + } + + binID, err := objAddr.Object().Marshal() + if err != nil { + return nil, fmt.Errorf("marshal ID: %w", err) + } + + var sig frostfscrypto.Signature + if err := sig.ReadFromV2(*idSig); err != nil { + return nil, fmt.Errorf("can't read signature: %w", err) + } + + if !sig.Verify(binID) { + return nil, errors.New("invalid object ID signature") + } + case *objectV2.SplitInfo: + si := object.NewSplitInfoFromV2(v) + + return nil, object.NewSplitInfoError(si) + } + + objv2 := new(objectV2.Object) + objv2.SetHeader(hdr) + objv2.SetSignature(idSig) + + obj := object.NewFromV2(objv2) + obj.SetID(objAddr.Object()) + + // convert the object + return obj, nil + })) + return p, nil }