Lua binding: Improve performance

Signed-off-by: Jianhui Zhao <jianhuizhao329@gmail.com>
main
Jianhui Zhao 2018-07-21 16:57:45 +08:00
parent ab2e23977a
commit 52f35b9109
2 changed files with 191 additions and 85 deletions

View File

@ -41,18 +41,28 @@ local srv = uh.new(port)
uh.log(uh.LOG_INFO, "Listen on:" .. port)
srv:set_error404_cb(function(cl, opt)
srv:set_error404_cb(function(cl, path)
uh.send_header(cl, 200, "OK", -1)
uh.append_header(cl, "Myheader", "Hello")
uh.header_end(cl)
uh.chunk_send(cl, "<h1>Libuhttpd-Lua: Not found</h1>")
uh.chunk_send(cl, string.format("<h1>Libuhttpd-Lua: '%s' Not found</h1>", path))
uh.request_done(cl)
end)
srv:set_request_cb(function(cl, opt)
if opt.path ~= "/hello" then
local http_methods = {
[uh.HTTP_METHOD_GET] = "GET",
[uh.HTTP_METHOD_POST] = "POST",
[uh.HTTP_METHOD_HEAD] = "HEAD"
}
local http_version = {
[uh.HTTP_VER_09] = "HTTP/0.9",
[uh.HTTP_VER_10] = "HTTP/1.0",
[uh.HTTP_VER_11] = "HTTP/1.1"
}
srv:set_request_cb(function(cl, path)
if path ~= "/hello" then
return uh.REQUEST_CONTINUE
end
@ -61,19 +71,32 @@ srv:set_request_cb(function(cl, opt)
uh.header_end(cl)
uh.chunk_send(cl, string.format("<h1>Hello Libuhttpd %s</h1>", uh.VERSION))
uh.chunk_send(cl, string.format("<h1>REMOTE_ADDR: %s</h1>", opt.peer_addr))
uh.chunk_send(cl, string.format("<h1>METHOD: %s</h1>", opt.method))
uh.chunk_send(cl, string.format("<h1>HTTP Version: %s</h1>", opt.version))
uh.chunk_send(cl, string.format("<h1>PATH: %s</h1>", opt.path))
uh.chunk_send(cl, string.format("<h1>URL: %s</h1>", opt.url))
uh.chunk_send(cl, string.format("<h1>QUERY: %s</h1>", opt.query and opt.query or ""))
uh.chunk_send(cl, string.format("<h1>Body: %s</h1>", opt.body and opt.body or ""))
uh.chunk_send(cl, string.format("<h1>REMOTE_ADDR: %s</h1>", uh.get_remote_addr(cl)))
uh.chunk_send(cl, string.format("<h1>METHOD: %s</h1>", http_methods[uh.get_http_method(cl)]))
uh.chunk_send(cl, string.format("<h1>HTTP Version: %s</h1>", http_version[uh.get_http_version(cl)]))
uh.chunk_send(cl, string.format("<h1>URL: %s</h1>", uh.get_url(cl)))
uh.chunk_send(cl, string.format("<h1>QUERY: %s</h1>", uh.get_query(cl) or ""))
uh.chunk_send(cl, string.format("<h1>Body: %s</h1>", uh.get_body(cl) or ""))
for k, v in pairs(opt.vars) do
-- Get a http var
local var_x = uh.get_var(cl, "x")
uh.chunk_send(cl, string.format("<h1>Var x: %s</h1>", var_x or ""))
-- Get a http header
local user_agent = uh.get_header(cl, "user-agent")
uh.chunk_send(cl, string.format("<h1>User-Agent: %s</h1>", user_agent))
uh.chunk_send(cl, "<hr />")
-- Get all http vars
local vars = uh.get_var(cl)
for k, v in pairs(vars) do
uh.chunk_send(cl, string.format("<h1>%s: %s</h1>", k, v))
end
for k, v in pairs(opt.headers) do
uh.chunk_send(cl, "<hr />")
-- Get all http headers
local headers = uh.get_header(cl)
for k, v in pairs(headers) do
uh.chunk_send(cl, string.format("<h1>%s: %s</h1>", k, v))
end

View File

@ -45,85 +45,18 @@ static void *uh_create_userdata(lua_State *L, size_t size, const luaL_Reg *reg,
return obj;
}
static inline void add_all_var(struct uh_client *cl, lua_State *L)
{
const char *name, *value;
lua_newtable(L);
kvlist_for_each(&cl->request.var, name, value) {
lua_pushstring(L, value);
lua_setfield(L, -2, name);
}
lua_setfield(L, -2, "vars");
}
static inline void add_all_header(struct uh_client *cl, lua_State *L)
{
const char *name, *value;
lua_newtable(L);
kvlist_for_each(&cl->request.header, name, value) {
lua_pushstring(L, value);
lua_setfield(L, -2, name);
}
lua_setfield(L, -2, "headers");
}
static inline void add_body(struct uh_client *cl, lua_State *L)
{
int len;
const char *body;
body = cl->get_body(cl, &len);
lua_pushlstring(L, body, len);
lua_setfield(L, -2, "body");
}
static void lua_prepare_action_argument(struct uh_client *cl, lua_State *L)
{
lua_pushlightuserdata(L, cl);
lua_newtable(L);
lua_pushstring(L, cl->get_peer_addr(cl));
lua_setfield(L, -2, "peer_addr");
lua_pushstring(L, cl->get_method(cl));
lua_setfield(L, -2, "method");
lua_pushstring(L, cl->get_version(cl));
lua_setfield(L, -2, "version");
lua_pushstring(L, cl->get_path(cl));
lua_setfield(L, -2, "path");
lua_pushstring(L, cl->get_url(cl));
lua_setfield(L, -2, "url");
lua_pushstring(L, cl->get_query(cl));
lua_setfield(L, -2, "query");
add_body(cl, L);
add_all_var(cl, L);
add_all_header(cl, L);
}
static int lua_uh_on_request(struct uh_client *cl)
{
struct lua_uh_server *lsrv = container_of(cl->srv, struct lua_uh_server, srv);
const char *path = cl->get_path(cl);
lua_State *L = cl->srv->L;
lua_getglobal(L, "__uh_request_cb");
lua_rawgeti(L, -1, lsrv->request_cb_ref);
lua_remove(L, -2);
lua_prepare_action_argument(cl, L);
lua_pushlightuserdata(L, cl);
lua_pushstring(L, path);
lua_call(L, 2, 1);
@ -165,13 +98,15 @@ static int lua_uh_set_request_cb(lua_State *L)
static void http_callback_404(struct uh_client *cl)
{
struct lua_uh_server *lsrv = container_of(cl->srv, struct lua_uh_server, srv);
const char *path = cl->get_path(cl);
lua_State *L = cl->srv->L;
lua_getglobal(L, "__uh_error404_cb");
lua_rawgeti(L, -1, lsrv->error404_cb_ref);
lua_remove(L, -2);
lua_prepare_action_argument(cl, L);
lua_pushlightuserdata(L, cl);
lua_pushstring(L, path);
lua_call(L, 2, 0);
}
@ -339,6 +274,128 @@ static int lua_uh_request_done(lua_State *L)
return 0;
}
static int lua_uh_get_http_method(lua_State *L)
{
struct uh_client *cl = lua_touserdata(L, 1);
lua_pushinteger(L, cl->request.method);
return 1;
}
static int lua_uh_get_http_version(lua_State *L)
{
struct uh_client *cl = lua_touserdata(L, 1);
lua_pushinteger(L, cl->request.version);
return 1;
}
static int lua_uh_get_remote_addr(lua_State *L)
{
struct uh_client *cl = lua_touserdata(L, 1);
const char *addr = cl->get_peer_addr(cl);
if (addr)
lua_pushstring(L, addr);
else
lua_pushnil(L);
return 1;
}
static int lua_uh_get_header(lua_State *L)
{
struct uh_client *cl = lua_touserdata(L, 1);
const char *name = lua_tostring(L, 2);
const char *value;
if (name) {
value = cl->get_header(cl, name);
if (value)
lua_pushstring(L, value);
else
lua_pushnil(L);
return 1;
}
lua_newtable(L);
kvlist_for_each(&cl->request.header, name, value) {
lua_pushstring(L, value);
lua_setfield(L, -2, name);
}
return 1;
}
static int lua_uh_get_var(lua_State *L)
{
struct uh_client *cl = lua_touserdata(L, 1);
const char *name = lua_tostring(L, 2);
const char *value;
if (name) {
value = cl->get_var(cl, name);
if (value)
lua_pushstring(L, value);
else
lua_pushnil(L);
return 1;
}
lua_newtable(L);
kvlist_for_each(&cl->request.var, name, value) {
lua_pushstring(L, value);
lua_setfield(L, -2, name);
}
return 1;
}
static int lua_uh_get_query(lua_State *L)
{
struct uh_client *cl = lua_touserdata(L, 1);
const char *query = cl->get_query(cl);
if (query)
lua_pushstring(L, query);
else
lua_pushnil(L);
return 1;
}
static int lua_uh_get_url(lua_State *L)
{
struct uh_client *cl = lua_touserdata(L, 1);
const char *url = cl->get_url(cl);
if (url)
lua_pushstring(L, url);
else
lua_pushnil(L);
return 1;
}
static int lua_uh_get_body(lua_State *L)
{
struct uh_client *cl = lua_touserdata(L, 1);
const char *body;
int len;
body = cl->get_body(cl, &len);
if (body)
lua_pushlstring(L, body, len);
else
lua_pushnil(L);
return 1;
}
static int lua_uh_log(lua_State *L)
{
int priority = lua_tointeger(L, 1);
@ -368,6 +425,14 @@ static const luaL_Reg uhttpd_fun[] = {
{"send_error", lua_uh_send_error},
{"redirect", lua_uh_redirect},
{"request_done", lua_uh_request_done},
{"get_http_method", lua_uh_get_http_method},
{"get_http_version", lua_uh_get_http_version},
{"get_remote_addr", lua_uh_get_remote_addr},
{"get_header", lua_uh_get_header},
{"get_var", lua_uh_get_var},
{"get_query", lua_uh_get_query},
{"get_url", lua_uh_get_url},
{"get_body", lua_uh_get_body},
{"log", lua_uh_log},
{"set_log_threshold", lua_uh_set_log_threshold},
{NULL, NULL}
@ -409,5 +474,23 @@ int luaopen_uhttpd(lua_State *L)
lua_pushinteger(L, UH_REQUEST_CONTINUE);
lua_setfield(L, -2, "REQUEST_CONTINUE");
lua_pushinteger(L, UH_HTTP_VER_09);
lua_setfield(L, -2, "HTTP_VER_09");
lua_pushinteger(L, UH_HTTP_VER_10);
lua_setfield(L, -2, "HTTP_VER_10");
lua_pushinteger(L, UH_HTTP_VER_11);
lua_setfield(L, -2, "HTTP_VER_11");
lua_pushinteger(L, UH_HTTP_METHOD_GET);
lua_setfield(L, -2, "HTTP_METHOD_GET");
lua_pushinteger(L, UH_HTTP_METHOD_POST);
lua_setfield(L, -2, "HTTP_METHOD_POST");
lua_pushinteger(L, UH_HTTP_METHOD_HEAD);
lua_setfield(L, -2, "HTTP_METHOD_HEAD");
return 1;
}