Symfoware

Symfowareについての考察blog

luvi luvを使用してhttp getリクエストを実行する

Lua言語で簡単にバイナリ形式の実行ファイルが作成できるluvi
luviでLuaプログラムをバイナリの実行形式に変換する

インターネットリソースを取得する方法を調べてみます。
要するにhttp getして、webの情報を取得したい。


uv.tcp_connect



どうやれば良いか、とっかかりがなかったのですが
luvのサンプルを見ていると、tcpコネクションは貼れるようです。
tcp-echo-client.lua

luvは「uv」というモジュール名で、luviに同梱されています。
これが使えそう。

tcpコネクションだけでhttp getする方法はこちらが参考になりました。

telnetでWebサーバに接続してみよう
[Web] HTTPリクエストの中身を学んでみた。GETやPOSTの違いなど

GETに続いて、取得したいリソース名を指定すれば良いようです。

適当な文字列を返すwebページを用意しておきました。

667_01.png



このページを取得するサンプルはこんな感じになりました。

・main.lua


  1. local uv = require('uv')
  2. local client = uv.new_tcp()
  3. uv.tcp_connect(client, "127.0.0.1", 80, function (err)
  4.     assert(not err, err)
  5.     
  6.     uv.write(client, "GET /sample.html\n")
  7.     
  8.     uv.read_start(client, function (err, chunk)
  9.      assert(not err, err)
  10.      if chunk then
  11.         print(chunk)
  12.      else
  13.         uv.close(client)
  14.      end
  15.     end)
  16. end)
  17. uv.run('default')





実行すると、ちゃんと内容が取得できています。


$ ./luvi my_app
hello






uv.getaddrinfo



tcp_connectの引数にはIPアドレスを渡してやる必要があります。
名前からIPアドレスを取得するにはuv.getaddrinfoを使用すれば良いようです。

lots-o-dns.lua

symfo.web.fc2.comのIPアドレスを調べてみます。


  1. local uv = require('uv')
  2. uv.getaddrinfo('symfo.web.fc2.com', nil, {
  3.     v4mapped = true,
  4.     all = true,
  5.     addrconfig = true,
  6.     canonname = true,
  7.     numericserv = true,
  8.     socktype = "STREAM"
  9.     
  10. }, function (err, data)
  11.     assert(not err, err)
  12.     
  13.     -- テーブルの内容をすべて表示
  14.     for k,v in pairs(data) do
  15.         print(k, v)
  16.         for k1,v1 in pairs(v) do
  17.             print(k1, v1)
  18.         end
  19.     end
  20.     
  21.     print('----')
  22.     
  23.     -- ここでIPアドレスが取得できる
  24.     print(data[1].addr)
  25. end)





IPアドレスが取得出来ました。


$ ./luvi my_app
1    table: 0x4037f3f8
addr    208.71.106.43
canonname    symfo.web.fc2.com
family    inet
socktype    stream
2    table: 0x4037f750
addr    208.71.106.43
protocol    packet
family    inet
socktype    dgram
3    table: 0x4037f5e0
addr    208.71.106.43
family    inet
socktype    raw
----
208.71.106.43




test-dns.lua
こちらを参考に、単純にIPアドレスが取得したいだけの場合、こんな感じのコードで良いようです。


  1. local uv = require('uv')
  2. local hostinfo = uv.getaddrinfo('symfo.web.fc2.com')
  3. print(hostinfo[1].addr)




$ ./luvi my_app
208.71.106.43








ページの内容を取得



試行錯誤して作成したプログラムはこちら。


  1. local uv = require('uv')
  2. local host = 'symfo.web.fc2.com'
  3. local hostinfo = uv.getaddrinfo(host)
  4. local ip = hostinfo[1].addr
  5. local client = uv.new_tcp()
  6. uv.tcp_connect(client, ip, 80, function (err)
  7.     assert(not err, err)
  8.     
  9.     uv.write(client, string.format('GET http://%s/\n', host))
  10.     
  11.     uv.read_start(client, function (err, chunk)
  12.      assert(not err, err)
  13.      if chunk then
  14.         print(chunk)
  15.      else
  16.         uv.close(client)
  17.      end
  18.     end)
  19. end)
  20. uv.run('default')




実行してみると、http://symfo.web.fc2.com/のHTMLが取得出来ました。





ちゃんとリクエストを送信する



PHPのデバッグサーバーに対してリクエストを送ると、応答がありません。

改行コードを最後に2つつけるのが正しい作法のようです。
以下のコードではうまく動いてくれました。


  1. local uv = require('uv')
  2. local client = uv.new_tcp()
  3. uv.tcp_connect(client, '127.0.0.1', 8080, function (err)
  4.     assert(not err, err)
  5.     
  6.     uv.write(client, 'GET /sample.php HTTP/1.1\n\n')
  7.     
  8.     uv.read_start(client, function (err, chunk)
  9.      assert(not err, err)
  10.      if chunk then
  11.         print(chunk)
  12.         print('---')
  13.      else
  14.         uv.close(client)
  15.      end
  16.     end)
  17. end)
  18. uv.run('default')




$ ./luvi my_app
HTTP/1.1 200 OK
Connection: close
X-Powered-By: PHP/5.5.32-1+deb.sury.org~trusty+1
Content-type: text/html

hello
---





関連記事

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2016/02/17(水) 21:33:58|
  2. Lua
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集
<<luvi 別ファイルに記載したプログラムを読み込む | ホーム | luvi 実行ファイルに同梱されているファイルの取得>>

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック

トラックバック URL
http://symfoware.blog68.fc2.com/tb.php/1843-d8f9c162
この記事にトラックバックする(FC2ブログユーザー)