Repository navigation
Open
Labels
Description
请确认以下事项
-
我已确认阅读并同意 AGPL-3.0 第15条 。
本程序不提供任何明示或暗示的担保,使用风险由您自行承担。 -
我已确认阅读并同意 AGPL-3.0 第16条 。
无论何种情况,版权持有人或其他分发者均不对使用本程序所造成的任何损失承担责任。 -
我确认我的描述清晰,语法礼貌,能帮助开发者快速定位问题,并符合社区规则。
-
我已确认阅读了OpenList文档。
-
我已确认没有重复的问题或讨论。
-
我已确认是
OpenList的问题,而不是其他原因(例如 网络 ,依赖或操作)。 -
我认为此问题必须由
OpenList处理,而非第三方。 -
我已确认这个问题在最新版本中没有被修复。
-
我没有阅读这个清单,只是闭眼选中了所有的复选框,请关闭这个 Issue 。
OpenList 版本(必填)
v4.2.6
使用的存储驱动(必填)
本机存储(Local)
问题描述(必填)
概要
通过 Web 界面以「分片上传(multipart)」上传文件,会话悬挂(init 之后中断,无任何 chunk、无 complete)后,对同一文件改用「流式上传(stream)」重新上传成功,且已完整下载验证。约 30 分钟后,悬挂的分片会话被 GC 清理,清理动作把该路径上已由 stream 上传写完整的文件一并删除,造成静默数据丢失。
详细过程(时间为 UTC+8)
00:14 ~ 00:20多次上传尝试(直传 + 分片),期间出现过会话交错、complete时目标文件已不存在的情况。00:32:32POST /api/fs/multipart/init(第一次)00:32:49POST /api/fs/remove(手动清理目录中的不完整文件)00:32:55POST /api/fs/multipart/init(第二次)——此后无任何 chunk 上传、无 complete,会话悬挂00:36:51改用 stream 模式上传同名文件,PUT /api/fs/put成功(约 190MB)00:53:39 ~ 00:55:59通过分享链接完整下载成功(多个 206 响应,文件确认可用)- 约
01:03(00:32:55 + 30 分钟 session TTL)文件从磁盘上消失,期间没有任何删除操作日志、没有任何 SSH/计划任务/面板操作 08:03起分享链接持续报object not found
复现步骤(推测的最小复现)
- 通过 Web 界面以「分片上传」模式上传一个文件,在
init请求发出后中断/放弃(不发送任何分片、不取消、不 complete)。此时目录中会出现一个不完整文件,服务端保留一个悬挂会话。 - 30 分钟以内,对同一文件名改用「stream 模式」重新上传(成功),确认文件完整、可下载。
- 静置等待。从第 1 步
init时刻起约 30 分钟后,multipart GC 会清理悬挂会话。 - 观察:第 2 步成功上传的完整文件被删除,列表与分享均报文件不存在。
机制分析(v4.2.6 源码,internal/multipart/session.go)
defaultSessionTTL = 30 * time.Minute,gcInterval = time.Minute:过期会话每分钟被Manager.gc()扫描。Manager.Init():对同路径同大小的新上传,会terminate旧会话("superseded by a new upload of the same path and size");并且 Init 会立即调用startAttemptLocked(),后者启动后台go put(ctx, dstDir, fileStream, ...),即分片上传一开始就创建并写入目标文件。Manager.gc()→Manager.terminate()→Session.killAttemptLocked():取消 context(s.cancel())并关闭 window(CloseWithError(errAborted))。errAborted的注释明确写道:"a driver blocked on the stream sees the abort as a canceled request and runs its cancellation cleanup"——该取消清理会删除目标路径上的文件。- 问题在于:清理删除的是"路径",并不校验该文件是否由本会话写入。当同名文件已被 stream 上传(或另一个会话)写完整时,会被误删。
期望行为
过期/被取消的分片上传会话,其清理动作应只影响该会话自身的临时数据(ring/window)与其写入的半成品;不应删除已被其他上传写完整、与本次会话无关的同路径文件。若实现上需要删除,建议删除前校验目标文件是否为本会话产物(如写入句柄一致性、文件大小/哈希比对等)。
影响
- 用户已成功上传并验证过的完整文件被静默删除,无回收站、无日志。
- 触发场景常见:Web 界面提供 multipart / stream 两种模式,用户在上传失败后换模式重传同一文件即可触发。
日志(必填)
(以下为 OpenList 运行日志节选,已隐去域名与文件名)
[GIN] 2026/10/10 - 00:32:32 | 200 | 177.088µs | POST "/api/fs/multipart/init"
[GIN] 2026/10/10 - 00:32:49 | 200 | 238.697µs | POST "/api/fs/remove"
[GIN] 2026/10/10 - 00:32:55 | 200 | 174.21µs | POST "/api/fs/multipart/init" <-- 悬挂会话:此后无 chunk、无 complete
[GIN] 2026/10/10 - 00:36:51 | 200 | 1.53s | PUT "/api/fs/put" <-- stream 模式上传成功(约 190MB)
[GIN] 2026/10/10 - 00:37:18 | 200 | 10.06ms | POST "/api/share/create"
[GIN] 2026/10/10 - 00:53:39 | 206 | 1.2s | GET "/sd/******/?pwd=***" <-- 完整下载验证通过
[GIN] 2026/10/10 - 00:53:42 | 200 | 4.42s | GET "/sd/******/?pwd=***"
[GIN] 2026/10/10 - 00:55:59 | 206 | 861.54ms | GET "/sd/******/?pwd=***"
(约 01:03 无任何日志——文件在此时消失)
[GIN] 2026/10/10 - 08:03:44 | 200 | 881.065µs | GET "/api/public/offline_download_tools?path=%2F%40s%2F******"
WARN[2026-10-10 08:03:44] failed get sharing ******/: failed to get obj: object not found
WARN[2026-10-10 08:03:51] failed get sharing ******/: failed to get obj: object not found
(此后 08:04 ~ 10:34 反复出现同样的 object not found)
同一时间段更早的一次分片上传失败(会话交错,complete 时目标文件已不存在,可能与同一缺陷相关):
ERRO[2026-10-10 00:20:37] [local] failed to change time of /opt/openlist/data/files/xxx.apk:
chtimes /opt/openlist/data/files/xxx.apk: no such file or directory
配置文件内容(必填)
{
"site_url": "",
"cdn": "",
"jwt_secret": "<已脱敏>",
"token_expires_in": 48,
"database": {
"type": "sqlite3",
"db_file": "data/data.db",
"table_prefix": "x_"
},
"scheme": {
"address": "0.0.0.0",
"http_port": 5244,
"https_port": -1,
"force_https": false
},
"temp_dir": "data/temp",
"bleve_dir": "data/bleve",
"log": {
"enable": true,
"name": "data/log/log.log",
"max_size": 50,
"max_backups": 30,
"max_age": 28,
"compress": false
}
}复现链接(可选)
No response
AI生成内容
- 我使用了AI工具生成此内容
- 我没有使用AI工具生成此内容
AI模型是
deepseek-v4.1-flash
Activity
github-actions commentedon Oct 10, 2026
感谢您联系OpenList。我们会尽快回复您。
Thanks for contacting OpenList. We will reply to you as soon as possible.
由于您提出的 Issue 中包含部分未确认的项目,为了更好地管理项目,在人工审核后可能会直接关闭此问题。
如果您能确认并补充相关未确认项目的信息,欢迎随时重新提交。我们会及时关注并处理。感谢您的理解与支持!
Since your issue contains some unchecked tasks, it may be closed after manual review.
If you can confirm and provide information for the unchecked tasks, feel free to resubmit.
We will pay attention and handle it in a timely manner.
感谢您的理解与支持!
Thank you for your understanding and support!