Files
SKYMirror 7a9015aad0
CI 测试 / go vet + go test (push) Failing after 5s
26.9:直链下载 + 过期回收 + SHA512 去重 + 防盗链 + 媒体预览 + 文件夹上传提示
- 对象存储直链: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
2026-09-08 04:54:05 +08:00

13 KiB
Raw Permalink Blame History

环境变量与配置项

配置分三层:默认值 → FCB_* 环境变量 → 数据库 settings KV(管理端运行时修改)。 26.9 起进程必需的环境变量为空集:数据库默认 SQLitemodernc.org/sqlite 纯 Go 驱动,零外部依赖, DSN 缺省落 ./data/fileshare.db);FCB_DB_DRIVER=postgresFCB_DB_DSN 必需(需求 ⑧)。

环境变量(进程级)

变量 必需 默认 说明
FCB_DB_DRIVER sqlite 数据库驱动:sqlite / postgres(需求 ⑧)
FCB_DB_DSN 视驱动 ./data/fileshare.db postgres:连接串(必需,如 postgres://user:pass@host:5432/filecodebox?sslmode=disable);sqlite:数据库文件路径(可空,父目录自动创建)
FCB_REDIS_ADDR Redis 地址(如 redis:6379),也支持 redis://[:password@]host:port[/db] / rediss://TLSURL 形式;空则缓存降级为进程内存实现(缓存故障时自动降级为进程内限流计数)
FCB_REDIS_DB 0 Redis 逻辑库号 0-15;URL 形式地址显式携带 /N 时以 URL 为准
FCB_ADMIN_PASSWORD 设置后服务首次启动即自动初始化管理员(≥8 位,不足告警跳过),消除 /setup 被抢占窗口;初始化完成后建议移除
FCB_LISTEN :8466 HTTP 监听地址
FCB_STORAGE_ENGINE local 存储引擎:local / s3 / webdav
FCB_TRUSTED_PROXIES 可信代理 CIDR(逗号分隔),命中时从 X-Forwarded-For 解析真实客户端 IP
  • SQLite 连接参数(驱动自动注入):busy_timeout=10s + WAL 日志模式 + foreign_keys=1;连接池 8/4。
  • Postgres 连接池沿用 v1 参数(32/8,1h 轮换);FCB_DB_DRIVER=postgres 且未设 FCB_DB_DSN启动直接报错

引擎相关环境变量(种子注入 settings KV,见《存储引擎配置》):FCB_LOCAL_STORAGE_PATHFCB_STORAGE_PATHFCB_S3_ACCESS_KEY_IDFCB_S3_SECRET_ACCESS_KEYFCB_AWS_SESSION_TOKENFCB_S3_BUCKET_NAMEFCB_S3_ENDPOINT_URLFCB_S3_REGION_NAMEFCB_S3_ADDRESSING_STYLEFCB_WEBDAV_URLFCB_WEBDAV_USERNAMEFCB_WEBDAV_PASSWORDFCB_WEBDAV_ROOT_PATH

部署用编排变量(deploy/.env.example):WEB_PORT(默认 8466)、 POSTGRES_USER / POSTGRES_PASSWORD / POSTGRES_DB(默认 fileshare,仅 --profile postgres 时使用)。

配置项(settings KV,默认值对齐参考实现)

键名/类型/默认值/边界以 server/internal/config/schema.goKVSchema() 为单一事实来源 (schema 同步测试保证与 defaults() 逐键一致);26.9 新增键统一 snake_case。

站点信息与展示(需求 ①②③)

类型/边界 默认 说明
site_name / name string 文件快传 站点名称(site_name 优先)
site_domain string,≤256 26.9:站点对外域名(http(s)://host[:port],不带路径;裸主机自动补 http://)。配置后分享链接(结果卡/管理端复制)用该域名生成——内网部署也能把公网链接发出去;留空=用当前访问地址
description string 开箱即用的文件快传系统 站点描述
page_explain string (合规声明) 页面说明文案
keywords string 文件快传, 文件分享… SEO 关键词
logo_url string 空(前端回落本地打包 /assets/logo-*.svg,需求 ⑤) 页面导航 Logo,管理端可设任意 URL
favicon_url string 空(前端回落本地打包 /assets/favicon-*.png,需求 ⑤) favicon / 备用 Logo
opacity float 0.9 界面不透明度
background string 背景图 URL(参考实现既有键,v1 兼容保留)
background_url string,≤2048 字符 26.9 需求 ①:背景图 URL 或上传后地址(空=主题默认;取值时 legacy background 键兜底)。管理端保存时校验协议白名单:仅 http(s)data:image/* 与站内相对路径(防 javascript: 注入,非法 400
footer_text string,≤2000 字符 26.9 需求 ②:页脚自定义内容(纯文本或受控 HTML 片段)
footer_beian string,≤128 字符 26.9 需求 ②:备案号(如 京ICP备2024xxxxxx号-1),展示于页脚
notify_enabled int0/1 1 26.9 需求 ③:通知开关(1=前台右上角悬浮窗展示 / 0=关闭)
notify_title string,≤128 字符 系统通知 通知标题
notify_content string,≤2000 字符 欢迎使用… 通知正文(服务端白名单净化:仅保留纯文本与 <a href> 为 http(s)/站内相对/# 锚点的链接,其余标签与事件属性剥离,保存与读取双侧生效)
showAdminAddr int0/1 0 是否展示后台入口
robotsText string User-agent: *\nDisallow: / robots.txt 内容(由公开端点 GET /robots.txt 输出)

保存策略(需求 ④,上传页动态读取并在范围内选择)

类型/边界 默认 说明
max_save_seconds int640~31536000 0 最长保存秒数上限(0=仅默认 7 天兜底;>0 时按时间过期超限 403「限制最长时间为 X,可换用其他方式」)。26.9:管理界面以「小时/天」下拉单位编辑(≥1 天自动显示天),提交时前端换算为秒——canonical 单位保持秒,接口语义不变
max_save_count int0~100000 0 26.9 新增:单次分享最大可取(保存)次数上限(0=不限制;expire_style=countexpire_value 超上限时 403「限制次数最多为 N 次」)
expireStyle []string ["day","hour","minute","forever","count"] 允许的过期方式白名单(上传时不在白名单 400「过期时间类型错误」)

存储策略(需求 ④⑩)

类型/边界 默认 说明
uploadSize int641024~10GiB 1048576010MB 单文件大小上限(字节),参考实现语义;max_file_size=0 时作为生效上限
max_file_size int640~10GiB 0 26.9 新增:存储策略-单文件上限(字节),0=回落 uploadSize;超出 403(文案 humanSize 自适应 B/KB/MB/GB)。26.9:管理界面以「MB/GB」下拉单位编辑(≥1 GiB 自动显示 GB),提交时前端换算为字节
allowed_file_types []string ["*"] 允许类型白名单(扩展名/MIME 通配,* 不限制;非白名单 403「不允许上传该类型文件」)
storageLimit int64,≥0 0 站点总容量(字节),0=不限制(超限 507)
openUpload int0/1 1 游客上传开关(0 时上传接口要求管理员令牌 403)
enableChunk int0/1 0 启用分片上传

上传频率限制(需求 ④,既有键对齐参考 ip_limit["upload"]

类型/边界 默认 说明
uploadCount / uploadMinute int110000 / 11440 10 / 1 窗口内允许上传次数 / 窗口分钟(上传成功才计数,超限 423;管理端修改后运行时同步限流规则,立即生效)
upload_rate / download_rate int640~1 GiB/s 0 / 0 26.9:上下行带宽字节/秒,0=不限速;管理端改后立即生效(每请求动态读 KV)。详见《带宽限速
recycle_enabled 0/1 1 26.9:过期分享自动回收开关(定时扫描 + 取件惰性回收)
recycle_interval int6460~86400 秒) 1800 26.9:回收扫描间隔(秒;管理端以分钟展示)
retention_days int640~3650 天) 0 26.9:最长存储时长(天),上传超过该天数的分享自动回收;0=不限制
dedup_enabled 0/1 1 26.9:SHA512 内容去重,相同文件仅存储一份(多分享引用同一对象,引用计数删除)
direct_download 0/1 1 26.9:对象存储直链下载(S3 引擎 302 到预签名 URL,文件不经过本站带宽)
direct_link_expire int6460~3600 秒) 900 26.9:直链签名有效期(秒;不超过分享剩余时效)
hotlink_enabled 0/1 0 26.9:下载防盗链(Referer 白名单校验;空 Referer 放行)
hotlink_whitelist string(≤2048 26.9:防盗链白名单,逗号分隔域名,支持 *.example.com 通配;空=仅同源放行
errorCount / errorMinute int 10 / 1 取件错误(失败计数)+ metadata 每次计数
loginCount / loginMinute int 5 / 15 登录失败计数

安全与会话

默认 说明
admin_token 空(未初始化) 管理员密码哈希(sha256$salt$hash);GET 配置时屏蔽为空串
jwt_secret JWT 签名密钥(初始化/改密时自动生成轮换;不下发;settings.SensitiveKeys 双模式下一致屏蔽)
adminSessionExpire 6048007 天) 管理员会话秒数(须 1~365 整天)

存储引擎(26.9 运行时可配 + 热切换)

storage_engine26.9 新增键):stringlocal|s3|webdav,默认空=回落启动值 FCB_STORAGE_ENGINE。 运行时切换走 POST /admin/storage/switch(JWT 保护):构建新引擎 → 健康检查通过才生效; 失败返回 503「存储引擎切换失败,已保持原引擎: …」且不改 KV。成功后持久化 storage_engine,重启沿用。 GET /api/v1/config 公开下发 storage_engine 当前名(仅名称,任何引擎参数/凭据不下发)。

引擎参数键(管理端可改;保存后对应引擎实例缓存失效,下次切换/构建生效):

默认
file_storage local
storage_path
local_storage_path 空(容器内由 FCB_LOCAL_STORAGE_PATH=/app/data 注入)
s3_access_key_id / s3_secret_access_key / aws_session_token
s3_bucket_name / s3_endpoint_url / s3_hostname
s3_region_name auto
s3_signature_version s3v4
s3_addressing_style auto
s3_proxy 0
webdav_url / webdav_username / webdav_password
webdav_root_path filebox_storage
webdav_proxy 0

敏感键 webdav_password / s3_secret_access_key / aws_session_token26.9 加入 settings.SensitiveKeys): 管理端 GET 返回掩码 ******PATCH 时空串或 ****** 表示不修改。直接写库 settings KV 后重启同样生效。

策略动态生效机制(26.9 需求 ④⑩)

上传页通过 GET /api/v1/configconfig 字段读取当前策略快照并在范围内渲染选项; 上传链路(/share/file/chunk/*/presign/*每次请求实时读取 settings KV 同一组值校验:

  • 管理端改策略(PATCH /admin/config/update)→ 公开 config 即时反映 → 后续上传立即按新策略执行(含 403/400 拒绝与恢复放行)。
  • 生效上限:max_file_size > 0 时为 max_file_size,否则回落 uploadSize
  • 校验点覆盖:单文件(/share/file)、分片 init 按分片数上限、分片上传累计、分片 complete 累计、预签名 init 声明大小,五处口径一致(api.UploadPolicy.CheckSize)。

公共配置接口

前端启动时经 GET /api/v1/config 获取站点公开配置(无需认证;26.9 扩展需求 ①②③④⑩):

{
  "code": 200, "msg": "ok",
  "data": {
    "config": {
      "name": "文件快传",
      "description": "开箱即用的文件快传系统",
      "explain": "请勿上传或分享违法内容…",
      "logo_url": "",
      "favicon_url": "",
      "background_url": "",
      "footer_text": "自定义页脚内容",
      "footer_beian": "京ICP备2024xxxxxx号-1",
      "notify_enabled": 1,
      "notify_title": "系统通知",
      "notify_content": "欢迎使用文件快传…",
      "uploadSize": 10485760,
      "max_file_size": 10485760,
      "maxFileSize": 10485760,
      "allowedFileTypes": ["*"],
      "expireStyle": ["day", "hour", "minute", "forever", "count"],
      "max_save_seconds": 0,
      "maxSaveSeconds": 0,
      "max_save_count": 0,
      "maxSaveCount": 0,
      "uploadCount": 10,
      "uploadMinute": 1,
      "enableChunk": false,
      "openUpload": true
    },
    "meta": {
      "version": "26.9",
      "features": { "chunkUpload": false, "guestUpload": true }
    }
  }
}

策略字段 snake_case 与 camelCase 双份下发(前端宽松解析);响应为白名单显式构造, 任何敏感键(admin_token/jwt_secret)均不会出现。

健康检查

curl -s http://localhost:8466/api/v1/health
{
  "code": 200, "msg": "ok",
  "data": {
    "status": "ok",
    "version": "26.9",
    "storage": "local",
    "time": "2025-06-01T12:00:00+08:00"
  }
}