字符界面下的下载工具-curl
2012-10-14 20:56:43 阿炯

cURL是一款始于1997年的字符界面下的命令行工具开源项目,支持 HTTP,HTTPS,FTP,FTPS,GOPHER,TFTP,SCP,SFTP,SMB,TELNET,DICT,LDAP,LDAPS,FILE,IMAP,SMTP,POP3,RTSP 和 RTMP 等协议。此外还具有cookies支持、断点续传、FTP上传、密码支持、SSL支持和代理支持等特性,而 curl 的底层使用的是 libcurl 库,libcurl 库与 curl 工具组成了 cURL 项目。开发者可以基于这个库开发其他下载工具,从而广泛应用在 Unix/Linux 发行版中,也有 Windows 的移植版本。其主要的产品是curl(命令行工具)和libcurl(C语言的API函数库),两者功能均是:基于网络协议,对指定URL进行网络传输。它只涉及是任何网络协议传输,并不涉及对具体数据的具体处理。采用C语言开发并在MIT协议下授权。


curl is a command line tool for transferring data with URL syntax, supporting DICT, FILE, FTP, FTPS, Gopher, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, POP3, POP3S, RTMP, RTSP, SCP, SFTP, SMTP, SMTPS, Telnet and TFTP. curl supports SSL certificates, HTTP POST, HTTP PUT, FTP uploading, HTTP form based upload, proxies, cookies, user+password authentication (Basic, Digest, NTLM, Negotiate, kerberos...), file transfer resume, proxy tunneling and a busload of other useful tricks.

Curl是一个功能强大的命令行工具,可以看做是命令行浏览器。用于与服务器进行数据交互,支持多种数据传输协议,支持文件的上传和下载,所以是综合传输工具。因此其用法也参考比较庞大,其用法可参考本站的《curl下载工具使用参考》。

