vital.vim の Web.Http.request を使ってみた その2
get/post/request
get({url}, {param}, {header}) Vital.Web.Http.get() post({url}, {param}, {header}) Vital.Web.Http.post() request(...) Vital.Web.Http.request()
get/post に関しては request のラッパであり, request() が使えるようになればいい.
function! s:get(url, ...) let settings = { \ 'url': a:url, \ 'param': a:0 > 0 ? a:1 : {}, \ 'headers': a:0 > 1 ? a:2 : {}, \ } return s:request(settings) endfunction function! s:post(url, ...) let settings = { \ 'url': a:url, \ 'data': a:0 > 0 ? a:1 : {}, \ 'headers': a:0 > 1 ? a:2 : {}, \ 'method': a:0 > 2 ? a:3 : 'POST', \ } return s:request(settings) endfunction
client/command
"client" Default: "curl" or "wget" (executable one) HTTP client used for a request. "command" Command name for client. You should use with "client".
- 現状, "client" には "curl" か "wget" しか設定できない.
"command" は使い道がわからない. たとえば "curl" と全く同じ引数をとるコマンド "hoge" が存在するなら, 以下のように設定すればいいはずだが...- "command" は "client" へのフルパスを指定するのを想定しているらしい.
{"client" : "curl", "command" : "hoge"}
"maxRedirect"
manpage of curl
リダイレクト追跡回数の上限を指示します
-
- wget は指定方法が間違っている気がする.
- let command .= ' --max-redirect ' . a:settings.maxRedirect + let command .= ' --max-redirect=' . a:settings.maxRedirect
"param"
-
- dictionary or string と書いてあるが, string は動作しない.
"param" Default: (None) Get parameters. This is a string or a dictionary. If dictionary, it is converted to a string by |Vital.Web.Http.encodeURI()|.
-
- "data" は対応しているのでバグだとおもう
- let getdatastr = s:encodeURI(settings.param) + if s:Prelude.is_dict(settings.param) + let getdatastr = s:encodeURI(settings.param) + else + let getdatastr = settings.param + endif
"data"
元のコマンドとの対応
Vital | curl | wget |
---|---|---|
maxRedirect | --max-redirs | --max-redirect |
timeout | --max-time | --timeout |
username/password | --anyauth --user | --http-user, --http-password |
data | --data-binary | --post-file? |
headers | -H | --header |
復帰値
ヘルプに復帰値に関しての説明はほとんどない. 実行結果での比較
let g:VITAL = vital#of('vital') let HTTP = g:VITAL.import('Web.Http') echo HTTP.get("localhost") { 'status': 200, 'success': 1, 'header': [ 'Date: Tue, 07 May 2013 06:24:47 GMT', 'Server: Apache/2.2.22 (Ubuntu)', 'Last-Modified: Fri, 26 Feb 2010 10:31:14 GMT', 'ETag: "64d92-2d-4807e66192080"', 'Accept-Ranges: bytes', 'Content-Length: 45', 'Content-Type: text/html' ], 'statusText': 'OK', 'content': '<html><body><h1>It works!</h1></body></html> '}
% telnet localhost 80 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. GET / HTTP/1.0 HTTP/1.1 200 OK <== status, statusText Date: Tue, 07 May 2013 06:30:25 GMT Server: Apache/2.2.22 (Ubuntu) Last-Modified: Fri, 26 Feb 2010 10:31:14 GMT ETag: "64d92-2d-4807e66192080" Accept-Ranges: bytes Content-Length: 45 Connection: close Content-Type: text/html <html><body><h1>It works!</h1></body></html> Connection closed by foreign host.
- 一番問題なのは正常終了か異常終了かの確認方法が記述されていないこと.
- HTTP から復帰がある場合には, "success", "status", "statusText" に値が設定される.
- HTTP の status コードをみて, "success" に 0 (異常)または 1 (正常/200番台)が設定される.
- たとえばネットワークエラーで web サーバに接続できなかったときには "success" は設定されない.
- エラーメッセージも得られない. 何か異常があったことだけはわかる.
- たとえば 302 が返ってきた場合にも 0 (異常)が設定される
- あとから追加された "maxRedirect" の考慮不足かな. うちのせい?
- HTTP から復帰がある場合には, "success", "status", "statusText" に値が設定される.
- "header" はヘッダ部の情報が一行ずつ文字列としてリストに格納される.
- 解析には parseHeader を使うと良い
parseHeader
parseHeader({headers}) Vital.Web.Http.parseHeader()
- request/get/post 関数で得られるヘッダ部は「文字列のリスト」でそれを解析して辞書に変形する.
- requst() 関数の処理を軽くするために別にしてあるのだと思う.
let g:VITAL = vital#of('vital') let HTTP = g:VITAL.import('Web.Http') let RET = HTTP.get("localhost") echo HTTP.parseHeader(RET.header) { 'ETag': '"64d92-2d-4807e66192080"', 'Content-Type': 'text/html', 'Date': 'Tue, 07 May 2013 06:39:55 GMT', 'Accept-Ranges': 'bytes', 'Content-Length': '45', 'Last-Modified': 'Fri, 26 Feb 2010 10:31:14 GMT', 'Server': 'Apache/2.2.22 (Ubuntu)' }
encodeURI/decodeURI
encodeURI({param}) Vital.Web.Http.encodeURI() decodeURI({str}) Vital.Web.Http.decodeURI()
URL エンコード/デコードをする. まだ使っていない. ローカルの関数を呼び出し中. そのうち使う
encodeURIComponent
encodeURIComponent({str}) Vital.Web.Http.encodeURIComponent()
まだ使っていない. 使い道もしらない.
まとめ
- いまだに csh 環境で Vitalize するとカレントディレクトリに "1" という空ファイルができるバグは残っている.
- カレントディレクトリの 1 ファイルを壊すバグが残っている
- (続):Vitalize を複数回実行するとカレントディレクトリに空ファイルができる. - vim 初心者の作業メモ
- 実行環境に curl か wget がインストールされている必要がある.
- 復帰値に関する説明がほとんどない.
- エラー処理に関する記述はない
- 接続エラーなどの情報は全く得られない
- 302 が返ってきた場合にも "success" に 0 が設定される
- エラー処理に関する記述はない
- request(param) に string が指定できない (ドキュメントとの差異)
- "curl -F" がないから, pukiwiki.vim における curl 直呼び出し部分は完全に削除できない?? 理解不足かな?
- デバッグ用の手段を用意して欲しい.
差分
--- autoload/vital/__latest__/web/http.vim 2013-05-05 23:55:12.000000000 +0900 +++ autoload/vital/_3370e3e/web/http.vim 2013-05-07 22:12:02.000000000 +0900 @@ -116,7 +116,11 @@ let settings.headers['Content-Type'] = settings.contentType endif if has_key(settings, 'param') - let getdatastr = s:encodeURI(settings.param) + if s:Prelude.is_dict(settings.param) + let getdatastr = s:encodeURI(settings.param) + else + let getdatastr = settings.param + endif if strlen(getdatastr) let settings.url .= '?' . getdatastr endif @@ -194,7 +198,7 @@ let command .= ' -O ' . a:quote . a:settings._file.content . a:quote let command .= ' --server-response -q -L ' if has_key(a:settings, 'maxRedirect') - let command .= ' --max-redirect ' . a:settings.maxRedirect + let command .= ' --max-redirect=' . a:settings.maxRedirect endif let command .= s:_make_header_args(a:settings.headers, '--header=', a:quote) let timeout = get(a:settings, 'timeout', '') @@ -210,7 +214,7 @@ let command .= ' ' . a:quote . a:settings.url . a:quote if has_key(a:settings._file, 'post') let file = a:settings._file.post - let command .= ' --post-data @' . a:quote . file . a:quote + let command .= ' --post-file ' . a:quote . file . a:quote endif call s:Prelude.system(command)