Documentation
¶
Index ¶
- Constants
- Variables
- func ScanMessage(buffers iprotobuf.BuffersSlice, scheme MessageScheme, opts ScanMessageOptions) error
- func ScanMessageOrdered(buffers iprotobuf.BuffersSlice, scheme MessageScheme, ...) (bool, error)
- type BinaryFieldKind
- type FieldType
- type MessageField
- type MessageScheme
- type ScanMessageOptions
- type ScanMessageOrderedOptions
- type SchemeAlias
Constants ¶
const ( BinaryFieldKindSHA256 BinaryFieldKindNeo3Address BinaryFieldKindUUIDV4 )
const ( FieldTypeUint32 FieldTypeUint64 FieldTypeEnum FieldTypeRepeatedEnum FieldTypeBool FieldTypeString FieldTypeBytes FieldTypeNestedMessage )
All FieldType values supported by this package.
const (
SchemeAliasObjectHeader
)
Variables ¶
var ( VersionScheme = newSimpleFieldsScheme( newSimpleField(protorefs.FieldVersionMajor, "major", FieldTypeUint32), newSimpleField(protorefs.FieldVersionMinor, "minor", FieldTypeUint32), ) ChecksumScheme = newSimpleFieldsScheme( newSimpleField(protorefs.FieldChecksumType, "type", FieldTypeEnum), newSimpleField(protorefs.FieldChecksumValue, "value", FieldTypeBytes), ) SignatureScheme = newSimpleFieldsScheme( newSimpleField(protorefs.FieldSignatureKey, "key", FieldTypeBytes), newSimpleField(protorefs.FieldSignatureValue, "value", FieldTypeBytes), newSimpleField(protorefs.FieldSignatureScheme, "scheme", FieldTypeEnum), ) TokenLifetimeScheme = newSimpleFieldsScheme( newSimpleField(protosession.FieldTokenLifetimeExp, "exp", FieldTypeUint64), newSimpleField(protosession.FieldTokenLifetimeNbf, "nbf", FieldTypeUint64), newSimpleField(protosession.FieldTokenLifetimeIat, "iat", FieldTypeUint64), ) )
Simple messages.
var ( ContainerIDScheme = newIDScheme(BinaryFieldKindSHA256) ObjectIDScheme = newIDScheme(BinaryFieldKindSHA256) UserIDScheme = newIDScheme(BinaryFieldKindNeo3Address) )
IDs.
var ( SessionSubjectScheme = MessageScheme{ Fields: map[protowire.Number]MessageField{ protosession.FieldTargetOwnerID: NewMessageField("owner", FieldTypeNestedMessage), protosession.FieldTargetNNSName: NewMessageField("NNS name", FieldTypeString), }, NestedMessageFields: map[protowire.Number]MessageScheme{ protosession.FieldTargetOwnerID: UserIDScheme, }, } SessionContextScheme = MessageScheme{ Fields: map[protowire.Number]MessageField{ protosession.FieldSessionContextV2Container: NewMessageField("container", FieldTypeNestedMessage), protosession.FieldSessionContextV2Verbs: NewMessageField("verbs", FieldTypeRepeatedEnum), }, NestedMessageFields: map[protowire.Number]MessageScheme{ protosession.FieldSessionContextV2Container: ContainerIDScheme, }, } SessionTokenBodyScheme = MessageScheme{ Fields: map[protowire.Number]MessageField{ protosession.FieldSessionTokenV2BodyVersion: NewMessageField("version", FieldTypeUint32), protosession.FieldSessionTokenV2BodyAppdata: NewMessageField("appdata", FieldTypeBytes), protosession.FieldSessionTokenV2BodyIssuer: NewMessageField("issuer", FieldTypeNestedMessage), protosession.FieldSessionTokenV2BodySubjects: NewMessageField("subject", FieldTypeNestedMessage), protosession.FieldSessionTokenV2BodyLifetime: NewMessageField("lifetime", FieldTypeNestedMessage), protosession.FieldSessionTokenV2BodyContexts: NewMessageField("contexts", FieldTypeNestedMessage), protosession.FieldSessionTokenV2BodyFinal: NewMessageField("final", FieldTypeBool), }, NestedMessageFields: map[protowire.Number]MessageScheme{ protosession.FieldSessionTokenV2BodyIssuer: UserIDScheme, protosession.FieldSessionTokenV2BodySubjects: SessionSubjectScheme, protosession.FieldSessionTokenV2BodyLifetime: TokenLifetimeScheme, protosession.FieldSessionTokenV2BodyContexts: SessionContextScheme, }, } SessionTokenScheme = MessageScheme{ Fields: map[protowire.Number]MessageField{ protosession.FieldSessionTokenV2Body: NewMessageField("body", FieldTypeNestedMessage), protosession.FieldSessionTokenV2Signature: NewMessageField("signature", FieldTypeNestedMessage), protosession.FieldSessionTokenV2Origin: NewMessageField("origin", FieldTypeNestedMessage), }, NestedMessageFields: map[protowire.Number]MessageScheme{ protosession.FieldSessionTokenV2Body: SessionTokenBodyScheme, protosession.FieldSessionTokenV2Signature: SignatureScheme, }, RecursiveField: protosession.FieldSessionTokenV2Origin, } )
Session token.
var ( SessionV1ContextScheme = MessageScheme{ Fields: map[protowire.Number]MessageField{ protosession.FieldObjectSessionContextTargetContainer: NewMessageField("container", FieldTypeNestedMessage), protosession.FieldObjectSessionContextTargetObjects: NewMessageField("objects", FieldTypeNestedMessage), }, NestedMessageFields: map[protowire.Number]MessageScheme{ protosession.FieldObjectSessionContextTargetContainer: ContainerIDScheme, protosession.FieldObjectSessionContextTargetObjects: ObjectIDScheme, }, } SessionV1ObjectContextScheme = MessageScheme{ Fields: map[protowire.Number]MessageField{ protosession.FieldObjectSessionContextVerb: NewMessageField("verb", FieldTypeEnum), protosession.FieldObjectSessionContextTarget: NewMessageField("target", FieldTypeNestedMessage), }, NestedMessageFields: map[protowire.Number]MessageScheme{ protosession.FieldObjectSessionContextTarget: SessionV1ContextScheme, }, } SessionV1ContainerContextScheme = MessageScheme{ Fields: map[protowire.Number]MessageField{ protosession.FieldContainerSessionContextVerb: NewMessageField("verb", FieldTypeEnum), protosession.FieldContainerSessionContextWildcard: NewMessageField("wildcard", FieldTypeBool), protosession.FieldContainerSessionContextContainerID: NewMessageField("container", FieldTypeNestedMessage), }, NestedMessageFields: map[protowire.Number]MessageScheme{ protosession.FieldContainerSessionContextContainerID: ContainerIDScheme, }, } SessionV1TokenBodyScheme = MessageScheme{ Fields: map[protowire.Number]MessageField{ protosession.FieldSessionTokenBodyID: NewMessageField("id", FieldTypeBytes), protosession.FieldSessionTokenBodyOwnerID: NewMessageField("owner", FieldTypeNestedMessage), protosession.FieldSessionTokenBodyLifetime: NewMessageField("lifetime", FieldTypeNestedMessage), protosession.FieldSessionTokenBodySessionKey: NewMessageField("session key", FieldTypeBytes), protosession.FieldSessionTokenBodyObject: NewMessageField("object context", FieldTypeNestedMessage), protosession.FieldSessionTokenBodyContainer: NewMessageField("container context", FieldTypeNestedMessage), }, BinaryFields: map[protowire.Number]BinaryFieldKind{ protosession.FieldSessionTokenBodyID: BinaryFieldKindUUIDV4, }, NestedMessageFields: map[protowire.Number]MessageScheme{ protosession.FieldSessionTokenBodyOwnerID: UserIDScheme, protosession.FieldSessionTokenBodyLifetime: TokenLifetimeScheme, protosession.FieldSessionTokenBodyObject: SessionV1ObjectContextScheme, protosession.FieldSessionTokenBodyContainer: SessionV1ContainerContextScheme, }, } SessionV1TokenScheme = MessageScheme{ Fields: map[protowire.Number]MessageField{ protosession.FieldSessionTokenBody: NewMessageField("body", FieldTypeNestedMessage), protosession.FieldSessionTokenSignature: NewMessageField("signature", FieldTypeNestedMessage), }, NestedMessageFields: map[protowire.Number]MessageScheme{ protosession.FieldSessionTokenBody: SessionV1TokenBodyScheme, protosession.FieldSessionTokenSignature: SignatureScheme, }, } )
Session V1.
var ( ObjectAttributeScheme = newSimpleFieldsScheme( newSimpleField(protoobject.FieldAttributeKey, "key", FieldTypeString), newSimpleField(protoobject.FieldAttributeValue, "value", FieldTypeString), ) ObjectSplitHeaderScheme = MessageScheme{ Fields: map[protowire.Number]MessageField{ protoobject.FieldHeaderSplitParent: NewMessageField("parent", FieldTypeNestedMessage), protoobject.FieldHeaderSplitPrevious: NewMessageField("previous", FieldTypeNestedMessage), protoobject.FieldHeaderSplitParentSignature: NewMessageField("parent signature", FieldTypeNestedMessage), protoobject.FieldHeaderSplitParentHeader: NewMessageField("parent header", FieldTypeNestedMessage), protoobject.FieldHeaderSplitChildren: NewMessageField("children", FieldTypeNestedMessage), protoobject.FieldHeaderSplitSplitID: NewMessageField("split ID", FieldTypeBytes), protoobject.FieldHeaderSplitFirst: NewMessageField("first", FieldTypeNestedMessage), }, BinaryFields: map[protowire.Number]BinaryFieldKind{ protoobject.FieldHeaderSplitSplitID: BinaryFieldKindUUIDV4, }, NestedMessageFields: map[protowire.Number]MessageScheme{ protoobject.FieldHeaderSplitParent: ObjectIDScheme, protoobject.FieldHeaderSplitPrevious: ObjectIDScheme, protoobject.FieldHeaderSplitParentSignature: SignatureScheme, protoobject.FieldHeaderSplitChildren: ObjectIDScheme, protoobject.FieldHeaderSplitFirst: ObjectIDScheme, }, NestedMessageAliases: map[protowire.Number]SchemeAlias{ protoobject.FieldHeaderSplitParentHeader: SchemeAliasObjectHeader, }, } ObjectHeaderScheme = MessageScheme{ Fields: map[protowire.Number]MessageField{ protoobject.FieldHeaderVersion: NewMessageField("version", FieldTypeNestedMessage), protoobject.FieldHeaderContainerID: NewMessageField("container ID", FieldTypeNestedMessage), protoobject.FieldHeaderOwnerID: NewMessageField("owner ID", FieldTypeNestedMessage), protoobject.FieldHeaderCreationEpoch: NewMessageField("creation epoch", FieldTypeUint64), protoobject.FieldHeaderPayloadLength: NewMessageField("payload length", FieldTypeUint64), protoobject.FieldHeaderPayloadHash: NewMessageField("payload hash", FieldTypeNestedMessage), protoobject.FieldHeaderObjectType: NewMessageField("type", FieldTypeEnum), protoobject.FieldHeaderHomomorphicHash: NewMessageField("homomorphic hash", FieldTypeNestedMessage), protoobject.FieldHeaderSessionToken: NewMessageField("session V1 token", FieldTypeNestedMessage), protoobject.FieldHeaderAttributes: NewMessageField("attribute", FieldTypeNestedMessage), protoobject.FieldHeaderSplit: NewMessageField("split", FieldTypeNestedMessage), protoobject.FieldHeaderSessionV2: NewMessageField("session token", FieldTypeNestedMessage), }, NestedMessageFields: map[protowire.Number]MessageScheme{ protoobject.FieldHeaderVersion: VersionScheme, protoobject.FieldHeaderContainerID: ContainerIDScheme, protoobject.FieldHeaderOwnerID: UserIDScheme, protoobject.FieldHeaderPayloadHash: ChecksumScheme, protoobject.FieldHeaderHomomorphicHash: ChecksumScheme, protoobject.FieldHeaderAttributes: ObjectAttributeScheme, protoobject.FieldHeaderSessionToken: SessionV1TokenScheme, protoobject.FieldHeaderSplit: ObjectSplitHeaderScheme, protoobject.FieldHeaderSessionV2: SessionTokenScheme, }, } ObjectScheme = MessageScheme{ Fields: map[protowire.Number]MessageField{ protoobject.FieldObjectID: NewMessageField("ID", FieldTypeNestedMessage), protoobject.FieldObjectSignature: NewMessageField("signature", FieldTypeNestedMessage), protoobject.FieldObjectHeader: NewMessageField("header", FieldTypeNestedMessage), protoobject.FieldObjectPayload: NewMessageField("payload", FieldTypeBytes), }, NestedMessageFields: map[protowire.Number]MessageScheme{ protoobject.FieldObjectID: ObjectIDScheme, protoobject.FieldObjectSignature: SignatureScheme, protoobject.FieldObjectHeader: ObjectHeaderScheme, }, } ObjectHeaderWithSignatureScheme = MessageScheme{ Fields: map[protowire.Number]MessageField{ protoobject.FieldHeaderWithSignatureHeader: NewMessageField("header", FieldTypeNestedMessage), protoobject.FieldHeaderWithSignatureSignature: NewMessageField("signature", FieldTypeNestedMessage), }, NestedMessageFields: map[protowire.Number]MessageScheme{ protoobject.FieldHeaderWithSignatureHeader: ObjectHeaderScheme, protoobject.FieldHeaderWithSignatureSignature: SignatureScheme, }, } ObjectSplitInfoScheme = MessageScheme{ Fields: map[protowire.Number]MessageField{ protoobject.FieldSplitInfoSplitID: NewMessageField("split ID", FieldTypeBytes), protoobject.FieldSplitInfoLastPart: NewMessageField("last part", FieldTypeNestedMessage), protoobject.FieldSplitInfoLink: NewMessageField("link", FieldTypeNestedMessage), protoobject.FieldSplitInfoFirstPart: NewMessageField("first part", FieldTypeNestedMessage), }, BinaryFields: map[protowire.Number]BinaryFieldKind{ protoobject.FieldSplitInfoSplitID: BinaryFieldKindUUIDV4, }, NestedMessageFields: map[protowire.Number]MessageScheme{ protoobject.FieldSplitInfoLastPart: ObjectIDScheme, protoobject.FieldSplitInfoLink: ObjectIDScheme, protoobject.FieldSplitInfoFirstPart: ObjectIDScheme, }, } )
Object.
var ( ResponseStatusDetailScheme = newSimpleFieldsScheme( newSimpleField(protostatus.FieldStatusDetailID, "ID", FieldTypeUint32), newSimpleField(protostatus.FieldStatusDetailValue, "value", FieldTypeBytes), ) ResponseStatusScheme = MessageScheme{ Fields: map[protowire.Number]MessageField{ protostatus.FieldStatusCode: NewMessageField("code", FieldTypeUint32), protostatus.FieldStatusMessage: NewMessageField("message", FieldTypeString), protostatus.FieldStatusDetails: NewMessageField("details", FieldTypeNestedMessage), }, NestedMessageFields: map[protowire.Number]MessageScheme{ protostatus.FieldStatusDetails: ResponseStatusDetailScheme, }, } ResponseMetaHeaderScheme = MessageScheme{ Fields: map[protowire.Number]MessageField{ protosession.FieldResponseMetaHeaderVersion: NewMessageField("version", FieldTypeNestedMessage), protosession.FieldResponseMetaHeaderEpoch: NewMessageField("epoch", FieldTypeUint64), protosession.FieldResponseMetaHeaderTTL: NewMessageField("TTL", FieldTypeUint32), protosession.FieldResponseMetaHeaderXHeaders: NewMessageField("X-headers", FieldTypeNestedMessage), protosession.FieldResponseMetaHeaderOrigin: NewMessageField("origin", FieldTypeNestedMessage), protosession.FieldResponseMetaHeaderStatus: NewMessageField("status", FieldTypeNestedMessage), }, NestedMessageFields: map[protowire.Number]MessageScheme{ protosession.FieldResponseMetaHeaderVersion: VersionScheme, protosession.FieldResponseMetaHeaderXHeaders: ObjectAttributeScheme, protosession.FieldResponseMetaHeaderStatus: ResponseStatusScheme, }, RecursiveField: protosession.FieldResponseMetaHeaderOrigin, } ResponseVerificationHeaderScheme = MessageScheme{ Fields: map[protowire.Number]MessageField{ protosession.FieldResponseVerificationHeaderBodySignature: NewMessageField("body signature", FieldTypeNestedMessage), protosession.FieldResponseVerificationHeaderMetaSignature: NewMessageField("meta signature", FieldTypeNestedMessage), protosession.FieldResponseVerificationHeaderOriginSignature: NewMessageField("origin signature", FieldTypeNestedMessage), protosession.FieldResponseVerificationHeaderOrigin: NewMessageField("origin", FieldTypeNestedMessage), }, NestedMessageFields: map[protowire.Number]MessageScheme{ protosession.FieldResponseVerificationHeaderBodySignature: SignatureScheme, protosession.FieldResponseVerificationHeaderMetaSignature: SignatureScheme, protosession.FieldResponseVerificationHeaderOriginSignature: SignatureScheme, }, RecursiveField: protosession.FieldResponseVerificationHeaderOrigin, } ResponseScheme = MessageScheme{ Fields: map[protowire.Number]MessageField{ protobuf.FieldResponseBody: NewMessageField("body", FieldTypeNestedMessage), protobuf.FieldResponseMetaHeader: NewMessageField("meta header", FieldTypeNestedMessage), protobuf.FieldResponseVerificationHeader: NewMessageField("verification header", FieldTypeNestedMessage), }, NestedMessageFields: map[protowire.Number]MessageScheme{ protobuf.FieldResponseMetaHeader: ResponseMetaHeaderScheme, protobuf.FieldResponseVerificationHeader: ResponseVerificationHeaderScheme, }, } ObjectHeadResponseBodyScheme = MessageScheme{ Fields: map[protowire.Number]MessageField{ protoobject.FieldHeadResponseBodyHeader: NewMessageField("header", FieldTypeNestedMessage), protoobject.FieldHeadResponseBodyShortHeader: NewMessageField("short header", FieldTypeNestedMessage), protoobject.FieldHeadResponseBodySplitInfo: NewMessageField("split info", FieldTypeNestedMessage), }, NestedMessageFields: map[protowire.Number]MessageScheme{ protoobject.FieldHeadResponseBodyHeader: ObjectHeaderWithSignatureScheme, protoobject.FieldHeadResponseBodySplitInfo: ObjectSplitInfoScheme, }, } ObjectGetResponseInitScheme = MessageScheme{ Fields: map[protowire.Number]MessageField{ protoobject.FieldGetResponseBodyInitObjectID: NewMessageField("ID", FieldTypeNestedMessage), protoobject.FieldGetResponseBodyInitSignature: NewMessageField("signature", FieldTypeNestedMessage), protoobject.FieldGetResponseBodyInitHeader: NewMessageField("header", FieldTypeNestedMessage), }, NestedMessageFields: map[protowire.Number]MessageScheme{ protoobject.FieldGetResponseBodyInitObjectID: ObjectIDScheme, protoobject.FieldGetResponseBodyInitSignature: SignatureScheme, protoobject.FieldGetResponseBodyInitHeader: ObjectHeaderScheme, }, } ObjectGetResponseBodyScheme = MessageScheme{ Fields: map[protowire.Number]MessageField{ protoobject.FieldGetResponseBodyInit: NewMessageField("init", FieldTypeNestedMessage), protoobject.FieldGetResponseBodyChunk: NewMessageField("chunk", FieldTypeBytes), protoobject.FieldGetResponseBodySplitInfo: NewMessageField("split info", FieldTypeNestedMessage), }, NestedMessageFields: map[protowire.Number]MessageScheme{ protoobject.FieldGetResponseBodyInit: ObjectGetResponseInitScheme, protoobject.FieldGetResponseBodySplitInfo: ObjectSplitInfoScheme, }, } ObjectGetRangeResponseBodyScheme = MessageScheme{ Fields: map[protowire.Number]MessageField{ protoobject.FieldRangeResponseBodyChunk: NewMessageField("chunk", FieldTypeBytes), protoobject.FieldRangeResponseBodySplitInfo: NewMessageField("split info", FieldTypeNestedMessage), }, NestedMessageFields: map[protowire.Number]MessageScheme{ protoobject.FieldRangeResponseBodySplitInfo: ObjectSplitInfoScheme, }, } )
Responses.
var ErrContinue = errors.New("continue")
ErrContinue is a continuation error.
Functions ¶
func ScanMessage ¶
func ScanMessage(buffers iprotobuf.BuffersSlice, scheme MessageScheme, opts ScanMessageOptions) error
ScanMessage is an alternative for ScanMessageOrdered when field order does not matter.
func ScanMessageOrdered ¶
func ScanMessageOrdered(buffers iprotobuf.BuffersSlice, scheme MessageScheme, opts ScanMessageOrderedOptions) (bool, error)
ScanMessageOrdered checks whether buffers contain a complete and valid Protocol Buffers V3 message according to the given scheme. It goes over each field one-by-one and checks that it is encoded correctly. If the field is unknown, ScanMessageOrdered fails. Field repetition is unchecked. Empty buffers is not an error.
Boolean return is a flag of direct field order: it states whether fields are arranged in ascending numerical order in all messages at all nesting levels.
Types ¶
type BinaryFieldKind ¶
type BinaryFieldKind uint8
BinaryFieldKind enumerates binary fields of specific format.
func (BinaryFieldKind) String ¶
func (x BinaryFieldKind) String() string
String implements fmt.Stringer.
type FieldType ¶
type FieldType uint8
FieldType is an enumeration of Protocol Buffers V3 field types used in NeoFS API protocol.
type MessageField ¶
type MessageField struct {
// contains filtered or unexported fields
}
MessageField describes message field.
func NewMessageField ¶
func NewMessageField(name string, typ FieldType) MessageField
NewMessageField is a MessageField constructor.
type MessageScheme ¶
type MessageScheme struct {
// Field number -> descriptor mapping.
Fields map[protowire.Number]MessageField
// Field of bytes type -> format mapping.
BinaryFields map[protowire.Number]BinaryFieldKind
// Field of nested message type -> scheme mapping.
NestedMessageFields map[protowire.Number]MessageScheme
// Field of nested message type -> scheme alias mapping.
NestedMessageAliases map[protowire.Number]SchemeAlias
// Number of field having same scheme as current message if any.
RecursiveField protowire.Number
}
MessageScheme describes scheme of particular NeoFS API protocol message for proper scanning.
type ScanMessageOptions ¶
type ScanMessageOptions struct {
// If InterceptNested returns nil, [ScanMessage] does not scan its argument. In
// this case, the caller is responsible for processing the field itself. To
// continue scanning the field as usual, the function should return
// [ErrContinue].
InterceptNested func(protowire.Number, iprotobuf.BuffersSlice) error
// contains filtered or unexported fields
}
ScanMessageOptions groups optional ScanMessage parameters.
Interceptors allow to intercept typed field values of fields declared in message scheme to handle them specifically. If the function returns an error, ScanMessage immediately returns it as is generally.
type ScanMessageOrderedOptions ¶
type ScanMessageOrderedOptions struct {
// The checkOrder parameter specifies whether caller should check field order in
// bs. Accordingly, bool return reports the result of this check.
//
// If InterceptNested returns nil error, [ScanMessageOrdered] does not scan its
// argument. In this case, the caller is responsible for processing the field
// itself. To continue scanning the field as usual, the function should return
// [ErrContinue].
InterceptNested func(num protowire.Number, bs iprotobuf.BuffersSlice, checkOrder bool) (bool, error)
// contains filtered or unexported fields
}
ScanMessageOrderedOptions groups optional ScanMessageOrdered parameters.
Interceptors allow to intercept typed field values to handle them specifically. If the function returns an error, ScanMessageOrdered immediately returns it as is generally.
type SchemeAlias ¶
type SchemeAlias = uint8
SchemeAlias allows to resolve cross-dependency of messages.