curl --max-filesize 使用详解:文件大小上限限制机制、字节后缀语法与退出码 63
【免费下载链接】curlA command line tool and library for transferring data with URL syntax, supporting DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, MQTTS, POP3, POP3S, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET, TFTP, WS and WSS. libcurl offers a myriad of powerful features项目地址: https://gitcode.com/GitHub_Trending/cu/curl
--max-filesize是 curl 命令行工具中用于限制下载文件最大尺寸的关键选项:当服务器通告的文件体积超过上限时,传输会在开始前被拒绝并返回退出码 63;从 8.4.0 起,即使大小未知,也会在传输中途越界时立即中止。本文以 max-filesize.md 为主干,结合 curl 仓库的 命令行动作源码、libcurl 底层校验逻辑、HTTP 头部处理、FTP/MQTT 处理 与 错误字符串映射,完整讲解其参数语法、单位后缀、版本演进、底层拦截机制与 libcurl 编程接口,帮助读者精确控制任意一次下载的体积边界,防止意外拉取超大文件耗尽带宽或磁盘。
一、选项定位:它解决什么问题
--max-filesize在官方选项元数据中定义为:
| 元数据 | 值 | 说明 |
|---|---|---|
| Long | --max-filesize | 选项长名称 |
| Arg | <bytes> | 必需参数:以字节为单位的体积上限 |
| Help | Maximum file size to download | 选项用途 |
| Protocols | FTP HTTP MQTT | 明确声明支持的协议(FTP、HTTP、MQTT) |
| Category | connection ftp http mqtt | 帮助分类 |
| Added | 7.10.8 | 引入版本 |
| Multi | single | 每行 curl 命令最多指定一次 |
该选项的核心语义为:设置一个非零值后,它表示允许下载的文件的最大字节数。如果请求的文件比这个值更大,传输不会开始,curl 直接以退出码 63 结束;把上限设为0则禁用限制。同一行的 curl 帮助(curl --help max-filesize)与手册文档均由此元数据生成,且同时对应 libcurl 编程接口CURLOPT_MAXFILESIZE/CURLOPT_MAXFILESIZE_LARGE(参见 include/curl/curl.h 中两个选项的声明)。
二、参数语法:后缀单位、大小写与小数
--max-filesize的参数是一个字节数,并支持 1024 进制的单位后缀。文档原话:追加k或K表示按千字节(kilobytes)计数,m或M表示兆字节(megabytes),依此类推。所有后缀(k、M、G、T、P)均为 1024 进制(即 1K = 1024 字节),而不是 1000 进制,这一点与硬盘厂商的十进制标注不同,需要特别注意。
在仓库中,后缀解析表位于 src/tool_getparam.c 的sizeunit数组,源码精确给出了每个后缀对应的乘数:
| 后缀(大小写不敏感) | 乘数(字节) | 含义 |
|---|---|---|
k/K | 1024 | Kilo |
m/M | 1048576(1024²) | Mega |
g/G | 1073741824(1024³) | Giga |
t/T | 1099511627776(1024⁴) | Tera |
p/P | 1125899906842624(1024⁵) | Peta |
从getunit()的实现((unit | 0x20) == list[i].unit)可见匹配对大小写不敏感,200K、200k等价。文档给出的合法示例有:200K、3m、1G(后缀语法于 7.58.0 加入)。此外,解析函数GetSizeParameter()(src/tool_getparam.c)还会接受不带后缀或显式字母b的值按纯字节处理(代码注释(unit | 0x20) == 'b'分支),但对纯字节不允许出现小数部分,否则返回参数错误PARAM_BAD_USE,因为无法处理“部分字节”。
2.1 小数上限(8.19.0 起)
从8.19.0开始,上限可以使用小数表示,例如2.5M表示两个半兆字节。解析代码会先读取整数部分,遇到.后继续读取小数精度,再通过add = mul * prec / frac折算为整数字节数。需要强调文档中的两个限制:
- 只支持英文句点
.作为小数分隔符,与系统 locale(本地化设置)无关——例如在欧洲部分地区习惯使用逗号,这里仍然必须写2.5M而非2,5M; - 若小数的精度位数导致无法折算成整数倍(例如
1.5b这类纯字节小数),会被判定为非法用法直接拒绝。
三、拦截的第一道关卡:传输前已知大小的预检
当服务器在响应头(HTTP 的Content-Length)或协议握手阶段明确通告了文件大小时,curl 会在开始传输前就完成比较,超限则整个传输不启动。仓库中的三个典型实现点如下。
3.1 HTTP:基于Content-Length的http_size()检查
在 lib/http.c 的http_size()函数中,当Content-Length已被解析、且请求体未处于“忽略”状态时:
if(data->set.max_filesize && !k->ignorebody && (k->size >>failf(data, "Exceeded the maximum allowed file size " "(%" FMT_OFF_T ") with %" FMT_OFF_T " bytes", >if(data->set.max_filesize && ((curl_off_t)delta >># 上限 100K(102400 字节),超过则退出码 63 curl --max-filesize 100K https://example.com/big.bin -o big.bin # 上限 2.6M curl --max-filesize 2.6M https://example.com/archive.zip -o archive.zip # 纯字节写法,禁止 4MB 以上的下载 curl --max-filesize 4194304 https://example.com/file.iso -o file.iso # 8.19.0+ 支持小数:2.5 兆字节 curl --max-filesize 2.5M https://example.com/data.tar.gz -o data.tar.gz # 与 --compressed 组合:解压后体积同样受控(8.20.0+) curl --compressed --max-filesize 50M https://example.com/dump.gz -o dump # 上限设 0 显式禁用限制(默认即禁用) curl --max-filesize 0 https://example.com/anything在 shell 脚本中判断是否因体积超限而失败:
curl --max-filesize 1M "$URL" -o out.bin if [ $? -eq 63 ]; then echo "文件过大:已达到 --max-filesize 设定的上限" fi退出码 63 的权威错误文本映射于 lib/strerror.c:CURLE_FILESIZE_EXCEEDED对应的说明正是"Maximum file size exceeded";退出码的通用说明见 _EXITCODES.md。此外,把速率与体积同时约束是常见组合,例如配合--limit-rate限制带宽占用(参考 limit-rate.md),配合--max-time限制总耗时。
七、源码级链路:命令行参数如何到达传输引擎
--max-filesize从敲入命令到真正生效要经过一条清晰的调用链,全部环节都能在仓库中定位:
- 参数解析:命令行解析器命中
C_MAX_FILESIZE分支(src/tool_getparam.c),调用GetSizeParameter()把字符串(含后缀、小数)换算成curl_off_t整数,存入config->max_filesize(类型为curl_off_t,见 src/tool_cfgable.h); - 回写 libcurl 选项:工具随后以大整数变体下发选项——
my_setopt_offt(curl, CURLOPT_MAXFILESIZE_LARGE, config->max_filesize)(src/config2setopts.c); - 选项落地:在 lib/setopt.c 的
CURLOPT_MAXFILESIZE_LARGE分支中,负值会被拒绝(返回CURLE_BAD_FUNCTION_ARGUMENT),合法值写入会话设置data->set.max_filesize; - 运行时消费:
data->set.max_filesize被前文提到的 lib/http.c、lib/ftp.c、lib/mqtt.c、lib/sendf.c、lib/progress.c 各检查点读取,决定是否中止。
之所以命令行使用CURLOPT_MAXFILESIZE_LARGE下发,是因为它不受平台long位宽限制、能以完整的curl_off_t表达超大上限,天然兼容后续单位后缀换算出的、可能超过 32 位long的量级。
八、libcurl 编程接口:CURLOPT_MAXFILESIZE与CURLOPT_MAXFILESIZE_LARGE
该功能对 libcurl 使用者同样开放,两个选项均声明于 include/curl/curl.h:
| 选项 | 类型 | 选项号 | 说明 |
|---|---|---|---|
CURLOPT_MAXFILESIZE | CURLOPTTYPE_LONG(long) | 114 | 常规上限,适用long位宽足够的场景 |
CURLOPT_MAXFILESIZE_LARGE | CURLOPTTYPE_OFF_T(curl_off_t) | 117 | 大文件上限,推荐用于追求跨平台一致的大体积场景 |
在代码中设置任一选项,即会把data->set.max_filesize置为该值,从而触发与命令行完全相同的预检与运行时拦截。一个最小可编译的调用示例:
#include <curl/curl.h> int main(void) { CURL *curl = curl_easy_init(); if(curl) { curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/big.bin"); /* 限制下载文件不超过 1 GiB = 1073741824 字节 */ curl_easy_setopt(curl, CURLOPT_MAXFILESIZE_LARGE, (curl_off_t)1073741824); curl_easy_setopt(curl, CURLOPT_WRITEDATA, /* 你的 FILE* 或回调上下文 */); CURLcode rc = curl_easy_perform(curl); if(rc == CURLE_FILESIZE_EXCEEDED) { /* 文件超过上限,传输未完成 */ } curl_easy_cleanup(curl); } return 0; }程序可通过返回值CURLE_FILESIZE_EXCEEDED(退出码 63 对应的 libcurl 错误码)精确区分“文件过大”与其它失败。各选项的完整契约见 CURLOPT_MAXFILESIZE.md 与 CURLOPT_MAXFILESIZE_LARGE.md。
九、边界条件与版本演进汇总
9.1 需要注意的行为边界
- 单位后缀一律1024 进制:
1K = 1024字节,1M = 1048576字节; - 上限为
0(或未设置)表示不限制; - 传输前拦截依赖服务器提供大小信息(HTTP 的
Content-Length、FTP 的尺寸应答、MQTT 的剩余长度);对大小未知的流式数据,只有8.4.0+会在传输中途执行运行时截停; --compressed下的解压膨胀体积自8.20.0起同样纳入上限核算;- 小数分隔符恒为
.,不受本地 locale 影响(8.19.0+); - 该选项与“忽略响应体”(
ignorebody,例如-I/--head一类场景)互斥——忽略 body 时不进行此检查,源码见 lib/http.c 的条件。
9.2 版本时间线(以官方文档与仓库为准)
| 版本 | 变更 |
|---|---|
| 7.10.8 | 首次引入--max-filesize |
| 7.58.0 | 支持k/K、m/M、G、T、P等单位后缀(1024 进制) |
| 8.4.0 | 传输过程中动态越界即中止,不再依赖预先已知大小 |
| 8.19.0 | 支持小数上限,如2.5M,仅接受.作分隔符 |
| 8.20.0 | --compressed自动解压造成的越界同样触发停止 |
十、总结
--max-filesize是 curl 在下载侧的一条“双保险”护栏:在有协议通告时于传输开始前拦截(HTTP/FTP/MQTT 各有实现),在没有通告时于 8.4.0 之后的流式写入路径上实时截停,并在 8.20.0 之后把--compressed解压造成的体积膨胀也一并纳入预算。理解其 1024 进制后缀、小数点语法、退出码 63 的错误文本("Maximum file size exceeded")以及CURLOPT_MAXFILESIZE/CURLOPT_MAXFILESIZE_LARGE两个编程选项,即可在命令行与 libcurl 两种使用形态下稳定地把每次下载约束在预期体积之内,为脚本化采集、镜像同步与自动化运维提供可靠保障。
【免费下载链接】curlA command line tool and library for transferring data with URL syntax, supporting DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, MQTTS, POP3, POP3S, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET, TFTP, WS and WSS. libcurl offers a myriad of powerful features项目地址: https://gitcode.com/GitHub_Trending/cu/curl
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考