こんにちわ、ゴリラです。
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
lets: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通信をしてみました。
興味あるかたはぜひ試してみてください。
サンプルコードはこちらに置いてあります。