curl 命令常用操作
查看网页源码
$ curl https://dbwu.tech/
# 可以使用参数将网页内容保存到指定文件中
$ curl -o /tmp/index.html https://dbwu.tech/
跟踪跳转
# 请求会自动跟踪
$ curl -L https://dbwu.tech/
显示响应头
$ curl -i https://dbwu.tech/
默认情况下,-i 选项会同时输出响应头部和内容,如果只希望输出响应头部,可以使用 -I 选项
$ curl -I https://dbwu.tech/
# 输出如下
HTTP/2 200
content-type: text/html; charset=utf-8
access-control-allow-origin: *
cache-control: public, max-age=0, must-revalidate
referrer-policy: strict-origin-when-cross-origin
x-content-type-options: nosniff
vary: Accept-Encoding
cf-cache-status: DYNAMIC
server: cloudflare
...
隐藏响应内容
如果只希望确认通信双方是否可以正常通信,可以利用重定向到 /dev/null
文件来隐藏响应内容。
$ curl -o /dev/null https://dbwu.tech/
# 输出如下
# 例如可以用来检测文件的下载速度
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 19595 0 19595 0 0 14328 0 --:--:-- 0:00:01 --:--:-- 14334
或者使用 -D -
参数,将响应头写到标准输出,同时配合 -o /dev/null
只输出响应头。
$ curl -D - -o /dev/null https://dbwu.tech
显示通信过程
$ curl -v https://dbwu.tech/
# 如果只希望输出响应头部,配合 -I 参数即可
$ curl -v -I https://dbwu.tech
# 输出如下
* Trying [2606:4700:3036::ac43:936e]:443...
* Trying 172.67.147.110:443...
* Connected to dbwu.tech (172.67.147.110) port 443
* ALPN: curl offers h2,http/1.1
* (304) (OUT), TLS handshake, Client hello (1):
* CAfile: /etc/ssl/cert.pem
* CApath: none
* (304) (IN), TLS handshake, Server hello (2):
* (304) (IN), TLS handshake, Unknown (8):
* (304) (IN), TLS handshake, Certificate (11):
* (304) (IN), TLS handshake, CERT verify (15):
* (304) (IN), TLS handshake, Finished (20):
* (304) (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / AEAD-CHACHA20-POLY1305-SHA256
...
* using HTTP/2
* [HTTP/2] [1] OPENED stream for https://dbwu.tech/
* [HTTP/2] [1] [:method: HEAD]
* [HTTP/2] [1] [:scheme: https]
* [HTTP/2] [1] [:authority: dbwu.tech]
* [HTTP/2] [1] [:path: /]
* [HTTP/2] [1] [user-agent: curl/8.4.0]
* [HTTP/2] [1] [accept: */*]
> HEAD / HTTP/2
> Host: dbwu.tech
> User-Agent: curl/8.4.0
> Accept: */*
>
< HTTP/2 200
HTTP/2 200
...
<
* Connection #0 to host dbwu.tech left intact
显示通信过程详情
# 将输出内容保存到指定的文件中
$ curl --trace /tmp/trace.txt https://dbwu.tech
# 查看输出内容
$ cat /tmp/trace.txt
# 内容和使用抓包工具时的输出结果查不多
== Info: Trying [2606:4700:3036::ac43:936e]:443...
== Info: Trying 104.21.71.166:443...
== Info: Connected to dbwu.tech (2606:4700:3036::ac43:936e) port 443
== Info: ALPN: curl offers h2,http/1.1
== Info: (304) (OUT), TLS handshake, Client hello (1):
=> Send SSL data, 314 bytes (0x13a)
0000: 01 00 01 36 03 03 bf a9 1d ca c9 c6 43 9c 14 86 ...6........C...
0010: 2c d6 73 46 1e cd 89 f6 05 8f 27 e3 38 13 50 e9 ,.sF......'.8.P.
0020: be 0f 87 15 5b d1 20 c0 7d 3f 4e 03 0f b6 d8 b9 ....[. .}?N.....
0030: 7d b1 ca 9f c1 1b 12 85 1f f6 6f bc b4 09 ab fc }.........o.....
...
...
0910: 72 69 70 74 3e 3c 21 2d 2d 20 43 6c 6f 75 64 66 ript><!-- Cloudf
0920: 6c 61 72 65 20 50 61 67 65 73 20 41 6e 61 6c 79 lare Pages Analy
0930: 74 69 63 73 20 2d 2d 3e 3c 2f 62 6f 64 79 3e 0a tics --></body>.
0940: 0a 3c 2f 68 74 6d 6c 3e 0a 0a .</html>..
== Info: Connection #0 to host dbwu.tech left intact
发送表单数据
GET 请求
直接在 URL 后面拼接参数即可。
$ curl https://dbwu.tech/?page=2&pageSize=20
POST 请求
使用 –data 参数指定表单数据。
$ curl -X POST --data "username=dbwu" https://dbwu.tech
# 使用 --data-urlencode 进行自动编码
$ curl -X POST --data "request body" https://dbwu.tech
其他请求
直接使用 -X
参数配合对应的 HTTP 方法即可。
# 发送 PUT 请求
$ curl -X PUT https://dbwu.tech
# 发送 DELETE 请求
$ curl -X DELETE https://dbwu.tech
文件上传
$ curl -X POST -F "[email protected]" https://dbwu.tech
指定 Referer
$ curl --referer https://google.com https://dbwu.tech
指定 User Agent
$ curl --user-agent "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" https://dbwu.tech
指定 Cookie
$ curl --cookie "name=xxx" https://dbwu.tech
# 保存响应中的 cookie 到指定文件
$ curl -c /tmp/cookie.txt https://dbwu.tech
# 查看 cookie 文件
$ cat /tmp/cookie.txt
# Netscape HTTP Cookie File
# https://curl.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.
# 使用指定文件作为 cookie 数据 (源) 文件
$ curl -b /tmp/cookie.txt https://dbwu.tech
设置请求头
$ curl --header "Content-Type:application/json" https://dbwu.tech
设置认证
$ curl --user username:password https://dbwu.tech
设置证书 (代理)
# 以特定证书访问某网站
$ curl -vvvv --cacert /path/to/root_ca.cer https://dbwu.tech
# 以特定代理访问某网站
$ curl -vvvv --proxy http://127.0.0.1:8080 https://dbwu.tech
访问 Socket
例如 Nginx 监听地址如下:
server {
listen unix:/tmp/nginx.sock;
...
}
# --unix-socket 指定 unix socket 文件路径
$ curl --unix-socket /tmp/nginx.sock http://localhost/path
分析 HTTP 请求链路各阶段耗时
一个 HTTP 请求,会涉及到网络各层的工作时间,-w
参数允许用户自定义输出格式,可以显示请求和响应的各种信息。
下面是常用的 curl -w
参数选项:
%{url_effective}
:请求 URL%{http_code}
:HTTP 响应状态码%{http_connect}
:从代理收到的 HTTP 响应代码%{time_total}
:完成请求的总时间,以秒为单位%{time_namelookup}
:DNS 解析花费时间,以秒为单位%{time_connect}
:TCP 连接建立所用时间,以秒为单位%{time_appconnect}
:SSL/SSH 握手所用时间,以秒为单位%{time_pretransfer}
:从客户端发起请求到准备传输数据所用时间,以秒为单位%{time_starttransfer}
:从客户端发起请求到开始接收响应的时间,以秒为单位%{size_request}
:请求的字节大小%{size_upload}
:上传的字节大小%{size_download}
:下载的字节大小%{speed_download}
:平均下载速度,以字节每秒为单位%{speed_upload}
:平均上传速度,以字节每秒为单位%{content_type}
:响应的 Content-Type
下面是一些使用 -w
参数的示例:
1. 显示 HTTP 状态码
$ curl -w "HTTP Status Code: %{http_code}\n" -o /dev/null -s https://www.dbwu.tech
# 输出如下
HTTP Status Code: 200
2. 显示请求总时间和 DNS 解析时间
$ curl -w "Total Time: %{time_total}\nDNS Lookup Time: %{time_namelookup}\n" -o /dev/null -s https://www.dbwu.tech
# 输出如下
Total Time: 0.382818
DNS Lookup Time: 0.006947
3. 显示多项信息
$ curl -w "HTTP Code: %{http_code}\nTotal Time: %{time_total}\nDownload Size: %{size_download}\n" -o /dev/null -s https://www.dbwu.tech
# 输出如下
HTTP Code: 200
Total Time: 0.478081
Download Size: 19493
4. 组合示例
下面是一个更复杂的示例,展示如何使用多个变量格式化输出:
$ curl -w "URL: %{url_effective}\nHTTP Code: %{http_code}\nTotal Time: %{time_total}\nDNS Lookup Time: %{time_namelookup}\nConnect Time: %{time_connect}\nPretransfer Time: %{time_pretransfer}\nStarttransfer Time: %{time_starttransfer}\nDownload Size: %{size_download}\nUpload Size: %{size_upload}\nDownload Speed: %{speed_download} bytes/sec\nUpload Speed: %{speed_upload} bytes/sec\nContent Type: %{content_type}\n" -o /dev/null -s https://www.dbwu.tech
# 输出如下
URL: https://www.dbwu.tech/
HTTP Code: 200
Total Time: 0.487167
DNS Lookup Time: 0.008145
Connect Time: 0.008359
Pretransfer Time: 0.333323
Starttransfer Time: 0.446315
Download Size: 19493
Upload Size: 0
Download Speed: 40012 bytes/sec
Upload Speed: 0 bytes/sec
Content Type: text/html; charset=utf-8
从输出结果中可以看到,请求中各个链路花费的时间:
- DNS 查询时间: 0.008145 秒,也就是 8.1 毫秒
- TCP 连接时间: 0.333323 - 0.008145 = 0.325178 秒,也就是 300 毫秒
- 服务器处理时间:0.446315 - 0.333323 = 0.112992 秒,也就是 112 毫秒
- 响应内容传输时间:0.487167 - 0.446315 = .040852 秒,也就是 40 毫秒
所以在整个请求中,占用时间最多的部分就是 TCP 三次握手建立连接的时间,占到了总时间的 60% 还多。
URL: %{url_effective}\n
HTTP Code: %{http_code}\n
Total Time: %{time_total}\n
DNS Lookup Time: %{time_namelookup}\n
Connect Time: %{time_connect}\n
Pretransfer Time: %{time_pretransfer}\n
Starttransfer Time: %{time_starttransfer}\n
Download Size: %{size_download}\n
Upload Size: %{size_upload}\n
Download Speed: %{speed_download} bytes/sec\n
Upload Speed: %{speed_upload} bytes/sec\n
Content Type: %{content_type}\n
5. 复用示例
如果希望复用 -w
的的输出格式,可以将格式写入文件中,然后 curl 访问时,通过 -w
参数来指定具体的文件名称即可。
例如将刚才的输出配置写入到 /tmp/curl-w.format 文件中。
$ cat /tmp/curl-w.format
# 输出如下
URL: %{url_effective}\n
HTTP Code: %{http_code}\n
Total Time: %{time_total}\n
DNS Lookup Time: %{time_namelookup}\n
Connect Time: %{time_connect}\n
Pretransfer Time: %{time_pretransfer}\n
Starttransfer Time: %{time_starttransfer}\n
Download Size: %{size_download}\n
Upload Size: %{size_upload}\n
Download Speed: %{speed_download} bytes/sec\n
Upload Speed: %{speed_upload} bytes/sec\n
Content Type: %{content_type}\n
使用 curl 访问时,通过将 -w
参数指定为具体的文件名称即可。
$ curl -w "@/tmp/curl-w.format" -o /dev/null -s https://www.dbwu.tech
# 输出如下
URL: https://www.dbwu.tech/
HTTP Code: 200
Total Time: 0.394064
DNS Lookup Time: 0.008351
Connect Time: 0.008593
Pretransfer Time: 0.267342
Starttransfer Time: 0.352437
Download Size: 19493
Upload Size: 0
Download Speed: 49466 bytes/sec
Upload Speed: 0 bytes/sec
Content Type: text/html; charset=utf-8
Python 小工具
Github 上有一个类似功能的开源程序,链接: https://github.com/reorx/httpstat。