26.9:直链下载 + 过期回收 + SHA512 去重 + 防盗链 + 媒体预览 + 文件夹上传提示
CI 测试 / go vet + go test (push) Failing after 5s
CI 测试 / go vet + go test (push) Failing after 5s
- 对象存储直链:S3 引擎 302 到限时预签名 URL(有效期钳位分享剩余时效),失败自动回落代理 - 过期回收:janitor 定时扫描 + 取件惰性回收 + 管理端手动触发(POST /admin/recycle/run), retention_days 最长存储时长;删除走引用计数(去重对象安全) - SHA512 内容去重:三条上传链路落库后计算哈希,命中即复用旧对象并删除本次副本 - 下载防盗链:Referer 白名单(同源/空 Referer/通配域名放行),挂 /share/download - 取件页图片/音频内联预览(下载地址直连,加载失败回退下载按钮) - 文件夹上传:拖拽目录明确提示"建议压缩后上传"(webkitGetAsEntry 探测) - 管理端设置卡「回收与下载安全」8 个新配置键(KVSchema + configKeys + UI + i18n) - 前端产物重建并同步 server/web/dist 与 web-embed - 文档:10-config 配置表、03-file-share 直链/防盗链/文件夹章节、07-admin 回收端点、openapi
This commit is contained in:
@@ -67,6 +67,15 @@ func defaults() map[string]any {
|
||||
"site_domain": "",
|
||||
"upload_rate": "0",
|
||||
"download_rate": "0",
|
||||
// 26.9 回收与下载安全
|
||||
"recycle_enabled": 1,
|
||||
"recycle_interval": 1800,
|
||||
"retention_days": 0,
|
||||
"dedup_enabled": 1,
|
||||
"hotlink_enabled": 0,
|
||||
"hotlink_whitelist": "",
|
||||
"direct_download": 1,
|
||||
"direct_link_expire": 900,
|
||||
// 站点信息
|
||||
"name": "文件快传",
|
||||
"site_name": "文件快传", // 新增:管理端可自定义
|
||||
@@ -298,6 +307,70 @@ func (c *Config) DownloadRate() int {
|
||||
return v
|
||||
}
|
||||
|
||||
// —— 26.9 回收与下载安全 ——
|
||||
|
||||
// RecycleEnabled 过期自动回收开关。
|
||||
func (c *Config) RecycleEnabled() bool { return c.GetInt(KeyRecycleEnabled) == 1 }
|
||||
|
||||
// RecycleInterval 回收扫描间隔(秒,钳位 60~86400)。
|
||||
func (c *Config) RecycleInterval() int64 {
|
||||
v := c.GetInt64(KeyRecycleInterval)
|
||||
if v < RecycleIntervalMin {
|
||||
return RecycleIntervalMin
|
||||
}
|
||||
if v > RecycleIntervalMax {
|
||||
return RecycleIntervalMax
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// RetentionDays 全局最长存储时长(天,0=不限制)。
|
||||
func (c *Config) RetentionDays() int64 {
|
||||
v := c.GetInt64(KeyRetentionDays)
|
||||
if v < 0 {
|
||||
return 0
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// DedupEnabled SHA512 内容去重开关。
|
||||
func (c *Config) DedupEnabled() bool { return c.GetInt(KeyDedupEnabled) == 1 }
|
||||
|
||||
// HotlinkEnabled 下载防盗链开关。
|
||||
func (c *Config) HotlinkEnabled() bool { return c.GetInt(KeyHotlinkEnabled) == 1 }
|
||||
|
||||
// HotlinkWhitelist 防盗链 Referer 白名单(逗号分隔域名,返回小写去空白切片)。
|
||||
func (c *Config) HotlinkWhitelist() []string {
|
||||
raw := c.GetString(KeyHotlinkWhitelist)
|
||||
if strings.TrimSpace(raw) == "" {
|
||||
return nil
|
||||
}
|
||||
parts := strings.Split(raw, ",")
|
||||
out := make([]string, 0, len(parts))
|
||||
for _, p := range parts {
|
||||
p = strings.ToLower(strings.TrimSpace(p))
|
||||
if p != "" {
|
||||
out = append(out, p)
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// DirectDownload 对象存储直链下载开关。
|
||||
func (c *Config) DirectDownload() bool { return c.GetInt(KeyDirectDownload) == 1 }
|
||||
|
||||
// DirectLinkExpire 直链有效期(秒,钳位 60~3600)。
|
||||
func (c *Config) DirectLinkExpire() int64 {
|
||||
v := c.GetInt64(KeyDirectLinkExpire)
|
||||
if v < DirectLinkExpireMin {
|
||||
return DirectLinkExpireMin
|
||||
}
|
||||
if v > DirectLinkExpireMax {
|
||||
return DirectLinkExpireMax
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// SiteDomain 站点对外域名(26.9):空=分享链接用当前访问地址。
|
||||
func (c *Config) SiteDomain() string {
|
||||
return strings.TrimRight(strings.TrimSpace(c.GetString("site_domain")), "/")
|
||||
|
||||
Reference in New Issue
Block a user