curl の -b, -c (--cookie, --cookie-jar) オプションが便利

この記事は以下のページに移転しました.

blog.ryota-ka.me

体系だった大掛かりな記事を書こうとすると,なかなか気力と労力が必要で,結局書き上がった頃には多大なる時間を費やしているということがままあるので,もう少し雑にお役立ち情報を書いていきたい.そこで,TIL (Today I Learned) を (GitHub に push するのではなく) 記事にしていこうと思う.

既に today ではないのだが,先週末に curl について便利なオプションを知ったのでまとめておく.curlcookie を送受信する際には -b / --cookie -c / --cookie-jar という便利なコマンドがあるのでこれが使えるという話.

動作検証用に Node.js で簡単な HTTP サーバを立てておく.

const http = require('http');

http.createServer((req, res) => {
  if (req.url === '/set-cookie') {
    res.writeHead(200, { 'Set-Cookie': ['foo=6', 'bar=28', 'baz=496'] });
    res.write('Setting cookie');
  } else {
    res.write(req.headers.cookie || 'empty');
  }
  res.end();
}).listen(8000);

見ればわかるが, /set-cookie にリクエストが来ると,Set-Cookie ヘッダを書き出すようになっている.

$ curl -i localhost:8000/set-cookie
HTTP/1.1 200 OK
Set-Cookie: foo=6
Set-Cookie: bar=28
Set-Cookie: baz=496
Date: Wed, 22 Mar 2017 00:00:00 GMT
Connection: keep-alive
Transfer-Encoding: chunked

Setting cookie

また,/set-cookie 以外の適当なパスにリクエストを送ると,リクエストの Cookie ヘッダの中身がレスポンスボディに出力される.

$ curl -i localhost:8000
HTTP/1.1 200 OK
Date: Wed, 22 Mar 2017 00:00:00 GMT
Connection: keep-alive
Transfer-Encoding: chunked

empty
$ curl -i -H 'Cookie: foo=6; bar=28; baz=496' localhost:8000
HTTP/1.1 200 OK
Date: Wed, 22 Mar 2017 00:00:00 GMT
Connection: keep-alive
Transfer-Encoding: chunked

foo=6; bar=28; baz=496

下の例は Cookie ヘッダを直接書いているが,-b (または --cookie) オプション を用いて,下記のようにも指定できる.

$ curl -i -b 'foo=6; bar=28; baz=496' localhost:8000
HTTP/1.1 200 OK
Date: Wed, 22 Mar 2017 00:00:00 GMT
Connection: keep-alive
Transfer-Encoding: chunked

foo=6; bar=28; baz=496

これだけだと Cookie: の8文字が消えただけでほとんど何も嬉しくないが,実は -b の引数の文字列に = を含まない場合は,ファイル名と解釈され,このファイルに書かれたクッキーの情報をリクエストヘッダに含めてくれる.

どういう形式のファイルを用意すればいいのか,という話だが,ここで先に,-c (または --cookie-jar) オプションを紹介しておこう.これは,レスポンスヘッダに含まれるクッキーの情報を,引数で指定したファイルに書き出してくれる.

curl -i -c /path/to/cookiejar localhost:8000/set-cookie
HTTP/1.1 200 OK
Set-Cookie: foo=6
Set-Cookie: bar=28
Set-Cookie: baz=496
Date: Wed, 22 Mar 2017 00:00:00 GMT
Connection: keep-alive
Transfer-Encoding: chunked

Setting cookie
$ cat /path/to/cookiejar
# Netscape HTTP Cookie File
# https://curl.haxx.se/docs/http-cookies.html
# This file was generated by libcurl! Edit at your own risk.

localhost   FALSE   /   FALSE   0  foo 6
localhost   FALSE   /   FALSE   0  bar 28
localhost   FALSE   /   FALSE   0  baz 496

実は -b / --cookie オプションは,このファイルの形式をそのまま使える.

curl -i -b /path/to/cookiejar localhost:8000
HTTP/1.1 200 OK
Date: Wed, 22 Mar 2017 00:00:00 GMT
Connection: keep-alive
Transfer-Encoding: chunked

bar=28; baz=496; foo=6

便利.

以上は curl 7.51.0 および Node.js 7.7.4 で検証した.