blog.ryota-ka.me

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

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

既に "today" ではないのだが,先週末に curl について便利なオプションを知ったのでまとめておく.curl で cookie を送受信する際には -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 で検証した.