mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-18 01:43:47 +00:00
swarm/...: There is a response header to show if content was encrypted
DPA.Retrieve() also returns this information
This commit is contained in:
parent
3d1a1aa459
commit
c342a8c376
11 changed files with 49 additions and 28 deletions
|
|
@ -238,7 +238,7 @@ func (self *Api) Upload(uploadDir, index string, toEncrypt bool) (hash string, e
|
||||||
}
|
}
|
||||||
|
|
||||||
// DPA reader API
|
// DPA reader API
|
||||||
func (self *Api) Retrieve(key storage.Key) storage.LazySectionReader {
|
func (self *Api) Retrieve(key storage.Key) (reader storage.LazySectionReader, isEncrypted bool) {
|
||||||
return self.dpa.Retrieve(key)
|
return self.dpa.Retrieve(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -344,7 +344,7 @@ func (self *Api) Get(key storage.Key, path string) (reader storage.LazySectionRe
|
||||||
} else {
|
} else {
|
||||||
mimeType = entry.ContentType
|
mimeType = entry.ContentType
|
||||||
log.Trace("content lookup key", "key", key, "mimetype", mimeType)
|
log.Trace("content lookup key", "key", key, "mimetype", mimeType)
|
||||||
reader = self.dpa.Retrieve(key)
|
reader, _ = self.dpa.Retrieve(key)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
status = http.StatusNotFound
|
status = http.StatusNotFound
|
||||||
|
|
@ -482,7 +482,7 @@ func (self *Api) AppendFile(mhash, path, fname string, existingSize int64, conte
|
||||||
|
|
||||||
buf := make([]byte, buffSize)
|
buf := make([]byte, buffSize)
|
||||||
|
|
||||||
oldReader := self.Retrieve(oldKey)
|
oldReader, _ := self.Retrieve(oldKey)
|
||||||
io.ReadAtLeast(oldReader, buf, int(offset))
|
io.ReadAtLeast(oldReader, buf, int(offset))
|
||||||
|
|
||||||
newReader := bytes.NewReader(content)
|
newReader := bytes.NewReader(content)
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ func TestClientUploadDownloadFiles(t *testing.T) {
|
||||||
Size: int64(len(data)),
|
Size: int64(len(data)),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
hash, err := client.Upload(file, manifest)
|
hash, err := client.Upload(file, manifest, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
@ -168,7 +168,7 @@ func TestClientUploadDownloadDirectory(t *testing.T) {
|
||||||
// upload the directory
|
// upload the directory
|
||||||
client := NewClient(srv.URL)
|
client := NewClient(srv.URL)
|
||||||
defaultPath := filepath.Join(dir, testDirFiles[0])
|
defaultPath := filepath.Join(dir, testDirFiles[0])
|
||||||
hash, err := client.UploadDirectory(dir, defaultPath, "")
|
hash, err := client.UploadDirectory(dir, defaultPath, "", false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("error uploading directory: %s", err)
|
t.Fatalf("error uploading directory: %s", err)
|
||||||
}
|
}
|
||||||
|
|
@ -224,7 +224,7 @@ func TestClientFileList(t *testing.T) {
|
||||||
defer os.RemoveAll(dir)
|
defer os.RemoveAll(dir)
|
||||||
|
|
||||||
client := NewClient(srv.URL)
|
client := NewClient(srv.URL)
|
||||||
hash, err := client.UploadDirectory(dir, "", "")
|
hash, err := client.UploadDirectory(dir, "", "", false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("error uploading directory: %s", err)
|
t.Fatalf("error uploading directory: %s", err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -273,7 +273,7 @@ func retrieveToFile(quitC chan bool, dpa *storage.DPA, key storage.Key, path str
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
reader := dpa.Retrieve(key)
|
reader, _ := dpa.Retrieve(key)
|
||||||
writer := bufio.NewWriter(f)
|
writer := bufio.NewWriter(f)
|
||||||
size, err := reader.Size(quitC)
|
size, err := reader.Size(quitC)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -556,13 +556,15 @@ func (s *Server) HandleGet(w http.ResponseWriter, r *Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// check the root chunk exists by retrieving the file's size
|
// check the root chunk exists by retrieving the file's size
|
||||||
reader := s.api.Retrieve(key)
|
reader, isEncrypted := s.api.Retrieve(key)
|
||||||
if _, err := reader.Size(nil); err != nil {
|
if _, err := reader.Size(nil); err != nil {
|
||||||
getFail.Inc(1)
|
getFail.Inc(1)
|
||||||
Respond(w, r, fmt.Sprintf("root chunk not found %s: %s", key, err), http.StatusNotFound)
|
Respond(w, r, fmt.Sprintf("root chunk not found %s: %s", key, err), http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
w.Header().Set("X-Encrypted", fmt.Sprintf("%v", isEncrypted))
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case r.uri.Raw() || r.uri.DeprecatedRaw():
|
case r.uri.Raw() || r.uri.DeprecatedRaw():
|
||||||
// allow the request to overwrite the content type using a query
|
// allow the request to overwrite the content type using a query
|
||||||
|
|
@ -619,11 +621,12 @@ func (s *Server) HandleGetFiles(w http.ResponseWriter, r *Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// retrieve the entry's key and size
|
// retrieve the entry's key and size
|
||||||
reader := s.api.Retrieve(storage.Key(common.Hex2Bytes(entry.Hash)))
|
reader, isEncrypted := s.api.Retrieve(storage.Key(common.Hex2Bytes(entry.Hash)))
|
||||||
size, err := reader.Size(nil)
|
size, err := reader.Size(nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
w.Header().Set("X-Encrypted", fmt.Sprintf("%v", isEncrypted))
|
||||||
|
|
||||||
// write a tar header for the entry
|
// write a tar header for the entry
|
||||||
hdr := &tar.Header{
|
hdr := &tar.Header{
|
||||||
|
|
|
||||||
|
|
@ -472,7 +472,7 @@ func TestBzzRootRedirect(t *testing.T) {
|
||||||
Size: int64(len(data)),
|
Size: int64(len(data)),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
hash, err := client.Upload(file, "")
|
hash, err := client.Upload(file, "", false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -205,12 +205,12 @@ type manifestTrieEntry struct {
|
||||||
func loadManifest(dpa *storage.DPA, hash storage.Key, quitC chan bool) (trie *manifestTrie, err error) { // non-recursive, subtrees are downloaded on-demand
|
func loadManifest(dpa *storage.DPA, hash storage.Key, quitC chan bool) (trie *manifestTrie, err error) { // non-recursive, subtrees are downloaded on-demand
|
||||||
log.Trace("manifest lookup", "key", hash)
|
log.Trace("manifest lookup", "key", hash)
|
||||||
// retrieve manifest via DPA
|
// retrieve manifest via DPA
|
||||||
manifestReader := dpa.Retrieve(hash)
|
manifestReader, isEncrypted := dpa.Retrieve(hash)
|
||||||
log.Trace("reader retrieved", "key", hash)
|
log.Trace("reader retrieved", "key", hash)
|
||||||
return readManifest(manifestReader, hash, dpa, quitC)
|
return readManifest(manifestReader, hash, dpa, isEncrypted, quitC)
|
||||||
}
|
}
|
||||||
|
|
||||||
func readManifest(manifestReader storage.LazySectionReader, hash storage.Key, dpa *storage.DPA, quitC chan bool) (trie *manifestTrie, err error) { // non-recursive, subtrees are downloaded on-demand
|
func readManifest(manifestReader storage.LazySectionReader, hash storage.Key, dpa *storage.DPA, isEncrypted bool, quitC chan bool) (trie *manifestTrie, err error) { // non-recursive, subtrees are downloaded on-demand
|
||||||
|
|
||||||
// TODO check size for oversized manifests
|
// TODO check size for oversized manifests
|
||||||
size, err := manifestReader.Size(quitC)
|
size, err := manifestReader.Size(quitC)
|
||||||
|
|
@ -245,7 +245,7 @@ func readManifest(manifestReader storage.LazySectionReader, hash storage.Key, dp
|
||||||
|
|
||||||
trie = &manifestTrie{
|
trie = &manifestTrie{
|
||||||
dpa: dpa,
|
dpa: dpa,
|
||||||
encrypted: (len(hash) > dpa.HashSize()),
|
encrypted: isEncrypted,
|
||||||
}
|
}
|
||||||
for _, entry := range man.Entries {
|
for _, entry := range man.Entries {
|
||||||
trie.addEntry(entry, quitC)
|
trie.addEntry(entry, quitC)
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ func testGetEntry(t *testing.T, path, match string, multiple bool, paths ...stri
|
||||||
quitC := make(chan bool)
|
quitC := make(chan bool)
|
||||||
dpa := storage.NewDPA(nil, storage.NewDPAParams())
|
dpa := storage.NewDPA(nil, storage.NewDPAParams())
|
||||||
ref := make([]byte, dpa.HashSize())
|
ref := make([]byte, dpa.HashSize())
|
||||||
trie, err := readManifest(manifest(paths...), ref, dpa, quitC)
|
trie, err := readManifest(manifest(paths...), ref, dpa, false, quitC)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error making manifest: %v", err)
|
t.Errorf("unexpected error making manifest: %v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -101,7 +101,7 @@ func TestExactMatch(t *testing.T) {
|
||||||
mf := manifest("shouldBeExactMatch.css", "shouldBeExactMatch.css.map")
|
mf := manifest("shouldBeExactMatch.css", "shouldBeExactMatch.css.map")
|
||||||
dpa := storage.NewDPA(nil, storage.NewDPAParams())
|
dpa := storage.NewDPA(nil, storage.NewDPAParams())
|
||||||
ref := make([]byte, dpa.HashSize())
|
ref := make([]byte, dpa.HashSize())
|
||||||
trie, err := readManifest(mf, ref, dpa, quitC)
|
trie, err := readManifest(mf, ref, dpa, false, quitC)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("unexpected error making manifest: %v", err)
|
t.Errorf("unexpected error making manifest: %v", err)
|
||||||
}
|
}
|
||||||
|
|
@ -134,7 +134,7 @@ func TestAddFileWithManifestPath(t *testing.T) {
|
||||||
}
|
}
|
||||||
dpa := storage.NewDPA(nil, storage.NewDPAParams())
|
dpa := storage.NewDPA(nil, storage.NewDPAParams())
|
||||||
ref := make([]byte, dpa.HashSize())
|
ref := make([]byte, dpa.HashSize())
|
||||||
trie, err := readManifest(reader, ref, dpa, nil)
|
trie, err := readManifest(reader, ref, dpa, false, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -82,7 +82,7 @@ func (file *SwarmFile) Attr(ctx context.Context, a *fuse.Attr) error {
|
||||||
a.Gid = uint32(os.Getegid())
|
a.Gid = uint32(os.Getegid())
|
||||||
|
|
||||||
if file.fileSize == -1 {
|
if file.fileSize == -1 {
|
||||||
reader := file.mountInfo.swarmApi.Retrieve(file.key)
|
reader, _ := file.mountInfo.swarmApi.Retrieve(file.key)
|
||||||
quitC := make(chan bool)
|
quitC := make(chan bool)
|
||||||
size, err := reader.Size(quitC)
|
size, err := reader.Size(quitC)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -99,7 +99,7 @@ func (sf *SwarmFile) Read(ctx context.Context, req *fuse.ReadRequest, resp *fuse
|
||||||
sf.lock.RLock()
|
sf.lock.RLock()
|
||||||
defer sf.lock.RUnlock()
|
defer sf.lock.RUnlock()
|
||||||
if sf.reader == nil {
|
if sf.reader == nil {
|
||||||
sf.reader = sf.mountInfo.swarmApi.Retrieve(sf.key)
|
sf.reader, _ = sf.mountInfo.swarmApi.Retrieve(sf.key)
|
||||||
}
|
}
|
||||||
buf := make([]byte, req.Size)
|
buf := make([]byte, req.Size)
|
||||||
n, err := sf.reader.ReadAt(buf, req.Offset)
|
n, err := sf.reader.ReadAt(buf, req.Offset)
|
||||||
|
|
|
||||||
|
|
@ -216,7 +216,7 @@ func (r *TestRegistry) APIs() []rpc.API {
|
||||||
}
|
}
|
||||||
|
|
||||||
func readAll(dpa *storage.DPA, hash []byte) (int64, error) {
|
func readAll(dpa *storage.DPA, hash []byte) (int64, error) {
|
||||||
r := dpa.Retrieve(hash)
|
r, _ := dpa.Retrieve(hash)
|
||||||
buf := make([]byte, 1024)
|
buf := make([]byte, 1024)
|
||||||
var n int
|
var n int
|
||||||
var total int64
|
var total int64
|
||||||
|
|
|
||||||
|
|
@ -89,9 +89,12 @@ func NewDPA(store ChunkStore, params *DPAParams) *DPA {
|
||||||
// FS-aware API and httpaccess
|
// FS-aware API and httpaccess
|
||||||
// Chunk retrieval blocks on netStore requests with a timeout so reader will
|
// Chunk retrieval blocks on netStore requests with a timeout so reader will
|
||||||
// report error if retrieval of chunks within requested range time out.
|
// report error if retrieval of chunks within requested range time out.
|
||||||
func (self *DPA) Retrieve(key Key) LazySectionReader {
|
// It returns a reader with the chunk data and whether the content was encrypted
|
||||||
getter := NewHasherStore(self.ChunkStore, self.hashFunc, len(key) > self.hashFunc().Size())
|
func (self *DPA) Retrieve(key Key) (reader LazySectionReader, isEncrypted bool) {
|
||||||
return TreeJoin(key, getter, 0)
|
isEncrypted = len(key) > self.hashFunc().Size()
|
||||||
|
getter := NewHasherStore(self.ChunkStore, self.hashFunc, isEncrypted)
|
||||||
|
reader = TreeJoin(key, getter, 0)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Public API. Main entry point for document storage directly. Used by the
|
// Public API. Main entry point for document storage directly. Used by the
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,10 @@ func testDpaRandom(toEncrypt bool, t *testing.T) {
|
||||||
t.Errorf("Store error: %v", err)
|
t.Errorf("Store error: %v", err)
|
||||||
}
|
}
|
||||||
wait()
|
wait()
|
||||||
resultReader := dpa.Retrieve(key)
|
resultReader, isEncrypted := dpa.Retrieve(key)
|
||||||
|
if isEncrypted != toEncrypt {
|
||||||
|
t.Fatalf("isEncrypted expected %v got %v", toEncrypt, isEncrypted)
|
||||||
|
}
|
||||||
resultSlice := make([]byte, len(slice))
|
resultSlice := make([]byte, len(slice))
|
||||||
n, err := resultReader.ReadAt(resultSlice, 0)
|
n, err := resultReader.ReadAt(resultSlice, 0)
|
||||||
if err != io.EOF {
|
if err != io.EOF {
|
||||||
|
|
@ -69,7 +72,10 @@ func testDpaRandom(toEncrypt bool, t *testing.T) {
|
||||||
ioutil.WriteFile("/tmp/slice.bzz.16M", slice, 0666)
|
ioutil.WriteFile("/tmp/slice.bzz.16M", slice, 0666)
|
||||||
ioutil.WriteFile("/tmp/result.bzz.16M", resultSlice, 0666)
|
ioutil.WriteFile("/tmp/result.bzz.16M", resultSlice, 0666)
|
||||||
localStore.memStore = NewMemStore(db, defaultCacheCapacity)
|
localStore.memStore = NewMemStore(db, defaultCacheCapacity)
|
||||||
resultReader = dpa.Retrieve(key)
|
resultReader, isEncrypted = dpa.Retrieve(key)
|
||||||
|
if isEncrypted != toEncrypt {
|
||||||
|
t.Fatalf("isEncrypted expected %v got %v", toEncrypt, isEncrypted)
|
||||||
|
}
|
||||||
for i := range resultSlice {
|
for i := range resultSlice {
|
||||||
resultSlice[i] = 0
|
resultSlice[i] = 0
|
||||||
}
|
}
|
||||||
|
|
@ -109,7 +115,10 @@ func testDPA_capacity(toEncrypt bool, t *testing.T) {
|
||||||
t.Errorf("Store error: %v", err)
|
t.Errorf("Store error: %v", err)
|
||||||
}
|
}
|
||||||
wait()
|
wait()
|
||||||
resultReader := dpa.Retrieve(key)
|
resultReader, isEncrypted := dpa.Retrieve(key)
|
||||||
|
if isEncrypted != toEncrypt {
|
||||||
|
t.Fatalf("isEncrypted expected %v got %v", toEncrypt, isEncrypted)
|
||||||
|
}
|
||||||
resultSlice := make([]byte, len(slice))
|
resultSlice := make([]byte, len(slice))
|
||||||
n, err := resultReader.ReadAt(resultSlice, 0)
|
n, err := resultReader.ReadAt(resultSlice, 0)
|
||||||
if err != io.EOF {
|
if err != io.EOF {
|
||||||
|
|
@ -125,14 +134,20 @@ func testDPA_capacity(toEncrypt bool, t *testing.T) {
|
||||||
memStore.setCapacity(0)
|
memStore.setCapacity(0)
|
||||||
// check whether it is, indeed, empty
|
// check whether it is, indeed, empty
|
||||||
dpa.ChunkStore = memStore
|
dpa.ChunkStore = memStore
|
||||||
resultReader = dpa.Retrieve(key)
|
resultReader, isEncrypted = dpa.Retrieve(key)
|
||||||
|
if isEncrypted != toEncrypt {
|
||||||
|
t.Fatalf("isEncrypted expected %v got %v", toEncrypt, isEncrypted)
|
||||||
|
}
|
||||||
if _, err = resultReader.ReadAt(resultSlice, 0); err == nil {
|
if _, err = resultReader.ReadAt(resultSlice, 0); err == nil {
|
||||||
t.Errorf("Was able to read %d bytes from an empty memStore.", len(slice))
|
t.Errorf("Was able to read %d bytes from an empty memStore.", len(slice))
|
||||||
}
|
}
|
||||||
// check how it works with localStore
|
// check how it works with localStore
|
||||||
dpa.ChunkStore = localStore
|
dpa.ChunkStore = localStore
|
||||||
// localStore.dbStore.setCapacity(0)
|
// localStore.dbStore.setCapacity(0)
|
||||||
resultReader = dpa.Retrieve(key)
|
resultReader, isEncrypted = dpa.Retrieve(key)
|
||||||
|
if isEncrypted != toEncrypt {
|
||||||
|
t.Fatalf("isEncrypted expected %v got %v", toEncrypt, isEncrypted)
|
||||||
|
}
|
||||||
for i := range resultSlice {
|
for i := range resultSlice {
|
||||||
resultSlice[i] = 0
|
resultSlice[i] = 0
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue