cURL必知必会(txt+pdf+epub+mobi电子书下载)


发布时间:2021-02-25 04:23:54

点击下载

作者:(瑞典)丹尼尔·斯坦伯格(Daniel Stenberg)

出版社:人民邮电出版社有限公司

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

cURL必知必会

cURL必知必会试读:

前言

简介

本书是一本针对curl的指南,介绍了该项目、命令行工具和库,以及curl的起源和演变过程。

本书对于一般读者和经验丰富的开发人员来说都很有趣,而且很有用,它为你提供了一些可选择的内容。无须从前向后逐章阅读,你可以只阅读自己感兴趣的章节,并在认为合适的情况下进行跳跃式阅读。

我希望本书能够像我做过的其他项目一样:向大众公开,完全免费下载和阅读,任何人都可以发表评论、做贡献和提供帮助。

本书的撰写始于2015年9月底。英文版网址

https://bookcurl.haxx.se是英文版官方主页。它提供了易于访问的链接,你可以在线阅读,也可以下载副本离线阅读,支持的格式包括PDF、ePUB和MOBI。

https://ec.haxx.se是HTML版本的快捷链接。

https://github.com/bagder/everything-curl托管了书中的所有内容。电子书

扫描如下二维码,即可购买本书中文电子版。第 1 章 cURL项目

开源项目比较有趣的一点是,它们通常被称为“项目”,好像它们在某种程度上也会受到时间的限制或者永远无法完成一样。cURL“项目”团队实际上是由一些致力于软件开发的个人志愿者组成的,他们肩负着共同的使命:使用网络协议进行可靠的数据传输,并提供任何人都可以使用的免费代码。1.1 它是如何开始的