Curl错误代码列表
CURLE_UNSUPPORTED_PROTOCOL (1) – 您传送给 libcurl 的网址使用了此 libcurl 不支持的协议。可能是没有使用的编译时选项造成了这种情况可能是协议字符串拼写有误,或没有指定协议 libcurl 代码。
CURLE_FAILED_INIT (2) – 非常早期的初始化代码失败。 可能是内部错误或问题。
CURLE_URL_MALFORMAT (3) – 网址格式不正确。
CURLE_COULDNT_RESOLVE_PROXY (5) – 无法解析代理服务器。 指定的代理服务器主机无法解析。
CURLE_COULDNT_RESOLVE_HOST (6) – 无法解析主机。 指定的远程主机无法解析。
CURLE_COULDNT_CONNECT (7) – 无法通过 connect() 连接至主机或代理服务器。
CURLE_FTP_WEIRD_SERVER_REPLY (8) – 在连接到 FTP 服务器后,libcurl 需要收到特定的回复。 此错误代码表示收到了不正常或不正确的回复。 指定的远程服务器可能不是正确的 FTP 服务器。
CURLE_REMOTE_ACCESS_DENIED (9) – 我们无法访问网址中指定的资源。 对于 FTP,如果尝试更改为远程目录,就会发生这种情况。
CURLE_FTP_WEIRD_PASS_REPLY (11) – 在将 FTP 密码发送到服务器后,libcurl 需要收到正确的回复。 此错误代码表示返回的是意外的代码。
CURLE_FTP_WEIRD_PASV_REPLY (13) – libcurl 无法从服务器端收到有用的结果,作为对 PASV 或 EPSV 命令的响应。 服务器有问题。
CURLE_FTP_WEIRD_227_FORMAT (14) – FTP 服务器返回 227 行作为对 PASV 命令的响应。 如果 libcurl 无法解析此行,就会返回此代码。
CURLE_FTP_CANT_GET_HOST (15) – 在查找用于新连接的主机时出现内部错误。
CURLE_FTP_COULDNT_SET_TYPE (17) – 在尝试将传输模式设置为二进制或 ascii 时发生错误。
CURLE_PARTIAL_FILE (18) – 文件传输尺寸小于或大于预期。 当服务器先报告了一个预期的传输尺寸,然后所传送的数据与先前指定尺寸不相符时,就会发生此错误。
CURLE_FTP_COULDNT_RETR_FILE (19) – ‘RETR’ 命令收到了不正常的回复,或完成的传输尺寸为零字节。
CURLE_QUOTE_ERROR (21) – 在向远程服务器发送自定义 “QUOTE” 命令时,其中一个命令返回的错误代码为 400 或更大的数字对于 FTP,或以其他方式表明命令无法成功完成。
CURLE_HTTP_RETURNED_ERROR (22) – 如果 CURLOPT_FAILONERROR 设置为 TRUE,且 HTTP 服务器返回 >= 400 的错误代码,就会返回此代码。 此错误代码以前又称为CURLE_HTTP_NOT_FOUND。
CURLE_WRITE_ERROR (23) – 在向本地文件写入所收到的数据时发生错误,或由写入回调 (write callback) 向 libcurl 返回了一个错误。
CURLE_UPLOAD_FAILED (25) – 无法开始上传。 对于 FTP,服务器通常会拒绝执行 STOR 命令。 错误缓冲区通常会提供服务器对此问题的说明。 此错误代码以前又称为CURLE_FTP_COULDNT_STOR_FILE。
CURLE_READ_ERROR (26) – 读取本地文件时遇到问题,或由读取回调 (read callback) 返回了一个错误。
CURLE_OUT_OF_MEMORY (27) – 内存分配请求失败。 此错误比较严重,若发生此错误,则表明出现了非常严重的问题。
CURLE_OPERATION_TIMEDOUT (28) – 操作超时。 已达到根据相应情况指定的超时时间。 请注意: 自 Urchin 6.6.0.2 开始,超时时间可以自行更改。 要指定远程日志下载超时,请打开 urchin.conf 文件,取消以下行的注释标记:#DownloadTimeout: 30
CURLE_FTP_PORT_FAILED (30) – FTP PORT 命令返回错误。 在没有为 libcurl 指定适当的地址使用时,最有可能发生此问题。 请参阅 CURLOPT_FTPPORT。
CURLE_FTP_COULDNT_USE_REST (31) – FTP REST 命令返回错误。 如果服务器正常,则应当不会发生这种情况。
CURLE_RANGE_ERROR (33) – 服务器不支持或不接受范围请求。
CURLE_HTTP_POST_ERROR (34) – 此问题比较少见,主要由内部混乱引发。
CURLE_SSL_CONNECT_ERROR (35) – 同时使用 SSL/TLS 时可能会发生此错误。可以访问错误缓冲区查看相应信息,其中会对此问题进行更详细的介绍。可能是证书文件格式、路径、许可、密码及其他因素导致了此问题。
CURLE_FTP_BAD_DOWNLOAD_RESUME (36) – 尝试恢复超过文件大小限制的 FTP 连接。
CURLE_FILE_COULDNT_READ_FILE (37) – 无法打开 FILE:// 路径下的文件。 原因很可能是文件路径无法识别现有文件。 建议您检查文件的访问权限。
CURLE_LDAP_CANNOT_BIND (38) – LDAP 无法绑定。LDAP 绑定操作失败。
CURLE_LDAP_SEARCH_FAILED (39) – LDAP 搜索无法进行。
CURLE_FUNCTION_NOT_FOUND (41) – 找不到函数。 找不到必要的 zlib 函数。
CURLE_ABORTED_BY_CALLBACK (42) – 由回调中止。 回调向 libcurl 返回了 “abort”。
CURLE_BAD_FUNCTION_ARGUMENT (43) – 内部错误。 使用了不正确的参数调用函数。
CURLE_INTERFACE_FAILED (45) – 界面错误。指定的外部界面无法使用。请通过 CURLOPT_INTERFACE 设置要使用哪个界面来处理外部连接的来源 IP 地址。此错误代码以前又称为CURLE_HTTP_PORT_FAILED。
CURLE_TOO_MANY_REDIRECTS (47) – 重定向过多。 进行重定向时,libcurl 达到了网页点击上限。 请使用 CURLOPT_MAXREDIRS 设置上限。
CURLE_UNKNOWN_TELNET_OPTION (48) – 无法识别以 CURLOPT_TELNETOPTIONS 设置的选项。 请参阅相关文档。
CURLE_TELNET_OPTION_SYNTAX (49) – telnet 选项字符串的格式不正确。
CURLE_PEER_FAILED_VERIFICATION (51) – 远程服务器的 SSL 证书或 SSH md5 指纹不正确。
CURLE_GOT_NOTHING (52) – 服务器未返回任何数据,在相应情况下,未返回任何数据就属于出现错误。
CURLE_SSL_ENGINE_NOTFOUND (53) – 找不到指定的加密引擎。
CURLE_SSL_ENGINE_SETFAILED (54) – 无法将选定的 SSL 加密引擎设为默认选项。
CURLE_SEND_ERROR (55) – 无法发送网络数据。
CURLE_RECV_ERROR (56) – 接收网络数据失败。
CURLE_SSL_CERTPROBLEM (58) – 本地客户端证书有问题。
CURLE_SSL_CIPHER (59) – 无法使用指定的密钥。
CURLE_SSL_CACERT (60) – 无法使用已知的 CA 证书验证对等证书。
CURLE_BAD_CONTENT_ENCODING (61) – 无法识别传输编码。
CURLE_LDAP_INVALID_URL (62) – LDAP 网址无效。
CURLE_FILESIZE_EXCEEDED (63) – 超过了文件大小上限。
CURLE_USE_SSL_FAILED (64) – 请求的 FTP SSL 级别失败。
CURLE_SEND_FAIL_REWIND (65) – 进行发送操作时,curl 必须回转数据以便重新传输,但回转操作未能成功。
CURLE_SSL_ENGINE_INITFAILED (66) – SSL 引擎初始化失败。
CURLE_LOGIN_DENIED (67) – 远程服务器拒绝 curl 登录7.13.1 新增功能。
CURLE_TFTP_NOTFOUND (68) – 在 TFTP 服务器上找不到文件。
CURLE_TFTP_PERM (69) – 在 TFTP 服务器上遇到权限问题。
CURLE_REMOTE_DISK_FULL (70) – 服务器磁盘空间不足。
CURLE_TFTP_ILLEGAL (71) – TFTP 操作非法。
CURLE_TFTP_UNKNOWNID (72) – TFTP 传输 ID 未知。
CURLE_REMOTE_FILE_EXISTS (73) – 文件已存在,无法覆盖。
CURLE_TFTP_NOSUCHUSER (74) – 运行正常的 TFTP 服务器不会返回此错误。
CURLE_CONV_FAILED (75) – 字符转换失败。
CURLE_CONV_REQD (76) – 调用方必须注册转换回调。
CURLE_SSL_CACERT_BADFILE (77) – 读取 SSL CA 证书时遇到问题可能是路径错误或访问权限问题。
CURLE_REMOTE_FILE_NOT_FOUND (78) – 网址中引用的资源不存在。
CURLE_SSH (79) – SSH 会话中发生无法识别的错误。
CURLE_SSL_SHUTDOWN_FAILED (80) – 无法终止 SSL 连接。

