forked from TrueCloudLab/restic
Implement streaming chunker using io.Reader
This commit is contained in:
parent
a5c33d80d8
commit
bda33e612c
6 changed files with 300 additions and 147 deletions
58
server.go
58
server.go
|
@ -4,6 +4,7 @@ import (
|
|||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/restic/restic/backend"
|
||||
"github.com/restic/restic/debug"
|
||||
|
@ -179,6 +180,63 @@ func (s Server) Save(t backend.Type, data []byte, id backend.ID) (Blob, error) {
|
|||
return blob, nil
|
||||
}
|
||||
|
||||
// SaveFrom encrypts data read from rd and stores it to the backend as type t.
|
||||
func (s Server) SaveFrom(t backend.Type, id backend.ID, length uint, rd io.Reader) (Blob, error) {
|
||||
if id == nil {
|
||||
return Blob{}, errors.New("id is nil")
|
||||
}
|
||||
|
||||
// create a new blob
|
||||
blob := Blob{
|
||||
ID: id,
|
||||
Size: uint64(length),
|
||||
}
|
||||
|
||||
var ciphertext []byte
|
||||
|
||||
// allocate slice for plaintext
|
||||
plaintext := GetChunkBuf("ch.Save()")
|
||||
defer FreeChunkBuf("ch.Save()", plaintext)
|
||||
|
||||
// if the data is small enough, use a slice from the pool for the ciphertext
|
||||
if length <= maxCiphertextSize-ivSize-hmacSize {
|
||||
ciphertext = GetChunkBuf("ch.Save()")
|
||||
defer FreeChunkBuf("ch.Save()", ciphertext)
|
||||
} else {
|
||||
l := length + ivSize + hmacSize
|
||||
|
||||
debug.Log("Server.Save", "create large slice of %d bytes for ciphertext", l)
|
||||
|
||||
// use a new slice
|
||||
ciphertext = make([]byte, l)
|
||||
}
|
||||
|
||||
plaintext = plaintext[:length]
|
||||
_, err := io.ReadFull(rd, plaintext)
|
||||
if err != nil {
|
||||
return Blob{}, err
|
||||
}
|
||||
|
||||
// encrypt blob
|
||||
n, err := s.Encrypt(ciphertext, plaintext)
|
||||
if err != nil {
|
||||
return Blob{}, err
|
||||
}
|
||||
|
||||
ciphertext = ciphertext[:n]
|
||||
|
||||
// save blob
|
||||
sid, err := s.Create(t, ciphertext)
|
||||
if err != nil {
|
||||
return Blob{}, err
|
||||
}
|
||||
|
||||
blob.Storage = sid
|
||||
blob.StorageSize = uint64(len(ciphertext))
|
||||
|
||||
return blob, nil
|
||||
}
|
||||
|
||||
// SaveJSON serialises item as JSON and uses Save() to store it to the backend as type t.
|
||||
func (s Server) SaveJSON(t backend.Type, item interface{}) (Blob, error) {
|
||||
// convert to json
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue