diff --git a/src/main/actions_lua.c b/src/main/actions_lua.c index bd0c061..9254d03 100644 --- a/src/main/actions_lua.c +++ b/src/main/actions_lua.c @@ -88,6 +88,19 @@ static liHandlerResult lua_action_func(liVRequest *vr, gpointer param, gpointer lua_pop(L, 1); res = LI_HANDLER_ERROR; } else { + if (!lua_isnil(L, -1)) { + int rc = lua_tointeger(L, -1); + switch (rc) { + case LI_HANDLER_GO_ON: + case LI_HANDLER_COMEBACK: + case LI_HANDLER_WAIT_FOR_EVENT: + case LI_HANDLER_ERROR: + res = rc; + break; + default: + res = LI_HANDLER_ERROR; + } + } lua_pop(L, 1); } lua_remove(L, errfunc); diff --git a/src/main/chunk_lua.c b/src/main/chunk_lua.c index 0ee9a74..1cef7e1 100644 --- a/src/main/chunk_lua.c +++ b/src/main/chunk_lua.c @@ -4,6 +4,8 @@ #include #include +#include + #define LUA_CHUNK "liChunk*" #define LUA_CHUNKQUEUE "liChunkQueue*" @@ -11,6 +13,101 @@ static void init_chunk_mt(lua_State *L) { /* TODO */ } +typedef int (*lua_ChunkQueue_Attrib)(liChunkQueue *cq, lua_State *L); + +static int lua_chunkqueue_attr_read_is_closed(liChunkQueue *cq, lua_State *L) { + lua_pushboolean(L, cq->is_closed); + return 1; +} + +static int lua_chunkqueue_attr_write_is_closed(liChunkQueue *cq, lua_State *L) { + cq->is_closed = lua_toboolean(L, 3); + return 0; +} + +#define AR(m) { #m, lua_chunkqueue_attr_read_##m, NULL } +#define AW(m) { #m, NULL, lua_chunkqueue_attr_write_##m } +#define ARW(m) { #m, lua_chunkqueue_attr_read_##m, lua_chunkqueue_attr_write_##m } + +static const struct { + const char* key; + lua_ChunkQueue_Attrib read_attr, write_attr; +} chunkqueue_attribs[] = { + ARW(is_closed), + + { NULL, NULL, NULL } +}; + +static int lua_chunkqueue_index(lua_State *L) { + liChunkQueue *cq; + const char *key; + int i; + + if (lua_gettop(L) != 2) { + lua_pushstring(L, "incorrect number of arguments"); + lua_error(L); + } + + if (li_lua_metatable_index(L)) return 1; + + cq = lua_get_chunkqueue(L, 1); + if (!cq) return 0; + + if (lua_isnumber(L, 2)) return 0; + if (!lua_isstring(L, 2)) return 0; + + key = lua_tostring(L, 2); + for (i = 0; chunkqueue_attribs[i].key ; i++) { + if (0 == strcmp(key, chunkqueue_attribs[i].key)) { + if (chunkqueue_attribs[i].read_attr) + return chunkqueue_attribs[i].read_attr(cq, L); + break; + } + } + + lua_pushstring(L, "cannot read attribute "); + lua_pushstring(L, key); + lua_pushstring(L, " in chunkqueue"); + lua_concat(L, 3); + lua_error(L); + + return 0; +} + +static int lua_chunkqueue_newindex(lua_State *L) { + liChunkQueue *cq; + const char *key; + int i; + + if (lua_gettop(L) != 3) { + lua_pushstring(L, "incorrect number of arguments"); + lua_error(L); + } + + cq = lua_get_chunkqueue(L, 1); + if (!cq) return 0; + + if (lua_isnumber(L, 2)) return 0; + if (!lua_isstring(L, 2)) return 0; + + key = lua_tostring(L, 2); + for (i = 0; chunkqueue_attribs[i].key ; i++) { + if (0 == strcmp(key, chunkqueue_attribs[i].key)) { + if (chunkqueue_attribs[i].write_attr) + return chunkqueue_attribs[i].write_attr(cq, L); + break; + } + } + + lua_pushstring(L, "cannot write attribute "); + lua_pushstring(L, key); + lua_pushstring(L, "in chunkqueue"); + lua_concat(L, 3); + lua_error(L); + + return 0; +} + static int lua_chunkqueue_add(lua_State *L) { liChunkQueue *cq; const char *s; @@ -22,16 +119,54 @@ static int lua_chunkqueue_add(lua_State *L) { if (lua_isstring(L, 2)) { s = lua_tolstring(L, 2, &len); li_chunkqueue_append_mem(cq, s, len); + } else if (lua_istable(L, 2)) { + const char *filename = NULL; + GString *g_filename = NULL; + + lua_getfield(L, -1, "filename"); + if (!lua_isnil(L, -1)) { + filename = lua_tostring(L, -1); + if (filename) g_filename = g_string_new(filename); + } + lua_pop(L, 1); + + if (g_filename) { + struct stat st; + + if (-1 != stat(g_filename->str, &st) && S_ISREG(st.st_mode)) { + li_chunkqueue_append_file(cq, g_filename, 0, st.st_size); + } + } else { + goto fail; + } } else { - lua_pushliteral(L, "Wrong type for chunkqueue add"); - lua_error(L); + goto fail; } + return 0; + +fail: + lua_pushliteral(L, "Wrong type for chunkqueue add"); + lua_error(L); + + return -1; +} + +static int lua_chunkqueue_reset(lua_State *L) { + liChunkQueue *cq; + + cq = lua_get_chunkqueue(L, 1); + li_chunkqueue_reset(cq); + return 0; } static const luaL_Reg chunkqueue_mt[] = { + { "__index", lua_chunkqueue_index }, + { "__newindex", lua_chunkqueue_newindex }, + { "add", lua_chunkqueue_add }, + { "reset", lua_chunkqueue_reset }, { NULL, NULL } }; diff --git a/src/main/core_lua.c b/src/main/core_lua.c index d3c0c39..18acb64 100644 --- a/src/main/core_lua.c +++ b/src/main/core_lua.c @@ -126,6 +126,16 @@ static int li_lua_debug(lua_State *L) { return 0; } +static void lua_push_constants(lua_State *L, int ndx) { + lua_pushinteger(L, LI_HANDLER_GO_ON); + lua_setfield(L, ndx, "HANDLER_GO_ON"); + lua_pushinteger(L, LI_HANDLER_COMEBACK); + lua_setfield(L, ndx, "HANDLER_COMEBACK"); + lua_pushinteger(L, LI_HANDLER_WAIT_FOR_EVENT); + lua_setfield(L, ndx, "HANDLER_WAIT_FOR_EVENT"); + lua_pushinteger(L, LI_HANDLER_ERROR); + lua_setfield(L, ndx, "HANDLER_ERROR"); +} void li_lua_init(liServer *srv, lua_State *L) { lua_init_chunk_mt(L); @@ -156,6 +166,8 @@ void li_lua_init(liServer *srv, lua_State *L) { lua_pushcclosure(L, li_lua_debug, 1); lua_setfield(L, LUA_GLOBALSINDEX, "debug"); + lua_push_constants(L, LUA_GLOBALSINDEX); + li_lua_store_globals(L); } diff --git a/src/main/response_lua.c b/src/main/response_lua.c index 4433724..67d0aab 100644 --- a/src/main/response_lua.c +++ b/src/main/response_lua.c @@ -19,7 +19,7 @@ static int lua_response_attr_read_status(liResponse *resp, lua_State *L) { } static int lua_response_attr_write_status(liResponse *resp, lua_State *L) { - int status = luaL_checkinteger(L, 3); + int status = luaL_checkint(L, 3); if (status < 200 || status > 999) { lua_pushliteral(L, "Invalid http response status: "); lua_pushinteger(L, status); diff --git a/src/main/virtualrequest_lua.c b/src/main/virtualrequest_lua.c index 5d3da76..3ababa9 100644 --- a/src/main/virtualrequest_lua.c +++ b/src/main/virtualrequest_lua.c @@ -43,6 +43,17 @@ static int lua_vrequest_attr_read_phys(liVRequest *vr, lua_State *L) { return 1; } +static int lua_vrequest_attr_read_is_handled(liVRequest *vr, lua_State *L) { + lua_pushboolean(L, li_vrequest_is_handled(vr)); + return 1; +} + +static int lua_vrequest_attr_read_has_response(liVRequest *vr, lua_State *L) { + lua_pushboolean(L, vr->state >= LI_VRS_HANDLE_RESPONSE_HEADERS); + return 1; +} + + #define AR(m) { #m, lua_vrequest_attr_read_##m, NULL } #define AW(m) { #m, NULL, lua_vrequest_attr_write_##m } #define ARW(m) { #m, lua_vrequest_attr_read_##m, lua_vrequest_attr_write_##m } @@ -58,6 +69,8 @@ static const struct { AR(req), AR(resp), AR(phys), + AR(is_handled), + AR(has_response), { NULL, NULL, NULL } }; @@ -197,15 +210,6 @@ static int lua_vrequest_handle_direct(lua_State *L) { return 1; } -static int lua_vrequest_is_handled(lua_State *L) { - liVRequest *vr; - vr = lua_get_vrequest(L, 1); - - lua_pushboolean(L, li_vrequest_is_handled(vr)); - - return 1; -} - static const luaL_Reg vrequest_mt[] = { { "__index", lua_vrequest_index }, { "__newindex", lua_vrequest_newindex }, @@ -216,7 +220,6 @@ static const luaL_Reg vrequest_mt[] = { { "debug", lua_vrequest_debug }, { "handle_direct", lua_vrequest_handle_direct }, - { "is_handled", lua_vrequest_is_handled }, { NULL, NULL } };