Curl团队的C语言代码规范

代码风格统一有助于团队协作与代码review,业界用的比较多的是google的风格,来看看咱们平时用的比较多的工具curl团队的代码规范是什么样子的。从几个方面看看curl的C语言开发规范:命名、缩进、注释、长行、大括号、'else' 在下一行、括号前不加空格、使用布尔条件、条件中不要赋值、新块在新行上、运算符周围加空格、返回值不加括号、sizeof 参数加括号、列对齐、平台相关代码、不要 typedef 结构体。

命名
新的函数和变量名称应该是逻辑的、可理解的,并且根据它们的用途进行命名。文件局部函数应该被声明为静态的,建议是小写字母名称。

缩进
只使用空格进行缩进,不使用制表符。每个新的开放大括号使用两个空格。
if(something_is_true) {
  while(second_statement == fine) {
    moo();
  }
}

注释
由于编写的是 C89 代码,不允许使用 // 注释。它们直到 C99 标准才被引入。只使用 **/* 注释 */**。
/* 这是一个注释 */

长行
curl 中的源代码永远不应该超过 79 列,即使在现代大屏幕和高分辨率屏幕时代,仍然有两个原因要保持这一点:
1.较窄的列比较宽的列更容易阅读。有一个原因是报纸几十年甚至几个世纪来一直使用列。
2.较窄的列允许开发人员更容易地在不同的窗口中并排显示多个代码片段。它允许在同一个屏幕上并排显示两个或三个源代码窗口 - 以及多个终端和调试窗口。

大括号
在 if/while/do/for 表达式中,我们将开放大括号写在与关键字同一行,然后将闭合大括号设置在与初始关键字相同缩进级别的同一行。就像这样:
if(age < 40) {
  /* 显然是年轻人 */
}

如果它们只包含一个一行语句,则可以省略大括号:
if(!x)
  continue;

