Fix: download archived file anonymously

pull/247/head
HFO4 5 years ago
parent 00ef240bea
commit c102c74d6d

@ -27,6 +27,7 @@ type Group struct {
type GroupOption struct {
ArchiveDownloadEnabled bool `json:"archive_download"`
ArchiveTaskEnabled bool `json:"archive_task"`
OneTimeDownloadEnabled bool `json:"one_time_download"`
}
// GetAria2Option 获取用户离线下载设备

@ -38,13 +38,16 @@ func (fs *FileSystem) Compress(ctx context.Context, folderIDs, fileIDs []uint) (
}
// 创建临时压缩文件
zipFilePath := filepath.Join(model.GetSettingByName("temp_path"), fmt.Sprintf("archive_%d.zip", time.Now().UnixNano()))
zipFilePath := filepath.Join(
model.GetSettingByName("temp_path"),
fmt.Sprintf("archive_%d.zip", time.Now().UnixNano()),
)
zipFile, err := util.CreatNestedFile(zipFilePath)
defer zipFile.Close()
if err != nil {
util.Log().Warning("%s", err)
return "", err
}
defer zipFile.Close()
// 创建压缩文件Writer
zipWriter := zip.NewWriter(zipFile)

@ -2,7 +2,6 @@ package filesystem
import (
"context"
"errors"
"github.com/HFO4/cloudreve/models"
"github.com/HFO4/cloudreve/pkg/filesystem/local"
"github.com/HFO4/cloudreve/pkg/filesystem/response"
@ -121,10 +120,11 @@ func (fs *FileSystem) dispatchHandler() error {
}
// NewFileSystemFromContext 从gin.Context创建文件系统
// TODO 用户不存在时使用匿名文件系统
func NewFileSystemFromContext(c *gin.Context) (*FileSystem, error) {
user, exist := c.Get("user")
if !exist {
return nil, errors.New("无法找到用户")
return NewAnonymousFileSystem()
}
fs, err := NewFileSystem(user.(*model.User))
return fs, err

@ -40,6 +40,7 @@ type group struct {
AllowShare bool `json:"allowShare"`
AllowRemoteDownload bool `json:"allowRemoteDownload"`
AllowTorrentDownload bool `json:"allowTorrentDownload"`
AllowArchiveDownload bool `json:"allowArchiveDownload"`
}
type storage struct {
@ -72,6 +73,7 @@ func BuildUser(user model.User) User {
AllowShare: user.Group.ShareEnabled,
AllowRemoteDownload: aria2Option[0],
AllowTorrentDownload: aria2Option[2],
AllowArchiveDownload: user.Group.OptionsSerialized.ArchiveDownloadEnabled,
},
}
}

@ -4,7 +4,6 @@ import (
"github.com/HFO4/cloudreve/middleware"
"github.com/HFO4/cloudreve/pkg/conf"
"github.com/HFO4/cloudreve/routers/controllers"
"github.com/gin-contrib/cors"
"github.com/gin-contrib/pprof"
"github.com/gin-gonic/gin"
)
@ -19,13 +18,13 @@ func InitRouter() *gin.Engine {
*/
r.Use(middleware.Session(conf.SystemConfig.SessionSecret))
// CORS TODO: 根据配置文件来
r.Use(cors.New(cors.Config{
AllowOrigins: []string{"http://localhost:3000"},
AllowMethods: []string{"PUT", "POST", "GET", "OPTIONS"},
AllowHeaders: []string{"Cookie", "Content-Length", "Content-Type", "X-Path", "X-FileName"},
AllowCredentials: true,
}))
//// CORS TODO: 根据配置文件来
//r.Use(cors.New(cors.Config{
// AllowOrigins: []string{"http://localhost:3000"},
// AllowMethods: []string{"PUT", "POST", "GET", "OPTIONS"},
// AllowHeaders: []string{"Cookie", "Content-Length", "Content-Type", "X-Path", "X-FileName"},
// AllowCredentials: true,
//}))
// 测试模式加入Mock助手中间件
if gin.Mode() == gin.TestMode {
@ -67,8 +66,10 @@ func InitRouter() *gin.Engine {
{
file := sign.Group("file")
{
// 下載文件
// 文件外链
file.GET("get/:id/:name", controllers.AnonymousGetContent)
// 下載已经打包好的文件
file.GET("archive/:id/archive.zip", controllers.DownloadArchive)
}
}
@ -104,8 +105,6 @@ func InitRouter() *gin.Engine {
file.GET("source/:id", controllers.GetSource)
// 打包要下载的文件
file.POST("archive", controllers.Archive)
// 下載已经打包好的文件
file.Use(middleware.SignRequired()).GET("archive/:id", controllers.DownloadArchive)
}
// 目录

@ -6,11 +6,9 @@ import (
"github.com/HFO4/cloudreve/pkg/filesystem"
"github.com/HFO4/cloudreve/pkg/filesystem/fsctx"
"github.com/HFO4/cloudreve/pkg/serializer"
"github.com/HFO4/cloudreve/pkg/util"
"github.com/gin-gonic/gin"
"io"
"net/http"
"os"
"time"
)
@ -48,21 +46,20 @@ func (service *ArchiveDownloadService) Download(ctx context.Context, c *gin.Cont
return serializer.Err(serializer.CodeNotSet, err.Error(), err)
}
if fs.User.Group.OptionsSerialized.OneTimeDownloadEnabled {
// 清理资源,删除临时文件
_ = cache.Deletes([]string{service.ID}, "archive_")
}
c.Header("Content-Disposition", "attachment;")
c.Header("Content-Type", "application/zip")
http.ServeContent(c.Writer, c.Request, "archive.zip", time.Now(), rs)
http.ServeContent(c.Writer, c.Request, "", time.Now(), rs)
// 检查是否需要关闭文件
if fc, ok := rs.(io.Closer); ok {
err = fc.Close()
}
// 清理资源,删除临时文件
_ = cache.Deletes([]string{service.ID}, "archive_")
err = os.Remove(zipPath.(string))
if err != nil {
util.Log().Warning("无法删除临时文件 %s %s", zipPath, err)
}
return serializer.Response{
Code: 0,
}

@ -61,13 +61,13 @@ func (service *ItemService) Archive(ctx context.Context, c *gin.Context) seriali
}
zipID := util.RandStringRunes(16)
signedURI, err := auth.SignURI(
fmt.Sprintf("/api/v3/file/archive/%s", zipID),
time.Now().Unix()+120,
fmt.Sprintf("/api/v3/file/archive/%s/archive.zip", zipID),
time.Now().Unix()+30,
)
finalURL := siteURL.ResolveReference(signedURI).String()
// 将压缩文件记录存入缓存
err = cache.Set("archive_"+zipID, zipFile, 120)
err = cache.Set("archive_"+zipID, zipFile, 30)
if err != nil {
return serializer.Err(serializer.CodeIOFailed, "无法写入缓存", err)
}

Loading…
Cancel
Save