环境:
nginx v1.19.8
seafile Pro v8.0.8 for centos 7
aria2c v1.36 for windows
IE 11
Firefox v91(windows)/Android v91.1
Chrome v92(windows)/chrome v79.xPC端的火狐/IE 11/Chrome下载seafile网页端任意文件,都可以随意暂停并继续,偶然在安卓上发现不支持,使用一些专业的下载工具,比如 ADM、IDM+、安卓系统自带的下载管理器去下载文件,ADM和IDM+会直接在新建任务/刚开始任务就提示服务端不支持断点续传,安卓端的Firefox和Chrome也不支持断点续传,系统的自带下载管理器则没有暂停按钮,只有取消。
PC和安卓移动端差异巨大,做进一步测试:
换了一个自己实现的简单http下载服务的浏览器,X浏览器内置的简易下载功能,含完整的range范围请求实现,发现可以随意暂停继续下载进程,而不会被迫重头开始下载。
测试到这里已经初步有怀疑目标了,差异体现在客户端发出的header和服务端对此作出的response,更换机子为某三星手机,结果又推翻了我的推测,系统上的火狐/chrome 都能支持断点续传,检查Chrome和firefox内核版本,相差不大。
这时候进一步测试结果让我怀疑是seafile对 range header支持存在问题,aria2c 发出 range请求时,seafile 直接返回整个资源大小, 响应字段的名字也没有,只有个值,0-xxxx(xxx为文件末尾),我的Accept-Ranges
呢?下载工具直接炸裂,报不支持断点续传提示......
Invalid range header.
Request: 146800640-147849215/2343470573
Response: 0-2343470572/2343470573
但是此时直接说seafile问题不太妥当,因为PC端的Chrome/Firefox是正常实现断点续传的,查看细节,seafile对客户端range请求没有返回206状态码(即成功获取部分资源),而是返回200,并直接返回整个文件。
有几种情况,seafile收到了客户端的 Range: bytes=xxxx-xxxx
,但是没回应 Accept-Ranges=xxxxx-xxxxx
,客户端炸裂,报服务端不支持断点续传,另一个就是seafile收到了标准的range请求,但没正确处理和响应header。
查询nginx日志,seafile后端都是回复200状态码,返回整个资源,seafile的相关日志并没有记录收到的header的文件。
结合之前测试情况,合理推测是seafile并未收到客户端发出的 range字段的header,这个推测是有依据的,因为我是通过nginx反向代理到本地的127.0.0.1上面的后端,反向代理配置的参数也没有携带range转发。
查询nginx反向代理关于header处理参数时,发现nginx对 range 有一个参数可以对range进行一些额外处理,proxy_force_ranges on | off;
不管代理响应中的“Accept-Ranges”是什么,都对响应强制启用Accept-Ranges支持。,默认值是关闭状态,,把它添加到seafile自身的seafhttp前端的location位置,并启用。
另一方面处理nginx反向代理时没有转发相关range header给后端。
在nginx seafhttp location 位置添加这几行配置:
location /seafhttp {
#强制响应 range请求,对客户端返回 Accept-Ranges ,修复在线播放视频无法拖动进度条问题
proxy_force_ranges on;
#转发range header转发到seafile后端,解决移动端range header 未按预期 Response range导致断点续传失败。
proxy_set_header Range $http_range;
proxy_set_header If-Range $http_if_range;
...省略若干...
}
重启nginx, 此时seafile 在线播放视频支持拖动进度条了,同时断点续传在PC端和移动端全部正常了,seafile安卓端app是不支持断点续传,客户端的锅,请使用移动端H5代替。