Lua勉強日記(12) CGI

やっぱり、apacheで簡単に動かない物を作っても楽しくないので、cgilua*1で提供されているSAPIの上でCGIを作るのを諦めました。(cgiluaは、mod_luaやfcgiとの差違を吸収するSAPIという抽象化層を介して操作するために、単なるCGIを動かすのに余分な手間がかかるので)

そこで、cgiluaと決別して、単純なCGIライブラリを作ることにしました。下のように、拡張子cgiのファイルから使えるものです。

greeting.cgi
#!C:/Kepler/1.1/bin/lua5.1.exe
package.path = [[C:/Program Files/Apache Group/Apache2/htdocs/users/lua/?.lua;]] .. package.path
require "cgi"
local request = cgi.Request.new()
local response = cgi.Response.new()
local greeting = request.params['greeting']
response.put(string.format([[
  <html><body>hello, %s!
]], greeting)

cgiluaの中には、ポータブルな捨てがたいライブラリが入っているので、それらは使っていきたいです。

cgilua/lp.lua
JSPやPHPのようなテンプレートエンジン。素晴しいことに1つのファイルで実装されていて、他への依存が無い
cgilua/urlcode.lua
エスケープ処理などのユーティリティ

作成中のcgiライブラリは、以下のような感じになってます。

cgi.lua

主な内容は、RequestクラスとResponseクラスだけです。

----------------------------------------------------------------------------
-- CGI library.
----------------------------------------------------------------------------
local stdout = io.stdout
local getenv = os.getenv
local setmetatable = setmetatable
local require = require
local string = string
local table = table
module("cgi")
local lp = require "cgilua.lp"
local get_path_infos = function(path_info)
  local ret = {}
  if not path_info or string.len(path_info) < 2 then
    return ret
  end
  string.gsub(path_info ,"/?([^\/]+)/?",
  function (x)
    table.insert(ret, x)
  end
  )
  return ret
end
Request = {}
function Request.new()
  local self = {
    path_info = getenv('PATH_INFO'),
    path_infos = get_path_infos(getenv('PATH_INFO')),
    script_filename = getenv('SCRIPT_FILENAME'),
    script_name = getenv('SCRIPT_NAME'),
    app_name = string.gsub(getenv('SCRIPT_NAME'), "[^\/]+$", ""),
  }
  return setmetatable(self, {__index = Request})
end
Response = {}
function Response.new()
  local self = {
    script_filename = getenv('SCRIPT_FILENAME')
  }
  return setmetatable(self, {__index = Response})
end
function Response:put(...)
  stdout:write(...)
end
function Response:forward(filename, env)
  self:put("Content-Type: text/html;charset=UTF-8;\n\n")
  lp.include(self.script_filename .. '/../' .. filename, env)
end
function Response:redirect(to, env)
  self:put("location: " .. to .. "\n\n")
end
-- vim: set ft=lua ts=4 sw=4 sts=4 expandtab :

まだまだ作成途中ですが、他のスクリプト言語と同じように非常に簡単にCGIスクリプトを書くのに取り掛かれるようにはなりそうです。

*1:というかkepler

1件のコメント

コメントする

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


reCaptcha の認証期間が終了しました。ページを再読み込みしてください。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください