Open9
Gun メモ
ninenines/gun: HTTP/1.1, HTTP/2, Websocket client (and more) for Erlang/OTP.
Erlang/OTP で HTTP クライアントを使うならこれ。ただ情報が少なすぎるので、使ってる人が少ないので、まとめていきたい。
非同期
- gun:open
- gun:await_up
- gun:post
- gun:await_body
ドキュメントを穴が開くまで読むのをオススメ。特にオプション系。
それでも足りない場合はテストを読むこと。
- connect_timeout
- これデフォルト無制限なので制限かけたほうがいいかもしれない
- retry
- デフォルトで 5 回リトライしてしまう
- リトライはアプリ側でハンドリングしたほうがいいので 0 にする方がいいかもしれない
Proxy
- Proxy 先が HTTPS の場合は gun:connect を利用する
- gun:connect/2 を使った場合は必ず
{up, Protocol} = gun:await/2
で待つこと
- gun:connect/2 を使った場合は必ず
- Proxy 先が HTTP の場合は CONNECT が不要な場合が多いので Path に URL を入れて処理する
- Gun は Path に URL を入れても問題無い
Path
- gun は path に
<<>>
が指定できてしまう、ただ path が<<>>
なのは RFC 違反なので要注意 - uri_string:parse/1 で path が無い場合は
<<$/>>
を追加するロジックを書いた方が良い
TLS
- Gun の TLS は ssl アプリケーションを利用するが、基本的にドキュメントはないので要注意
- CaCerts は OS の値を取得できるようになってるので積極的に使う事をお勧め
- もちろん個別のを設定できるようにしても良い
- SNI は常に指定するようにした方がいい
- customize_hostname_check は https 用のが public_key に用意されているのでそれを使うと良い
CaCerts = public_key:cacerts_get(),
[{versions, ['tlsv1.3', 'tlsv1.2']},
{verify, verify_peer},
{server_name_indication, Hostname},
{depth, 3},
{customize_hostname_check, [{match_fun, public_key:pkix_verify_hostname_match_fun(https)}]},
{cacerts, CaCerts}]
IPv6
- IPv6 を利用する場合は tcp_opts に inet6 を指定する
- AAAA しか設定されていないホスト名ではエラーになるので事前に inet_res アプリケーションを利用して AAAA が登録されているかどうかを確認するという処理が必要になる
HTTP Proxy
gun:connect/2 を使った際は、必ず gun:await で {up, Protocol} が帰ってくるのを待つ必要がある。
これをしないと {gun_tunnel_up, ... が突き抜けてくる。
終了処理
- 正常系は gun:shutdown/1
- 異常系は gun:close/1 読んだ後に gun:flush/1 を呼ぶ
- これをしないと {gun_down, ... が突き抜けてくる