无法使用 mod_lua 从 PostgreSQL 获取数据
Unable to get data from PostgreSQL using mod_lua
这是我的设置:
OS: Linux Ubuntu 14.04 64 位
数据库:Postgres 9.4(从官方 Postgres 存储库安装)
Apache:2.4.7 mod_lua 从 Apache 2.4.20 中的源代码手动编译并安装
数据库初始化脚本如下:
CREATE TABLE users (
id SERIAL PRIMARY KEY,
client VARCHAR(20) NOT NULL UNIQUE,
secret VARCHAR(20) NOT NULL
);
INSERT INTO users(client, secret) VALUES('john' , 'john' );
INSERT INTO users(client, secret) VALUES('apple', 'orange');
INSERT INTO users(client, secret) VALUES('kiwi' , 'pear' );
INSERT INTO users(client, secret) VALUES('peach', 'berry' );
Apache 已启用 mod_dbd,配置如下:
<IfModule dbd_module>
DBDriver pgsql
DBDPersist on
DBDMax 20
DBDParams "host='localhost' port='5432' dbname='demousers' user='postgres' password='postgres'"
DBDPrepareSQL 'SELECT u.secret FROM users u WHERE u.client=%s' client_secret
</IfModule>
还有mod_lua是这样配置的:
<IfModule lua_module>
LuaRoot /vagrant/luatest
LuaScope thread
LuaCodeCache stat
LuaHookAccessChecker /vagrant/luatest/cookie_handler.lua handler early
LuaHookAccessChecker /vagrant/luatest/handler.lua handler late
</IfModule>
这是我尝试在 handler.lua 中执行但失败的示例代码:
require "string"
require "apache2"
local inspect = require "inspect"
function handler(r)
local db, err = r:dbacquire()
if not db then
r:debug("[500] DB Error: " .. err)
return 500
end
r:debug("Acquired database")
local statement, errmsg = db:prepared(r, "client_secret")
if not statement then
r:debug("[500] DB Error: " .. errmsg)
db:close()
return 500
end
r:info("Acquired prepared statement")
local secret
local result, emsg = statement:select("john")
if not emsg then
r:info("Fetch rows")
local rows = result(0, true)
r:debug("Rows " .. inspect(rows))
for k, row in pairs(rows) do
r:info("Pass " .. k .. inspect(row))
if row[1] then
secret = string.format("%s", row[1])
end
end
else
r:debug( "Error : " .. emsg)
end
db:close()
return 403
end
查看 postgres sql 日志,我发现查询已正确执行并传递了参数。问题是我得到的记录没有值,只是 lua table 中的零占位符 - 行是这样的
{ {} }
那么,这是错误还是我的错误?
不幸的是这是一个错误。详情见:
这是解决问题的方法
# Install Apache 2.4.10 from backports repo that has working mod_lua
sudo apt-get install -y -t trusty-backports apache2 apache2-dev apache2-utils
sudo apt-get install -y libaprutil1-dbd-pgsql
# Install lua dependencies
sudo apt-get build-dep -y lua5.1
sudo apt-get install -y lua5.1
sudo apt-get install -y liblua5.1-0-dev
# Get the source code
APACHEVER='2.4.10'
cd /tmp/
apt-get source -y apache2="$APACHEVER"
mv "apache2-$APACHEVER/modules/lua/lua_dbd.c" "apache2-$APACHEVER/modules/lua/lua_dbd.c_original"
# Applying the patch for https://bz.apache.org/bugzilla/show_bug.cgi?id=56379
# without it dbd + lua + postgres do not work - you need to previously prepare the patched c file
cp -u /vagrant/lua_dbd.c "apache2-$APACHEVER/modules/lua/"
cd "apache2-$APACHEVER/modules/lua"
# Build and install patched lua module
sudo apxs -I/usr/include/lua5.1 -cia mod_lua.c lua_*.c -lm -llua5.1
sudo service apache2 restart
这是我的设置:
OS: Linux Ubuntu 14.04 64 位
数据库:Postgres 9.4(从官方 Postgres 存储库安装)
Apache:2.4.7 mod_lua 从 Apache 2.4.20 中的源代码手动编译并安装
数据库初始化脚本如下:
CREATE TABLE users (
id SERIAL PRIMARY KEY,
client VARCHAR(20) NOT NULL UNIQUE,
secret VARCHAR(20) NOT NULL
);
INSERT INTO users(client, secret) VALUES('john' , 'john' );
INSERT INTO users(client, secret) VALUES('apple', 'orange');
INSERT INTO users(client, secret) VALUES('kiwi' , 'pear' );
INSERT INTO users(client, secret) VALUES('peach', 'berry' );
Apache 已启用 mod_dbd,配置如下:
<IfModule dbd_module>
DBDriver pgsql
DBDPersist on
DBDMax 20
DBDParams "host='localhost' port='5432' dbname='demousers' user='postgres' password='postgres'"
DBDPrepareSQL 'SELECT u.secret FROM users u WHERE u.client=%s' client_secret
</IfModule>
还有mod_lua是这样配置的:
<IfModule lua_module>
LuaRoot /vagrant/luatest
LuaScope thread
LuaCodeCache stat
LuaHookAccessChecker /vagrant/luatest/cookie_handler.lua handler early
LuaHookAccessChecker /vagrant/luatest/handler.lua handler late
</IfModule>
这是我尝试在 handler.lua 中执行但失败的示例代码:
require "string"
require "apache2"
local inspect = require "inspect"
function handler(r)
local db, err = r:dbacquire()
if not db then
r:debug("[500] DB Error: " .. err)
return 500
end
r:debug("Acquired database")
local statement, errmsg = db:prepared(r, "client_secret")
if not statement then
r:debug("[500] DB Error: " .. errmsg)
db:close()
return 500
end
r:info("Acquired prepared statement")
local secret
local result, emsg = statement:select("john")
if not emsg then
r:info("Fetch rows")
local rows = result(0, true)
r:debug("Rows " .. inspect(rows))
for k, row in pairs(rows) do
r:info("Pass " .. k .. inspect(row))
if row[1] then
secret = string.format("%s", row[1])
end
end
else
r:debug( "Error : " .. emsg)
end
db:close()
return 403
end
查看 postgres sql 日志,我发现查询已正确执行并传递了参数。问题是我得到的记录没有值,只是 lua table 中的零占位符 - 行是这样的
{ {} }
那么,这是错误还是我的错误?
不幸的是这是一个错误。详情见:
这是解决问题的方法
# Install Apache 2.4.10 from backports repo that has working mod_lua
sudo apt-get install -y -t trusty-backports apache2 apache2-dev apache2-utils
sudo apt-get install -y libaprutil1-dbd-pgsql
# Install lua dependencies
sudo apt-get build-dep -y lua5.1
sudo apt-get install -y lua5.1
sudo apt-get install -y liblua5.1-0-dev
# Get the source code
APACHEVER='2.4.10'
cd /tmp/
apt-get source -y apache2="$APACHEVER"
mv "apache2-$APACHEVER/modules/lua/lua_dbd.c" "apache2-$APACHEVER/modules/lua/lua_dbd.c_original"
# Applying the patch for https://bz.apache.org/bugzilla/show_bug.cgi?id=56379
# without it dbd + lua + postgres do not work - you need to previously prepare the patched c file
cp -u /vagrant/lua_dbd.c "apache2-$APACHEVER/modules/lua/"
cd "apache2-$APACHEVER/modules/lua"
# Build and install patched lua module
sudo apxs -I/usr/include/lua5.1 -cia mod_lua.c lua_*.c -lm -llua5.1
sudo service apache2 restart