mirror of
https://github.com/PeernetOfficial/core.git
synced 2026-07-17 02:47:51 +01:00
warehouse: Minor refactoring. Use native hash encoding for FileExists.
This commit is contained in:
@@ -7,9 +7,9 @@ Author: Peter Kleissner
|
|||||||
package warehouse
|
package warehouse
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/hex"
|
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ const (
|
|||||||
// CreateFile creates a new file in the warehouse
|
// CreateFile creates a new file in the warehouse
|
||||||
func (wh *Warehouse) CreateFile(data io.Reader) (hash []byte, status int, err error) {
|
func (wh *Warehouse) CreateFile(data io.Reader) (hash []byte, status int, err error) {
|
||||||
// create a temporary file to hold the body content
|
// create a temporary file to hold the body content
|
||||||
tmpFile, err := wh.TempFile()
|
tmpFile, err := wh.tempFile()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, StatusErrorCreateTempFile, err
|
return nil, StatusErrorCreateTempFile, err
|
||||||
}
|
}
|
||||||
@@ -60,10 +60,9 @@ func (wh *Warehouse) CreateFile(data io.Reader) (hash []byte, status int, err er
|
|||||||
}
|
}
|
||||||
|
|
||||||
hash = hashWriter.Sum(nil)
|
hash = hashWriter.Sum(nil)
|
||||||
hashA := hex.EncodeToString(hash)
|
|
||||||
|
|
||||||
// Check if the file exists
|
// Check if the file exists
|
||||||
if _, _, valid := wh.FileExists(hashA); valid {
|
if _, _, status, _ := wh.FileExists(hash); status == StatusOK {
|
||||||
// file exists already, temp file not needed
|
// file exists already, temp file not needed
|
||||||
os.Remove(tmpFileName)
|
os.Remove(tmpFileName)
|
||||||
|
|
||||||
@@ -72,7 +71,7 @@ func (wh *Warehouse) CreateFile(data io.Reader) (hash []byte, status int, err er
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Destination
|
// Destination
|
||||||
pathFull, err := wh.createFilePath(hashA)
|
pathFull, err := wh.createFilePath(hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
os.Remove(tmpFileName)
|
os.Remove(tmpFileName)
|
||||||
return nil, StatusErrorCreatePath, err
|
return nil, StatusErrorCreatePath, err
|
||||||
@@ -117,20 +116,13 @@ func (wh *Warehouse) CreateFileFromPath(file string) (hash []byte, status int, e
|
|||||||
// ReadFile reads a file from the warehouse and outputs it to the writer
|
// ReadFile reads a file from the warehouse and outputs it to the writer
|
||||||
// Offset is the position in the file to start reading. Limit (0 = not used) defines how many bytes to read starting at the offset.
|
// Offset is the position in the file to start reading. Limit (0 = not used) defines how many bytes to read starting at the offset.
|
||||||
func (wh *Warehouse) ReadFile(hash []byte, offset, limit int64, writer io.Writer) (status int, err error) {
|
func (wh *Warehouse) ReadFile(hash []byte, offset, limit int64, writer io.Writer) (status int, err error) {
|
||||||
hashA, err := ValidateHash(hash)
|
path, _, status, err := wh.FileExists(hash)
|
||||||
if err != nil {
|
if status != StatusOK { // file does not exist or invalid hash
|
||||||
return StatusInvalidHash, err
|
return status, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// read the file from disk
|
||||||
var reader io.ReadSeeker
|
var reader io.ReadSeeker
|
||||||
|
|
||||||
path, _, valid := wh.FileExists(hashA)
|
|
||||||
if !valid {
|
|
||||||
// file does not exist
|
|
||||||
return StatusFileNotFound, os.ErrNotExist
|
|
||||||
}
|
|
||||||
|
|
||||||
// read from drive
|
|
||||||
retryCount := 0
|
retryCount := 0
|
||||||
retryOpenFile:
|
retryOpenFile:
|
||||||
|
|
||||||
@@ -174,14 +166,9 @@ retryOpenFile:
|
|||||||
|
|
||||||
// DeleteFile deletes a file from the warehouse
|
// DeleteFile deletes a file from the warehouse
|
||||||
func (wh *Warehouse) DeleteFile(hash []byte) (status int, err error) {
|
func (wh *Warehouse) DeleteFile(hash []byte) (status int, err error) {
|
||||||
hashA, err := ValidateHash(hash)
|
path, _, status, err := wh.FileExists(hash)
|
||||||
if err != nil {
|
if status != StatusOK {
|
||||||
return StatusInvalidHash, err
|
return status, err
|
||||||
}
|
|
||||||
|
|
||||||
path, _, valid := wh.FileExists(hashA)
|
|
||||||
if !valid {
|
|
||||||
return StatusFileNotFound, os.ErrNotExist
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := os.Remove(path); err != nil {
|
if err := os.Remove(path); err != nil {
|
||||||
@@ -190,3 +177,30 @@ func (wh *Warehouse) DeleteFile(hash []byte) (status int, err error) {
|
|||||||
|
|
||||||
return StatusOK, nil
|
return StatusOK, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FileExists checks if the file exists
|
||||||
|
func (wh *Warehouse) FileExists(hash []byte) (path string, fileInfo os.FileInfo, status int, err error) {
|
||||||
|
hashA, err := ValidateHash(hash)
|
||||||
|
if err != nil {
|
||||||
|
return "", nil, StatusInvalidHash, err
|
||||||
|
}
|
||||||
|
|
||||||
|
a, b := buildPath(wh.Directory, hashA)
|
||||||
|
path = filepath.Join(a, b)
|
||||||
|
|
||||||
|
if fileInfo, err := os.Stat(path); err == nil {
|
||||||
|
// file exists
|
||||||
|
return path, fileInfo, StatusOK, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return "", nil, StatusFileNotFound, os.ErrNotExist
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteWarehouse deletes all files in the warehouse
|
||||||
|
func (wh *Warehouse) DeleteWarehouse() (err error) {
|
||||||
|
return wh.IterateFiles(func(Hash []byte, Size int64) (Continue bool) {
|
||||||
|
wh.DeleteFile(Hash)
|
||||||
|
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -24,9 +24,6 @@ type Warehouse struct {
|
|||||||
Temp string // Temporary folder
|
Temp string // Temporary folder
|
||||||
}
|
}
|
||||||
|
|
||||||
// LogError is called for any error. The caller can use it to capture any errors.
|
|
||||||
//var LogError func(function, format string, v ...interface{}) = func(function, format string, v ...interface{}) {}
|
|
||||||
|
|
||||||
// Init initializes the warehouse
|
// Init initializes the warehouse
|
||||||
func Init(Directory string) (wh *Warehouse, err error) {
|
func Init(Directory string) (wh *Warehouse, err error) {
|
||||||
// The temp folder will always be a sub-folder named "_Temp"
|
// The temp folder will always be a sub-folder named "_Temp"
|
||||||
@@ -42,41 +39,6 @@ func Init(Directory string) (wh *Warehouse, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// TempFile creates a temporary file in the Warehouse. Do not forget to delete.
|
|
||||||
func (wh *Warehouse) TempFile() (file *os.File, err error) {
|
|
||||||
file, err = ioutil.TempFile(wh.Temp, "wh")
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// createFilePath creates the file path for the specified hash and returns the full file path
|
|
||||||
func (wh *Warehouse) createFilePath(hash string) (pathFull string, err error) {
|
|
||||||
path, filename := buildPath(wh.Directory, hash)
|
|
||||||
return filepath.Join(path, filename), createDirectory(path)
|
|
||||||
}
|
|
||||||
|
|
||||||
// FileExists checks if the file exists
|
|
||||||
func (wh *Warehouse) FileExists(hash string) (path string, fileInfo os.FileInfo, valid bool) {
|
|
||||||
a, b := buildPath(wh.Directory, hash)
|
|
||||||
path = filepath.Join(a, b)
|
|
||||||
|
|
||||||
if fileInfo, err := os.Stat(path); err == nil {
|
|
||||||
// file exists
|
|
||||||
return path, fileInfo, true
|
|
||||||
}
|
|
||||||
|
|
||||||
return "", nil, false
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeleteWarehouse deletes all files in the warehouse
|
|
||||||
func (wh *Warehouse) DeleteWarehouse() (err error) {
|
|
||||||
return wh.IterateFiles(func(Hash []byte, Size int64) (Continue bool) {
|
|
||||||
wh.DeleteFile(Hash)
|
|
||||||
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---- hash functions ----
|
// ---- hash functions ----
|
||||||
|
|
||||||
func ValidateHash(hash []byte) (hashA string, err error) {
|
func ValidateHash(hash []byte) (hashA string, err error) {
|
||||||
@@ -106,6 +68,19 @@ func buildPath(storagePath, hash string) (directory string, filename string) {
|
|||||||
return newPath, filename
|
return newPath, filename
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// tempFile creates a temporary file in the Warehouse. Do not forget to delete.
|
||||||
|
func (wh *Warehouse) tempFile() (file *os.File, err error) {
|
||||||
|
file, err = ioutil.TempFile(wh.Temp, "wh")
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// createFilePath creates the file path for the specified hash and returns the full file path
|
||||||
|
func (wh *Warehouse) createFilePath(hash []byte) (pathFull string, err error) {
|
||||||
|
path, filename := buildPath(wh.Directory, hex.EncodeToString(hash))
|
||||||
|
return filepath.Join(path, filename), createDirectory(path)
|
||||||
|
}
|
||||||
|
|
||||||
// IterateFiles iterates through all the files and calls the callback
|
// IterateFiles iterates through all the files and calls the callback
|
||||||
func (wh *Warehouse) IterateFiles(Callback func(Hash []byte, Size int64) (Continue bool)) (err error) {
|
func (wh *Warehouse) IterateFiles(Callback func(Hash []byte, Size int64) (Continue bool)) (err error) {
|
||||||
// list all directories in the local Storage folder. We have to walk 2 levels down to see the actual files.
|
// list all directories in the local Storage folder. We have to walk 2 levels down to see the actual files.
|
||||||
|
|||||||
@@ -145,10 +145,10 @@ func apiBlockchainFileAdd(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
// Verify that the file exists in the warehouse. Folders are exempt from this check as they are only virtual.
|
// Verify that the file exists in the warehouse. Folders are exempt from this check as they are only virtual.
|
||||||
if !file.IsVirtualFolder() {
|
if !file.IsVirtualFolder() {
|
||||||
if hashA, err := warehouse.ValidateHash(file.Hash); err != nil {
|
if _, err := warehouse.ValidateHash(file.Hash); err != nil {
|
||||||
http.Error(w, "", http.StatusBadRequest)
|
http.Error(w, "", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
} else if _, _, valid := core.UserWarehouse.FileExists(hashA); !valid {
|
} else if _, _, status, _ := core.UserWarehouse.FileExists(file.Hash); status != warehouse.StatusOK {
|
||||||
EncodeJSON(w, r, apiBlockchainBlockStatus{Status: blockchain.StatusNotInWarehouse})
|
EncodeJSON(w, r, apiBlockchainBlockStatus{Status: blockchain.StatusNotInWarehouse})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -233,10 +233,10 @@ func apiBlockchainFileUpdate(w http.ResponseWriter, r *http.Request) {
|
|||||||
for _, file := range input.Files {
|
for _, file := range input.Files {
|
||||||
// Verify that the file exists in the warehouse. Folders are exempt from this check as they are only virtual.
|
// Verify that the file exists in the warehouse. Folders are exempt from this check as they are only virtual.
|
||||||
if !file.IsVirtualFolder() {
|
if !file.IsVirtualFolder() {
|
||||||
if hashA, err := warehouse.ValidateHash(file.Hash); err != nil {
|
if _, err := warehouse.ValidateHash(file.Hash); err != nil {
|
||||||
http.Error(w, "", http.StatusBadRequest)
|
http.Error(w, "", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
} else if _, _, valid := core.UserWarehouse.FileExists(hashA); !valid {
|
} else if _, _, status, _ := core.UserWarehouse.FileExists(file.Hash); status != warehouse.StatusOK {
|
||||||
EncodeJSON(w, r, apiBlockchainBlockStatus{Status: blockchain.StatusNotInWarehouse})
|
EncodeJSON(w, r, apiBlockchainBlockStatus{Status: blockchain.StatusNotInWarehouse})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user