diff --git a/models/migration.go b/models/migration.go index 12b73c7..f1d87f2 100644 --- a/models/migration.go +++ b/models/migration.go @@ -102,6 +102,7 @@ solid #e9e9e9;"bgcolor="#fff"> 0 { + expires = time.Now().Unix() + ttl + } + + // 签名下载地址 + sourcePath := base64.RawURLEncoding.EncodeToString([]byte(file.SourceName)) + authInstance := auth.HMACAuth{SecretKey: []byte(handler.Policy.SecretKey)} + signedURI, err = auth.SignURI( + authInstance, + fmt.Sprintf("%s/%s", controller, sourcePath), + expires, + ) + + if err != nil { + return "", serializer.NewError(serializer.CodeEncryptError, "无法对URL进行签名", err) + } + + finalURL := serverURL.ResolveReference(signedURI).String() + return finalURL, nil + } // Token 获取上传策略和认证Token -// TODO 测试 func (handler Handler) Token(ctx context.Context, TTL int64, key string) (serializer.UploadCredential, error) { // 生成回调地址 siteURL := model.GetSiteURL() diff --git a/pkg/filesystem/response/common.go b/pkg/filesystem/response/common.go index fe95a6c..02a93bc 100644 --- a/pkg/filesystem/response/common.go +++ b/pkg/filesystem/response/common.go @@ -7,11 +7,11 @@ import "io" // 有些直接写文件数据到浏览器 type ContentResponse struct { Redirect bool - Content io.ReadSeeker + Content RSCloser URL string } -// 存储策略适配器返回的文件流,有些策略需要带有Closer +// RSCloser 存储策略适配器返回的文件流,有些策略需要带有Closer type RSCloser interface { io.ReadSeeker io.Closer diff --git a/routers/controllers/file.go b/routers/controllers/file.go index 2a64b01..01e2436 100644 --- a/routers/controllers/file.go +++ b/routers/controllers/file.go @@ -151,7 +151,9 @@ func Preview(c *gin.Context) { // 是否需要重定向 if res.Code == -301 { c.Redirect(301, res.Data.(string)) + return } + // 是否有错误发生 if res.Code != 0 { c.JSON(200, res) } diff --git a/service/explorer/file.go b/service/explorer/file.go index 588a652..20dd8b2 100644 --- a/service/explorer/file.go +++ b/service/explorer/file.go @@ -196,14 +196,24 @@ func (service *SingleFileService) PreviewContent(ctx context.Context, c *gin.Con } defer fs.Recycle() - // 获取文件流 - rs, err := fs.GetDownloadContent(ctx, service.Path) + // 获取文件预览响应 + resp, err := fs.Preview(ctx, service.Path) if err != nil { return serializer.Err(serializer.CodeNotSet, err.Error(), err) } - defer rs.Close() - http.ServeContent(c.Writer, c.Request, fs.FileTarget[0].Name, fs.FileTarget[0].UpdatedAt, rs) + // 重定向到文件源 + if resp.Redirect { + return serializer.Response{ + Code: -301, + Data: resp.URL, + } + } + + // 直接返回文件内容 + defer resp.Content.Close() + + http.ServeContent(c.Writer, c.Request, fs.FileTarget[0].Name, fs.FileTarget[0].UpdatedAt, resp.Content) return serializer.Response{ Code: 0,