package plugin import ( "bytes" "crypto/sha256" "fmt" "io" "os" "sync" ) type PayloadReader interface { Reader() io.Reader Bytes() ([]byte, error) } var ( _ PayloadReader = (*PayloadFile)(nil) _ PayloadReader = (*MemoryPayload)(nil) ) type MemoryPayload []byte func (m MemoryPayload) Reader() io.Reader { return bytes.NewReader(m) } func (m MemoryPayload) Bytes() ([]byte, error) { return m, nil } type PayloadFile struct { Path string payload []byte Checksum []byte readOnce sync.Once } func (f *PayloadFile) Reader() io.Reader { return bytes.NewReader(f.payload) } func (f *PayloadFile) Bytes() ([]byte, error) { if err := f.readPayloadFile(); err != nil { return nil, err } return f.payload, nil } func (f *PayloadFile) readPayloadFile() (err error) { f.readOnce.Do(func() { f.payload, err = os.ReadFile(f.Path) if err != nil { return } hash := sha256.New() _, _ = hash.Write(f.payload) actualHash := hash.Sum(nil) if !bytes.Equal(f.Checksum, actualHash) { err = fmt.Errorf("plugin checksum mismatch: expected %x, got %x", f.Checksum, actualHash) } }) return }