Wi-FiとLuaとPIO等が使えるオモチャSDカード、FlashAirで遊んでみよう。
用意するもの:
- FlashAir(第3世代)
- ファームウエアは最新版(3.00.01)にアップグレードしておく。
- PIOとかで遊ぶ目的(カメラに挿すのではなく)であれば、容量は8GBで十分だろう。
- ファームウエアは最新版(3.00.01)にアップグレードしておく。
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 = {
['"']=""",
["'"]="'",
["&"]="&",
["<"]="<",
[">"]=">"
}
-- 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インタプリタにコマンドライン引数を渡してるだけだったりするのだろうか。
なぜかクエリ文字列の最後に改行がついている。
できるかどうか不明なこと
- POSTリクエストの処理
- 各種HTTPヘッダの取得
ピンバック: FlashAirで遊ぶ — Lチカ編 | 雑記帳