upload chunks

This commit is contained in:
celogeek 2022-03-01 15:13:27 +01:00
parent c123051dd0
commit 1c5b200151
Signed by: celogeek
GPG Key ID: E6B7BDCFC446233A

View File

@ -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",
})
}