强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

curl 深度教程 / 第 01 章:curl 简介与生态

第 01 章:curl 简介与生态

curl 是互联网基础设施中沉默的巨人——你可能从未直接使用过它,但你每天的网络活动几乎都有它的参与。


1.1 curl 的历史

起源:一个瑞典开发者的业余项目

时间事件
1996 年瑞典开发者 Daniel Stenberg 开始编写一个名为 httpget 的工具
1998 年更名为 curlClient URL),添加对 FTP、GOPHER 等协议的支持
2001 年libcurl 库发布,允许其他程序复用 curl 的网络能力
2008 年curl 支持 IPv6 和 HTTP/1.1 Keep-Alive
2013 年引入 HTTP/2 支持(基于 nghttp2)
2018 年支持 HTTP/2 over QUIC 实验性构建
2020 年curl 7.72.0 发布,累计超过 200 个命令行选项
2023 年curl 8.0 发布,象征性版本号升级
2024 年Daniel Stenberg 获得 IETF 杰出贡献奖

curl 的"无处不在"

curl 可能是被编译、嵌入和调用最广泛的网络库之一:

  • 📱 Android 和 iOS 中的网络栈底层有 libcurl 的身影
  • 🌐 PHPfile_get_contents() 底层可使用 libcurl
  • 🐍 Pythonpycurl 绑定直接调用 libcurl
  • 🐳 Docker 官方镜像自带 curl,用于健康检查
  • 🚗 汽车、路由器、智能家电 的固件中嵌入了 libcurl
  • 🎮 PlayStation、Xbox 游戏机使用 libcurl 进行网络通信

📊 据统计,curl 的代码被嵌入到了 超过 100 亿台设备中。


1.2 设计理念

curl 的设计遵循几个核心原则:

命令行优先(CLI-First)

curl 的首要身份是一个 命令行工具。这意味着:

# 一切都是命令行参数
curl -X POST https://api.example.com/users \
  -H "Content-Type: application/json" \
  -d '{"name": "张三"}' \
  -o response.json
  • 可组合:可与 grepjqxargs 等工具管道组合
  • 可脚本化:无需交互,适合 CI/CD 自动化
  • 可复现:一个命令就是一个完整的操作记录

协议无关(Protocol-Agnostic)

curl 不只是 HTTP 工具,它支持超过 25 种协议

协议说明示例
HTTP/HTTPS最常用curl https://example.com
FTP/FTPS文件传输curl ftp://ftp.example.com/file.txt
SCP/SFTP安全文件传输curl sftp://user@host/file
SMTP/SMTPS发送邮件curl smtp://mail.example.com
POP3/POP3S接收邮件curl pop3://mail.example.com
IMAP/IMAPS邮件访问curl imaps://mail.example.com
LDAP/LDAPS目录服务curl ldap://ldap.example.com
TFTP简单文件传输curl tftp://tftp.example.com/file
MQTT物联网消息curl mqtt://broker.example.com
DICT字典查询curl dict://dict.org/d:hello
RTSP/RTP流媒体curl rtsp://media.example.com/stream
GOPHER早期互联网协议curl gopher://gopher.example.com

不做假设(No Assumptions)