对于函数,开放大括号应该写在单独的一行上:
int main(int argc, char **argv)
{
  return 1;
}

'else' 在下一行
在使用大括号添加 else 子句到条件表达式时,我们将其添加到关闭大括号后的新行。就像这样:
if(age < 40) {
  /* 显然是年轻人 */
}
else {
  /* 可能是脾气暴躁的 */
}

括号前不加空格
在使用 if/while/do/for 表达式时,关键字与开放括号之间不应有空格。就像这样:
while(1) {
  /* 永远循环 */
}

使用布尔条件
在 if/while 条件中,我们更喜欢测试条件值,如布尔值与 TRUE 或 FALSE、指针与 NULL 或 != NULL 以及整数与零或非零,而不是:
result = do_something();
if(!result) {
  /* 出现了问题 */
  return result;
}

条件中不要赋值
为了增加可读性并减少条件的复杂性,避免在 if/while 条件中进行变量赋值。不赞成这种风格:
if((ptr = malloc(100)) == NULL)
  return NULL;

而是鼓励更清晰地表达:
ptr = malloc(100);
if(!ptr)
  return NULL;

新块在新行上
永远不会在同一行上写多个语句,即使是短的 if() 条件也不例外。
if(a)
  return TRUE;
else if(b)
  return FALSE;

永远不要这样:
if(a) return TRUE;
else if(b) return FALSE;

运算符周围加空格
请在 C 表达式中运算符的两侧使用空格。后缀 (), [], ->, ., ++, -- 和一元 +, -, !, ~, & 操作符除外,它们不应该有空格。示例:
bla = func();
who = name[0];
age += 1;
true = !false;
size += -2 + 3 *

 (a + b);
ptr->member = a++;
struct.field = b--;
ptr = &address;
contents = *pointer;
complement = ~bits;
empty = (!*string) ? TRUE : FALSE;

返回值不加括号
在 'return' 语句中不加额外的括号:
int works(void)
{
  return TRUE;
}

sizeof 参数加括号
在代码中使用 sizeof 运算符时,我们更喜欢在其参数周围加上括号:
int size = sizeof(int);

列对齐
一些语句不能在单行上完成,因为行太长、语句太难读,或者是由于上述其他风格指南。在这种情况下,语句跨越多行。

如果一个连续行是表达式或子表达式的一部分,那么你应该在适当的列上对齐,以便能够清楚地知道它是语句的哪一部分。运算符不应该起始于连续行。在其他情况下,遵循 2 个空格的缩进指南。以下是来自 libcurl 的一些示例:
if(Curl_pipeline_wanted(handle->multi, CURLPIPE_HTTP1) &&
   (handle->set.httpversion != CURL_HTTP_VERSION_1_0) &&
   (handle->set.httpreq == HTTPREQ_GET ||
    handle->set.httpreq == HTTPREQ_HEAD))
  /* 没有要求 HTTP/1.0 并且是 GET 或 HEAD 请求 */
  return TRUE;

如果没有括号,使用默认缩进:
data->set.http_disable_hostname_check_before_authentication =
  (0 != va_arg(param, long)) ? TRUE : FALSE;

函数调用时使用开放括号:
if(option) {
  result = parse_login_details(option, strlen(option),
                               (userp ? &user : NULL),
                               (passwdp ? &passwd : NULL),
                               NULL);
}

与 "current open" 括号对齐:
DEBUGF(infof(data, "Curl_pp_readresp_ %d bytes of trailing "
             "server response left\n",
             (int)clipamount));

平台相关代码
使用 #ifdef HAVE_FEATURE 进行条件代码。我们避免在 #ifdef 行中检查特定操作系统或硬件。HAVE_FEATURE 应该由 configure 脚本为类 Unix 系统生成,并且它们在其他系统的 config-[system].h 文件中硬编码。

还鼓励在 libcurl 构建时,使用可能为空或定义为常量的宏/函数,以使代码无缝。就像这个例子,其中 magic() 函数根据构建时的条件不同而工作:
#ifdef HAVE_MAGIC
void magic(int a)
{
  return a + 2;
}
#else
#define magic(x) 1
#endif

int content = magic(3);

不要 typedef 结构体
尽管可以使用结构体,但不要对其进行 typedef。使用 struct name 的方式来标识它们:
struct something {
   void *valid;
   size_t way_to_write;
};
struct something instance;

