move on on complete upload
This commit is contained in:
parent
87f2e08227
commit
0bd48fa166
@ -8,6 +8,7 @@ import (
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
@ -19,10 +20,11 @@ const (
|
||||
)
|
||||
|
||||
var (
|
||||
ErrUploadNotExists = errors.New("upload id doesn't exists")
|
||||
ErrUploadPartTooLarge = fmt.Errorf("upload part too large (> %d B)", MaxUploadPartSize)
|
||||
ErrUploadPartWrongSha256 = errors.New("upload part wrong sha256")
|
||||
ErrFileAlreadExists = errors.New("file already exists")
|
||||
ErrUploadNotExists = errors.New("upload id does not exists")
|
||||
ErrUploadPartTooLarge = fmt.Errorf("upload part too large (> %d B)", MaxUploadPartSize)
|
||||
ErrUploadPartWrongSha256 = errors.New("upload part sha256 does not match")
|
||||
ErrFileAlreadExists = errors.New("file already exists")
|
||||
ErrUploadPartsCombineWrongSha256 = errors.New("upload parts combined sha256 does not match")
|
||||
)
|
||||
|
||||
// Model
|
||||
@ -71,6 +73,36 @@ type UploadCompleteRequest struct {
|
||||
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) {
|
||||
var (
|
||||
upload Upload
|
||||
@ -156,13 +188,52 @@ func (s *Service) UploadComplete(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
f, err := s.StorageUpload.Stat(uploadCompleteRequest.Sha256[0:1], uploadCompleteRequest.Sha256[1:2], uploadCompleteRequest.Sha256)
|
||||
fmt.Println(err)
|
||||
if err == nil && f.Mode().IsRegular() {
|
||||
if f, err := s.StorageUpload.Stat(uploadCompleteRequest.File(nil)...); err == nil && f.Mode().IsRegular() {
|
||||
c.AbortWithError(http.StatusConflict, ErrFileAlreadExists)
|
||||
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)
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user