前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Learn Http with Curl

Learn Http with Curl

原创
作者头像
王磊-字节跳动
修改2022-04-22 18:17:03
1.4K0
修改2022-04-22 18:17:03
举报
文章被收录于专栏:01ZOO01ZOO

Curl 是一个常见的命令行工具,能力非常强大,在大家的工作中很常用,但是完整读过 curl 的 manual 的应该不多。其实 curl manual 是一个学习 http 协议的很好的材料,这篇文章总结从 curl manual 可以学习到的一些有趣知识点。

  1. --alt-svc: 让 curl 支持解析 alt-svc, alt-svc 是什么呢,可以参考[这篇文章](HTTP Alternative Services 介绍 | JerryQu 的小站) ([(这篇文章有点老了,对于浏览器的支持那块不太对, 可以参考这里,实际大部分浏览器都已经支持了](Alt-Svc - HTTP | MDN)),简单来说 alt-svc 有点类似实现于浏览器层的针对 dns 的 302,比如访问 www.a.com, 服务器发现当前压力太大了,可以让浏览器把对 www.a.com 的所有请求都发送到 www.b.com, 这个信息就可以通过 alt-svc 来返回。这样做的好处是比 改 cdn 快,又不影响浏览器上层的行为。
  2. --aws-sigv4: aws 的 v4 鉴权。没想到吧,某一天云厂商的 api 会影响如此深远,甚至一些几十年历史的工具都会对他特殊支持。
  3. --digest: 支持 HTTP摘要认证 这种认证方式是对 basic 认证的一种增强。我们知道 http basic 认证是很不安全的,用户的账号密码会明文传输(会 base64,其实和明文没啥区别)摘要认证的作用对 basic 认证做了增强,其中关键的点在于:1. 传输的是一个和账号密码有关的 md5 值,而不是账号密码,这样不容易泄漏;2. 这个 md5 值是根据访问的访问、URI、时间 (nonce、cnonce) 是相关的,这样可以避免重放攻击
  4. --dns-interface --dns-ipv4-addr --dns-ipv6-addr: 让 curl 指定 source 端口、Ip 来发送 dns 请求,这样做的目的是什么呢。dns 支持根据不同的 source ip 返回不同的结果,一个简单的例子是:我有一个域名绑定了两个地址,一个国内地址,一个海外地址,我希望海外的 dns 请求返回海外地址,国内的 dns 请求返回国内地址。所以我们有时候在 curl 或者使用 dig 之类的工具发送 dns 请求的时候会希望设置 source ip 来影响 dns 服务器返回的结果。
  5. --doh-xxx: doh 即 DNS over HTTPS 的相关配置,这种 dns 方式会更安全,使用加密的HTTPS协议进行DNS解析请求,避免原始DNS协议中用户的DNS解析请求被窃听或者修改的问题(例如中间人攻击)来达到保护用户隐私的目的,现在已经有很多 dns 服务商支持了这种功能。
  6. --egd-file: 要了解 egd-file 是啥玩意需要先学习一下 linux 的 /dev/random\ /dev/urandom 设备的原理,可以参考 /dev/random 和 /dev/urandom 的原理,简单的说 /dev/random 的原理是收集 linux 中的一些随机事件(熵)作为随机源,而这些设备产生的随机数是 linux 系统中很多应用(在 curl 中主要是用来 seed SSL connection)的重要依赖。而 egd-file 则是 /dev/random 的一种替代,用于比如在一些没有 /dev/random 设备的场景。
  7. --etag-compare --etag-save: ETag - HTTP | MDNETaHTTP响应头是资源的特定版本的标识符, 这个标识符让缓存更高效。简单的说就是 某个 http 资源 etag 是 'a', 那么在下一次访问的时候可以设置 If-None-Match:"a" 头,那么如果 这个 http 资源没有变化,etag 还是 'a', 服务器会返回 304 未修改状态。对应到 curl 的这两个参数上面,--etag-save 会把 etag 保存到一个文件里面,而 --etag-compare 会从文件里面读取 etag 然后设置到 If-None-Match 头。
  8. --expect100-timeout: 这个参数和 header 100 Continue 有关,100 Continue header 的作用是允许 client 像 server 发送大的数据包的时候先和 server 做一个协商, 当 server 允许 client 发送的时候 client 再继续发送内容,这样可以避免 client 端浪费资源开销。
  9. -G, --get: --data 等参数表述的内容默认都是通过 POST 发送,设置这个参数则使用 GET 发送。和这个参数相关的是一个有趣的面试题:"GET 和 POST 有什么区别"?实际上 restful 协议只是一种非常弱的约定, 在实际的 HTTP 语义/规范上来讲,GET 和 POST 完全没有区别。
  10. --happy-eyeballs-timeout-ms: 你有没有想过,当一个域名有 ipv4 和 ipv6 双栈地址当时候,curl 或者浏览器是怎么访问的?happy-eyeballs 算法是一个解决这个问题的简单方法:即优先用 ipv6,等几百 ms 后发现不行,再试 ipv4 地址,这个参数就是用来控制等待时间的,具体可以参考这篇文章:IPV6 & Happy Eyeballs - 云+社区 - 腾讯云
  11. --haproxy-protocol: 让 curl 在 connect 的时候传递 HAProxy PROXY protocol v1 header, 这个协议的介绍可以参考这里:proxy protocol介绍及nginx配置 - 简书
  12. --hsts <file name>: hsts 的解释可以参考这里:HTTP严格传输安全 - 维基百科 这种协议的作用是强制客户端(如浏览器)使用HTTPS与服务器建立连接(即使输入的是 http 地址),不过这种协议需要依赖第一个请求的 hsts 返回,curl 的配置则是设置一个HSTS cache file
  13. -k, --insecure :这是一个比较常用的参数,用于让 curl 对 server 的 tls 证书不做校验
  14. -4, --ipv4; -6, --ipv6: 让 curl 使用 ipv4 或者 ipv6 地址访问,一个小例子: ➜ curl -v -4 www.qq.com Trying 221.198.70.47:80... ➜ curl -v -6 www.qq.com Trying 2402:4e00:1900:1400:0:9227:71e8:2ccc:80...
  15. --keepalive-time: 这是 curl 设置的是 tcp 的 keepalive 选项TCP_KEEPIDLE; 关于 tcp 的 keepalive 和 http 的 keepalive 区别也是一个常见的面试题,具体可以参考前面的链接,简单来说就是 tcp 的 keepalive 是内核实现用于 tcp 连接保活(没有主动关闭的前提下定期探测看是否存活),默认是小时级别(7200s),而 http1.0 的 keepalive 是 tcp 连接复用,降低创建销毁成本,是应用层实现,一般是秒级别 (比如 10s );另外一个相关的问题:为什么 curl 提供的选项只有 tcp keepalive 没有 http keepalive 选项呢?实际上 curl 默认就是会 reuse connection的,至于Keep-Alive - HTTP Header)只是 client 对于 server 的一个 hint,当然也可以设置,具体 server 是否要 keep alive 和 keep 多久取决于 server 端的处理。
  16. --libcurl <file>: 和一些高级的 http client 类似,curl 实际上也支持把一个 http 请求直接转化为代码,使用这个选项就会转化为 使用 libcurl 的 c 代码。
  17. -L, --location: 如果返回是 30x curl 会自动访问 redirect 的地址,另一个相关的参数是 --max-redirs 规定了最多能 redirect 的次数。关于 20x 和 30x 的区别有一个非常好的图(如下)
  18. --negotiate: 使用 Spnego 认证,一种由微软提出的使用GSS-API接口的认证模式
  19. --no-npn --no-alpn: 不使用 npn/alpn 即 Next Protocol Negotiation,npn 现在的版本叫 ALPN 是一种在 tls 握手时顺便进行协议协商的 tls 扩展,具体可以参考这篇文章: 谈谈 HTTP/2 的协议协商机制 | JerryQu 的小站
  20. --no-sessionid: sessionid 是一种 tls TLS/SSL 会话复用 机制,默认 curl 会使用这种机制,有助于复用 session 提高 https 传输(握手)性能;设置这个选项可以关闭默认的行为。
  21. --ntlm-wb --ntlm: ntlm 是 Microsoft 设计的一种鉴权协议。
  22. --preproxy -p, --proxytunnel:proxy 相关的选项很多,而且我也比较感兴趣,后面单开一篇重点分析。
  23. --tcp-fastopen: 我们知道 tcp 一个被诟病的问题是建立连接比较耗时,需要三次握手,我们已经做了很多方法来减少建立 tcp 连接的次数,比如 内核层 keepalive,http 的 keepalive;那么有没有办法直接让 tcp 建立连接本身变得更快呢,一个办法就是 TCP Fastopen, 他是怎么运作的可以参考 wiki 或者这两篇文章:TCP 的那些事 | TCP Fast Open_CoderAndClimber的博客-CSDN博客_fastopenLinux的TCP实现之:三次握手 | Zorro’s Linux Book; 这里我也简单概括一下,就是在客户端非第一次建立连接的时候可以带一个 cookieid 标识连接身份,这样服务端在握手完成之前就可以发送数据,这样能减少一次 RTT(根据测试数据,TFO可以减少15%的HTTP传输延迟,全页面的下载时间平均节省10%,最高可达40%)
  24. --tcp-nodelay: 操作 TCP_NODELAY 选项,这个选项默认就是打开的,理解这个选项先要了解一下 纳格Nagle算法 ,简单的说,这个算法早期是为了节约网络带宽,小包合并发送,和实际上在现代网络环境中,Nagel 算法一般是被关闭的,尤其是在 HTTP2 中,这也是为什么 curl 里 默认 --tcp-nodelay 也是 true
  25. -w, --write-out <format>: format 是一个可以使用 curl 生成的一些变量的模板,比如这个例子,我只想看 curl 命令返回的 http_code: ➜ curl -s -o /dev/null -w "%{http_code}" http://www.qq.com/ 302%`
  26. --version: 输出版本,这个选项的重点在于还输出了 curl 支持的 Features, 我们逐个来看一下 Feature解释alt-svc见上面的 alt-svc 参数AsynchDNS异步 dns 解析,为什么 dns 都能异步?实际上这还是一个常见需求,比如 curl 的域名比较多,或者一个爬虫场景,dns 解析可能是瓶颈,这时候异步 dns 的帮助是很大的brotli支持 Brotli压缩算法 类似的 feature 还有 libz/zstdgsasl使用 libgsasl 支持 sasl 加密算法GSS-API支持 GSS-APIHSTS参考上面的 --hsts 选项HTTP2/HTTP3支持 HTTP2/HTTP3HTTPS-proxy支持 HTTPS-proxyIDN支持 IDN, 什么是 IDN以及 IDN 带来的风险,可以参考这篇文章IPv6支持 IPv6Kerberos支持 Kerberos V5 鉴权,类似的 feature 还有 NTLM/SPNEGO/TLS-SRP/SSPIMultiSSLmultiple TLS backend,这里的 backend 指的是如: bearssl, gnutls, gskit, mbedtls, mesalink, nss, openssl, rustls, schannel,secure-transport, wolfssl 的具体实现PSL支持 Public Suffix List, 我们常见的 '.com', '.cn' 都是属于 psl,实际上 psl 的列表已经非常大,它的使用场景有例如 Firefox 用它在地址栏高亮 URL 的关键部分。PSL 更重要的用途是用在浏览器同源策略上:例如通过 document.cookie 设置 cookie,或者通过 document.domain 设置当前 domain,都不允许将 domain 设置为 PSL 中的记录,curl 的使用场景也是这个 cookie 相关的设置。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
命令行工具
腾讯云命令行工具 TCCLI 是管理腾讯云资源的统一工具。使用腾讯云命令行工具,您可以快速调用腾讯云 API 来管理您的腾讯云资源。此外,您还可以基于腾讯云的命令行工具来做自动化和脚本处理,以更多样的方式进行组合和重用。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档