Feat: get permanent URL for OneDrive policy

pull/807/head
HFO4 3 years ago
parent 6fb419d998
commit a5f80a4431

@ -12,6 +12,7 @@ import (
"time"
model "github.com/cloudreve/Cloudreve/v3/models"
"github.com/cloudreve/Cloudreve/v3/pkg/auth"
"github.com/cloudreve/Cloudreve/v3/pkg/cache"
"github.com/cloudreve/Cloudreve/v3/pkg/filesystem/fsctx"
"github.com/cloudreve/Cloudreve/v3/pkg/filesystem/response"
@ -155,6 +156,19 @@ func (handler Driver) Source(
cacheKey := fmt.Sprintf("onedrive_source_%d_%s", handler.Policy.ID, path)
if file, ok := ctx.Value(fsctx.FileModelCtx).(model.File); ok {
cacheKey = fmt.Sprintf("onedrive_source_file_%d_%d", file.UpdatedAt.Unix(), file.ID)
// 如果是永久链接,则返回签名后的中转外链
if ttl == 0 {
signedURI, err := auth.SignURI(
auth.General,
fmt.Sprintf("/api/v3/file/source/%d/%s", file.ID, file.Name),
ttl,
)
if err != nil {
return "", err
}
return baseURL.ResolveReference(signedURI).String(), nil
}
}
// 尝试从缓存中查找

@ -126,7 +126,7 @@ func (fs *FileSystem) Preview(ctx context.Context, id uint, isText bool) (*respo
// 否则重定向到签名的预览URL
ttl := model.GetIntSetting("preview_timeout", 60)
previewURL, err := fs.signURL(ctx, &fs.FileTarget[0], int64(ttl), false)
previewURL, err := fs.SignURL(ctx, &fs.FileTarget[0], int64(ttl), false)
if err != nil {
return nil, err
}
@ -234,7 +234,7 @@ func (fs *FileSystem) GetDownloadURL(ctx context.Context, id uint, timeout strin
// 生成下載地址
ttl := model.GetIntSetting(timeout, 60)
source, err := fs.signURL(
source, err := fs.SignURL(
ctx,
fileTarget,
int64(ttl),
@ -264,7 +264,7 @@ func (fs *FileSystem) GetSource(ctx context.Context, fileID uint) (string, error
)
}
source, err := fs.signURL(ctx, &fs.FileTarget[0], 0, false)
source, err := fs.SignURL(ctx, &fs.FileTarget[0], 0, false)
if err != nil {
return "", serializer.NewError(serializer.CodeNotSet, "无法获取外链", err)
}
@ -272,7 +272,8 @@ func (fs *FileSystem) GetSource(ctx context.Context, fileID uint) (string, error
return source, nil
}
func (fs *FileSystem) signURL(ctx context.Context, file *model.File, ttl int64, isDownload bool) (string, error) {
// SignURL 签名文件原始 URL
func (fs *FileSystem) SignURL(ctx context.Context, file *model.File, ttl int64, isDownload bool) (string, error) {
fs.FileTarget = []model.File{*file}
ctx = context.WithValue(ctx, fsctx.FileModelCtx, *file)

@ -88,6 +88,29 @@ func AnonymousGetContent(c *gin.Context) {
}
}
// AnonymousPermLink 文件签名后的永久链接
func AnonymousPermLink(c *gin.Context) {
// 创建上下文
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
var service explorer.FileAnonymousGetService
if err := c.ShouldBindUri(&service); err == nil {
res := service.Source(ctx, c)
// 是否需要重定向
if res.Code == -302 {
c.Redirect(302, res.Data.(string))
return
}
// 是否有错误发生
if res.Code != 0 {
c.JSON(200, res)
}
} else {
c.JSON(200, ErrorResponse(err))
}
}
// GetSource 获取文件的外链地址
func GetSource(c *gin.Context) {
// 创建上下文

@ -162,8 +162,10 @@ func InitMasterRouter() *gin.Engine {
{
file := sign.Group("file")
{
// 文件外链
// 文件外链(直接输出文件数据)
file.GET("get/:id/:name", controllers.AnonymousGetContent)
// 文件外链(301跳转)
file.GET("source/:id/:name", controllers.AnonymousPermLink)
// 下載已经打包好的文件
file.GET("archive/:id/archive.zip", controllers.DownloadArchive)
// 下载文件

@ -184,6 +184,33 @@ func (service *FileAnonymousGetService) Download(ctx context.Context, c *gin.Con
}
}
// Source 重定向到文件的有效原始链接
func (service *FileAnonymousGetService) Source(ctx context.Context, c *gin.Context) serializer.Response {
fs, err := filesystem.NewAnonymousFileSystem()
if err != nil {
return serializer.Err(serializer.CodeGroupNotAllowed, err.Error(), err)
}
defer fs.Recycle()
// 查找文件
err = fs.SetTargetFileByIDs([]uint{service.ID})
if err != nil {
return serializer.Err(serializer.CodeNotSet, err.Error(), err)
}
// 获取文件流
res, err := fs.SignURL(ctx, &fs.FileTarget[0],
int64(model.GetIntSetting("preview_timeout", 60)), false)
if err != nil {
return serializer.Err(serializer.CodeNotSet, err.Error(), err)
}
return serializer.Response{
Code: -302,
Data: res,
}
}
// CreateDocPreviewSession 创建DOC文件预览会话返回预览地址
func (service *FileIDService) CreateDocPreviewSession(ctx context.Context, c *gin.Context) serializer.Response {
// 创建文件系统

Loading…
Cancel
Save