diff --git a/drivers/alias/util.go b/drivers/alias/util.go index 69a88330d81..b19b0fc0ef5 100644 --- a/drivers/alias/util.go +++ b/drivers/alias/util.go @@ -2,12 +2,15 @@ package alias import ( "context" + "fmt" stdpath "path" "strings" "github.com/alist-org/alist/v3/internal/fs" "github.com/alist-org/alist/v3/internal/model" + "github.com/alist-org/alist/v3/internal/sign" "github.com/alist-org/alist/v3/pkg/utils" + "github.com/alist-org/alist/v3/server/common" ) func (d *Alias) listRoot() []model.Obj { @@ -76,6 +79,18 @@ func (d *Alias) list(ctx context.Context, dst, sub string) ([]model.Obj, error) } func (d *Alias) link(ctx context.Context, dst, sub string, args model.LinkArgs) (*model.Link, error) { - link, _, err := fs.Link(ctx, stdpath.Join(dst, sub), args) + reqPath := stdpath.Join(dst, sub) + storage, err := fs.GetStorage(reqPath) + if err != nil { + return nil, err + } + if common.ShouldProxy(storage, stdpath.Base(sub)) { + return &model.Link{ + URL: fmt.Sprintf("/p%s?sign=%s", + utils.EncodePath(reqPath, true), + sign.Sign(reqPath)), + }, nil + } + link, _, err := fs.Link(ctx, reqPath, args) return link, err } diff --git a/drivers/local/driver.go b/drivers/local/driver.go index fffeec9484e..e3943ee01e7 100644 --- a/drivers/local/driver.go +++ b/drivers/local/driver.go @@ -144,7 +144,7 @@ func (d *Local) Link(ctx context.Context, file model.Obj, args model.LinkArgs) ( } srcBuf = videoBuf } else { - imgData, err := ioutil.ReadFile(fullPath) + imgData, err := os.ReadFile(fullPath) if err != nil { return nil, err } diff --git a/internal/fs/link.go b/internal/fs/link.go index e8c73a79650..3dfd7e5a35e 100644 --- a/internal/fs/link.go +++ b/internal/fs/link.go @@ -2,9 +2,12 @@ package fs import ( "context" + "strings" "github.com/alist-org/alist/v3/internal/model" "github.com/alist-org/alist/v3/internal/op" + "github.com/alist-org/alist/v3/server/common" + "github.com/gin-gonic/gin" "github.com/pkg/errors" ) @@ -13,5 +16,14 @@ func link(ctx context.Context, path string, args model.LinkArgs) (*model.Link, m if err != nil { return nil, nil, errors.WithMessage(err, "failed get storage") } - return op.Link(ctx, storage, actualPath, args) + l, obj, err := op.Link(ctx, storage, actualPath, args) + if err != nil { + return nil, nil, errors.WithMessage(err, "failed link") + } + if l.URL != "" && !strings.HasPrefix(l.URL, "http://") && !strings.HasPrefix(l.URL, "https://") { + if c, ok := ctx.(*gin.Context); ok { + l.URL = common.GetApiUrl(c.Request) + l.URL + } + } + return l, obj, nil } diff --git a/server/common/check.go b/server/common/check.go index 84479ad2448..38684094f6d 100644 --- a/server/common/check.go +++ b/server/common/check.go @@ -5,6 +5,8 @@ import ( "regexp" "strings" + "github.com/alist-org/alist/v3/internal/conf" + "github.com/alist-org/alist/v3/internal/driver" "github.com/alist-org/alist/v3/internal/model" "github.com/alist-org/alist/v3/pkg/utils" ) @@ -49,3 +51,18 @@ func CanAccess(user *model.User, meta *model.Meta, reqPath string, password stri // validate password return meta.Password == password } + +// ShouldProxy TODO need optimize +// when should be proxy? +// 1. config.MustProxy() +// 2. storage.WebProxy +// 3. proxy_types +func ShouldProxy(storage driver.Driver, filename string) bool { + if storage.Config().MustProxy() || storage.GetStorage().WebProxy { + return true + } + if utils.SliceContains(conf.SlicesMap[conf.ProxyTypes], utils.Ext(filename)) { + return true + } + return false +} diff --git a/server/handles/down.go b/server/handles/down.go index b76eee45cbf..eac191c2aa3 100644 --- a/server/handles/down.go +++ b/server/handles/down.go @@ -2,6 +2,7 @@ package handles import ( "fmt" + "io" stdpath "path" "strings" @@ -14,6 +15,7 @@ import ( "github.com/alist-org/alist/v3/pkg/utils" "github.com/alist-org/alist/v3/server/common" "github.com/gin-gonic/gin" + log "github.com/sirupsen/logrus" ) func Down(c *gin.Context) { @@ -24,11 +26,10 @@ func Down(c *gin.Context) { common.ErrorResp(c, err, 500) return } - if shouldProxy(storage, filename) { + if common.ShouldProxy(storage, filename) { Proxy(c) return } else { - link, _, err := fs.Link(c, rawPath, model.LinkArgs{ IP: c.ClientIP(), Header: c.Request.Header, @@ -38,6 +39,14 @@ func Down(c *gin.Context) { common.ErrorResp(c, err, 500) return } + if link.Data != nil { + defer func(Data io.ReadCloser) { + err := Data.Close() + if err != nil { + log.Errorf("close data error: %s", err) + } + }(link.Data) + } c.Header("Referrer-Policy", "no-referrer") c.Header("Cache-Control", "max-age=0, no-cache, no-store, must-revalidate") if setting.GetBool(conf.ForwardDirectLinkParams) { @@ -102,21 +111,6 @@ func Proxy(c *gin.Context) { } } -// TODO need optimize -// when should be proxy? -// 1. config.MustProxy() -// 2. storage.WebProxy -// 3. proxy_types -func shouldProxy(storage driver.Driver, filename string) bool { - if storage.Config().MustProxy() || storage.GetStorage().WebProxy { - return true - } - if utils.SliceContains(conf.SlicesMap[conf.ProxyTypes], utils.Ext(filename)) { - return true - } - return false -} - // TODO need optimize // when can be proxy? // 1. text file diff --git a/server/handles/fsmanage.go b/server/handles/fsmanage.go index 27108c8bce9..5751cf6dca4 100644 --- a/server/handles/fsmanage.go +++ b/server/handles/fsmanage.go @@ -2,6 +2,7 @@ package handles import ( "fmt" + "io" stdpath "path" "regexp" @@ -15,6 +16,7 @@ import ( "github.com/alist-org/alist/v3/server/common" "github.com/gin-gonic/gin" "github.com/pkg/errors" + log "github.com/sirupsen/logrus" ) type MkdirOrLinkReq struct { @@ -379,6 +381,14 @@ func Link(c *gin.Context) { common.ErrorResp(c, err, 500) return } + if link.Data != nil { + defer func(Data io.ReadCloser) { + err := Data.Close() + if err != nil { + log.Errorf("close link data error: %v", err) + } + }(link.Data) + } common.SuccessResp(c, link) return }