cURL-7.72.0(scheme)

2020-10-23 10:09:53 浏览数 (1)

温柔是一种力量,可能转化成爱,可能变成一个防护罩,也可能是支持两个人距离的一种松紧。如何看待温柔,温柔便转化成你心目中的那个模样 小马

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并不会注意到,也不关心这些,它只会继续执行自己的操作。

scheme

我们看看是什么意思呢

就是这个东西

URL以“scheme”作为开头,scheme是“http://”这部分内容的官方名称,用于告诉curl传入的URL使用了哪个协议。scheme必须受当前curl版本支持,否则curl将显示错误消息并退出。此外,scheme既不能以空格开头,也不能包含空格,你打个http都能打错。。。

scheme分隔符

“://”(一个冒号和两个斜杠)将scheme标识符与URL的其余部分分开。有些URL只包含一个斜杠,但curl不支持这种格式。关于斜杠的数量,需要注意的事项有两个。

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

代码语言:javascript复制
file://类型的URL写作file://<hostname>/<path>

但主机名部分只能是localhost、127.0.0.1或空白(什么都没有)。

代码语言:javascript复制
        file://localhost/path/to/file
        file://127.0.0.1/path/to/file
        file:///path/to/file

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

注意以上的第三个示例

代码语言:javascript复制
(file:///path/to/file)

,路径前面有三个斜杠。这也是一个常见错误,但浏览器允许用户使用这种错误语法,因此它被视为例外。Windows系统上的curl也允许这种不正确的格式。

代码语言:javascript复制
        file://X:/path/to/file

其中X是Windows的磁盘分区符。

不使用scheme

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

你可以通过--proto-default选项将默认协议修改为HTTP以外的其他协议。

用户名和密码

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

代码语言:javascript复制
       curl ftp://user:password@example.com/

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

主机名或地址

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

代码语言:javascript复制
curl http://127.0.0.1/

如果使用的是IPv6地址,则需要将其放在方括号中。

代码语言:javascript复制
   curl http://[::1]/

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

端口号

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

代码语言:javascript复制
 curl http://example.com:8080/

将主机名指定为IPv4地址:

代码语言:javascript复制
   curl http://127.0.0.1:8080/

将主机名指定为IPv6地址:

代码语言:javascript复制
        curl http://[fdea::1]:8080/

路径

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

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

代码语言:javascript复制
  curl ftp://ftp.example.com/README

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

代码语言:javascript复制
   curl ftp://ftp.example.com/tmp/

FTP类型

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

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

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

代码语言:javascript复制
       curl "ftp://example.com/foo; type=A"

curl默认为FTP使用二进制传输模式,但是你也可以在URL中通过type=I来指定二进制类型。

代码语言:javascript复制
        curl "ftp://example.com/foo; type=I"

如果你传给curl的类型是D,那么就是表明请求的资源是一个目录。

代码语言:javascript复制
 curl "ftp://example.com/foo; type=D"

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

片段

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

浏览器的“地址栏”

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

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

有时你在浏览器地址栏中看到的内容与传给curl的内容存在很大差别。

多个选项和多个URL

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

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

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

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

URL的单独选项

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

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

例如,我们向一个URL发起HTTP GET请求,再向另一个URL发起HTTP POST请求,然后向第三个URL发起HEAD请求。以下代码将这些写在一个命令行中。

代码语言:javascript复制

        curl --location http://example.com/1--next
          --data sendthis http://example.com/2--next
          --head http://example.com/3

去除--next选项会使得以上命令行变成非法的,因为curl会尝试将POST和HEAD结合在一起。

代码语言:javascript复制
        Warning: You can only select one HTTP request method! You asked for both POST
        Warning: (-d, --data) and HEAD (-I, --head).

连接重用

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

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

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

0 人点赞