β

命令行http调试利器 —— curl

昔我往矣 24 阅读

curl 是一个相当强大的命令行版的 http 客户端,本文由浅入深的讲解了部分 curl 常用的参数和用法。在没有桌面的环境下, curl 将是一把无比锋利的工具。

基本功能

简单用法

下面是一条最简单的 curl 用法:

$ curl https://github.com/

可以看到返回了一堆 html 数据,这些就是 github 网站首页的 html 代码。

传递数据

http协议 有各种请求的方法(method),如, GET POST HEAD PUT 等等。这些方法 curl 都支持。使用 -X 指定请求方法,没有指定的情况下,默认使用 GET 请求方法。 POST PUT 方法提交的数据用 -d 参数指定。

# GET 方法,GET参数通常放在url中
$ curl http://example.com/?page=2

# HEAD方法(不使用-X指定方法,使用-I),获取http响应的头部数据
$ curl -I http://example.com/

# POST 方法,通常用于向网站提交数据,比如提交用户名和密码用于登录认证
$ curl -X POST http://example.com/ -d "username=admin&password=123"

# PUT 方法,多用于http restful api 环境
curl -X PUT http:///example.com/user -d '{"name":"xnow"}'

头部数据

值得注意的是,在 向网站发起请求 分析网站返回的数据 时,除了 body 部分, head 也十分重要。比如,用于认证身份的 cookie 就放在 request head 中。

request head

我们可以使用 -H 参数修改请求 head

# 修改请求中的host头部,在http 1.1中,host头部用于区别拥有相同IP,不同域名的虚拟主机。
# 使用域名请求的时候默认就有携带该head。
curl -H "host: xnow.me" http://35.201.224.126 

# 修改请求的cookie。
# 在head中,新加的 logged_in 和 dotcom_user是`github`给浏览器种下的cookie中的两个。
$ curl -H "cookie: logged_in=yes;dotcom_user=someone" https://developer.github.com/v3/

响应头部(response head)

对于网站响应的 head ,我们只能查看:

$ curl -I https://github.com/
HTTP/1.1 200 OK
Server: GitHub.com
Date: Mon, 05 Mar 2018 11:24:28 GMT
Content-Type: text/html; charset=utf-8
X-Request-Id: abd62496d38c658b9c68d1c7d81ae143
Set-Cookie: logged_in=no; domain=.github.com; path=/; expires=Fri, 05 Mar 2038 11:24:28 -0000; secure; HttpOnly
...

github 响应的头部很大,这里只保留其中一部分,第一行 HTTP/1.1 200 OK ,表明网站使用 http/1.1 协议返回,请求被正常处理和返回。 Set-Cookie 头部向浏览器种 cookie 信息,浏览器下次请求网站的时候,就会携带这段 cookie ,用于验证。 X-Request-Id github 自定义的头部,非标准头部通常会以 X- 开头,比如 X-Forward-For 头部会告诉网站,客户端的真实IP地址。

总之,在 http 中,头部占着很重要的地位,值得好好研究。这里不详细展开。

查看响应头部(response haed)和响应数据(response body)

$ curl -i https://xnow.me

查看详细请求和响应过程

-v 可以看到 curl 发起请求的 head 和获取到的响应 head body

$ curl -v http://xnow.me # 尝试自己分辨一下吧

实操,我的网页呢?

如果你直接 curl http://github.com ,你会发现没有返回数据,说好的 body 呢?这时,你可以通过 curl 来分析了。

如果没有 body ,那我们首先使用 -I 看看 head 吧。

$ curl -I  http://github.com
HTTP/1.1 301 Moved Permanently
Content-length: 0
Location: https://github.com/

分析
第一行,显示使用了 HTTP/1.1 协议,返回码未 301 ,后面的 Moved Permanently 解释指页面被是 永久转移 了。
第二行,返回的 body 长度为0,没有返回 body ,符合事实。
第三行,Location指定了页面新的地址是 https://github.com/

这就说明,页面被重定向到 https://github.com/ 了,那我们再访问 https://github.com/ 就好咯。

遇到这种情况,有没有自动跳转的,而不是这么手动判断的?方法也是有的,curl的 -L 参数就可以做到。

$ curl -L http://github.com

哇塞, body 又回来了,因为 curl 帮我们自动完成跳转。

高级一点

查看请求或响应的具体某一指标

作为运维或者开发人员,我们需要考虑网站的性能和访问速度,用 curl 就可以看到。

$ curl -w %{http_code} http://github.com -o /dev/null  
   # 看到网站的返回码是301,表示网站换地址了。记得吗,前文的200标识请求成功完成

$ curl -s -w "%{time_total}\n%{size_download}\n" https://github.com/  -o /dev/null
.553  # 请求响应的总时长,还有更详细的参数
0  # 响应的内容大小

解释

  • -o /dev/null, 把 response body 部分写入文件 /dev/null (Linux黑洞设备)
  • -s 不要显示讨厌的进度条
  • -w 指定显示特定的指标,比如 DNS解析耗时 总耗时 文件大小 返回码 等,可以在 man curl 中了解,支持二十多种返回类型。

完成认证

作为研发或者运维,你肯定遇到过浏览器弹框验证用户名和密码,例如:

http-basic-auth

这是因为开启了 basic auth 验证。用 curl 处理起来也十分简单

curl --basic --user "admin:123" http://example.com/

当年房东的路由器就是这种验证方式,最后使用这条指令,暴力破解出来了。

带https的虚拟主机

这个需求应该很少有人遇到吧。起因是,我们的 nginx 上有不止一个 https 虚拟主机,当我迁移新的 https 域名到这个 nginx 上之前,想用IP做一次验证。这就涉及到 https sni 问题, sni 是另一个常见的问题,这里不展开讲, sni 就是为了 ssl 支持虚拟主机而添加的扩展。反正,如果直接 curl nginx 会用第一张证书验证,而不是匹配域名的证书。所以会握手出错。例如

$ curl -H "host: www.xnow.me" https://1.1.1.1/
\curl: (51) SSL: certificate subject name (*.xnow.me) does not match target host name 'www.xnow.com'

报错的意思是,我有一张 *.xnow.me 的证书,和你请求的 www.xnow.me 不匹配。

后来,在 curl 7.18.1 中,开始支持 sni 了,请求方法还是有点诡异的。

curl -Iv https://www.xnow.com/ --resolve "www.xnow.com:443:192.168.1.1"

总结

Linux下有很多实用好用的工具,值得深入发现和好好学习。

作者:昔我往矣
原文地址:命令行http调试利器 —— curl, 感谢原作者分享。

发表评论