2
0
Fork 0
lighttpd2/src/main/response_lua.c

161 lines
3.5 KiB
C

#include <lighttpd/core_lua.h>
#include <lualib.h>
#include <lauxlib.h>
#define LUA_RESPONSE "liResponse*"
typedef int (*lua_Response_Attrib)(liResponse *resp, lua_State *L);
static int lua_response_attr_read_headers(liResponse *resp, lua_State *L) {
li_lua_push_http_headers(L, resp->headers);
return 1;
}
static int lua_response_attr_read_status(liResponse *resp, lua_State *L) {
lua_pushinteger(L, resp->http_status);
return 1;
}
static int lua_response_attr_write_status(liResponse *resp, lua_State *L) {
int status = luaL_checkint(L, 3);
if (status < 200 || status > 999) {
lua_pushliteral(L, "Invalid http response status: ");
lua_pushinteger(L, status);
lua_concat(L, 2);
lua_error(L);
}
resp->http_status = status;
return 0;
}
#define AR(m) { #m, lua_response_attr_read_##m, NULL }
#define AW(m) { #m, NULL, lua_response_attr_write_##m }
#define ARW(m) { #m, lua_response_attr_read_##m, lua_response_attr_write_##m }
static const struct {
const char* key;
lua_Response_Attrib read_attr, write_attr;
} response_attribs[] = {
AR(headers),
ARW(status),
{ NULL, NULL, NULL }
};
static int lua_response_index(lua_State *L) {
liResponse *resp;
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;
resp = li_lua_get_response(L, 1);
if (!resp) return 0;
if (lua_isnumber(L, 2)) return 0;
if (!lua_isstring(L, 2)) return 0;
key = lua_tostring(L, 2);
for (i = 0; response_attribs[i].key ; i++) {
if (0 == strcmp(key, response_attribs[i].key)) {
if (response_attribs[i].read_attr)
return response_attribs[i].read_attr(resp, L);
break;
}
}
lua_pushstring(L, "cannot read attribute ");
lua_pushstring(L, key);
lua_pushstring(L, " in response");
lua_concat(L, 3);
lua_error(L);
return 0;
}
static int lua_response_newindex(lua_State *L) {
liResponse *resp;
const char *key;
int i;
if (lua_gettop(L) != 3) {
lua_pushstring(L, "incorrect number of arguments");
lua_error(L);
}
resp = li_lua_get_response(L, 1);
if (!resp) return 0;
if (lua_isnumber(L, 2)) return 0;
if (!lua_isstring(L, 2)) return 0;
key = lua_tostring(L, 2);
for (i = 0; response_attribs[i].key ; i++) {
if (0 == strcmp(key, response_attribs[i].key)) {
if (response_attribs[i].write_attr)
return response_attribs[i].write_attr(resp, L);
break;
}
}
lua_pushstring(L, "cannot write attribute ");
lua_pushstring(L, key);
lua_pushstring(L, "in response");
lua_concat(L, 3);
lua_error(L);
return 0;
}
static const luaL_Reg response_mt[] = {
{ "__index", lua_response_index },
{ "__newindex", lua_response_newindex },
{ NULL, NULL }
};
static void init_response_mt(lua_State *L) {
luaL_register(L, NULL, response_mt);
}
void li_lua_init_response_mt(lua_State *L) {
if (luaL_newmetatable(L, LUA_RESPONSE)) {
init_response_mt(L);
}
lua_pop(L, 1);
}
liResponse* li_lua_get_response(lua_State *L, int ndx) {
if (!lua_isuserdata(L, ndx)) return NULL;
if (!lua_getmetatable(L, ndx)) return NULL;
luaL_getmetatable(L, LUA_RESPONSE);
if (lua_isnil(L, -1) || lua_isnil(L, -2) || !lua_equal(L, -1, -2)) {
lua_pop(L, 2);
return NULL;
}
lua_pop(L, 2);
return *(liResponse**) lua_touserdata(L, ndx);
}
int li_lua_push_response(lua_State *L, liResponse *resp) {
liResponse **presp;
presp = (liResponse**) lua_newuserdata(L, sizeof(liResponse*));
*presp = resp;
if (luaL_newmetatable(L, LUA_RESPONSE)) {
init_response_mt(L);
}
lua_setmetatable(L, -2);
return 1;
}