使用wget特定选项从Ceph对象存储下载文件遇403错误的原因及解决
问题原因
当同时使用wget的-c(断点续传)和--content-disposition(解析响应头中的Content-Disposition以确定文件名)选项时,wget会触发特定逻辑:
--content-disposition需要读取响应头里的Content-Disposition字段,以此确定本地保存的文件名-c需要获取文件的总大小,用来判断已下载内容的长度,进而计算续传的起始位置
为了一次性获取这两类信息,wget会先发送HEAD请求到预签名URL,而非直接发起GET请求。但Ceph对象存储的预签名URL默认仅授权GET方法的访问权限,未包含HEAD方法的权限,因此该HEAD请求会被拒绝,返回403错误。
而单独使用其中一个选项时,wget无需同时获取两类信息:
- 单独用
-c:GET请求的响应头已包含文件大小,无需额外发送HEAD - 单独用
--content-disposition:GET请求的响应头已包含Content-Disposition字段,直接解析即可,也无需HEAD请求
解决方法
以下是三种可行的解决思路,按操作便捷性排序:
1. 手动指定文件名,放弃--content-disposition
直接用-O参数指定保存的文件名,同时保留-c实现断点续传。这种方式下wget只会发送GET请求,不会触发HEAD请求:
wget -c -O "目标文件名.zip" <你的预签名URL>
优点:操作最简单,无需额外步骤;缺点:需要提前知晓或自行指定文件名。
2. 拆分操作,先获取文件名再续传
先单独用--content-disposition(配合--spider仅请求响应头不下载内容)获取文件名,再用-c和指定文件名进行续传:
# 第一步:获取服务器指定的文件名(仅请求响应头,不下载文件内容) wget --content-disposition --spider <你的预签名URL> # 假设输出中显示文件名是"example_file.zip",第二步执行断点续传 wget -c -O "example_file.zip" <你的预签名URL>
如果--spider仍触发HEAD请求导致403,可以改为先下载一小部分文件(用--limit-rate限制速度,下载后立即中断)来获取文件名:
# 快速获取文件名后中断下载 wget --content-disposition --limit-rate=1k <你的预签名URL> # 接着用-c续传刚才的文件 wget -c <你的预签名URL>
3. 改用curl替代wget
curl在处理断点续传和Content-Disposition时,默认只会发送GET请求,不会触发HEAD请求,可直接满足需求:
curl -C - -O -J <你的预签名URL>
参数说明:
-C -:启用断点续传,自动判断已下载部分的长度-O:按服务器指定的文件名保存文件-J:遵循响应头中的Content-Disposition字段确定文件名
内容的提问来源于stack exchange,提问作者Lachlan Campbell
相关产品推荐
相关产品推荐