早在1996年,我就在业余时间开发了一个IRC机器人。它是一个自动化程序,为运行在Amiga计算机(IRC网络EFnet上的#amiga)上的聊天室用户提供服务。后来,我觉得让机器人为聊天室用户提供实时在线汇率服务会非常有趣,比如用户可以让机器人“将200美元换成瑞典克朗”。

为了让汇率尽可能准确,机器人每天从汇率网站下载汇率数据。要想完成这个任务,需要使用一个小工具通过HTTP下载数据。当时,我找到了一款名为HttpGet的小工具(由巴西人Rafael Sagula开发)。这个工具可以用于下载数据,只是需要做一些调整。我很快就接管了这个工具几百行代码的维护任务。

1997年4月8日,HttpGet 1.0发布,它提供了全新的HTTP代理支持。

很快,这个工具就支持了通过GOPHER获取汇率数据。添加FTP下载支持后,我们修改了项目名称,并于1997年8月发布了urlget 2.0。至此,只支持HTTP的日子一去不复返了。

这个项目逐渐发展壮大。添加上传功能后,由于名字容易引起误解,我们进行了第二次改名,并于1998年3月20日发布了curl 4(保留了之前的版本编号)。

我们认为1998年3月20日才是curl的生日。1.2 命名问题

命名是一件很困难的事。

这个工具用于上传和下载URL指定的数据。它会显示数据(默认情况下),用户可以看到(see)URL,并且see可以简写为单个字母c。此外,它是一个客户端程序,一个URL客户端,字母c也可以表示客户端(client),因此就有了cURL这个名字。

这些已经足够了,所以就选择了这个名字,并且再也没有改过。

后来,有人指出,curl实际上可以是一个聪明的“递归缩写”(缩写词中的第一个字母指向缩写词本身):“Curl URL Request Library”。

虽然这个想法很棒,但实际上与最初的想法不一样了。我们倒是希望自己有那么聪明……

其他项目也以各种方式在使用curl这个名字,但在命名curl时,我们并不知道这些。1.2.1 发音问题

大多数人用k作为curl的开头音,就像英语单词curl那样。它与girl和earl很押韵。1.2.2 混淆

创建curl不久后,另一个“curl”出现了,它是一门编程语言,现在仍然存在。

一些其他语言的libcurl绑定也使用术语curl或CURL来描述它们的绑定,因此,有时候你会发现当有人正在讨论curl时,可能指的并不是这个项目生成的命令行工具或库。1.2.3 作为动词

有时候,“curl一些东西”指的是使用非浏览器工具下载URL指定的文件或资源。1.3 curl可以做什么

cURL项目的主要目的和侧重点围绕着两个产品展开:● 命令行工具curl;● 提供C API的libcurl库。

这个工具和库都基于网络协议,为指定的URL资源执行网络传输。

curl关心所有与网络协议传输相关的东西,那些与此无关的就留给其他项目和产品去操心吧。

curl和libcurl试图避免直接处理被传输的数据。例如,它们对HTML或通过HTTP传输的内容一无所知,只知道如何通过HTTP传输这些数据。

这两个产品不仅用于驱动互联网世界的数百万个脚本和应用程序,而且广泛应用于服务器测试、协议探测和尝试新事物。

libcurl库可以用于各种需要网络传输的嵌入式设备:车载信息娱乐系统、电视机、蓝光播放器、机顶盒、打印机、路由器、游戏系统等。1.3.1 命令行工具curl

curl通过命令行运行。我只考虑使用可以将数据输出到stdout(终端)的工具。我一直信奉Unix哲学中的“一切皆管道”。像cat或其他Unix工具一样,curl将数据发送到stdout,以便与其他工具一起实现你想要的效果。所以,curl提供的那些支持从文件读取数据或将数据写入文件的选项,也支持将数据写到stdout或从stdin读取数据。

贯彻Unix命令行工具的一贯风格,curl也可支持多个URL。

curl可以被完美地应用在脚本或自动化程序中。它不提供GUI或UI,只支持输入文本和输出文本。1.3.2 libcurl库

2000年,curl的核心引擎被抽离成一个库,同年8月,libcurl 7.1发布,其中包含了所有沿用至今的概念。从那时起,curl就成了一个基于libcurl构建命令行工具的逻辑层。

想要在软件、平台、架构中添加客户端文件传输功能的人都可以使用libcurl,这也是libcurl的设计目标。libcurl的许可协议非常自由,避免给人们带来任何麻烦。

libcurl是用传统的C语言开发的,不过也有使用其他语言开发的版本,人们为其他语言创建了相应的libcurl绑定。1.4 开发团队

我是该项目的创始人和负责人。后来,陆陆续续有其他人加入到项目的贡献行列中,一些贡献者在开发了一段时间之后又离开了。大多数贡献者只是短暂停留,修复了一些错误或添加了一些新功能。算上所有已知姓名的贡献者,共有近2000人1为这个项目做出了贡献。

1这个数据统计截止到2019年7月29日。——编者注

在过去几年中,以下这些人经常出现在讨论和代码提交者名单中:● Daniel Stenberg● Steve Holme● Jay Satiro● Dan Fandrich● Marc Hörsken● Kamil Dudka● Alessandro Ghedini● Yang Tse● Günter Knauf● Tatsuhiro Tsujikawa● Patrick Monnerat● Nick Zitzmann● Marcel Raad● Michael Kaufmann1.5 curl的用户

我们曾经说过curl有十亿用户,但实际上这并不是一个确切的数字。我们只是基于一些观察和趋势进行了估算和猜测。当然,这还取决于你所认为的“用户”指的是什么。1.5.1 开源

这个项目是开源的,并且其发行许可非常自由,几乎任何人都可以重新发行curl的源代码或二进制文件。1.5.2 下载量

用户可以从curl网站下载适用于大多数操作系统的curl命令行工具和libcurl库,也可以通过第三方安装程序来安装,而且越来越多的操作系统默认安装了这些工具。因此,只通过curl网站计算下载量并不能准确地反映实际的数字。1.5.3 找出用户

因此,我们无法准确地计算下载量,因为任何人都可以进行重新发行,人们也没有义务告诉我们,他们是否使用了curl。那么如何才能算出这些数字?如何找出用户?答案是,我们根本无法获得准确的数字。

不过,我们可以依赖目击者报告、间接证据、互联网上的调查结果、偶尔发现的“关于”对话框、提及curl的许可协议,或者开发者在寻求帮助时会告诉我们他们正在使用curl。

curl的许可协议要求用户在使用时写明他们正在使用curl(比如在文档中),但在很多情况下,我们不知道用户是否照做了,如果他们不遵守这个小小的许可要求,我们也没有办法。1.5.4 命令行工具用户

世界各地的程序员在shell和批处理脚本中使用curl,用来调试服务器或执行测试。毫无疑问,每天都有数百万人使用它。1.5.5 嵌入式库

因为有了libcurl,我们的项目才会被大量用户采用。很多用户希望能够快速又轻松地将客户端文件传输功能添加到应用程序中,而libcurl的可移植性帮了大忙:你可以在各种平台上开发大致相同的应用程序,并保持使用libcurl进行数据传输。

libcurl是用C语言开发的,几乎没有或只有少量依赖项,因此很容易被用在嵌入式系统中。

libcurl被广泛地应用在智能手机操作系统、车载信息娱乐系统、电视机、机顶盒、蓝光播放器和高端接收器等音频和视频设备中,也常用于家用路由器和打印机。

Windows和游戏主机上也有大量畅销游戏在使用libcurl。1.5.6 网站后端

用于PHP的libcurl绑定是libcurl的第一批真正得到了广泛应用的绑定之一。它很快就成了PHP用户传输数据的默认方式,由于这样的状态保持了十多年,PHP已经被证明是互联网领域相当流行的技术(最近的数据显示,大概四分之一的网站都在使用PHP)。

一些流量很大的站点也在使用PHP,并在后端使用了libcurl,比如Facebook和雅虎。1.5.7 著名的用户

用户没有义务告诉我们他们是否在服务或产品中使用了curl或libcurl。我们通常只能通过对话、文档和许可协议偶然发现他们正在使用curl或libcurl。当然,也有一些公司会直接告诉我们。

我们在网站上收集了在“商业环境”中使用这些工具的公司和产品名称。这样做主要是为了告诉其他大品牌:如果这些公司可以基于这些工具构建产品,你们也可以。

名单中有200多家公司,以下列出的是比较大或比较著名的品牌。当然,它们只是其中的一小部分:

Adobe、Altera、AOL、苹果、AT&T、BBC、Blackberry、宝马、博世、Broadcom、雪佛兰、思科、康卡斯特、Facebook、谷歌、日立、霍尼韦尔、惠普、华为、HTC、IBM、英特尔、LG、马自达、梅赛德斯奔驰、摩托罗拉、Netflix、任天堂、甲骨文、松下、飞利浦、先锋、RBS、三星、SanDisk、SAP、SAS研究所、SEB、夏普、西门子、索尼、Spotify、Sun、Swisscom、Tomtom、东芝、VMware、Xilinx、雅虎、雅马哈。第 2 章 命令行基础

curl是一个命令行工具,多年来,用户一直在shell和脚本中使用它。curl已经成为一个可以帮助你完成工作的可靠工具。二进制文件和不同平台

curl是一个可执行的二进制文件,但cURL项目本身不提供二进制文件。curl的二进制文件需要根据不同的操作系统进行构建,而且通常受不同版本系统的约束。

你需要从某个地方获取与你的平台和操作系统相匹配的可执行文件。很多人基于cURL项目提供的源代码构建属于自己的可执行文件,也有很多人通过操作系统的包管理器来安装curl,还有一部分人从他们信任的来源下载二进制安装包。

不管选择哪种方式,请确保你获取的版本来自受信任的来源,并验证过它们的数字签名或包的真实性。

另外,curl通常需要使用第三方库,因此必须先安装这些库,具体需要哪些库取决于你获取的curl版本。命令行、引号和别名

curl可以用于不同的命令行、shell和命令提示符。它们具有各自的限制、规则和需要遵循的指南。curl的目标是能够顺畅地在这些环境中运行,但有时你的命令行系统会与其他人使用的或文档中记录的不同。

例如,不同的命令行系统中引号的用法可能存在差异。使用引号将命令行参数括起来,就可以在参数中嵌入空格和特殊符号。在大多数Unix风格的shell中,你可以使用双引号(")和单引号('),具体取决于你是否允许在字符串中使用变量扩展,但Windows不支持单引号。

在Windows的PowerShell这样的环境中,当用户输入curl时,命令行系统可能会优先使用其他工具代替curl。要想在PowerShell中正确使用curl,需要输入它的全名,包括扩展名:“curl.exe”。

不同的命令行系统允许的最大命令行长度也不相同,并强制用户限制单个命令行的数据量。curl提供了-K选项,以通过文件或标准输入(stdin)来提供命令行选项。种瓜得瓜,种豆得豆

curl很少会自己决定做什么,它试图在最大程度上让你做自己想做的。你给它什么,它就会处理什么。如果你提供一个拼写错误的选项,那么它可能会做出预想不到的事情。如果你给它一个不合法的URL,那么它仍然会继续处理它。这意味着,你可以通过选项传给它一些疯狂的数据,它会在传输操作中传递这些数据。

这是一种设计选择,它允许你调整curl如何进行协议通信,让你能够以最具创造性的方式与服务器交互。2.1 命令行选项

在使用curl时,你可以使用零到多个命令行选项以及你想要访问的URL或URL集合来调用它。curl支持200多个不同的选项。2.1.1 短选项

命令行选项可以将你想要用curl执行的任务的信息传给curl。例如,你可以通过-v选项让curl切换到详细(verbose)模式。curl -v http://example.com

-v是一种“短选项”,即一个减号后面跟一个字母。很多选项属于切换开关,用于启用某些功能或切换两个已知状态。指定对应的选项名称即可使用这些选项。你也可以在减号后面组合使用多个单字母选项。例如,让curl打开详细模式并进行HTTP重定向:curl -vL http://example.com

curl的命令行解析器会解析整行命令,你可以将选项放在任意位置,它们甚至可以出现在URL之后。curl http://example.com -Lv

当然,你也可以单独指定短选项,如下所示。curl -v -L http://example.com2.1.2 长选项

短选项使用起来非常方便,因为它们的名字很简短。但因为字母的数量有限,需要用到的选项又比较多,所以并非所有选项都可以使用单个字母来表示,于是就有了长选项。另外,为了方便,也为了让脚本更易于阅读,大多数短选项都有对应的长选项别名。

长选项使用两个减号(或者称为破折号),后面跟上选项名,而且每两个减号后面只能跟一个选项名。使用长选项打开详细模式如下所示。curl --verbose http://example.com

使用长选项进行HTTP重定向如下所示。curl --verbose --location http://example.com2.1.3 选项的参数

并非所有选项都只用于启用或禁用某项功能。对于一些选项,你需要向它们传递一些数据,如用户名或文件路径。你需要先指定选项,然后给出参数,中间用空格分隔。例如,可以通过HTTP POST将一个字符串发送给服务器。curl -d arbitrary http://example.com

你也可以使用长选项。curl --data arbitrary http://example.com

实际上,如果使用带参数的短选项,可以不使用空格进行分隔。curl -darbitrary http://example.com2.1.4 带空格的参数

有时你会想要向选项传递参数,而且参数中包含了一个或多个空格。例如,你可能想要将user-agent字段设置为I am your father,包括当中的三个空格。此时你需要给字符串加上引号。使用的引号因不同的shell或命令提示符而异,但大多数情况下可以使用双引号。curl -A "I am your father" http://example.com

如果没有使用引号,则如下所示。curl -A I am your father http://example.com

这样一来,curl只会将“I”作为user-agent字符串,剩下的字符串“am”“your”等将被视为单独的URL,因为它们不是以-开头,这表示它们不是选项,而curl只处理选项和URL。

如果字符串本身包含了双引号,比如想要向服务器发送JSON字符串(这种情况很常见),你可能需要使用单引号(但在Windows系统上使用单引号可能不行)。发送JSON字符串{ "name": "Darth" }就是一个很好的示例。curl -d '{ "name": "Darth" }' http://example.com

如果想要避免使用单引号,则可以通过文件将数据传给curl,这样就无须使用额外的引用。假设json文件包含了上述数据:curl -d @json http://example.com2.1.5 负选项

对于开关选项,既可以用它们打开某些功能,也可以通过它们关闭功能。你也可以使用长选项,在选项名前面加上“no-”前缀。例如,关闭详细模式。curl --no-verbose http://example.com2.2 不同版本的选项

curl最早于1998年出现在命令行中。它被用于访问指定的URL,有的没有使用选项,有的使用一个或多个选项。

从那时起,我们加入了更多选项。我们一直在添加选项,几乎每个新版本都会添加一个或几个新选项,以便用户可以更灵活地使用curl。

curl每八周就会发布一个新版本,因此不可避免的是,你并不总能使用到最新版的curl。有时你使用的可能是几年前的版本。

本书中所描述的命令行选项都是在某个时间点添加到curl中的,其中只有很小一部分是在1998年的首个版本中发布的。你可以检查一下自己的curl版本,并交叉检查curl手册页,看看相应的选项是在什么时候添加的。如果要将基于新curl版本编写的curl命令行用于带有旧版本curl的操作系统,那么这一点尤为重要。

curl的开发人员努力不去改变已有行为。1998年、2003年或2010年编写的命令行都可以不经修改直接使用现今的curl来运行。2.3 URL

之所以称为curl,是因为curl的名字中包含了URL(Uniform Resource Locator,统一资源定位符)。URL就是curl的操作对象。URL就是通常使用的网址字符串,如经常看到的以http://为前缀或以www开头的网址。

严格来说,URL是之前使用的名称,URI(Uniform Resource Identifier,统一资源标识符)才是更现代、更正确的叫法。RFC 3986给出了它们的语法定义。

curl接受“URL”作为输入,但实际上是“URI”。curl支持的大多数协议也有相应的URI语法文档,这些文档描述了这些URI格式的工作原理。

curl假定你会传给它一个有效的URL,它只对格式进行有限的检查,以提取执行操作所需要的信息。你可能会将包含非法字符的URL传给curl,但curl并不会注意到,也不关心这些,它只会继续执行自己的操作。2.3.1 scheme

URL以“scheme”作为开头,scheme是“http://”这部分内容的官方名称,用于告诉curl传入的URL使用了哪个协议。scheme必须受当前curl版本支持,否则curl将显示错误消息并退出。此外,scheme既不能以空格开头,也不能包含空格。2.3.2 scheme分隔符“://”(一个冒号和两个斜杠)将scheme标识符与URL的其余部分分开。有些URL只包含一个斜杠,但curl不支持这种格式。关于斜杠的数量,需要注意的事项有两个。

curl允许一些非法语法,并尝试在内部纠正它们,因此它也可以理解并接受一些带有一个或三个斜杠的URL,即使它们的格式不正确。curl这么做的原因是,浏览器已经开始支持这些URL,进而导致这种URL大量存在。

file://类型的URL写作file:///,但主机名部分只能是localhost、127.0.0.1或空白(什么都没有)。file://localhost/path/to/filefile://127.0.0.1/path/to/filefile:///path/to/file

如果在主机名部分使用其他主机名,curl将返回错误。

注意以上的第三个示例(file:///path/to/file),路径前面有三个斜杠。这也是一个常见错误,但浏览器允许用户使用这种错误语法,因此它被视为例外。Windows系统上的curl也允许这种不正确的格式。file://X:/path/to/file

其中X是Windows的磁盘分区符。2.3.3 不使用scheme

为方便起见,curl还允许用户省略URL的scheme部分。curl会根据主机名的第一部分猜测要使用哪种协议。这是一种非常基本的猜测,因为它只检查主机名的第一部分是否与一组协议中的某个协议匹配,并假定你打算使用的就是这个协议。这主要基于传统的服务器命名方式。可以通过这种方式检测的协议包括FTP、DICT、LDAP、IMAP、SMTP和POP3。没有提供scheme的其他URL将默认使用HTTP。

你可以通过--proto-default选项将默认协议修改为HTTP以外的其他协议。2.3.4 用户名和密码

scheme后面可以跟用户名和密码。现在通常不建议使用这种语法,因为这样很容易在脚本或其他地方泄露这些信息。例如,使用给定的用户名和密码列出FTP服务器目录中的内容:curl ftp://user:password@example.com/

在URL中显示用户名和密码只是可选项,curl还允许在URL之外,即通过正常的命令行选项来提供这些信息。2.3.5 主机名或地址

URL的主机名部分只是一个可以解析为数字IP地址的名字,或者是数字IP地址本身。在指定数字IP地址时,可以使用IPv4地址。curl http://127.0.0.1/

如果使用的是IPv6地址,则需要将其放在方括号中。curl http://[::1]/

如果使用的是主机名,系统解析器会将主机名转换为IP地址。这通常需要在/etc/hosts文件(或等效文件)中进行本地域名查找。2.3.6 端口号

每个协议都有一个“默认端口”,除非特别指定了端口号。在URL中指定端口号时,先在主机名后面添加一个冒号,然后是十进制的端口号。例如,我们可以请求端口8080上的HTTP文档。curl http://example.com:8080/

将主机名指定为IPv4地址:curl http://127.0.0.1:8080/

将主机名指定为IPv6地址:curl http://[fdea::1]:8080/2.3.7 路径

每个URL都包含一个路径。如果没有指定,则默认使用“/”。路径将被发送给指定的服务器,用于识别要请求的资源。

路径的用法取决于具体的协议。以下展示了如何使用匿名用户从FTP服务器获取README文件。curl ftp://ftp.example.com/README

对于具有目录概念的协议,可以在URL尾部以一个斜杠表示它是目录,而不是文件。因此,请求FTP服务器的目录列表时需要使用斜杠。curl ftp://ftp.example.com/tmp/2.3.8 FTP类型

这是一个没有被广泛使用的特性。

用于标识FTP服务器文件的URL提供了一个特性来告诉客户端(这里是curl)资源的文件类型。这是因为FTP可以改变传输模式,在不同的模式下使用不同的处理方式。

通过在URL中附加“;type=A”,你可以告诉curl当前的FTP资源是ASCII类型。你可以从example.com根目录获取ASCII类型的foo文件,如下所示。curl "ftp://example.com/foo;type=A"

curl默认为FTP使用二进制传输模式,但是你也可以在URL中通过type=I来指定二进制类型。curl "ftp://example.com/foo;type=I"

如果你传给curl的类型是D,那么就是表明请求的资源是一个目录。curl "ftp://example.com/foo;type=D"

这可以作为目录的替代格式,不需要像之前那样在路径尾部添加斜杠。2.3.9 片段

URL中还可以包含“片段”,这通常由井号(#)和网页中的特定名字组成。curl可以支持带有片段的URL,但实际上片段并不会被发送出去,因此,无论是否存在,它对curl的操作并没有任何影响。2.3.10 浏览器的“地址栏”

现代Web浏览器的“地址栏”中一般使用的不是URL或URI。实际上,它们主要使用IRI,也就是URI的超集,以支持国际化(如支持非拉丁符号)。它们还会处理空格、编码地址等,但规范中并没有说明这些事情应该由客户端完成。

地址栏只是一个简单的界面,让人可以输入和看到URI风格的字符串。

有时你在浏览器地址栏中看到的内容与传给curl的内容存在很大差别。2.3.11 多个选项和多个URL

如上所述,curl支持数百个命令行选项和无限数量的URL。如果你的shell或命令行系统能够支持,那么传给curl的命令行长度实际上是没有限制的。

curl首先会解析整个命令行,应用给定的命令行选项,然后(按从左到右的顺序)遍历URL并执行相应操作。

对于某些选项(如告诉curl将输出内容保存在哪里的-o或-O),你可能希望为每个URL单独指定。

curl会在处理完最后一个URL后返回一个退出码。想让curl在第一次出现错误时就退出,则可以使用--fail-early选项。2.3.12 URL的单独选项

前面介绍了curl如何解析命令行的所有选项并将它们应用于所有的URL。

curl还提供了另一个选项(--next,短格式为-;),用于在一组选项和URL之间插入间隔。当命令行解析器遇到--next选项时,它会将后面的选项应用于下一组URL。因此,--next选项其实是一组选项和URL之间的分隔符。使用多少个--next选项取决于实际的需要。

例如,我们向一个URL发起HTTP GET请求,再向另一个URL发起HTTP POST请求,然后向第三个URL发起HEAD请求。以下代码将这些写在一个命令行中。curl --location http://example.com/1 --next --data sendthis http://example.com/2 --next --head http://example.com/3

去除--next选项会使得以上命令行变成非法的,因为curl会尝试将POST和HEAD结合在一起。Warning: You can only select one HTTP request method! You asked for both POSTWarning: (-d, --data) and HEAD (-I, --head).2.3.13 连接重用

即使是在高带宽的网络中,建立TCP连接(尤其是TLS连接)也是一个缓慢的过程。

curl在内部维护着一个连接池,这可以让之前使用过的连接继续存活一段时间,因此后续发给相同主机的请求可以重用这些已经建立的连接。

连接池中的连接可以在curl运行期间保持活跃状态,但最好还是在同一个命令行中完成多次传输,而不是单独运行多个curl命令行。2.4 URL通配

有时你会有一组大致相同的URL,它们只有一小部分不同。不同的部分可能是一组数字或一组名字。curl提供了“通配”(globbing)的方式来指定这类URL。

curl使用保留符号[]和{}进行通配,它们一般不是合法URL的组成部分(IPv6地址除外,但curl可以很好地处理它们)。如果通配影响到了你,可以使用-g或--globoff禁用它。

虽然curl中与传输相关的大多数功能是由libcurl库提供的,但URL通配功能并不是!2.4.1 数值范围

你可以使用[N-M]语法来指定一个数值范围,其中N是起始索引,M是结束索引(包括M在内)。例如,你可以请求100个以数字命名的图像。curl -O http://example.com/[1-100].png

它甚至可以使用零作为前缀,如三位数的数字。curl -O http://example.com/[001-100].png

如果只想请求数字为偶数的图像,那么可以指定步进(step counter)。以下示例的范围为0~100,步进为2。curl -O http://example.com/[0-100:2].png2.4.2 字母范围

curl也可以处理字母范围,例如,有些网页会包含a~z的部分。curl -O http://example.com/section[a-z].html2.4.3 列表

有时URL的不同部分不会遵循这些简单的模式,那么你可以指定完整的列表,但要放在花括号,而不是中括号中。curl -O http://example.com/{one,two,three,alpha,beta}.html2.4.4 组合

你可以在同一个URL中使用多个通配。例如,如果要下载Ben、Alice和Frank的图像,并且需要100×100和1000×1000的分辨率,那么可以使用以下方式。curl -O http://example.com/{Ben,Alice,Frank}-{100x100,1000x1000}.jpg

如果要下载棋盘的所有图像,则需要两个0~7的索引。curl -O http://example.com/chess-[0-7]x[0-7].jpg

当然,你也可以将范围混在一起。例如,获取Web服务器和邮件服务器一周内的日志。curl -O http://example.com/{web,mail}-log[0-6].txt2.4.5 输出变量

在前面的所有通配示例中,我们使用了-O或--remote-name选项,因此curl将使用URL中的文件名来保存目标文件。

但有时这样还不够。假设你正在下载多个文件,并希望将它们保存到不同的子目录中,或者以不同的名称保存文件。curl为这些情况提供了解决方案:输出文件名变量。

URL中的每个通配都对应一个单独的变量,可以通过 '#[num]' 来引用,即在 '#' 后面跟上与通配对应的数字,从1(对应第一个通配)开始,以最后一个通配结束。

保存两个不同网站的主页:curl http://{one,two}.example.com -o "file_#1.txt"

将输出内容保存到子目录中:curl http://{site,host}.host[1-5].example.com -o "subdir/#1_#2"2.5 列出所有的命令行选项

curl有200多个命令行选项,而且更多选项正在不断被添加进来。选项的数量可能在未来几年内达到250个。

为了找出特定操作需要用到的选项,你可以先列出所有可用选项,浏览选项列表,从中选择自己需要的选项。curl --help或curl -h将列出所有选项,并提供简要的说明。不过,如果不知道自己需要什么样的选项,这个列表对你来说可能还不够。

你可以使用curl --manual输出curl的整个手册页以及常见的用例教程。这是一份非常全面且详尽的文档,说明了每个选项的用法,总量达数千行。但浏览整个手册也是件烦琐的事,因此我们建议使用搜索功能。一些人更喜欢手册页的Web版本(https://curl.haxx.se/docs/manpage.html)。2.6 配置文件

curl命令行选项的数量很容易膨胀,变得难以维护。有时你的命令行长度甚至会达到命令行系统允许的最大长度。Windows命令提示符允许的命令行最大长度其实是很短的。

为了解决这个问题,curl提供了“配置文件”功能。它允许你将命令行选项写在文本文件中,然后告诉curl,除了读取命令行外,还要从这个文件中读取命令行选项。

你可以使用-K或--config选项告诉curl从特定文件中读取更多的命令行选项,如下所示:curl -K cmdline.txt http://example.com

cmdline.txt文件(当然,你可以使用任意文件名)中包含了你输入的每行命令:# 这是注释,我们要求跟踪重定向--location# 要求发送HEAD请求--head

配置文件可以接受短选项和长选项,就像你在命令行上写的那样。为了便于阅读,它还允许你使用不带破折号的长选项。如果使用了这种样式,以上的配置文件可以写成:# 这是注释,我们要求跟踪重定向location# 要求发送HEAD请求head

命令行选项的参数必须与该选项处于同一行。例如,可以使用以下代码修改user-agent头部:user-agent "Everything-is-an-agent"

为了让配置文件看起来更像真正的配置文件,它还允许你在选项及其参数之间使用'='或':'。虽然这样做不是必须的,但还是有人喜欢分隔符号所带来的这种清晰度。使用这种方式设置user-agent选项:user-agent = "Everything-is-an-agent"

选项的参数也可以不使用引号,curl将下一个空格或换行视为当前参数的结尾。不过,如果参数中带有空格,则必须使用双引号。

以上的user-agent字符串中没有空格,因此可以不使用引号:user-agent = Everything-is-an-agent

如果想在配置文件中指定URL,则必须使用--url或url,而且不会像在命令行中那样不是选项的所有东西都被视为URL。因此,你可以按照以下方式指定URL:url = "http://example.com"默认配置文件

当被调用时,curl会检查是否存在默认配置文件(除非使用了-q),如果存在,则使用这个配置文件。在类Unix系统上,它会查找.curlrc文件,在Windows系统上则查找_curlrc文件。

curl将按以下顺序来查找默认配置文件。

(1) 尝试找到“主目录”:它先检查CURL_HOME,然后是HOME环境变量。如果没有找到,它会在类Unix系统上调用getpwuid()(这个函数将返回当前用户的主目录)。在Windows系统上,它会检查APPDATA变量,如果没找到就尝试“%USERPROFILE%\Application Data”。

(2) 在Windows系统上,如果主目录中没有_curlrc文件,那么它会查找curl可执行文件所在的目录。在类Unix系统上,它只会尝试从主目录中加载.curlrc。2.7 密码和窥探

密码是敏感信息,泄露密码可能会令其他人也能访问到受保护的资源和数据。

curl提供了几种方式来接收用户的密码。

最基本的curl身份验证选项是-u或--user。它接受一个参数,即使用冒号分隔的用户名和密码。例如,alice想要请求一个需要HTTP身份验证的页面,她的密码是“12345”:

$ curl -u alice:12345 http://example.com/2.7.1 命令行泄露

这里可能会发生一些不太好的事情。首先,我们在命令行输入了密码,而命令行可能对同一系统上的其他用户是可见的(假设你使用的是多用户系统)。curl会尝试从进程列表中清空密码来降低密码泄露的风险。

避免在命令行上指定用户名和密码的一种方法是使用.netrc文件或配置文件。你也可以使用-u选项,但不指定密码,curl会在运行时提示用户输入密码。2.7.2 网络泄露

其次,命令行会将用户凭证发送给HTTP服务器,HTTP是一种明文协议,中间人或其他窥探者可以窥探连接,并查看发送的内容。在这个示例中,curl使用了基本的HTTP身份验证,这绝对是不安全的。

可以使用几种方法来避免这种情况,当然,最关键的是,避免使用通过网络发送明文凭证的协议或身份验证方案。最简单的方法可能是使用加密协议,比如使用HTTPS而不是HTTP,使用FTPS而不是FTP,等等。

如果一定要使用普通文本和不安全的协议,那么你可以看看能否使用不以明文形式发送凭证的身份验证方法。如果使用的是HTTP,那么可以尝试Digest(--digest)、Negotiate(--negotiate)和NTLM(--ntlm)。2.8 进度指示器

curl有一个内置的进度指示器。当调用curl来传输数据(上传或下载)时,它可以在终端上显示传输的进度,比如当前的传输速率、已经用掉的时间以及还需要多长时间才能完成传输。

如果curl需要在终端上输出内容,那么进度指示器就会被禁用,否则进度指示器会干扰输出内容,把要显示的内容弄得一团糟。用户还可以通过-s或--silent选项强制关闭进度指示器。

如果调用curl时没有看到进度指示器,则需要确保输出已经被重定向到终端以外的位置。

curl还提供了一个更简单的进度指示器,可以通过-#或--progress-bar来启用。正如其名字所暗示的那样,它使用进度条的方式来显示传输进度。

有时候,在使用curl传输数据时,它无法确定请求对象的大小,因此进度指示器只包含很少量的细节,并且无法预测传输时间等其他信息。2.8.1 单位

进度指示器显示的是字节数和每秒字节数。

对于很大的数据,它还会使用单位后缀,以1024为基础,因此1024是千字节(1 K),2048是2 K,并以此类推。curl支持以下这些单位后缀。后缀数量名称K2^10千字节M2^20兆字节G2^30千兆字节T2^40太字节P2^50拍字节

显示时间使用的是H:MM:SS格式,分别对应小时、分钟和秒。2.8.2 进度指示器图例

进度指示器是为了向用户展示传输的进展。% Total % Received % Xferd Average Speed Time Curr. Dload Upload Total Current Left Speed0 151M 0 38608 0 0 9406 0 4:41:43 0:00:04 4:41:39 9287

指示器中各个字段的含义如下所示(从左到右)。字段含义%整个传输完成的百分比Total整个传输的总大小(如果知道的话)%已完成的下载百分比Received已下载的字节数%已完成的上传百分比Xferd已上传的字节数Average Speed 目前整个下载的平均传输速率,以字节/秒为单位DloadAverage Speed 目前整个上传的平均传输速率,以字节/秒为单位Upload预期完成操作的时间,格式为H:MM:SS,分别对Time Total应小时、分钟和秒Time 从传输开始到现在的时间,格式为H:MM:SS,分Current别对应小时、分钟和秒预期完成操作所需要的剩余时间,格式为Time LeftH:MM:SS,分别对应小时、分钟和秒Curr.Speed过去5秒的平均传输速率,以字节/秒为单位第 3 章 使用curl

上一章介绍了curl和命令行的一些基本细节。

本章将深入介绍curl可以做什么,以及如何使用curl的这些功能。你应该将curl的这些功能视为不同的工具,以帮你尽可能方便地执行文件传输任务。支持的协议

curl支持或可以支持(需要进行构建)以下这些协议。

DICT、FILE、FTP、FTPS、GOPHER、HTTP、HTTPS、IMAP、IMAPS、LDAP、LDAPS、POP3、POP3S、RTMP、RTSP、SCP、SFTP、SMB、SMTP、SMTPS、TELNET和TFTP。3.1 详细模式

如果curl命令没有执行或返回所期望的东西,你的第一直觉反应应该是使用-v或--verbose选项来运行命令,以便获取更多详细信息。

如果启用了详细(verbose)模式,curl会显示更多信息,告诉你它正在做什么。它会用前缀'*'来打印信息。我们来看看curl在执行一个简单的HTTP请求时会打印些什么(将下载的数据保存在名为saved的文件中):$ curl -v http://example.com -o saved* Rebuilt URL to: http://example.com/

我们使用了一个curl认为不完整的URL,于是它帮我们添加了一个尾部斜杠。* Trying 93.184.216.34...

这行信息告诉我们,curl正在尝试连接到这个IP地址。域名“example.com”已被解析为一个或多个IP地址,这里显示的是第一个(也可能是唯一的一个)curl尝试连接的地址。* Connected to example.com (93.184.216.34) port 80 (#0)

curl连接到了目标网站,还说明了域名是如何映射到IP地址的,以及它连接到了哪个端口上。'(#0)'是curl为这个连接分配的内部数字。如果在同一命令行中指定多个URL,那么你就会看到它将使用多个连接或重用已有的连接,因此连接的计数器可能会增加,也可能不会增加,具体取决于curl需要执行的操作。

如果我们使用的是HTTPS URL而不是HTTP URL,那么还会有一大堆信息来解释curl如何验证服务器证书,以及显示服务器证书的一些细节,比如使用了哪些加密方式以及其他TLS细节。

除了curl内部提供的信息外,详细模式还会显示curl发送和接收的所有标头信息。对于没有标头信息的协议(如FTP、SMTP、POP3等),可以将命令和响应视为标头信息,这样它们也可以通过-v显示出来。

如果继续往下看上述命令的输出内容(忽略实际的HTML响应内容),那么curl将显示:> GET / HTTP/1.1> Host: example.com> User-Agent: curl/7.45.0> Accept: */*>

这是对网站的一个完整HTTP请求。这个请求是用7.45.0版本的curl发起的,不同版本之间可能略有不同,特别是添加了其他命令行选项时。

HTTP请求标头的最后一行是空的,这表示标头和正文之间的分隔,而且这个请求是没有“正文”的。

继续往下看,并假设一切正常,发送出去的请求将从服务器获得相应的响应,并且响应消息以标头作为开始:< HTTP/1.1 200 OK< Accept-Ranges: bytes< Cache-Control: max-age=604800< Content-Type: text/html< Date: Sat, 19 Dec 2015 22:01:03 GMT< Etag: "359670651"< Expires: Sat, 26 Dec 2015 22:01:03 GMT< Last-Modified: Fri, 09 Aug 2013 23:54:35 GMT< Server: ECS (ewr/15BD)< Vary: Accept-Encoding< X-Cache: HIT< x-ec-custom-error: 1< Content-Length: 1270<

这些在你看起来可能有点像天书,其实它们是HTTP响应消息的标头,也就是元数据。第一行的“200”是最重要的信息,表示“一切都很好”。

标头的最后一行是空的,HTTP用它来表示标头的结束。

标头后面是实际的响应正文,也就是数据载荷。常规的-v详细模式不显示这些数据,而是显示为:{ [1270 bytes data]

这里的1270个字节数据被保存在saved文件中。你还可以看到名为Content-Length:的标头,它表示正文包含的文件大小(这个标头不一定会出现在响应消息中)。3.1.1 --trace和--trace-ascii

有时只使用-v是不够的,特别是当你想要保存包括实际传输数据在内的完整消息时。

当curl使用HTTPS、FTPS或SFTP协议进行加密文件传输时,其他网络监视工具(如Wireshark或tcpdump)将无法帮你保存完整的消息。

为此,curl在-v之外又提供了两个选项。

--trace [filename]选项可以将完整的跟踪信息保存在指定的文件中,也可以使用'-'(单个减号)代替文件名,将内容打印到stdout。你可以按照以下方式使用:$ curl --trace dump http://example.com

命令执行完后,会生成一个叫作dump的文件,文件的前15行看起来如下所示:== Info: Rebuilt URL to: http://example.com/== Info: Trying 93.184.216.34...== Info: Connected to example.com (93.184.216.34) port 80 (#0)=> Send header, 75 bytes (0x4b)0000: 47 45 54 20 2f 20 48 54 54 50 2f 31 2e 31 0d 0a GET / HTTP/1.1..0010: 48 6f 73 74 3a 20 65 78 61 6d 70 6c 65 2e 63 6f Host: example.co0020: 6d 0d 0a 55 73 65 72 2d 41 67 65 6e 74 3a 20 63 m..User-Agent: c0030: 75 72 6c 2f 37 2e 34 35 2e 30 0d 0a 41 63 63 65 url/7.45.0..Acce0040: 70 74 3a 20 2a 2f 2a 0d 0a 0d 0a pt: */*....<= Recv header, 17 bytes (0x11)0000: 48 54 54 50 2f 31 2e 31 20 32 30 30 20 4f 4b 0d HTTP/1.1 200 OK.0010: 0a .<= Recv header, 22 bytes (0x16)0000: 41 63 63 65 70 74 2d 52 61 6e 67 65 73 3a 20 62 Accept-Ranges: b0010: 79 74 65 73 0d 0a ytes..

发送和接收的每个字节都以十六进制的数字显示出来。

如果觉得十六进制的数字没有什么帮助,那么你可以尝试使用--trace-ascii [filename](也可以使用'-'将内容打印到stdout),此时前15行的内容看起来如下所示:== Info: Rebuilt URL to: http://example.com/== Info: Trying 93.184.216.34...== Info: Connected to example.com (93.184.216.34) port 80 (#0)=> Send header, 75 bytes (0x4b)0000: GET / HTTP/1.10010: Host: example.com0023: User-Agent: curl/7.45.0003c: Accept: */*0049:<= Recv header, 17 bytes (0x11)0000: HTTP/1.1 200 OK<= Recv header, 22 bytes (0x16)0000: Accept-Ranges: bytes<= Recv header, 31 bytes (0x1f)0000: Cache-Control: max-age=6048003.1.2 --trace-time

如果使用了这个选项,则所有的输出信息前面都会被加上高精度的时间戳。它可以与常规的-v和--verbose选项以及--trace和--trace-ascii选项一起使用,如下所示:$ curl -v --trace-time http://example.com23:38:56.837164 * Rebuilt URL to: http://example.com/23:38:56.841456 * Trying 93.184.216.34...23:38:56.935155 * Connected to example.com (93.184.216.34) port 80 (#0)23:38:56.935296 > GET / HTTP/1.123:38:56.935296 > Host: example.com23:38:56.935296 > User-Agent: curl/7.45.0

试读结束[说明:试读内容隐藏了图片]

下载完整电子书


相关推荐

最新文章


© 2020 txtepub下载