upload chunks
This commit is contained in:
parent
c123051dd0
commit
1c5b200151
@ -4,10 +4,14 @@ import (
|
||||
"bytes"
|
||||
"crypto/sha1"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/fs"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strconv"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
@ -24,10 +28,83 @@ func (s *Service) PrepareStore() {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) StoreDir(checksum string) (string, error) {
|
||||
dir := filepath.Join(s.Config.StorePath, "original", checksum[0:0], checksum[1:1], checksum[2:])
|
||||
err := os.MkdirAll(dir, 0755)
|
||||
return dir, err
|
||||
}
|
||||
|
||||
func (s *Service) TempDir(checksum string) (string, error) {
|
||||
dir := filepath.Join(s.Config.StorePath, "tmp", checksum)
|
||||
err := os.MkdirAll(dir, 0755)
|
||||
return dir, err
|
||||
}
|
||||
|
||||
type FileChunks struct {
|
||||
N uint64
|
||||
Path fs.FS
|
||||
Name string
|
||||
}
|
||||
|
||||
func (s *Service) FileChunks(checksum string) ([]FileChunks, error) {
|
||||
base := filepath.Join(s.Config.StorePath, "tmp", checksum)
|
||||
baseDir := os.DirFS(base)
|
||||
dir, err := os.Open(base)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer dir.Close()
|
||||
|
||||
files, err := dir.Readdirnames(-1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
parts := []FileChunks{}
|
||||
for _, f := range files {
|
||||
n, err := strconv.ParseUint(f, 10, 64)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
parts = append(parts, FileChunks{n, baseDir, f})
|
||||
}
|
||||
|
||||
sort.Slice(parts, func(i, j int) bool {
|
||||
return parts[i].N < parts[j].N
|
||||
})
|
||||
return parts, nil
|
||||
}
|
||||
|
||||
func (s *Service) FileCreate(c *gin.Context) {
|
||||
var originalChecksum = c.Param("original_checksum")
|
||||
files, err := s.FileChunks(originalChecksum)
|
||||
if err != nil {
|
||||
s.Error(c, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
sum := sha1.New()
|
||||
size := uint64(0)
|
||||
for _, f := range files {
|
||||
b, err := fs.ReadFile(f.Path, f.Name)
|
||||
if err != nil {
|
||||
s.Error(c, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
sum.Write(b)
|
||||
size += uint64(len(b))
|
||||
}
|
||||
r := hex.EncodeToString(sum.Sum(nil))
|
||||
if r != originalChecksum {
|
||||
fmt.Printf("R=%s, O=%s\n", r, originalChecksum)
|
||||
s.Error(c, http.StatusExpectationFailed, ErrStoreMismatchChecksum)
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"original_checksum": originalChecksum,
|
||||
"status": "success",
|
||||
"checksum": originalChecksum,
|
||||
"nbParts": len(files),
|
||||
"size": size,
|
||||
})
|
||||
}
|
||||
|
||||
@ -47,18 +124,16 @@ func (s *Service) FileChunk(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
p, err := strconv.ParseUint(part, 10, 64)
|
||||
if err != nil || p < 1 {
|
||||
s.Error(c, http.StatusBadRequest, ErrStoreBadPartNumber)
|
||||
return
|
||||
}
|
||||
|
||||
b := bytes.NewBuffer([]byte{})
|
||||
io.Copy(b, c.Request.Body)
|
||||
c.Request.Body.Close()
|
||||
|
||||
f, err := os.Create(filepath.Join(s.Config.StorePath, "test"))
|
||||
if err != nil {
|
||||
s.Error(c, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
f.Write(b.Bytes())
|
||||
f.Close()
|
||||
|
||||
sum := sha1.New()
|
||||
sum.Write(b.Bytes())
|
||||
r := hex.EncodeToString(sum.Sum(nil))
|
||||
@ -68,13 +143,21 @@ func (s *Service) FileChunk(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
dir, err := s.TempDir(originalChecksum)
|
||||
if err != nil {
|
||||
s.Error(c, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
f, err := os.Create(filepath.Join(dir, part))
|
||||
if err != nil {
|
||||
s.Error(c, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
f.Write(b.Bytes())
|
||||
f.Close()
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"original_checksum": originalChecksum,
|
||||
"part": part,
|
||||
"part_checksum": partChecksum,
|
||||
"body": gin.H{
|
||||
"checksum": r,
|
||||
"size": b.Len(),
|
||||
},
|
||||
"status": "success",
|
||||
})
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user