FlashAirで遊ぶ — Luaスクリプト編

Wi-FiとLuaとPIO等が使えるオモチャSDカード、FlashAirで遊んでみよう。

用意するもの:

  • FlashAir(第3世代)
    • ファームウエアは最新版(3.00.01)にアップグレードしておく。
      • PIOとかで遊ぶ目的(カメラに挿すのではなく)であれば、容量は8GBで十分だろう。

FlashAirを用意したら、ネットワークを適当に設定して、パソコンからアクセスできるようにする。

FlashAir Developersガイドによれば、FlashAirでLuaを動かすタイミングとして以下の3つが用意されている。

  • FlashAirの起動時(機器に組み込む時に使いそう)
  • ファイル書き込み時(デジカメで撮った写真を自動でアップロードするとかいうのに使えそう)
  • HTTPアクセス時(CGIではないがCGI的な感じ)

この3番目のやつを試してみよう。まずはHello worldだ。

とりあえずHello world

以下の内容を、 hello1.lua という名前でSDカード直下に置く。

-- hello1.lua
print "Hello world!"

ブラウザで http://flashair.local/hello1.lua にアクセスする(ホスト名は適当に読み替える)。すると、 Hello world! と表示されているはずだ。

Luaの文法メモ:Luaの1行コメントは -- で始める。

Luaの文法メモ:Luaでは引数が文字列リテラル1個の場合に関数呼び出しのカッコを省略できる。

さて、ガイドには

HTTPリクエストに対する応答を標準出力に書き込むLuaスクリプトを作成します。 出力にはHTTPレスポンスヘッダも含む必要があります。

とあるが、試した限りでは io.write は使えない。これ本当に「標準出力」なのだろうか…。(print は出力の最後に改行をつけるという仕様があるので、文字列を出力するという目的なら io.write を使いたい)

HTTPヘッダを出力する

さっきの hello1.lua に telnet とかでアクセスしてみるとわかるが、 http://flashair.local/hello1.lua はHTTPヘッダを出力してない(FlashAir側で勝手につけてくれたりはしない)。これはよろしくない。

そこで、 HTTP/x.x から始まるHTTPレスポンスを出力する。

hello2.lua:

-- hello2.lua
print [[
HTTP/1.1 200 OK
Content-Type: text/plain

Hello world!
]]

Luaの文法メモ:Luaでは [[ ]] で複数行の文字列リテラルを書くことができる。この「長い」文字列リテラルでは、エスケープシークエンス等は効かない。[[ の直後が改行の場合、その改行は無視される。

クエリ文字列を受け取る

GETリクエストの ? 以下のクエリ文字列を受け取りたい。CGIだと QUERY_STRING とかの環境変数があったが、FlashAirのLuaだとそもそも os ライブラリがないので環境変数が取れない。

FlashAirのLuaスクリプトでクエリ文字列を受け取るには、 arg グローバル変数とトップレベルの ... が使えるようだ。

querytest.lua:

local HTML_escape_table = {
  ['"']=""",
  ["'"]="'",
  ["&"]="&",
  ["<"]="&lt;",
  [">"]="&gt;"
}
-- HTMLエスケープする関数
function escapeHTML(s)
  return (s:gsub(".",HTML_escape_table))
end
-- 文字列をLuaの文字列リテラル形式に直す関数(素の string.format("%q",) だと改行がアレ)
function escapeString(s)
  return (string.format("%q",s):gsub("\\\n","\\n"))
end
print[[
HTTP/1.1 200 OK
Content-Type: text/html

<!DOCTYPE html>
<html>
<head>
<title>Hello world!</title>
</head>
<body>
]]
-- ... の内容を出力
if select("#",...) > 0 then
  print(string.format("<pre>...=%s</pre>",escapeString(...)))
end
print[[
<table>
<tr><th>index</th><th>value</th></tr>
]]
-- arg グローバル変数の内容を出力(インデックスが -1 から始まるので ipairs は使わない)
for i=-1,#arg do
  print(string.format("<tr><td>%d</td><td><code>%s</code></td></tr>", i, escapeString(escapeHTML(arg[i]))))
end
print[[
</table>
</body>
</html>
]]

実行結果(http://flashair.local/query.lua?a=b&c=d):

...="a=b&c=d\n"
index value
-1 "lua"
0 "/querytest.lua"
1 "a=b&c=d\n"

arg グローバル変数はLuaインタプリタのコマンドライン引数の仕様と同様のようだ。というか、Luaインタプリタにコマンドライン引数を渡してるだけだったりするのだろうか。

なぜかクエリ文字列の最後に改行がついている。

参考:Getting query string parameters from an HTTP request in Lua – FlashAir Developers – Support – Developer Forum

できるかどうか不明なこと

  • POSTリクエストの処理
  • 各種HTTPヘッダの取得

参考ページ


FlashAirで遊ぶ — Luaスクリプト編」への1件のフィードバック

  1. ピンバック: FlashAirで遊ぶ — Lチカ編 | 雑記帳

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です