Mod lua

32
mod_lua Web ササササササ #5 2012/03/29 do_aki

description

 

Transcript of Mod lua

Page 1: Mod lua

mod_lua

Web サーバ勉強会 #52012/03/29

do_aki

Page 2: Mod lua

| 所属 | > 株式会社もしも    (ドロップシッピング・アフィリエイト ASP )

| 仕事 | > インフラ(サーバ管理)兼  Web アプリケーション開発

| 出現 | > 渋谷・山手線沿線| 特性 | > PHPer

do_aki ( どぅーあき )

http://do-aki.net/

Page 3: Mod lua

<< About mod_lua >>

Page 4: Mod lua

詳しくはここ見ると良いよ

http://blog.matsumoto-r.jp/?p=2117

Page 5: Mod lua

mod_lua

• configure --enable-lua する必要がある

• 2.3 から入った• 2.4 でも experimental state のまま• 2.4.x 系のリリース中に挙動変わるかもね

• http://httpd.apache.org/docs/2.4/en/mod/mod_lua.html

• ドキュメントは狼少年だった orz

Page 6: Mod lua

2 つの側面• cgi っぽいもの (like mod_php ,

mod_perl)– lua スクリプトを設置– handle 関数が呼ばれる– “AddHandler lua-script .lua” を指定する

だけ

• apache の hook 関数として– LuaHook* ディレクティブで指定

Page 7: Mod lua

共通していること• request_rec が引数として渡される– lua からは userdata として見える– r または rw なプロパティ– いくつかのメソッド

• apache2 モジュールが利用できる– ほとんど定数?

Page 8: Mod lua

hello.lua

function handle(r) r.content_type = 'text/html' r:puts([[ <!doctype html> <html> <head><title>hello</title></head> <body><h1>hello mod_lua</h1></body> </html> ]])end

Page 9: Mod lua

<< request_rec >>

Page 10: Mod lua

request_rec

• 関数の引数として渡される• modules/lua/lua_request.c@600

ap_lua_load_request_lmodule• apache の request_rec ラッパ +

ユーティリティ • is_https とかドキュメントにない変数も– 値は正しくないけど

• parse_body メソッドは存在しない

Page 11: Mod lua

[properties]

• document_root • hostname• method• protocol• content_type• args • is_https

etc…undocumented!

= query string

Page 12: Mod lua

headers_in / headers_out

• HTTP ヘッダ• ドキュメントには table 型とあるけど嘘• 実際には userdata 型

• ua = r.headers_in['User-Agent']• r.headers_out['X-lua'] = 'yes‘

• 列挙する方法がワカラン。。。

Page 13: Mod lua

puts/write method

• r:puts(string [,string…])• r:write(string)

• write の 2 つめ以降の引数は無視される• string 以外は許容しないので、 tostring

使うと便利• 例 : r:puts(tostring(r.user))

Page 14: Mod lua

add_output_filter method

• ドキュメントにはr:addoutputfilter(name|function)と書いてあるが嘘

• しかも、 string しか受け付けないっぽい

• ap_add_output_filter を呼び出してる• 別で定義された output filter を利用す

る?

Page 15: Mod lua

<< directives >>

Page 16: Mod lua

LuaRoot

• mod_lua 関連ディレクティブで指定する lua スクリプトのベースディレクトリを指定

• 相対パスで指定した場合の基準パスとなる

Page 17: Mod lua

LuaPackagePath

• Lua モジュール ( 主に .lua) へのパスを追加

• 複数指定可能• lua 内の package.path に相当

• 例 : LuaPackagePath /usr/local/share/lua/5.1/?.lua

Page 18: Mod lua

LuaPackageCPath

• Lua C モジュール ( 主に .so) へのパスを追加

• 複数指定可能• lua 内の package.cpath に相当

• 例 : LuaPackageCPath /usr/local/lib/lib?-lua.soLuaPackageCPath /usr/local/lib/lua/5.1/?.so

Page 19: Mod lua

LuaScope

• Lua interpreter のライフサイクルを指定

• once, request, conn, server or thread–mpm event だと server が指定できなかっ

• once 以外にすると、変数が ( 中途半端に ) 永続化

undocumented!

Page 20: Mod lua

LuaInherit

• LuaHook* ディレクティブの継承をするか

• また、外側と内側の設定どちらを優先するか (?)– none (default)– parent-first– parent-last

Page 21: Mod lua

LuaCodeCache

• Lua のインメモリコードキャッシュの設定– stat : 都度 mtime を確認– forever : 一度キャッシュしたらそのまま– never : キャッシュしない

• マニュアルにあるのに、使えない。• それどころかコードにも存在しない

Page 22: Mod lua

LuaMapHandler

• Lua スクリプト専用の rewrite みたいなもの

• uri と Lua スクリプト ( とその中の関数 ) を 紐付けることができる

• という説明

• マニュアルにあるのに、使えない。• それどころかコードにも存在しない

Page 23: Mod lua

LuaHook*

• 指定の仕方は全てLuaHook* script function

([early|late])• Lua スクリプトが読み込まれるのは実行

時– apache 起動時にファイル / 関数が無くても

怒られない– 今のところはね

Page 24: Mod lua

LuaHookTranslateName

• mod_rename の代替として– apache と分離してテストできる!

• <Directory> 内では使えなかった

• r.filename を指定して apache2.OK を返せばよい

• apache2.DECLINE を返すと保留 ( 他モジュールへ )

• ステータスコードを返すのもあり

Page 25: Mod lua

LuaHookMapToStorage LuaHookAccessChecker LuaHookFixups LuaQuickHandler

• 常に呼ばれた• QuickHandler -> TranslateName ->

MapToStorage -> AccessChecker-> Fixup• Qucik は Hook ではないようだが……

Page 26: Mod lua

LuaHookCheckUserID LuaHookTypeChecker LuaHookAuthChecker LuaHookInsertFilter

• どうやったら呼ばれるのかわからない

Page 27: Mod lua

LuaHookInsertFilter

• Syntax error• not yet implemented

Page 28: Mod lua

<< Conclusion >>

• まだ experimental • ドキュメントを信じてはいけない• apache の hook について知っていると

良さそう• lua 面白い

Page 29: Mod lua

end

Page 30: Mod lua

<< fluent-logger-lua >>

ちょーてきとーなおまけ

Page 31: Mod lua

fluent/logger.lualocal os = require 'os'local msgpack = require 'msgpack'local socket = require 'socket'module('fluent.logger')

local fluent = nil

function connect(host, port) fluent = socket.connect(host or '127.0.0.1', port or 24224)end

function post(tag, data) local p = msgpack.Packer() local msg = p:pack({tag, os.time(), data})

fluent:send(msg)end

function close() fluent:close()end

Page 32: Mod lua

caller

function handle(r) local logger = require 'fluent.logger' logger.connect() logger.post('test.test', {message='data'})

r.content_type = 'text/plain'; r:puts('ok')end