104 lines
2.2 KiB
Go
104 lines
2.2 KiB
Go
package api
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"path/filepath"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"gitlab.celogeek.com/photos/api/internal/photoserrors"
|
|
)
|
|
|
|
var CHUNK_SIZE int64 = 1 << 20
|
|
|
|
type File struct {
|
|
Sum string `json:"sum"`
|
|
Chunks []string `json:"chunks"`
|
|
}
|
|
|
|
func (s *Service) FileCreate(c *gin.Context) {
|
|
file := &File{}
|
|
if err := c.ShouldBindJSON(file); err != nil {
|
|
s.Error(c, http.StatusInternalServerError, err)
|
|
return
|
|
}
|
|
|
|
if len(file.Sum) != 40 {
|
|
s.Error(c, http.StatusBadRequest, photoserrors.ErrStoreBadChecksum)
|
|
return
|
|
}
|
|
if len(file.Chunks) == 0 {
|
|
s.Error(c, http.StatusBadRequest, photoserrors.ErrStoreMissingChunks)
|
|
return
|
|
}
|
|
|
|
for _, chunk := range file.Chunks {
|
|
if len(chunk) != 40 {
|
|
s.Error(c, http.StatusBadRequest, photoserrors.ErrStoreBadChecksum)
|
|
return
|
|
}
|
|
}
|
|
|
|
r, rs, err := s.Store.CombineTemp(file.Sum, file.Chunks)
|
|
if err != nil {
|
|
s.Error(c, http.StatusInternalServerError, err)
|
|
return
|
|
}
|
|
|
|
if r != file.Sum {
|
|
fmt.Printf("R=%s, O=%s\n", r, file.Sum)
|
|
s.Error(c, http.StatusExpectationFailed, photoserrors.ErrStoreMismatchChecksum)
|
|
return
|
|
}
|
|
|
|
if err = s.Store.CommitTemp(file.Sum, file.Chunks); err != nil {
|
|
s.Error(c, http.StatusInternalServerError, err)
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"status": "success",
|
|
"sum": file.Sum,
|
|
"nbChunks": len(file.Chunks),
|
|
"size": rs,
|
|
})
|
|
}
|
|
|
|
func (s *Service) FileCreateTemp(c *gin.Context) {
|
|
var (
|
|
origsum = c.Param("origsum")
|
|
sumb = c.Param("sum")
|
|
)
|
|
if len(origsum) != 40 || len(sumb) != 40 {
|
|
s.Error(c, http.StatusBadRequest, photoserrors.ErrStoreBadChecksum)
|
|
return
|
|
}
|
|
|
|
originaldir := s.Store.Dir("original", origsum)
|
|
originalname := filepath.Join(originaldir, origsum)
|
|
if s.Store.FileExists(originalname) {
|
|
s.Error(c, http.StatusBadRequest, photoserrors.ErrStoreAlreadyExists)
|
|
return
|
|
}
|
|
|
|
if c.Request.ContentLength > CHUNK_SIZE {
|
|
s.Error(c, http.StatusBadRequest, photoserrors.ErrStoreBadChunkSize)
|
|
return
|
|
}
|
|
|
|
b := bytes.NewBuffer([]byte{})
|
|
io.Copy(b, c.Request.Body)
|
|
c.Request.Body.Close()
|
|
|
|
if err := s.Store.SaveTemp(origsum, sumb, b.Bytes()); err != nil {
|
|
s.Error(c, http.StatusBadRequest, err)
|
|
return
|
|
}
|
|
|
|
c.JSON(http.StatusOK, gin.H{
|
|
"status": "success",
|
|
})
|
|
}
|