不要这样:
typedef struct {
   void *wrong;
   size_t way_to_write;
} something;
something instance;

放弃使用管道技术

cURL 作者 Daniel Stenberg 在其博客发布公告表示,从这个发布到 cURL 7.65.0 的提交开始,cURL 将删除全部支持 HTTP/1.1 Pipelining 技术的代码。早在 7.62.0 版本中,该特性就已在代码中被禁用,因此保持使用最新版本应用的开发者应该不会注意到差异。Daniel 表示,cURL 在支持 HTTP/1.1 Pipelining 的很长一段时间内,由于一系列已知的错误和缺乏足够的测试,其实这是一个脆弱的功能。此外,由于对时间非常敏感,对 pipelining 的调试相当棘手,经常需要启用调试输出或类似功能会完全改变性质的行为,影响十分大。

默认情况下,大型桌面浏览器从未启用 HTTP pipelining,因为它存在很多问题,例如服务器实现中断等。而且很长一段时间以来,Firefox 和 Chrome 都完全放弃了对管道技术的支持。随着时间的推移,cURL 在对管道方面技术的支持变得越来越孤独。也正是 HTTP pipelining 的糟糕现状,这成了 HTTP/2 及其多路复用功能背后的主要驱动因素。HTTP/2 多路复用是真正的“pipelining done right”。与 HTTP/1.1 Pipelining 相比,它更加稳定和实用,并能以更好的方式解决用例,具有更好的性能和更少的缺点和问题(自 7.62.0 起,cURL 默认启用多路复用)所以 Daniel 认为,在 2019 年更应放弃管道技术,转而使用 HTTP/2 来替代它。

将原生支持 JSON

2022年1月下旬消息,cURL 作者 Daniel Stenberg 在邮件透露了为 cURL 添加原生支持 JSON 的计划。Daniel 解释了为 cURL 添加原生支持 JSON 的理由:
1.在 REST APIs 等领域,发送 JSON 是十分普遍的做法;
2.许多人被问及选择 cURL 替代方案的考虑因素时,“易于使用 JSON”是常见的一项。

在 Stack Overflow 等网站上,相当多的人无法使用 cURL 发送正确的 JSON 和正确引用 JSON,因为 JSON 使用了双引号,而 Shell 不会在单引号内扩展变量;Daniel 还表示,由于自己不经常发送 JSON,所以完全靠他来设计这个功能并不合适。他需要其他人的帮助,让这个功能尽可能地有用。目前 Daniel 已在 wiki 中提供了关于此功能的草案,同时创建了讨论区。简单来说,Daniel 计划增加两个命令行选项:
1.发送已格式化的 JSON 作为 -d 的快捷方式,并附带相匹配的 Accept header;
2.通过构建 JSON request body 进行发送。

--json -|<data>|@filename
curl --json [whatever] http://example.com

上述命令行是一种快捷方式,其作用等同于 -d [whatever] -H "Content-Type: application/json"。
--jp [part]

('jp' 是 "JSON part" 的缩写)

构建 JSON request body,然后使用 request headerContent-Type: application/json发送 JSON。[part] 是构建 JSON 内容的指令。

详情请查看此处

curl 怎样成为影响世界的开源项目

作者|DANIEL STENBERG,译者|平川,策划|万佳

本节最初发布于 DANIEL STENBERG 的个人博客,遵循 CC BY-SA 4.0 许可,由 InfoQ 中文站翻译并分享。

作为当今用途最广的开源项目之一,curl 在全世界有超过 100 亿的安装。从红帽 Linux、Debian 再到 Mac OS、Windows 10、iOS 和 Android,甚至包括任天堂 Switch、Xbox 和索尼 PS5 以及电脑游戏、媒体播放器和机顶盒等,都不乏 curl 的身影。本文作者回顾了 curl 过去 23 年的发展历程,揭示了一个小型开源项目怎样保持生命力,发展成一个影响世界的存在。

curl 的官方生日是 1998 年 3 月 20 日,这一天,第一个可构建出工具名为 curl 的 tar 包发布。之所以将其命名为 curl 4.0,因为我保留了之前那个名字的版本号。准确的说,它是从 3.12 的基础上过来的,而 3.12 是是旧名 urlget 的最后一个版本。当然,curl 并非那天凭空产生的。其历史可追溯到一年多以前:1996 年 11 月 11 日发布的名为 httpget 的工具。它由 Rafael Sagula 开发,我发现这个项目并开始做贡献。httpget 0.1 是一个不到 300 行代码的 C 文件。(对于这个项目,我现在拥有最早的源代码是 httpget 1.3,可以在这里找到),之所以关注这个项目,是因为我想有一个小工具可以定期从网站上下载货币汇率,这样我就能在我的 IRC bot 货币兑换中提供它们。

