Compare commits

...

3 Commits

Author SHA1 Message Date
celogeek
0bd48fa166
move on on complete upload 2022-05-15 00:19:45 +02:00
celogeek
87f2e08227
clean faster 2022-05-15 00:19:16 +02:00
celogeek
0230a6ce4e
improve message 2022-05-15 00:19:10 +02:00
3 changed files with 81 additions and 8 deletions

View File

@ -98,6 +98,8 @@ func (c *UploadCommand) Execute(args []string) error {
- Name : %s - Name : %s
- Parts : %d - Parts : %d
- SHA256 : %s - SHA256 : %s
Committing...
`, `,
uploadId, uploadId,
completeRequest.Name, completeRequest.Name,

View File

@ -102,7 +102,7 @@ func (s *Service) CurrentSession(c *gin.Context) *Session {
func (s *Service) SessionCleaner() { func (s *Service) SessionCleaner() {
for range time.Tick(time.Minute) { for range time.Tick(time.Minute) {
t := time.Now().UTC().Add(-3 * time.Hour).Truncate(time.Minute) t := time.Now().UTC().Add(-30 * time.Minute).Truncate(time.Minute)
// s.LogOk.Printf("Session", "Cleaning old session < %s", t) // s.LogOk.Printf("Session", "Cleaning old session < %s", t)
if err := s.DB.Where("updated_at < ?", t).Delete(&Session{}).Error; err != nil { if err := s.DB.Where("updated_at < ?", t).Delete(&Session{}).Error; err != nil {
s.LogErr.Printf("Session", "Cleaning failed: %s", err) s.LogErr.Printf("Session", "Cleaning failed: %s", err)

View File

@ -8,6 +8,7 @@ import (
"io" "io"
"net/http" "net/http"
"os" "os"
"strings"
"time" "time"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
@ -19,10 +20,11 @@ const (
) )
var ( var (
ErrUploadNotExists = errors.New("upload id doesn't exists") ErrUploadNotExists = errors.New("upload id does not exists")
ErrUploadPartTooLarge = fmt.Errorf("upload part too large (> %d B)", MaxUploadPartSize) ErrUploadPartTooLarge = fmt.Errorf("upload part too large (> %d B)", MaxUploadPartSize)
ErrUploadPartWrongSha256 = errors.New("upload part wrong sha256") ErrUploadPartWrongSha256 = errors.New("upload part sha256 does not match")
ErrFileAlreadExists = errors.New("file already exists") ErrFileAlreadExists = errors.New("file already exists")
ErrUploadPartsCombineWrongSha256 = errors.New("upload parts combined sha256 does not match")
) )
// Model // Model
@ -71,6 +73,36 @@ type UploadCompleteRequest struct {
Parts uint `json:"parts" binding:"required"` Parts uint `json:"parts" binding:"required"`
} }
type UploadCompleteFileOptions struct {
Ext string
IsTemp bool
}
func (u *UploadCompleteRequest) Paths() []string {
return []string{u.Sha256[0:1], u.Sha256[1:2]}
}
func (u *UploadCompleteRequest) File(options *UploadCompleteFileOptions) []string {
filename := []string{}
if options == nil {
options = &UploadCompleteFileOptions{}
}
if options.IsTemp {
filename = append(filename, "._tmp_")
}
filename = append(filename, u.Sha256)
if len(options.Ext) > 0 {
filename = append(filename, ".", options.Ext)
}
return []string{
u.Sha256[0:1],
u.Sha256[1:2],
strings.Join(filename, ""),
}
}
func (s *Service) UploadPart(c *gin.Context) { func (s *Service) UploadPart(c *gin.Context) {
var ( var (
upload Upload upload Upload
@ -156,13 +188,52 @@ func (s *Service) UploadComplete(c *gin.Context) {
return return
} }
f, err := s.StorageUpload.Stat(uploadCompleteRequest.Sha256[0:1], uploadCompleteRequest.Sha256[1:2], uploadCompleteRequest.Sha256) if f, err := s.StorageUpload.Stat(uploadCompleteRequest.File(nil)...); err == nil && f.Mode().IsRegular() {
fmt.Println(err)
if err == nil && f.Mode().IsRegular() {
c.AbortWithError(http.StatusConflict, ErrFileAlreadExists) c.AbortWithError(http.StatusConflict, ErrFileAlreadExists)
return return
} }
if err := s.StorageUpload.Create(uploadCompleteRequest.Paths()...); err != nil {
c.AbortWithError(http.StatusInternalServerError, err)
return
}
f, err := os.Create(s.StorageUpload.Join(uploadCompleteRequest.File(&UploadCompleteFileOptions{IsTemp: true})...))
if err != nil {
c.AbortWithError(http.StatusInternalServerError, err)
return
}
fsha := sha256.New()
ft := io.MultiWriter(f, fsha)
defer f.Close()
for part := uint(1); part <= uploadCompleteRequest.Parts; part++ {
p, err := os.Open(s.StorageTmp.Join(upload.Id, fmt.Sprint(part)))
if err != nil {
c.AbortWithError(http.StatusNotFound, fmt.Errorf("upload part %d missing", part))
return
}
_, err = io.Copy(ft, p)
if err != nil {
c.AbortWithError(http.StatusInternalServerError, err)
return
}
}
if uploadCompleteRequest.Sha256 != hex.EncodeToString(fsha.Sum(nil)) {
c.AbortWithError(http.StatusExpectationFailed, ErrUploadPartsCombineWrongSha256)
return
}
f.Close()
if err := os.Rename(
s.StorageUpload.Join(uploadCompleteRequest.File(&UploadCompleteFileOptions{IsTemp: true})...),
s.StorageUpload.Join(uploadCompleteRequest.File(nil)...),
); err != nil {
c.AbortWithError(http.StatusInternalServerError, err)
return
}
c.Status(http.StatusNoContent) c.Status(http.StatusNoContent)
} }