Feat: get permanent URL for OneDrive policy
This commit is contained in:
parent
6fb419d998
commit
a5f80a4431
5 changed files with 72 additions and 5 deletions
|
@ -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…
Add table
Reference in a new issue