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で検証した.