curl 遵循 “你告诉它什么,它就做什么” 的原则:

  • 不会自动跟踪重定向(除非你指定 -L
  • 不会自动显示下载进度(除非输出到终端且非 -s
  • 不会自动保存响应(除非你指定 -o-O
  • 不会自动压缩(除非你指定 --compressed

这种"保守"的设计使得 curl 在脚本中行为可预测


1.3 curl vs wget vs httpie

这是开发者最常问的问题之一。以下是详细对比:

功能对比表

特性curlwgethttpie
主要用途数据传输文件下载API 调试
交互式使用中等极佳
脚本化能力极佳良好中等
协议支持25+HTTP/FTPHTTP/HTTPS
递归下载
彩色输出
JSON 语法高亮
断点续传✅(-C -)
HTTP/2✅(插件)
上传能力有限
Cookie 支持
代理支持
系统预装部分
依赖项无(静态编译)Python + 依赖
Docker 镜像中部分
学习曲线中等

curl vs wget:核心差异

# curl:精确控制每个请求
curl -X POST https://api.example.com/data \
  -H "Authorization: Bearer token" \
  -H "Content-Type: application/json" \
  -d '{"key": "value"}' \
  -o result.json

# wget:递归下载整站
wget --mirror --convert-links \
  --no-parent https://example.com/docs/

选择 curl 当你需要:

  • 精确控制 HTTP 请求的每个细节
  • 调试 API 端点
  • 在脚本中进行数据传输
  • 测试服务端行为

选择 wget 当你需要:

  • 递归下载整个网站
  • 后台断点续传大文件
  • 简单的镜像操作

curl vs httpie:API 调试场景

# curl 发送 JSON POST
curl -X POST https://api.example.com/users \
  -H "Content-Type: application/json" \
  -d '{"name": "张三", "age": 30}'

# httpie 发送同样的请求(更简洁)
http POST https://api.example.com/users name=张三 age:=30

选择 httpie 当你需要:

  • 频繁手动调试 REST API
  • 喜欢彩色格式化输出
  • 想要更简洁的 JSON 输入语法
  • 开发和演示环境

选择 curl 当你需要:

  • 生产环境脚本
  • 最大兼容性(curl 几乎预装在所有 Unix 系统中)
  • 精确控制每个请求细节
  • 高性能批量请求

1.4 适用场景

场景 1:API 开发与测试

# 测试 REST API 端点
curl -s https://api.example.com/users/1 | jq .

# 测试认证流程
curl -s -X POST https://api.example.com/auth \
  -H "Content-Type: application/json" \
  -d '{"username": "admin", "password": "secret"}' \
  -w "\nHTTP Status: %{http_code}\n"

场景 2:CI/CD 健康检查

# 在部署脚本中检查服务是否就绪
for i in $(seq 1 30); do
  if curl -sf http://localhost:8080/health > /dev/null; then
    echo "服务已就绪!"
    exit 0
  fi
  echo "等待服务启动... ($i/30)"
  sleep 2
done
echo "服务启动超时!"
exit 1

场景 3:文件下载与分发

# 下载大文件,显示进度,失败自动重试
curl -L -O -C - --retry 3 --retry-delay 5 \
  https://releases.example.com/v2.0/app.tar.gz

场景 4:Webhook 调试

# 向 webhook 端点发送测试事件
curl -X POST https://hooks.example.com/deploy \
  -H "Content-Type: application/json" \
  -H "X-Webhook-Secret: my-secret" \
  -d '{"event": "push", "branch": "main", "commit": "abc123"}'

场景 5:服务器诊断

# 检查 TLS 证书
curl -vI https://example.com 2>&1 | grep -E "expire|subject|issuer"

# 检查 HTTP/2 支持
curl -sI --http2 https://example.com 2>&1 | head -1

# 测量 TTFB(首字节时间)
curl -o /dev/null -s -w "TTFB: %{time_starttransfer}s\n" \
  https://example.com

1.5 curl 的生态系统

curl 不仅仅是一个命令行工具,它有一个完整的生态系统:

curl 生态系统
├── curl          ← 命令行工具(你正在学的)
├── libcurl       ← C 语言库(curl 的底层)
├── curl-config   ← 编译配置工具
├── CA cert bundle ← 证书包(ca-certificates)
├── curl-for-win  ← Windows 预编译版本
├── curl-fuzzer   ← 模糊测试工具
└── 第三方绑定
    ├── pycurl          (Python)
    ├── php-curl        (PHP)
    ├── node-libcurl    (Node.js)
    ├── curl-rust       (Rust)
    ├── ruby-curb       (Ruby)
    ├── go-curl         (Go)
    └── libcurl-java    (Java)

1.6 curl 的版本命名

理解 curl 的版本命名有助于你选择合适的版本:

版本含义
7.x经典版本线(1998-2023)
8.0+新版本线(2023 年起,象征性升级)
7.85.0+支持 URL 内联语法(url=user:pass@host
7.75.0+支持 URL globbing 和变量
# 查看当前版本
curl --version

# 输出示例:
# curl 8.5.0 (x86_64-pc-linux-gnu) libcurl/8.5.0 OpenSSL/3.1.4 ...
# Protocols: dict file ftp ftps gopher ...
# Features: alt-svc AsynchDNS brotli GSS-API HSTS HTTP2 HTTPS-proxy ...

注意事项

  1. curl 不是 wget:curl 默认将输出打印到 stdout,不会自动保存文件
  2. 引号很重要:URL 中的 &?= 等字符在 shell 中有特殊含义,必须用引号包裹
  3. 版本差异:不同操作系统预装的 curl 版本差异很大,注意检查版本
  4. 安全更新:curl 经常发布安全更新,建议保持较新版本
# ❌ 错误:URL 未加引号,& 被 shell 解释为后台运行
curl https://api.example.com/data?page=1&size=10

# ✅ 正确:URL 用引号包裹
curl "https://api.example.com/data?page=1&size=10"

扩展阅读


📖 下一章第 02 章:安装与编译 — 了解如何在各平台安装 curl,以及如何从源码编译自定义版本。