Ghost Downloader

下载引擎

HTTP 分片、加速算法、协议差异。

每种下载协议由对应功能包的步骤实现。HTTP 和 FTP 共享分片/加速/续传机制,M3U8 和 BT 委托外部工具(N_m3u8DL-RElibtorrent)。

源码:features/http_pack/task.pyfeatures/ftp_pack/task.py

HTTP 下载模式

下载前先做 Range 探测,结果决定下载模式:

HTTP 下载模式与运行时降级

探测结果模式行为
206 + content-range正常分片文件等分为 N 段,多线程并行下载,断点续传
200 + content-length不支持 Range单线程,重试时从头下载(截断文件)
200,无 content-length未知大小单线程,重试时从当前位置继续

正常分片模式下,每个分片持有一个字节区间,通过 Range 头并行下载,定位写入同一个文件。分片完成后自动接管剩余量最大的分片的后半段,减少尾部等待。进度文件每秒保存所有分片的字节偏移,用于断点续传。

FTP 与 HTTP 共享分片机制,用 REST 命令代替 Range 头,用 SIZE 命令获取文件大小(不需要探测)。

Range 探测

解析器创建任务时做两阶段探测:

偏移探测

发送 bytes=1-1,请求文件的第二个字节。偏移 1 而非 0,是因为 bytes=0-0 无法区分"服务器支持 Range 并返回了第一个字节"和"服务器忽略了 Range 从头返回整个文件"。

206 响应的 content-range 头中可以提取文件总大小。

回退探测

偏移探测失败时(服务器返回 200),再试 bytes=0-0,兼容只接受从 0 开始的 Range 请求的服务器。

416 响应(Range 不满足)的 content-range 头也可以提取文件大小。

如果扩展的资源缓存中已经有了元数据(文件大小、Range 支持情况),解析器跳过探测直接使用缓存数据。步骤执行时还会做一次轻量级探测,但只为跟随重定向拿到最终 URL,不重新判断 Range 支持。

运行时降级:下载过程中服务器返回 200(CDN 切换、限速策略变更),引擎自动从多线程降级为单线程:截断文件、删除进度文件、从头重下。

自动加速

每秒采样一次速度。累积 5 个样本后检查稳定性(最大偏差 < 15%),不稳定则跳过。

记录基线

记录当前并行数和速度,拆分 4 个剩余量最大的分片。拆分按剩余字节数选目标(不是按速度),将后半段分给新的分片。剩余量太小时跳过。

等待并比较

等待至少 5 秒,再次采样。比较速度增益和并行数增益。

增益 ≥ 80%:带宽还有空间,回到第一步继续加速。增益 < 80%:已接近带宽上限,永久停止加速

加速是一次性的。服务器的带宽上限在单次下载中不会变。如果增加并行度没有提速,再试也不会有效果。

本页目录