当时迅速做出的那些小决定,后来在很大程度上影响和塑造了我的生活。从那以后,curl 一直是我的主要爱好之一——当然,从几年前开始,它成了我的全职工作。

就在 1996 年 11 月的同一天,Wget 的第一个版本发布(1.4.0)。在发布前,这个项目也以另一个名字存在——回想起来,我都不知道它,我使用 httpget 来完成任务。也可能我发现它了,然后因为它太小又忽略了它。Wget 1.4.0 的 tar 包只有 171 KB。不久后,我承担起 httpget 维护者一职,并进一步扩展它的功能。后来,我添加了 Gopher 和 FTP 支持,并将其重命名为 urlget(这是由于我发现货币汇率也托管在这些服务器上)。1998 年春天,我还添加了对 FTP 上传的支持,这个工具的名称又一次产生误导性,我需要重新给它命名。

起名真的很难。我想要一个经典 Unix 风格的简短名字。我没有花太多时间,因为我很快就想到了一个有趣的词。该工具作用在 URL 上,而且是一个互联网客户端工具。' c '(客户端)和 URL 使' cURL '看起来非常贴切有趣,而且简短,还非常“unixy”。那时,我就已经希望 curl 成为 Unix 中使用管道和标准输出这一传统的一部分。我希望 curl 的工作方式像 cat 命令,但是针对 URL,在默认情况下,它会将 URL 发送到终端的 stdout。就像 cat 一样。然后,我们就可以“看到”该 URL 的内容。字母 C 的发音是 see,所以可以读作“see URL”。我喜欢双关语,这样就很好了(但我还是会把它读成“kurl”!)。

这是最初的 Logo,由 Henrik Hellerstedt 在 1998 年创建。我打包了 curl 4.0,并在那个周五进行发布。那时,它有 2200 行代码。在我几个月后发布的 curl 4.8 版本中,感谢文件中提到 7 位贡献者。我们花了将近 7 年的时间才将贡献者发展到 100 位。现如今,该文件列出了超过 2300 个名字,每年还要增加几百个。这不是一个人的项目!

1、没有什么特别的事情发生

curl 并没有取得巨大的成功。一些人发现了它,在第一个版本发布 14 天后,我上传了 4.1 版本,其中有一些 Bug 修复,一个延续几十年的传统开始了:不断发布更新,修复 Bug。“尽早且经常发布”是我们一直坚持的口号。1998 年年底,当发布超过 15 个版本时,我们在网站上发布了这样一段精彩的声明:

2、下载量 300!

对于这个项目和工具,我从来没有任何征服世界的想法或宏大愿景。我只是希望它能有效、快速、可靠地进行互联网传输,这就是我正在努力实现的。为了更好地向世人提供良好的互联网传输体验,我们引入了 libcurl 库,它在 2000 年夏天首次发布,使项目跃升了一个层次。随着时间的推移,libcurl 已经发展成为事实上的互联网传输 API。今天,在它 23 岁生日之际,这仍然是 curl 的重点,也是我在这里所做的。我相信,如果 curl 取得了一定程度的成功,那主要是因为一个特殊的品质。一个词:

坚持

我们坚持、忍耐,不断打磨。我们在这里是为了长远利益。我花了 2 年时间,它才达到 300 次下载量。又过了 10 年左右,它才真正被广泛使用。在 2008 年,curl 网站每月的下载数据量约为 100GB。这个月,它的下载数据量为 15600GB——有趣的是,156 个月的时间里数据量增加了 156 倍!当然,大多数用户不会从我们的网站上下载任何东西,他们是从他们的发行版或操作系统提供商那里获得 curl。

