对每个人而言,真正的职责只有一个:找到自我。然后在心中坚守其一生,全心全意,永不停息。所有其它的路都是不完整的,是人的逃避方式,是对大众理想的懦弱回归,是随波逐流,是对内心的恐惧 ——赫尔曼·黑塞《德米安》
写在前面
博文内容为 curl 不长用使用技巧简单整理
理解不足小伙伴帮忙指正
对每个人而言,真正的职责只有一个:找到自我。然后在心中坚守其一生,全心全意,永不停息。所有其它的路都是不完整的,是人的逃避方式,是对大众理想的懦弱回归,是随波逐流,是对内心的恐惧 ——赫尔曼·黑塞《德米安》
curl curl是用于从服务器传输数据或将数据传输到服务器的工具。它支持以下协议:DICT,FILE,FTP,FTPS,GOPHER,GOPHERS,HTTP,HTTPS,IMAP,IMAPS,LDAP,LDAPS,MQTT,POP3,POP3S,RTMP,RTMPS,RTSP,SCP,SFTP,SMB,SMBS,SMTP,SMTPS,TELNET,TFTP,WS和WSS
。它由 libcurl
提供支持,适用于所有与传输相关的功能
一、性能分析:深度指标监控 全链路耗时分析 -w
模板, 传输速度统计 :
1 2 3 4 5 6 ┌──[root@liruilongs.github.io]-[~] └─$curl -w "下载速度: %{speed_download} B/s\n上传速度: %{speed_upload} B/s\n" -o /dev/null -s https://example.com 下载速度: 1428 B/s 上传速度: 0 B/s ┌──[root@liruilongs.github.io]-[~] └─$
限速测试 用 --limit-rate
模拟弱网环境(限制 50KB/s):
1 2 3 4 5 ┌──[root@liruilongs.github.io]-[~] └─$curl --limit-rate 50K -O http://example.com/bigfile.iso % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 1256 100 1256 0 0 1604 0 --:--:-- --:--:-- --:--:-- 1604
访问指标获取 ,同样使用-w
模版
200 的情况
1 2 3 4 5 6 7 8 9 ┌──[liruilong@liruilongs.github.io]-[~] └─$curl -w "总时间: %{time_total}s\n名称解析时间: %{time_namelookup}s\n连接时间: %{time_connect}s\nTLS握手时间: %{time_appconnect}s\n等待时间: %{time_starttransfer}s\n数据传输时间: %{time_total}s\nHTTP状态码: %{http_code}\n" -o /dev/null -s baidu.com -k 总时间: 0.050962s 名称解析时间: 0.003813s 连接时间: 0.022080s TLS握手时间: 0.000000s 等待时间: 0.050661s 数据传输时间: 0.050962s HTTP状态码: 200
500 的情况
1 2 3 4 5 6 7 8 9 10 11 ┌──[liruilong@liruilongs.github.io]-[~] └─$curl -w "总时间: %{time_total}s\n名称解析时间: %{time_namelookup}s\n连接时间: %{time_connect}s\nTLS握手时间: %{time_appconnect}s\n等待时间: %{time_starttransfer}s\n数据传输时间: %{time_total}s\nHTTP状态码: %{http_code}\n" -o /dev/null -s https://liruilong.blog.csdn.net/ -k 总时间: 0.257467s 名称解析时间: 0.044719s 连接时间: 0.084697s TLS握手时间: 0.175856s 等待时间: 0.257414s 数据传输时间: 0.257467s HTTP状态码: 521 ┌──[liruilong@liruilongs.github.io]-[~] └─$
更多的参数获取
https://everything.curl.dev/usingcurl/verbose/writeout.html#available---write-out-variables
当然也支持文件的方式配置模版
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 curl --silent --output /dev/null --show-error -w @format.txt http://example.com/ Type: %{content_type}\nCode: %{response_code}\n\n From 8.1.0:\n\n Scheme: %{url.scheme}\n Host: %{url.host}\n Port: %{url.port}\n Read header content (v7.83.0):\n %header{date}
并行/并发测试 ,
通过路径参数化生成多个相同URL的变体,测试服务器对路径无关请求的并发处理能力,触发并发请求:
--parallel-immediate
强制立即启动所有并行请求,而非按队列逐个触发。
--parallel-max 3
限制同时活跃的最大连接数为 3
--parallel
启用并行请求模式,允许同时处理多个连接。
1 2 curl -I --parallel --parallel-immediate --parallel-max 3 "https://example.com/[1-3]" curl -I --parallel --parallel-immediate --parallel-max 3 stackoverflow.com google.com example.com
也可以通过 **–config 参数** 指定包含多个相同域名 URL 的配置文件(urls.conf):
1 2 3 4 5 6 7 url = "https://example.com" url = "https://example.com" url = "https://example.com" curl -I --parallel --parallel-immediate --parallel-max 3 --config urls.conf
二、协议魔改:突破常规请求方式 模拟浏览器访问 :通过 -H
自定义 User-Agent 伪装成 Chrome:
1 2 3 4 5 6 7 8 9 10 ┌──[root@liruilongs.github.io]-[~] └─$curl -H "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/91.0.4472.124" https://example.com <!doctype html> <html> <head> <title>Example Domain</title> 。。。。。。。。。。。。。。。。。。。。。 </html> ┌──[root@liruilongs.github.io]-[~] └─$
绕过 DNS 直接指定 IP :用 --resolve
强制解析域名到指定 IP(适用于测试 CDN 节点):
1 2 3 4 5 6 ┌──[root@liruilongs.github.io]-[~] └─$curl https://example.com --resolve example.com:443:23.215.0.136 <!doctype html> <html> <head> <title>Example Domain</title>
强制使用特定的本地网络接口 --interface
指定使用的网卡
1 curl --interface wlp5s0 https://example.com
强制使用特定的 DNS 服务器 --dns-ipv4-addr
1 curl --dns-ipv4-addr 1.1.1.1 https://example.com
Telnet 协议探测端口 :端口连通性测试,
通的情况
1 2 3 4 5 ┌──[root@vms100.liruilongs.github.io]-[~] └─$timeout 3 curl -vvv telnet://192.168.26.55:55555 * About to connect() to 192.168.26.55 port 55555 ( * Trying 192.168.26.55... * Connected to 192.168.26.55 (192.168.26.55) port 55555 (
不通的情况
1 2 3 4 5 6 7 8 9 10 ┌──[root@vms100.liruilongs.github.io]-[~] └─$timeout 3 curl -vvv telnet://192.168.26.55:443 * About to connect() to 192.168.26.55 port 443 ( * Trying 192.168.26.55... * 拒绝连接 * Failed connect to 192.168.26.55:443; 拒绝连接 * Closing connection 0 curl: (7) Failed connect to 192.168.26.55:443; 拒绝连接 ┌──[root@vms100.liruilongs.github.io]-[~] └─$
三、调试黑科技:逆向工程师最爱 显示完整通信过程 -v
输出详细通信日志(含 SSL 握手):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 ┌──[root@liruilongs.github.io]-[~] └─$curl -v --tlsv1.2 https://example.com * Trying 96.7.128.198:443... * Connected to example.com (96.7.128.198) port 443 ( * ALPN, offering h2 * ALPN, offering http/1.1 * successfully set certificate verify locations: * CAfile: /etc/pki/tls/certs/ca-bundle.crt * CApath: none * TLSv1.3 (OUT), TLS handshake, Client hello (1): * TLSv1.3 (IN), TLS handshake, Server hello (2): 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。 * Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0 * Using Stream ID: 1 (easy handle 0x5652e145a9b0) > GET / HTTP/2 > Host: example.com > user-agent: curl/7.79.1 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。 < cache-control: max-age=1907 < date: Tue, 25 Mar 2025 17:35:20 GMT < alt-svc: h3=":443" ; ma=93600,h3-29=":443" ; ma=93600,quic=":443" ; ma=93600; v="43" < content-length: 1256 < <!doctype html> <html> <head> <title>Example Domain</title>
强制忽略 SSL 证书验证 : -k
绕过 HTTPS 证书检查(测试环境专用):
1 2 3 4 5 6 ┌──[root@liruilongs.github.io]-[~] └─$curl -k https://example.com <!doctype html> <html> <head> <title>Example Domain</title>
原始报文捕获 :用 --trace-ascii
输出二进制通信记录:
1 2 3 4 5 6 7 ┌──[root@liruilongs.github.io]-[~] └─$curl --trace-ascii debug.log https://example.com <!doctype html> <html> <head> <title>Example Domain</title> ··........
输出的报文
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ┌──[root@liruilongs.github.io]-[~] └─$cat debug.log == Info: Trying 96.7.128.175:443... == Info: Connected to example.com (96.7.128.175) port 443 ( == Info: ALPN, offering h2 == Info: ALPN, offering http/1.1 == Info: successfully set certificate verify locations: == Info: CAfile: /etc/pki/tls/certs/ca-bundle.crt == Info: CApath: none => Send SSL data, 5 bytes (0x5) 0000: ..... == Info: TLSv1.3 (OUT), TLS handshake, Client hello (1): => Send SSL data, 512 bytes (0x200) 0000: ..............0%i[S.......N<.H.d.u.... e.k..M77....0_|.(...&..* 0040: ........>.......,.0.........+./...$.(.k. 0080: <.5./.....u.........example.com........................3t....... '' .........................'' 0240: cert.com/CPS0...U...........0...U.%..0...+.........+.......0.... 0280: U.....0..0H.F.D.Bhttp://crl3.digicert.com/DigiCertGlobalG3TLSECC
四、请求定制:高级数据处理技巧 发送 JSON 数据并压缩 结合 --compressed
启用压缩传输:
1 curl -X POST -H "Content-Type: application/json" --data '{"key":"value"}' --compressed https://api.example.com
多文件上传 使用 -F
批量上传文件(支持通配符):
1 curl -F "files=@/path/to/images/*.png" https://upload.example.com
断点续传 -C -
自动续传未完成下载:
1 curl -C - -O http://example.com/largefile.zip
五、协议全家桶:非 HTTP 玩法 除了上面的 telnet 之外,还支持下面的一些操作
FTP 文件操作 :上传/下载文件到 FTP 服务器:
1 2 curl -u user:pass -T localfile.txt ftp://ftp.example.com/remote/ curl -O ftp://user:pass@ftp.example.com/remote/file.zip
发送 SMTP 邮件 :通过 curl 直接发送邮件:
1 curl --mail-from sender@example.com --mail-rcpt receiver@example.com --upload-file email.txt smtp://smtp.example.com
博文部分内容参考 © 文中涉及参考链接内容版权归原作者所有,如有侵权请告知,这是一个开源项目,如果你认可它,不要吝啬星星哦 :)
https://martinheinz.dev/blog/113
© 2018-至今 liruilonger@gmail.com , All rights reserved. 保持署名-非商用-相同方式共享(CC BY-NC-SA 4.0)