diff --git a/service/meta.go b/service/meta.go index 3f01758..f1b4613 100644 --- a/service/meta.go +++ b/service/meta.go @@ -1,5 +1,13 @@ package service +import ( + "io" +) + +type extHdrSrcWrapper struct { + extHdrSrc ExtendedHeadersSource +} + // CutMeta returns current value and sets RequestMetaHeader to empty value. func (m *RequestMetaHeader) CutMeta() RequestMetaHeader { cp := *m @@ -11,3 +19,53 @@ func (m *RequestMetaHeader) CutMeta() RequestMetaHeader { func (m *RequestMetaHeader) RestoreMeta(v RequestMetaHeader) { *m = v } + +// ExtendedHeadersSignedData wraps passed ExtendedHeadersSource and returns SignedDataSource. +func ExtendedHeadersSignedData(headers ExtendedHeadersSource) SignedDataSource { + return &extHdrSrcWrapper{ + extHdrSrc: headers, + } +} + +// SignedData returns extended headers in a binary representation. +func (s extHdrSrcWrapper) SignedData() ([]byte, error) { + return SignedDataFromReader(s) +} + +// SignedDataSize returns the length of extended headers slice. +func (s extHdrSrcWrapper) SignedDataSize() (res int) { + if s.extHdrSrc != nil { + for _, h := range s.extHdrSrc.ExtendedHeaders() { + if h != nil { + res += len(h.Key()) + len(h.Value()) + } + } + } + + return +} + +// ReadSignedData copies a binary representation of the extended headers to passed buffer. +// +// If buffer length is less than required, io.ErrUnexpectedEOF returns. +func (s extHdrSrcWrapper) ReadSignedData(p []byte) (int, error) { + sz := s.SignedDataSize() + if len(p) < sz { + return 0, io.ErrUnexpectedEOF + } + + if s.extHdrSrc != nil { + off := 0 + for _, h := range s.extHdrSrc.ExtendedHeaders() { + if h == nil { + continue + } + + off += copy(p[off:], []byte(h.Key())) + + off += copy(p[off:], []byte(h.Value())) + } + } + + return sz, nil +} diff --git a/service/types.go b/service/types.go index dada0c8..87c3a77 100644 --- a/service/types.go +++ b/service/types.go @@ -301,3 +301,14 @@ type BearerToken interface { type BearerTokenSource interface { GetBearerToken() BearerToken } + +// ExtendedHeader is an interface of string key-value pair with read access. +type ExtendedHeader interface { + Key() string + Value() string +} + +// ExtendedHeadersSource is an interface of ExtendedHeader list with read access. +type ExtendedHeadersSource interface { + ExtendedHeaders() []ExtendedHeader +}