curlはURLを使ってdataを送受信するCLI toolです。この早見表はHTTP APIのrequest作成とdebugへ範囲を絞ります。
最頻出10項目
| 操作 | Option |
|---|---|
| GET | curl URL |
| headerも表示 | -i |
| 詳細debug | -v |
| redirect追従 | -L |
| header追加 | -H |
| JSON送信 | --json |
| method指定 | -X |
| HTTP errorで失敗 | --fail-with-body |
| timeout | --connect-timeout、--max-time |
| file保存 | -o、-O |
GETとResponse
curl https://api.example.com/health
curl -i https://api.example.com/health
curl -L https://example.com/old-path
-iはresponse headerをbodyと一緒にstdoutへ出します。headerだけを見る場合は-Iですが、これはHEAD requestになるため、GETと結果が異なるserverがあります。
curl -sS \
-o /dev/null \
-w '%{http_code}' \
https://api.example.com/health
-sSはprogressを隠しつつerrorを表示します。-wは転送後に指定情報を出します。
Query parameter
curl --get \
--data-urlencode 'q=HTML & CSS' \
--data-urlencode 'page=1' \
https://api.example.com/search
値を手作業でURLへ連結せず--data-urlencodeを使うとspaceや記号をencodeできます。
JSON
curl --json '{"name":"Ada","active":true}' \
https://api.example.com/users
--jsonはJSON bodyを送り、必要なcontent type・accept headerを設定します。fileから読む場合:
curl --json @payload.json \
https://api.example.com/users
@payload.jsonはfile内容を読みます。意図しないfileやsecretを送らないよう、実行前に対象を確認してください。
明示的に書く場合:
curl -X POST \
-H 'content-type: application/json' \
--data '{"name":"Ada"}' \
https://api.example.com/users
--dataを使うとcurlは通常POSTを選ぶため、単純なPOSTで-X POSTは必須ではありません。
Form
URL encoded form:
curl \
--data-urlencode 'email=user@example.com' \
--data-urlencode 'message=Hello world' \
https://example.com/contact
multipart formとfile upload:
curl \
-F 'title=report' \
-F 'file=@./report.pdf;type=application/pdf' \
https://api.example.com/uploads
@はlocal fileを読みます。pathを確認し、private fileを誤送信しないでください。
Header
curl \
-H 'accept: application/json' \
-H 'x-request-id: test-001' \
https://api.example.com/users
request headerだけを別fileへ置く方法もありますが、tokenを含むfileのpermissionと削除方法を決めます。
Response headerとbodyを分ける:
curl \
-D response.headers \
-o response.json \
https://api.example.com/users
既存fileを上書きするため、保存先を確認してください。response.headersにはSet-Cookieや認証関連headerが含まれる場合があります。共有directoryへ置かず、必要なら所有者だけが読める権限にし、Gitへ追加せず、確認後は安全に削除します。
Authentication
Basic認証:
curl -u 'username' \
https://api.example.com/private
passwordを省略するとpromptされ、command historyへ残しにくくなります。
Bearer token:
curl \
-H "authorization: Bearer ${API_TOKEN}" \
https://api.example.com/private
環境変数でもprocess環境やdebug logから漏れる可能性があります。共有terminal、CI log、shell historyへsecretを表示しません。-vはheaderを出すため、認証requestのlog共有前にredactします。
Cookie
curl \
-c cookies.txt \
-b cookies.txt \
https://example.com/account
-cは受信cookieを保存し、-bは送信に使います。cookie jarはsession secretを含む場合があるためGitへcommitせず、不要になったら安全に削除します。
Method
curl -X PUT --json '{"name":"Updated"}' URL
curl -X PATCH --json '{"active":false}' URL
curl -X DELETE URL
DELETEやPUTはdataを変更します。production URL、resource ID、認証先を実行前に再確認してください。可能ならtest environmentで試します。
ErrorとCI
curl \
--fail-with-body \
--silent \
--show-error \
https://api.example.com/health
--fail-with-bodyはHTTP 400以上でnon-zero終了しつつbodyを残します。network errorだけでなくHTTP statusもCI失敗にできます。
if ! curl --fail-with-body -sS URL; then
echo "request failed" >&2
exit 1
fi
retryはidempotentなrequestを基本にします。POSTを無条件にretryすると二重登録・二重決済につながる可能性があります。
curl \
--retry 3 \
--retry-delay 1 \
--connect-timeout 5 \
--max-time 20 \
URL
Download
curl -o archive.zip https://example.com/archive.zip
curl -O https://example.com/archive.zip
curl -C - -O https://example.com/large.iso
-Oはremote file名を使用します。既存file、保存directory、disk容量を確認します。download後は公式checksumやsignatureを検証してください。
curl -fL -o tool.tar.gz \
https://example.com/tool.tar.gz
sha256sum tool.tar.gz
curl ... | shはdownload内容をreviewせず実行するため避けます。
Upload
raw body:
curl -X PUT \
-H 'content-type: application/octet-stream' \
--data-binary @archive.zip \
https://api.example.com/files/archive.zip
--data-binaryは改行などを変換せず送ります。
TLSとProxy
curl -v https://example.com/
curl --tlsv1.2 https://example.com/
curl --cacert ./ca.pem https://internal.example.com/
curl -x http://proxy.example.com:8080 https://example.com/
certificate検証を無効化する-k / --insecureは中間者攻撃を検出できなくします。原因調査でも結果を本番手順へ残さず、正しいCA・hostname・時刻を修正します。
Timing
curl -sS -o /dev/null \
-w 'dns=%{time_namelookup} connect=%{time_connect} tls=%{time_appconnect} first=%{time_starttransfer} total=%{time_total}' \
https://example.com/
値は秒です。1回の結果だけで結論を出さず、network経路とserver logも確認します。
書式変数
| 変数 | 内容 |
|---|---|
%{http_code} | 最終HTTP status |
%{url_effective} | redirect後のURL |
%{remote_ip} | 接続先IP |
%{size_download} | download byte数 |
%{time_namelookup} | DNS完了まで |
%{time_connect} | TCP接続まで |
%{time_appconnect} | TLS handshakeまで |
%{time_starttransfer} | 最初のbyteまで |
%{time_total} | 全体時間 |
RedirectとCache確認
curl -sS -D - -o /dev/null \
https://example.com/old
curl -sS -L \
-o /dev/null \
-w '%{url_effective}' \
https://example.com/old
-Lを付ける前に最初のLocationを見ると、redirect loopやhttp/httpsの行き来を発見しやすくなります。
conditional request:
curl \
-H 'If-None-Match: "example-etag"' \
https://api.example.com/resource
serverが同じresourceと判断すれば304を返せます。ETagのquoteを含め、実際のresponse headerをそのまま使います。
Content negotiation
curl \
-H 'accept: application/json' \
-H 'accept-language: ja' \
https://example.com/resource
Content-Typeは送るbodyのformat、Acceptは受け取りたいresponse formatです。混同すると415や406の原因になります。
DNSを切り替えて確認
curl \
--resolve example.com:443:203.0.113.10 \
https://example.com/
--resolveは指定hostname・portを特定IPへ接続させつつ、URLのhostnameをTLSとHost headerに使います。DNS切替前のserver確認に利用できます。
対象IPを誤ると別serverへrequestを送ります。productionの認証cookieやtokenを付ける前に接続先を確認してください。
HTTP version
curl --http1.1 https://example.com/
curl --http2 https://example.com/
curl --http3 https://example.com/
curl buildが対応しているprotocolはcurl --versionで確認します。HTTP/3はcurl、TLS library、server、networkのすべてが対応している必要があります。
Debug
curl -v URL
curl --trace-ascii trace.txt URL
traceにはheader、cookie、body、tokenが含まれる可能性があります。共有前にsecret・個人情報を削除し、不要になったtrace fileも削除します。
よくある確認:
- DNS: hostnameが正しいか
- connect: portとfirewall
- TLS: certificate chain、hostname、時刻
- HTTP: method、path、status
- request: content typeとbody
- auth: header・token期限・scope
- redirect:
Locationと-L
FTP、SMTP、SFTP、WebSocketなどHTTP以外のprotocolはcurl manualの各optionを参照してください。