simplify error, compute global sha

This commit is contained in:
celogeek 2022-05-14 16:35:44 +02:00
parent 2078373889
commit fff782569f
Signed by: celogeek
GPG Key ID: E6B7BDCFC446233A
3 changed files with 83 additions and 35 deletions

View File

@ -9,6 +9,7 @@ import (
"io"
"os"
"path/filepath"
"strings"
"sync"
"github.com/go-resty/resty/v2"
@ -24,8 +25,15 @@ type UploadCommand struct {
}
type UploadError struct {
Error string `json:"error"`
Status string `json:"string"`
Err string `json:"error"`
Details []string `json:"details"`
}
func (u *UploadError) Error() string {
if len(u.Details) == 0 {
return u.Err
}
return fmt.Sprintf("%s: \n - %s", u.Err, strings.Join(u.Details, "\n - "))
}
type UploadCreate struct {
@ -39,6 +47,12 @@ type UploadPartResult struct {
PartSha256 string `json:"sha256"`
}
type UploadCompleteRequest struct {
Sha256 string `json:"sha256" binding:"required,sha256"`
Name string `json:"name" binding:"required"`
Parts uint `json:"parts" binding:"required"`
}
type UploadFileRequest struct {
Name string
Checksum string
@ -156,7 +170,7 @@ func (c *UploadCommand) FileUpload(sum string) error {
}
if err, ok := resp.Error().(*UploadError); ok {
wgErrors[w] = errors.New(err.Error)
wgErrors[w] = err
return
}
@ -179,7 +193,7 @@ func (c *UploadCommand) FileUpload(sum string) error {
if err, ok := resp.Error().(*UploadError); ok {
logger.Println("Upload failed")
return errors.New(err.Error)
return err
}
if result, ok := resp.Result().(*UploadFileResponse); ok {
@ -197,7 +211,7 @@ func (c *UploadCommand) Execute(args []string) error {
}
if err, ok := resp.Error().(*UploadError); ok {
return errors.New(err.Error)
return err
}
uploadId := resp.Result().(*UploadCreate).UploadId
@ -216,7 +230,8 @@ func (c *UploadCommand) Execute(args []string) error {
tee := io.TeeReader(f, progress)
b := make([]byte, photosapi.MaxUploadPartSize)
part := 0
parts := 0
completesha256 := sha256.New()
for {
n, err := tee.Read(b)
if err != nil {
@ -227,15 +242,16 @@ func (c *UploadCommand) Execute(args []string) error {
}
}
part++
parts++
partsha256 := sha256.New()
partsha256.Write(b[:n])
completesha256.Write(b[:n])
resp, err := cli.
R().
SetError(&UploadError{}).
SetResult(&UploadPartResult{}).
SetQueryParam("part", fmt.Sprint(part)).
SetQueryParam("part", fmt.Sprint(parts)).
SetQueryParam("sha256", hex.EncodeToString(partsha256.Sum(nil))).
SetBody(b[:n]).
SetPathParam("id", uploadId).
@ -246,16 +262,39 @@ func (c *UploadCommand) Execute(args []string) error {
}
if err, ok := resp.Error().(*UploadError); ok {
return errors.New(err.Error)
return err
}
}
fmt.Printf(
"Upload: %s\nParts: %d\n",
uploadId,
part,
parts,
)
resp, err = cli.
R().
SetError(&UploadError{}).
SetPathParam("id", uploadId).
SetBody(&UploadCompleteRequest{
Sha256: hex.EncodeToString(completesha256.Sum(nil)),
Parts: uint(parts),
Name: filepath.Base(c.File),
}).
Post("/upload/{id}")
if err != nil {
return err
}
if err, ok := resp.Error().(*UploadError); ok {
return err
}
fmt.Printf("Response: %s\n", resp.Body())
cli.R().SetPathParam("id", uploadId).Delete("/upload/{id}")
return nil
}

View File

@ -9,7 +9,6 @@ import (
"net/http"
"path/filepath"
"strings"
"time"
"github.com/dsoprea/go-exif/v3"
"github.com/gin-gonic/gin"
@ -30,28 +29,6 @@ var (
ErrStoreMissingName = errors.New("name required")
)
// Model
type File struct {
ID uint32 `gorm:"primary_key" json:"id"`
Name string `gorm:"not null" json:"name"`
Checksum string `gorm:"unique;size:44;not null"`
Size uint64 `gorm:"not null"`
Author *Account `gorm:"constraint:OnDelete:SET NULL,OnUpdate:CASCADE" json:"author"`
AuthorId *uint32 `json:"-"`
Chunks []*FileChunk `gorm:"constraint:OnDelete:CASCADE,OnUpdate:CASCADE"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
type FileChunk struct {
FileId uint32
File *File `gorm:"constraint:OnDelete:CASCADE,OnUpdate:CASCADE"`
Part uint32
Checksum string `gorm:"unique;size:44;not null"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
// Service
var CHUNK_SIZE int64 = 4 << 20

View File

@ -8,6 +8,7 @@ import (
"io"
"net/http"
"os"
"time"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
@ -23,6 +24,28 @@ var (
ErrUploadPartWrongSha256 = errors.New("upload part wrong sha256")
)
// Model
type File struct {
ID uint32 `gorm:"primary_key" json:"id"`
Name string `gorm:"not null" json:"name"`
Checksum string `gorm:"unique;size:44;not null"`
Size uint64 `gorm:"not null"`
Author *Account `gorm:"constraint:OnDelete:SET NULL,OnUpdate:CASCADE" json:"author"`
AuthorId *uint32 `json:"-"`
Chunks []*FileChunk `gorm:"constraint:OnDelete:CASCADE,OnUpdate:CASCADE"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
type FileChunk struct {
FileId uint32
File *File `gorm:"constraint:OnDelete:CASCADE,OnUpdate:CASCADE"`
Part uint32
Checksum string `gorm:"unique;size:44;not null"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
func (s *Service) UploadCreate(c *gin.Context) {
sha, err := uuid.NewRandom()
if err != nil {
@ -131,10 +154,19 @@ type UploadCompleteRequest struct {
}
func (s *Service) UploadComplete(c *gin.Context) {
var uploadCompleteRequest UploadCompleteRequest
if c.BindJSON(&uploadCompleteRequest) != nil {
var (
upload UploadUri
uploadCompleteRequest UploadCompleteRequest
)
if c.BindUri(&upload) != nil || c.BindJSON(&uploadCompleteRequest) != nil {
return
}
if !s.StorageTmp.Exists(upload.Id) {
c.AbortWithError(http.StatusNotFound, ErrUploadNotExists)
return
}
c.JSON(http.StatusOK, gin.H{
"sha256": uploadCompleteRequest.Sha256,
"parts": uploadCompleteRequest.Parts,