|
package handles |
|
|
|
import ( |
|
"fmt" |
|
"io" |
|
stdpath "path" |
|
"strings" |
|
|
|
"github.com/alist-org/alist/v3/internal/conf" |
|
"github.com/alist-org/alist/v3/internal/driver" |
|
"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" |
|
log "github.com/sirupsen/logrus" |
|
) |
|
|
|
func Down(c *gin.Context) { |
|
rawPath := c.MustGet("path").(string) |
|
filename := stdpath.Base(rawPath) |
|
storage, err := fs.GetStorage(rawPath, &fs.GetStoragesArgs{}) |
|
if err != nil { |
|
common.ErrorResp(c, err, 500) |
|
return |
|
} |
|
if common.ShouldProxy(storage, filename) { |
|
Proxy(c) |
|
return |
|
} else { |
|
link, _, err := fs.Link(c, rawPath, model.LinkArgs{ |
|
IP: c.ClientIP(), |
|
Header: c.Request.Header, |
|
Type: c.Query("type"), |
|
HttpReq: c.Request, |
|
}) |
|
if err != nil { |
|
common.ErrorResp(c, err, 500) |
|
return |
|
} |
|
if link.MFile != nil { |
|
defer func(ReadSeekCloser io.ReadCloser) { |
|
err := ReadSeekCloser.Close() |
|
if err != nil { |
|
log.Errorf("close data error: %s", err) |
|
} |
|
}(link.MFile) |
|
} |
|
c.Header("Referrer-Policy", "no-referrer") |
|
c.Header("Cache-Control", "max-age=0, no-cache, no-store, must-revalidate") |
|
if setting.GetBool(conf.ForwardDirectLinkParams) { |
|
query := c.Request.URL.Query() |
|
for _, v := range conf.SlicesMap[conf.IgnoreDirectLinkParams] { |
|
query.Del(v) |
|
} |
|
link.URL, err = utils.InjectQuery(link.URL, query) |
|
if err != nil { |
|
common.ErrorResp(c, err, 500) |
|
return |
|
} |
|
} |
|
c.Redirect(302, link.URL) |
|
} |
|
} |
|
|
|
func Proxy(c *gin.Context) { |
|
rawPath := c.MustGet("path").(string) |
|
filename := stdpath.Base(rawPath) |
|
storage, err := fs.GetStorage(rawPath, &fs.GetStoragesArgs{}) |
|
if err != nil { |
|
common.ErrorResp(c, err, 500) |
|
return |
|
} |
|
if canProxy(storage, filename) { |
|
downProxyUrl := storage.GetStorage().DownProxyUrl |
|
if downProxyUrl != "" { |
|
_, ok := c.GetQuery("d") |
|
if !ok { |
|
URL := fmt.Sprintf("%s%s?sign=%s", |
|
strings.Split(downProxyUrl, "\n")[0], |
|
utils.EncodePath(rawPath, true), |
|
sign.Sign(rawPath)) |
|
c.Redirect(302, URL) |
|
return |
|
} |
|
} |
|
link, file, err := fs.Link(c, rawPath, model.LinkArgs{ |
|
Header: c.Request.Header, |
|
Type: c.Query("type"), |
|
HttpReq: c.Request, |
|
}) |
|
if err != nil { |
|
common.ErrorResp(c, err, 500) |
|
return |
|
} |
|
if link.URL != "" && setting.GetBool(conf.ForwardDirectLinkParams) { |
|
query := c.Request.URL.Query() |
|
for _, v := range conf.SlicesMap[conf.IgnoreDirectLinkParams] { |
|
query.Del(v) |
|
} |
|
link.URL, err = utils.InjectQuery(link.URL, query) |
|
if err != nil { |
|
common.ErrorResp(c, err, 500) |
|
return |
|
} |
|
} |
|
err = common.Proxy(c.Writer, c.Request, link, file) |
|
if err != nil { |
|
common.ErrorResp(c, err, 500, true) |
|
return |
|
} |
|
} else { |
|
common.ErrorStrResp(c, "proxy not allowed", 403) |
|
return |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func canProxy(storage driver.Driver, filename string) bool { |
|
if storage.Config().MustProxy() || storage.GetStorage().WebProxy || storage.GetStorage().WebdavProxy() { |
|
return true |
|
} |
|
if utils.SliceContains(conf.SlicesMap[conf.ProxyTypes], utils.Ext(filename)) { |
|
return true |
|
} |
|
if utils.SliceContains(conf.SlicesMap[conf.TextTypes], utils.Ext(filename)) { |
|
return true |
|
} |
|
return false |
|
} |
|
|