curl 在 1998 年底被红帽 Linux 采用,在 1999 年 5 月成为 Debian 的一个软件包,2001 年 8 月,Mac OS X 10.1 也提供了这个工具。如今,Windows 10、iOS 和 Android 设备也默认安装了这款软件。不用说还有游戏机,包括任天堂 Switch、Xbox 和索尼 PS5。有趣的是,两大主流的移动操作系统都在使用 libcurl,但它们并没有提供 API,所以很多应用程序,包括很多非常大的应用程序都捆绑了自己的 libcurl 构建,包括 YouTube、Skype、Instagram、Spotif、谷歌 Photos、Netflix 等。这意味着,如今大多数智能手机用户的手机中都有许多不同的 curl 安装。此外,libcurl 还被许多电脑游戏所使用:《侠盗飞车 5》、《堡垒之夜》、《绝地求生》、《荒野大镖客:救赎 2》等等。libcurl 还被用在了媒体播放器和机顶盒中,如 Roku、Apple TV。

curl 和 libcurl 在几乎所有的互联网服务器上都可以使用,并且是 PHP 默认的传输引擎,而在全球近 20 亿个网站中,有近 80% 使用了 PHP。

汽车现在已经联网了。如今libcurl几乎被用于每一辆现代汽车之间的数据传输。然后还有媒体播放器、厨房和医疗设备、打印机、智能手表和许多“智能”的物联网的东西。实际上,几乎所有的连接互联网的设备都在运行 curl。如果我说curl 在全世界超过 100 亿个装置中存在时,我并没有夸大其词。

3、孤独的强者

在过去几年里,我尝试了几次,看看 curl 是否可以加入一个管理组织,但没有一个人接受我们,我认为这是最好的结果。我们是完全独立的,独立于任何组织和公司。我们想怎么做就怎么做,不用按别人的规矩来。在过去的几年里,赞助和捐赠的速度确实加快了,我们的状况很好,可以为 Bug Bounty 计划提供丰厚的奖励。我相信,我和 wolfSSL 合作提供的 curl 商业支持只会让 curl 变得更强大:它让我可以花更多的时间在 curl 上,让更多的公司觉得使用 curl 更有保障,最终让我们所有人都受益。1996 年底的 300 行代码到 2021 年 3 月已经增长到 17.2 万行。

4、未来展望

我们最重要的工作是“不要惹是生非”。在尽可能多的平台上提供你能找到的最好、最可靠的互联网传输库。但为了保持吸引力,我们也需要与时俱进,适应新出现的协议和使用习惯。支持新的协议版本,支持更好的做事方式,并随着时间的推移,以负责任的方式弃用不好的东西,同时避免对用户造成伤害。我认为在短期内,我们希望确保 HTTP/3 能够正常工作,让 Hyper 后端变得非常出色,看看 rustls 后端会如何发展。23 年过去了,我们还是没有任何宏大的愿景或路线图作为指导。我们以互联网和用户为引领,不断向前,不断攀登!

5、关于 23 岁的 curl,有这样 23 个数值

在这个生日的前几天,我用 #curl23 标签发布了该项目的 23 个“curl 数值”。以下是这 23 个数字和事实:
代码从 1998 年 3 月的 2200 行增长到 2021 年的 17 万行;
14 个不同的 TLS 库获得了 curl 的支持;
2348 名贡献者让 curl 成了今天的样子;
至今已经发布了 197 个版本;
有 6787 项 Bug 修复记录在案;
全世界 100 亿安装,让 curl 成为全世界使用最广泛的分发;
有 871 名提交者提供过代码;
curl docker 官方镜像拉取数为 9.35 亿;
至少有 22 个汽车品牌在它们的车辆中运行 curl;
每次提交和拉取请求都要运行 100 个 CI 作业;
Daniel 已经在这个项目上花了 15000 个小时的业务时间;
前 2 大移动操作系统都在它们设备的操作系统中使用了 curl;
已知有 86 种不同的操作系统在运行 curl;
2.5 亿台电视在运行 curl;
curl 支持 26 种不同的传输协议;
有 36 种不同的第三方库可以根据需要构建,供 curl 使用;
有 22 种不同的 CPU 体系结构运行 curl;
已为 Bug Bounty 支付了 4400 美元;
curl 有 240 个命令行选项;
curl 网站每月有 15600GB 的数据下载量;
有 60 种 libcurl 绑定,让程序员可以使用任何语言轻松地传输数据;
与 curl 操作相关的 RFC 总计有 1327449 个单词;
一位创始人兼首席开发者一直留在这个项目中。

6、太过优秀,谷歌都想自己来再实现;25 周年记

原文链接

cURL版本更新录(202x)


项目主页:http://curl.haxx.se/

该文章最后由 阿炯 于 2024-11-08 09:47:44 更新,目前是第 3 版。