请确认以下事项
OpenList 版本
v4.2.1
本地复现构建信息:
- Commit:
c3df8da5
- Docker 部署,数据目录持久化挂载
使用的存储驱动
- Source:
115 Cloud
- Destination:
PikPak
问题描述
从 115 Cloud 复制文件到 PikPak 时,复制任务会在 uploading 阶段失败,进度为 0。失败并不是 PikPak API 创建上传任务失败,而是在 PikPak Put 之前计算 GCID/读取源文件流时,请求 115 CDN 下载直链返回 403。
典型任务状态:
state=failed
status=uploading
progress=0
典型错误:
http request [https://cdnfhnfile.115cdn.net/<hash>/<filename>.mp4?t=<ts>&u=<uid>&s=<size>&d=<vip-node>&c=2&f=3&k=<key>&us=<size>&uc=10&v=1] failure,status: 403|Forbidden response:{"status":403,"message":"no cookie value","request_id":"6A12A7B2CA239135369215C9"}
也见到过同形态响应:
{"message":"no cookie value","request_id":"6A12AD0B8E4DDC3430511C7E","status":403}
复现方式
- 配置 115 Cloud 存储,Cookie 有效,存储状态为
work。
- 配置 PikPak 存储,存储状态为
work。
- 在 OpenList 中将 115 Cloud 文件复制到 PikPak。
- 任务进入
uploading,随后失败,错误为 115 CDN 403 no cookie value。
已验证的现象
复现环境中 115 Cookie 本身并非为空,也不是完全失效:
- 115 存储能正常加载,状态为
work。
- 通过
/api/fs/link 获取同一个 115 文件直链时,返回的 Link.Header 中包含 Cookie。
- 使用相同直链和 Cookie 手动请求 115 CDN 时,不同
User-Agent 会导致不同结果:
Cookie + normal browser/OpenList User-Agent => 206 Partial Content,能读到文件数据
Cookie + Mozilla/5.0 115Browser/<version> => 403 {"message":"no cookie value"}
因此这里的 no cookie value 容易误导:实际触发条件不是简单的“没有 Cookie”,而是后台复制链路里 115 CDN 请求使用的 User-Agent 与 Cookie/直链组合不被 CDN 接受。
根因分析
后台复制任务走的是:
FileTransferTask.RunWithNextTaskCallback
-> op.Link(..., model.LinkArgs{})
-> 115 Cloud Link
-> stream.NewSeekableStream
-> PikPak.Put
-> CacheFullAndHash / RangeRead 读取 115 CDN
复制任务调用 op.Link 时传入的是空 model.LinkArgs{},没有前端请求里的浏览器 User-Agent。115 driver 在生成下载链接和后续读取 CDN 时如果使用空 UA、115Browser UA,或生成直链时的 UA 与 Link.Header 中的 UA 不一致,就可能触发 115 CDN 403 no cookie value。
修复建议
在 115 Cloud driver 的 Link 中处理后台任务没有 User-Agent 的情况:
- 如果
args.Header.Get("User-Agent") 为空,使用 OpenList 通用浏览器 UA,例如 base.UserAgent,不要默认使用 Mozilla/5.0 115Browser/<version> 作为 CDN 下载 UA。
- 调用
DownloadWithUA 生成直链时使用该 UA。
- 返回
model.Link 时 clone downloadInfo.Header,并确保 Cookie 与同一个 User-Agent 被保留到 Link.Header,让后续 RangeRead 请求 115 CDN 时使用一致的 header。
示例修复方向:
userAgent := args.Header.Get("User-Agent")
if userAgent == "" {
userAgent = base.UserAgent
}
downloadInfo, err := d.client.DownloadWithUA(file.(*FileObj).PickCode, userAgent)
if err != nil {
return nil, err
}
header := http.Header{}
if downloadInfo.Header != nil {
header = downloadInfo.Header.Clone()
}
if header.Get("Cookie") == "" && d.Cookie != "" {
header.Set("Cookie", d.Cookie)
}
if header.Get("User-Agent") == "" {
header.Set("User-Agent", userAgent)
}
return &model.Link{
URL: downloadInfo.Url.Url,
Header: header,
}, nil
本地验证结果
按上述方向修改后,本地测试通过:
- 115 Cloud -> PikPak 复制 JPG 成功
- 115 Cloud -> PikPak 复制 MP4 成功
- 不再出现 115 CDN
403 no cookie value
- 目标文件能在 PikPak 目录中刷新看到
额外说明
PikPak 秒传/上传路径还可能出现任务已完成但进度停在 50 的显示问题:CacheFullAndHash 会将读源文件/算 GCID 的进度映射到 0-50,如果 PikPak 秒传成功后直接返回,进度不会补到 100。这可以在 PikPak Put 成功返回前补一次 up(100) 作为单独显示修复。
请确认以下事项
OpenList 版本
v4.2.1
本地复现构建信息:
c3df8da5使用的存储驱动
115 CloudPikPak问题描述
从
115 Cloud复制文件到PikPak时,复制任务会在uploading阶段失败,进度为0。失败并不是 PikPak API 创建上传任务失败,而是在 PikPakPut之前计算 GCID/读取源文件流时,请求 115 CDN 下载直链返回 403。典型任务状态:
典型错误:
也见到过同形态响应:
{"message":"no cookie value","request_id":"6A12AD0B8E4DDC3430511C7E","status":403}复现方式
work。work。uploading,随后失败,错误为 115 CDN403 no cookie value。已验证的现象
复现环境中 115 Cookie 本身并非为空,也不是完全失效:
work。/api/fs/link获取同一个 115 文件直链时,返回的Link.Header中包含Cookie。User-Agent会导致不同结果:因此这里的
no cookie value容易误导:实际触发条件不是简单的“没有 Cookie”,而是后台复制链路里 115 CDN 请求使用的User-Agent与 Cookie/直链组合不被 CDN 接受。根因分析
后台复制任务走的是:
复制任务调用
op.Link时传入的是空model.LinkArgs{},没有前端请求里的浏览器User-Agent。115 driver 在生成下载链接和后续读取 CDN 时如果使用空 UA、115BrowserUA,或生成直链时的 UA 与Link.Header中的 UA 不一致,就可能触发 115 CDN 403no cookie value。修复建议
在 115 Cloud driver 的
Link中处理后台任务没有User-Agent的情况:args.Header.Get("User-Agent")为空,使用 OpenList 通用浏览器 UA,例如base.UserAgent,不要默认使用Mozilla/5.0 115Browser/<version>作为 CDN 下载 UA。DownloadWithUA生成直链时使用该 UA。model.Link时 clonedownloadInfo.Header,并确保Cookie与同一个User-Agent被保留到Link.Header,让后续RangeRead请求 115 CDN 时使用一致的 header。示例修复方向:
本地验证结果
按上述方向修改后,本地测试通过:
403 no cookie value额外说明
PikPak 秒传/上传路径还可能出现任务已完成但进度停在
50的显示问题:CacheFullAndHash会将读源文件/算 GCID 的进度映射到0-50,如果 PikPak 秒传成功后直接返回,进度不会补到100。这可以在 PikPakPut成功返回前补一次up(100)作为单独显示修复。