feat(direct link): add option to get direct link with download enforced (#2651)

pull/2693/head
Aaron Liu 2025-07-15 13:22:04 +08:00
parent d19fc0e75c
commit e96b595622
5 changed files with 17 additions and 11 deletions

2
assets

@ -1 +1 @@
Subproject commit 3a6a22bb458783fcfd32f3b35f5fe6afc5414e25 Subproject commit e47a708f727bf5243512ddd6d9c6eabd5bf61751

View File

@ -168,7 +168,7 @@ func (m *manager) GetUrlForRedirectedDirectLink(ctx context.Context, dl *ent.Dir
) )
// Try to read from cache. // Try to read from cache.
cacheKey := entityUrlCacheKey(primaryEntity.ID(), int64(dl.Speed), dl.Name, false, cacheKey := entityUrlCacheKey(primaryEntity.ID(), int64(dl.Speed), dl.Name, o.IsDownload,
m.settings.SiteURL(ctx).String()) m.settings.SiteURL(ctx).String())
if cached, ok := m.kv.Get(cacheKey); ok { if cached, ok := m.kv.Get(cacheKey); ok {
cachedItem := cached.(EntityUrlCache) cachedItem := cached.(EntityUrlCache)
@ -185,7 +185,7 @@ func (m *manager) GetUrlForRedirectedDirectLink(ctx context.Context, dl *ent.Dir
m.l, m.config, m.dep.MimeDetector(ctx)) m.l, m.config, m.dep.MimeDetector(ctx))
downloadUrl, err := source.Url(ctx, downloadUrl, err := source.Url(ctx,
entitysource.WithExpire(o.Expire), entitysource.WithExpire(o.Expire),
entitysource.WithDownload(false), entitysource.WithDownload(o.IsDownload),
entitysource.WithSpeedLimit(int64(dl.Speed)), entitysource.WithSpeedLimit(int64(dl.Speed)),
entitysource.WithDisplayName(dl.Name), entitysource.WithDisplayName(dl.Name),
) )

View File

@ -86,12 +86,14 @@ func ExtractArchive(c *gin.Context) {
} }
// AnonymousPermLink 文件中转后的永久直链接 // AnonymousPermLink 文件中转后的永久直链接
func AnonymousPermLink(c *gin.Context) { func AnonymousPermLink(download bool) gin.HandlerFunc {
name := c.Param("name") return func(c *gin.Context) {
if err := explorer.RedirectDirectLink(c, name); err != nil { name := c.Param("name")
c.JSON(404, serializer.Err(c, err)) if err := explorer.RedirectDirectLink(c, name, download); err != nil {
c.Abort() c.JSON(404, serializer.Err(c, err))
return c.Abort()
return
}
} }
} }

View File

@ -245,7 +245,10 @@ func initMasterRouter(dep dependency.Dep) *gin.Engine {
{ {
source.GET(":id/:name", source.GET(":id/:name",
middleware.HashID(hashid.SourceLinkID), middleware.HashID(hashid.SourceLinkID),
controllers.AnonymousPermLink) controllers.AnonymousPermLink(false))
source.GET("d/:id/:name",
middleware.HashID(hashid.SourceLinkID),
controllers.AnonymousPermLink(true))
} }
shareShort := r.Group("s") shareShort := r.Group("s")

View File

@ -659,7 +659,7 @@ func (s *GetFileInfoService) Get(c *gin.Context) (*FileResponse, error) {
return BuildFileResponse(c, user, file, dep.HashIDEncoder(), nil), nil return BuildFileResponse(c, user, file, dep.HashIDEncoder(), nil), nil
} }
func RedirectDirectLink(c *gin.Context, name string) error { func RedirectDirectLink(c *gin.Context, name string, download bool) error {
dep := dependency.FromContext(c) dep := dependency.FromContext(c)
settings := dep.SettingProvider() settings := dep.SettingProvider()
@ -680,6 +680,7 @@ func RedirectDirectLink(c *gin.Context, name string) error {
expire := time.Now().Add(settings.EntityUrlValidDuration(c)) expire := time.Now().Add(settings.EntityUrlValidDuration(c))
res, earliestExpire, err := m.GetUrlForRedirectedDirectLink(c, dl, res, earliestExpire, err := m.GetUrlForRedirectedDirectLink(c, dl,
fs.WithUrlExpire(&expire), fs.WithUrlExpire(&expire),
fs.WithIsDownload(download),
) )
if err != nil { if err != nil {
return err return err