-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathserver.go
75 lines (69 loc) · 2.11 KB
/
server.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package daobackup
import (
context "context"
"errors"
"fmt"
"io"
"os"
"path/filepath"
)
type BasicFilesystemServer struct {
Root string
VerifyOnRead bool
VerifyOnWrite bool
}
func (server BasicFilesystemServer) getPath(hash ChunkHash) string {
hashstring := hash.String()
return filepath.Join(server.Root, hashstring[0:2], hashstring[2:4], hashstring[4:]) // /root/path/aa/bb/xxxxxxxxxx for hash aabbxxxxxxxxxx
}
func (server *BasicFilesystemServer) PutBlob(c context.Context, hashedblob *HashedBlob) (*RPCStatus, error) {
blobhash := ChunkHashFromBytes(hashedblob.Hash)
path := server.getPath(blobhash)
if server.VerifyOnWrite {
if !blobhash.Verify(hashedblob.Blob) {
err := fmt.Errorf("expected hash '%s', got different hash when hashing provided blob", blobhash)
return &RPCStatus{Succes: false, Message: err.Error()}, err
}
}
if _, err := os.Stat(path); errors.Is(err, os.ErrNotExist) {
if err = os.MkdirAll(filepath.Dir(path), 0700); err != nil {
return &RPCStatus{Succes: false, Message: err.Error()}, err
}
}
f, err := os.Create(path)
if err != nil {
return &RPCStatus{Succes: false, Message: err.Error()}, err
}
defer f.Close()
f.Write(hashedblob.Blob)
return &RPCStatus{Succes: true, Message: ""}, nil
}
func (server *BasicFilesystemServer) CheckBlob(c context.Context, chunkhash *Hash) (*RPCStatus, error) {
ch := ChunkHashFromBytes(chunkhash.Hash)
path := server.getPath(ch)
if _, err := os.Stat(path); errors.Is(err, os.ErrNotExist) {
return &RPCStatus{Succes: false, Message: ""}, nil
}
return &RPCStatus{Succes: true, Message: ""}, nil
}
func (server *BasicFilesystemServer) GetBlob(c context.Context, chunkhash *Hash) (*HashedBlob, error) {
ch := ChunkHashFromBytes(chunkhash.Hash)
path := server.getPath(ch)
f, err := os.Open(path)
if err != nil {
return nil, err
}
defer f.Close()
blob, err := io.ReadAll(f)
if err != nil {
return nil, err
}
hb := &HashedBlob{Blob: blob}
if server.VerifyOnRead {
hb.Hash = HashChunk(blob).Bytes()
} else {
hb.Hash = ch.Bytes()
}
return hb, nil
}
func (server *BasicFilesystemServer) mustEmbedUnimplementedDAOBackupServer() {}