LoginSignup
64
38

More than 3 years have passed since last update.

Vim本体だけでHTTP通信してみた話

Posted at

こんにちわ、ゴリラです。

Vimを使っているみなさんは、channel機能はご存知でしょうか?
channelを使用することで、他のプロセスと通信することができます。通信はTCP/IPプロトコルで行われます。

本記事はchannel機能を使って、HTTP通信をしてみた記事になります。(HTTPについては解説しません)
curlといった外部コマンドに頼らなくても簡易なGETなら、Vim本体だけで行うことができます。

では、早速解説していきます。

デモ

こんな感じです。
http.vim.gif

チャネルについて

channelRAWNLJSONJSといった通信フォーマットがあります。
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_requestGET /containers/json?all=1 HTTP/1.1変えるだけです。

http-vim-container.gif

Macの場合はsocat TCP-LISTEN:80,reuseaddr,fork UNIX-CONNECT:/var/run/docker.sockという感じでソケット通信をTCPに変換してからやってみてください。

まとめ

以上、とても簡単ですがVim本体だけでHTTP通信をしてみました。
興味あるかたはぜひ試してみてください。

サンプルコードはこちらに置いてあります。

64
38
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
64
38