mirror of
https://github.com/wgh136/nysoure.git
synced 2025-09-27 04:17:23 +00:00
add SHA-1 hash calculation for file uploads and update related API and model structures
This commit is contained in:
@@ -34,6 +34,7 @@ func initUpload(c fiber.Ctx) error {
|
||||
FileSize int64 `json:"file_size"`
|
||||
ResourceID uint `json:"resource_id"`
|
||||
StorageID uint `json:"storage_id"`
|
||||
Sha1 string `json:"sha1"`
|
||||
}
|
||||
|
||||
var req InitUploadRequest
|
||||
@@ -41,7 +42,7 @@ func initUpload(c fiber.Ctx) error {
|
||||
return model.NewRequestError("Invalid request parameters")
|
||||
}
|
||||
|
||||
result, err := service.CreateUploadingFile(uid, req.Filename, req.Description, req.FileSize, req.ResourceID, req.StorageID)
|
||||
result, err := service.CreateUploadingFile(uid, req.Filename, req.Description, req.FileSize, req.ResourceID, req.StorageID, req.Sha1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@@ -2,14 +2,15 @@ package dao
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"nysoure/server/model"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
"nysoure/server/model"
|
||||
"time"
|
||||
)
|
||||
|
||||
func CreateUploadingFile(filename string, description string, fileSize int64, blockSize int64, tempPath string, resourceID, storageID, userID uint) (*model.UploadingFile, error) {
|
||||
func CreateUploadingFile(filename string, description string, fileSize int64, blockSize int64, tempPath string, resourceID, storageID, userID uint, sha1 string) (*model.UploadingFile, error) {
|
||||
blocksCount := (fileSize + blockSize - 1) / blockSize
|
||||
uf := &model.UploadingFile{
|
||||
Filename: filename,
|
||||
@@ -21,6 +22,7 @@ func CreateUploadingFile(filename string, description string, fileSize int64, bl
|
||||
TargetResourceID: resourceID,
|
||||
TargetStorageID: storageID,
|
||||
UserID: userID,
|
||||
Sha1: sha1,
|
||||
}
|
||||
if err := db.Create(uf).Error; err != nil {
|
||||
return nil, err
|
||||
|
@@ -2,9 +2,10 @@ package model
|
||||
|
||||
import (
|
||||
"context"
|
||||
"reflect"
|
||||
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/schema"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
type UploadingFile struct {
|
||||
@@ -20,6 +21,7 @@ type UploadingFile struct {
|
||||
TempPath string
|
||||
Resource Resource `gorm:"foreignKey:TargetResourceID"`
|
||||
Storage Storage `gorm:"foreignKey:TargetStorageID"`
|
||||
Sha1 string
|
||||
}
|
||||
|
||||
func (uf *UploadingFile) BlocksCount() int {
|
||||
@@ -84,6 +86,7 @@ type UploadingFileView struct {
|
||||
BlocksCount int `json:"blocksCount"`
|
||||
StorageID uint `json:"storageId"`
|
||||
ResourceID uint `json:"resourceId"`
|
||||
Sha1 string `json:"sha1"`
|
||||
}
|
||||
|
||||
func (uf *UploadingFile) ToView() *UploadingFileView {
|
||||
@@ -96,5 +99,6 @@ func (uf *UploadingFile) ToView() *UploadingFileView {
|
||||
BlocksCount: uf.BlocksCount(),
|
||||
StorageID: uf.TargetStorageID,
|
||||
ResourceID: uf.TargetResourceID,
|
||||
Sha1: uf.Sha1,
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,8 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"crypto/sha1"
|
||||
"encoding/hex"
|
||||
"nysoure/server/config"
|
||||
"nysoure/server/dao"
|
||||
"nysoure/server/model"
|
||||
@@ -82,10 +84,13 @@ func init() {
|
||||
}()
|
||||
}
|
||||
|
||||
func CreateUploadingFile(uid uint, filename string, description string, fileSize int64, resourceID, storageID uint) (*model.UploadingFileView, error) {
|
||||
func CreateUploadingFile(uid uint, filename string, description string, fileSize int64, resourceID, storageID uint, sha1Str string) (*model.UploadingFileView, error) {
|
||||
if filename == "" {
|
||||
return nil, model.NewRequestError("filename is empty")
|
||||
}
|
||||
if sha1Str == "" {
|
||||
return nil, model.NewRequestError("sha1 is empty")
|
||||
}
|
||||
if len([]rune(filename)) > 128 {
|
||||
return nil, model.NewRequestError("filename is too long")
|
||||
}
|
||||
@@ -113,7 +118,7 @@ func CreateUploadingFile(uid uint, filename string, description string, fileSize
|
||||
log.Error("failed to create temp dir: ", err)
|
||||
return nil, model.NewInternalServerError("failed to create temp dir")
|
||||
}
|
||||
uploadingFile, err := dao.CreateUploadingFile(filename, description, fileSize, blockSize, tempPath, resourceID, storageID, uid)
|
||||
uploadingFile, err := dao.CreateUploadingFile(filename, description, fileSize, blockSize, tempPath, resourceID, storageID, uid, sha1Str)
|
||||
if err != nil {
|
||||
log.Error("failed to create uploading file: ", err)
|
||||
_ = os.Remove(tempPath)
|
||||
@@ -197,6 +202,8 @@ func FinishUploadingFile(uid uint, fid uint) (*model.FileView, error) {
|
||||
return nil, model.NewInternalServerError("failed to finish uploading file. please re-upload")
|
||||
}
|
||||
|
||||
h := sha1.New()
|
||||
|
||||
for i := 0; i < uploadingFile.BlocksCount(); i++ {
|
||||
blockPath := filepath.Join(uploadingFile.TempPath, strconv.Itoa(i))
|
||||
data, err := os.ReadFile(blockPath)
|
||||
@@ -206,6 +213,13 @@ func FinishUploadingFile(uid uint, fid uint) (*model.FileView, error) {
|
||||
_ = os.Remove(resultFilePath)
|
||||
return nil, model.NewInternalServerError("failed to finish uploading file. please re-upload")
|
||||
}
|
||||
_, err = h.Write(data)
|
||||
if err != nil {
|
||||
log.Error("failed to write block data to sha1: ", err)
|
||||
_ = file.Close()
|
||||
_ = os.Remove(resultFilePath)
|
||||
return nil, model.NewInternalServerError("failed to finish uploading file. please re-upload")
|
||||
}
|
||||
if _, err := file.Write(data); err != nil {
|
||||
log.Error("failed to write result file: ", err)
|
||||
_ = file.Close()
|
||||
@@ -218,6 +232,13 @@ func FinishUploadingFile(uid uint, fid uint) (*model.FileView, error) {
|
||||
_ = os.RemoveAll(uploadingFile.TempPath)
|
||||
tempRemoved = true
|
||||
|
||||
sum := h.Sum(nil)
|
||||
sumStr := hex.EncodeToString(sum)
|
||||
if sumStr != uploadingFile.Sha1 {
|
||||
_ = os.Remove(resultFilePath)
|
||||
return nil, model.NewRequestError("sha1 checksum is not correct")
|
||||
}
|
||||
|
||||
s, err := dao.GetStorage(uploadingFile.TargetStorageID)
|
||||
if err != nil {
|
||||
log.Error("failed to get storage: ", err)
|
||||
|
Reference in New Issue
Block a user