alist/server/controllers/down.go

101 lines
2.3 KiB
Go
Raw Normal View History

2022-06-28 10:00:11 +00:00
package controllers
import (
"github.com/alist-org/alist/v3/internal/db"
"github.com/alist-org/alist/v3/internal/driver"
"github.com/alist-org/alist/v3/internal/errs"
"github.com/alist-org/alist/v3/internal/fs"
"github.com/alist-org/alist/v3/internal/model"
"github.com/alist-org/alist/v3/internal/setting"
"github.com/alist-org/alist/v3/internal/sign"
"github.com/alist-org/alist/v3/pkg/utils"
"github.com/alist-org/alist/v3/server/common"
"github.com/gin-gonic/gin"
"github.com/pkg/errors"
stdpath "path"
"strings"
)
func Down(c *gin.Context) {
rawPath := parsePath(c.Param("path"))
filename := stdpath.Base(rawPath)
meta, err := db.GetNearestMeta(rawPath)
if err != nil {
if !errors.Is(errors.Cause(err), errs.MetaNotFound) {
common.ErrorResp(c, err, 500, true)
return
}
}
// verify sign
if needSign(meta, rawPath) {
s := c.Param("sign")
err = sign.Verify(filename, s)
if err != nil {
common.ErrorResp(c, err, 401, true)
return
}
}
account, err := fs.GetAccount(rawPath)
if err != nil {
common.ErrorResp(c, err, 500, true)
return
}
if needProxy(account, filename) {
link, err := fs.Link(c, rawPath, model.LinkArgs{
Header: c.Request.Header,
})
if err != nil {
common.ErrorResp(c, err, 500, true)
return
}
obj, err := fs.Get(c, rawPath)
if err != nil {
common.ErrorResp(c, err, 500, true)
return
}
err = common.Proxy(c.Writer, c.Request, link, obj)
if err != nil {
common.ErrorResp(c, err, 500, true)
return
}
} else {
link, err := fs.Link(c, rawPath, model.LinkArgs{
IP: c.ClientIP(),
Header: c.Request.Header,
})
if err != nil {
common.ErrorResp(c, err, 500, true)
return
}
c.Redirect(302, link.URL)
}
}
// TODO: implement
// path maybe contains # ? etc.
func parsePath(path string) string {
return utils.StandardizePath(path)
}
func needSign(meta *model.Meta, path string) bool {
if meta == nil || meta.Password == "" {
return false
}
if !meta.SubFolder && path != meta.Path {
return false
}
return true
}
func needProxy(account driver.Driver, filename string) bool {
config := account.Config()
if config.MustProxy() {
return true
}
proxyTypes := setting.GetByKey("proxy_types")
if strings.Contains(proxyTypes, utils.Ext(filename)) {
return true
}
return false
}