mirror of
https://github.com/eyebluecn/tank.git
synced 2026-10-20 00:15:40 +00:00
162 lines
5.8 KiB
Go
162 lines
5.8 KiB
Go
package rest
|
|
|
|
import (
|
|
"github.com/eyebluecn/tank/code/core"
|
|
"github.com/eyebluecn/tank/code/tool/result"
|
|
"github.com/eyebluecn/tank/code/tool/util"
|
|
"net/http"
|
|
)
|
|
|
|
// ChunkController handles chunked upload API endpoints
|
|
type ChunkController struct {
|
|
BaseController
|
|
chunkService *ChunkService
|
|
matterDao *MatterDao
|
|
uploadSessionDao *UploadSessionDao
|
|
uploadChunkDao *UploadChunkDao
|
|
}
|
|
|
|
func (this *ChunkController) Init() {
|
|
this.BaseController.Init()
|
|
|
|
b := core.CONTEXT.GetBean(this.chunkService)
|
|
if b, ok := b.(*ChunkService); ok {
|
|
this.chunkService = b
|
|
}
|
|
|
|
b = core.CONTEXT.GetBean(this.matterDao)
|
|
if b, ok := b.(*MatterDao); ok {
|
|
this.matterDao = b
|
|
}
|
|
|
|
b = core.CONTEXT.GetBean(this.uploadSessionDao)
|
|
if b, ok := b.(*UploadSessionDao); ok {
|
|
this.uploadSessionDao = b
|
|
}
|
|
|
|
b = core.CONTEXT.GetBean(this.uploadChunkDao)
|
|
if b, ok := b.(*UploadChunkDao); ok {
|
|
this.uploadChunkDao = b
|
|
}
|
|
}
|
|
|
|
func (this *ChunkController) RegisterRoutes() map[string]func(writer http.ResponseWriter, request *http.Request) {
|
|
routeMap := make(map[string]func(writer http.ResponseWriter, request *http.Request))
|
|
|
|
// Chunked upload endpoints
|
|
routeMap["/api/chunk/create/session"] = this.Wrap(this.CreateSession, USER_ROLE_USER)
|
|
routeMap["/api/chunk/upload"] = this.Wrap(this.Upload, USER_ROLE_USER)
|
|
routeMap["/api/chunk/merge"] = this.Wrap(this.Merge, USER_ROLE_USER)
|
|
routeMap["/api/chunk/session/info"] = this.Wrap(this.SessionInfo, USER_ROLE_USER)
|
|
routeMap["/api/chunk/cancel"] = this.Wrap(this.Cancel, USER_ROLE_USER)
|
|
routeMap["/api/chunk/clean/expired"] = this.Wrap(this.CleanExpired, USER_ROLE_ADMINISTRATOR)
|
|
|
|
return routeMap
|
|
}
|
|
|
|
// CreateSession creates a new chunked upload session
|
|
// Parameters:
|
|
// - puuid: parent directory uuid
|
|
// - filename: target filename
|
|
// - totalSize: total file size in bytes
|
|
// - chunkSize: size of each chunk (optional, default 5MB)
|
|
// - privacy: whether the file is private (optional, default true)
|
|
// - fileMd5: MD5 of the whole file (optional, for verification)
|
|
// - spaceUuid: space uuid (optional, default user's private space)
|
|
func (this *ChunkController) CreateSession(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
|
puuid := util.ExtractRequestString(request, "puuid")
|
|
filename := util.ExtractRequestString(request, "filename")
|
|
totalSize := util.ExtractRequestInt64(request, "totalSize")
|
|
chunkSize := util.ExtractRequestOptionalInt64(request, "chunkSize", DEFAULT_CHUNK_SIZE)
|
|
privacy := util.ExtractRequestOptionalBool(request, "privacy", true)
|
|
fileMd5 := util.ExtractRequestOptionalString(request, "fileMd5", "")
|
|
|
|
user := this.checkUser(request)
|
|
spaceUuid := util.ExtractRequestOptionalString(request, "spaceUuid", user.SpaceUuid)
|
|
space := this.spaceService.CheckWritableByUuid(request, user, spaceUuid)
|
|
|
|
dirMatter := this.matterDao.CheckWithRootByUuid(puuid, space)
|
|
|
|
session := this.chunkService.CreateSession(request, user, space, dirMatter, filename, totalSize, chunkSize, privacy, fileMd5)
|
|
|
|
return this.Success(session)
|
|
}
|
|
|
|
// Upload uploads a single chunk
|
|
// Parameters:
|
|
// - sessionUuid: upload session uuid
|
|
// - chunkIndex: chunk index (0-based)
|
|
// - file: chunk file data
|
|
// - chunkMd5: MD5 of the chunk (optional, for verification)
|
|
// - spaceUuid: space uuid (optional)
|
|
func (this *ChunkController) Upload(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
|
sessionUuid := util.ExtractRequestString(request, "sessionUuid")
|
|
chunkIndex := util.ExtractRequestInt(request, "chunkIndex")
|
|
chunkMd5 := util.ExtractRequestOptionalString(request, "chunkMd5", "")
|
|
|
|
user := this.checkUser(request)
|
|
spaceUuid := util.ExtractRequestOptionalString(request, "spaceUuid", user.SpaceUuid)
|
|
space := this.spaceService.CheckWritableByUuid(request, user, spaceUuid)
|
|
|
|
file, _, err := request.FormFile("file")
|
|
if err != nil {
|
|
panic(result.BadRequest("file is required: %s", err.Error()))
|
|
}
|
|
defer file.Close()
|
|
|
|
chunk := this.chunkService.UploadChunk(request, sessionUuid, chunkIndex, file, chunkMd5, user, space)
|
|
|
|
return this.Success(chunk)
|
|
}
|
|
|
|
// Merge merges all chunks into the final file
|
|
// Parameters:
|
|
// - sessionUuid: upload session uuid
|
|
// - spaceUuid: space uuid (optional)
|
|
func (this *ChunkController) Merge(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
|
sessionUuid := util.ExtractRequestString(request, "sessionUuid")
|
|
|
|
user := this.checkUser(request)
|
|
spaceUuid := util.ExtractRequestOptionalString(request, "spaceUuid", user.SpaceUuid)
|
|
space := this.spaceService.CheckWritableByUuid(request, user, spaceUuid)
|
|
|
|
matter := this.chunkService.MergeChunks(request, sessionUuid, user, space)
|
|
|
|
return this.Success(matter)
|
|
}
|
|
|
|
// SessionInfo gets the upload session info including uploaded chunks
|
|
// Parameters:
|
|
// - sessionUuid: upload session uuid
|
|
func (this *ChunkController) SessionInfo(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
|
sessionUuid := util.ExtractRequestString(request, "sessionUuid")
|
|
|
|
user := this.checkUser(request)
|
|
|
|
sessionInfo := this.chunkService.GetSessionInfo(sessionUuid, user)
|
|
|
|
return this.Success(sessionInfo)
|
|
}
|
|
|
|
// Cancel cancels an upload session
|
|
// Parameters:
|
|
// - sessionUuid: upload session uuid
|
|
// - spaceUuid: space uuid (optional)
|
|
func (this *ChunkController) Cancel(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
|
sessionUuid := util.ExtractRequestString(request, "sessionUuid")
|
|
|
|
user := this.checkUser(request)
|
|
spaceUuid := util.ExtractRequestOptionalString(request, "spaceUuid", user.SpaceUuid)
|
|
space := this.spaceService.CheckWritableByUuid(request, user, spaceUuid)
|
|
|
|
this.chunkService.CancelSession(sessionUuid, user, space)
|
|
|
|
return this.Success("OK")
|
|
}
|
|
|
|
// CleanExpired cleans up expired upload sessions (admin only)
|
|
func (this *ChunkController) CleanExpired(writer http.ResponseWriter, request *http.Request) *result.WebResult {
|
|
this.chunkService.CleanExpiredSessions()
|
|
return this.Success("OK")
|
|
}
|