こんにちわ、ゴリラです。
Vimを使っているみなさんは、channel
機能はご存知でしょうか?
channel
を使用することで、他のプロセスと通信することができます。通信はTCP/IP
プロトコルで行われます。
本記事はchannel
機能を使って、HTTP通信をしてみた記事になります。(HTTPについては解説しません)
curl
といった外部コマンドに頼らなくても簡易なGETなら、Vim本体だけで行うことができます。
では、早速解説していきます。
デモ
チャネルについて
channel
はRAW
、NL
、JSON
、JS
といった通信フォーマットがあります。
JSON
なら送信したメッセージがJSONに変換されます。例えばhello gorilla
を送信した場合、[1, "hello gorilla"]
に整形され送信できます。
RAW
ならテキストがそのまま送信することができます。HTTPの実態はプレーンテキストなので、今回はRAW
を使用します。
詳細は:h channel
を参照してください。
チャネルを開く
ch_open
関数を使用します。
let channel = ch_open("localhost:80", {"mode": "raw"})
だけで接続できます。
echo ch_status(channel)
でチャネルの状態を確認できます。open
は接続中、close
は接続終了を指します。
リクエストを送信
チャネルに対して送信するにはch_sendraw()
関数を使用します。これはテキストをそのまま送信する関数になります。
レスポンスはコールバック関数を使用することで受け取ることができます。
HTTPのGETリクエストをチャネルで送信処理は次になります。
func! MyHandler(channel, msg) abort
new RESPONSE | set buftype=nofile
call setline(".", a:msg->split("\r\n"))
nnoremap <buffer> <silent> q :bw!<CR>
endfunc
let s:get_request = "GET / HTTP/1.1\r\nHost: localhost\r\n\r\n"
call ch_sendraw(channel, s:get_request, {'callback': "MyHandler"})
ch_sendraw
の第2引数は送信したいテキスト、第3引数はコールバック関数MyHandler
を設定します。
MyHandler
では新たなバッファを作成して、受け取ったレスポンスをバッファに書き込んでいます。
Dockerのコンテナ一覧を取得
このやり方をちょっとだけ応用して、Dockerのコンテナ一覧を取得することもできます。
ch_open
でDockerのサーバーを指定してs:get_request
をGET /containers/json?all=1 HTTP/1.1
変えるだけです。
Macの場合はsocat TCP-LISTEN:80,reuseaddr,fork UNIX-CONNECT:/var/run/docker.sock
という感じでソケット通信をTCPに変換してからやってみてください。
まとめ
以上、とても簡単ですがVim本体だけでHTTP通信をしてみました。
興味あるかたはぜひ試してみてください。
サンプルコードはこちらに置いてあります。