mirror of
https://github.com/clearlinux/uwsgi.git
synced 2026-10-18 02:12:35 +00:00
preliminary api for language-independent body read another step completed body read language independent implementation ported gevent to the new read/write api ported websockets to the new read/write api removed channels subsystem removed channels subsystem ported lua to the new read/write api fixed post-buffering readline is still broken improved request body readline very difficult test for readline()/read() combo passed other improvements in postbuffering/read/readline ported --http-socket to the new api added X-Forwarded-SSL management removed old api more refactoring ported the RACK plugin to the new api ported psgi plugin to the new api defintely removed clustering simpified ifdel hell simpified ifdef hell removed useless configuration options
689 lines
14 KiB
C
689 lines
14 KiB
C
#include "../../uwsgi.h"
|
|
|
|
#include <lua.h>
|
|
#include <lualib.h>
|
|
#include <lauxlib.h>
|
|
|
|
extern struct uwsgi_server uwsgi;
|
|
|
|
struct uwsgi_lua {
|
|
struct lua_State **L;
|
|
|
|
char *filename;
|
|
} ulua;
|
|
|
|
#define lca(L, n) ulua_check_args(L, __FUNCTION__, n)
|
|
|
|
struct uwsgi_option uwsgi_lua_options[] = {
|
|
|
|
{"lua", required_argument, 0, "load lua wsapi app", uwsgi_opt_set_str, &ulua.filename, 0},
|
|
|
|
{0, 0, 0, 0},
|
|
|
|
};
|
|
|
|
static void ulua_check_args(lua_State *L, const char *func, int n) {
|
|
int args = lua_gettop(L);
|
|
char error[4096];
|
|
if (args != n) {
|
|
if (n == 1) {
|
|
snprintf(error, 4096, "uwsgi.%s takes 1 parameter", func+10);
|
|
}
|
|
else {
|
|
snprintf(error, 4096, "uwsgi.%s takes %d parameters", func+10, n);
|
|
}
|
|
lua_pushstring(L, error);
|
|
lua_error(L);
|
|
}
|
|
}
|
|
|
|
static int uwsgi_api_log(lua_State *L) {
|
|
|
|
const char *logline ;
|
|
|
|
lca(L, 1);
|
|
|
|
if (lua_isstring(L, 1)) {
|
|
logline = lua_tolstring(L, 1, NULL);
|
|
uwsgi_log( "%s\n", logline);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int uwsgi_api_register_rpc(lua_State *L) {
|
|
|
|
uint8_t argc = lua_gettop(L);
|
|
const char *name;
|
|
// a hack for 64bit;
|
|
int func;
|
|
long lfunc;
|
|
|
|
if (argc < 2) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
name = lua_tolstring(L, 1, NULL);
|
|
|
|
lua_pushvalue(L, 2);
|
|
func = luaL_ref(L, LUA_REGISTRYINDEX);
|
|
|
|
uwsgi_log("registered function %d in global table\n", func);
|
|
lfunc = func;
|
|
|
|
if (uwsgi_register_rpc((char *)name, 6, 0, (void *) lfunc)) {
|
|
lua_pushnil(L);
|
|
}
|
|
else {
|
|
lua_pushboolean(L, 1);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
|
|
|
|
static char *encode_lua_table(lua_State *L, int index, uint16_t *size) {
|
|
|
|
char *buf, *ptrbuf;
|
|
char *key;
|
|
char *value;
|
|
size_t keylen;
|
|
size_t vallen;
|
|
|
|
*size = 0;
|
|
|
|
lua_pushnil(L);
|
|
while (lua_next(L, index) != 0) {
|
|
if (lua_isstring(L, -2) && lua_isstring(L, -1)) {
|
|
key = (char *) lua_tolstring(L, -2, &keylen);
|
|
value = (char *) lua_tolstring(L, -1, &vallen);
|
|
if (keylen > 0xffff || vallen > 0xffff) continue;
|
|
*size += (2+keylen+2+vallen);
|
|
}
|
|
lua_pop(L, 1);
|
|
}
|
|
|
|
buf = uwsgi_malloc(*size);
|
|
|
|
ptrbuf = buf;
|
|
lua_pushnil(L);
|
|
while (lua_next(L, index) != 0) {
|
|
if (lua_isstring(L, -2) && lua_isstring(L, -1)) {
|
|
key = (char *) lua_tolstring(L, -2, &keylen);
|
|
value = (char *) lua_tolstring(L, -1, &vallen);
|
|
|
|
if (keylen > 0xffff || vallen > 0xffff) continue;
|
|
|
|
*ptrbuf++ = (uint8_t) (keylen & 0xff);
|
|
*ptrbuf++ = (uint8_t) ((keylen >>8) & 0xff);
|
|
memcpy(ptrbuf, key, keylen); ptrbuf += keylen;
|
|
*ptrbuf++ = (uint8_t) (vallen & 0xff);
|
|
*ptrbuf++ = (uint8_t) ((vallen >>8) & 0xff);
|
|
memcpy(ptrbuf, value, vallen); ptrbuf += vallen;
|
|
}
|
|
lua_pop(L, 1);
|
|
}
|
|
|
|
return buf;
|
|
}
|
|
|
|
static int uwsgi_api_cache_set(lua_State *L) {
|
|
|
|
int args = lua_gettop(L);
|
|
const char *key ;
|
|
const char *value ;
|
|
uint64_t expires = 0;
|
|
size_t vallen;
|
|
|
|
|
|
if (args > 1) {
|
|
|
|
key = lua_tolstring(L, 1, NULL);
|
|
value = lua_tolstring(L, 2, &vallen);
|
|
if (args > 2) {
|
|
expires = lua_tonumber(L, 3);
|
|
}
|
|
|
|
uwsgi_cache_set((char *)key, strlen(key), (char *)value, (uint16_t) vallen, expires, 0);
|
|
|
|
}
|
|
|
|
lua_pushnil(L);
|
|
return 1;
|
|
|
|
}
|
|
|
|
static int uwsgi_api_register_signal(lua_State *L) {
|
|
|
|
int args = lua_gettop(L);
|
|
uint8_t sig;
|
|
long lhandler;
|
|
const char *who;
|
|
|
|
if (args >= 3) {
|
|
|
|
sig = lua_tonumber(L, 1);
|
|
who = lua_tostring(L, 2);
|
|
lua_pushvalue(L, 3);
|
|
lhandler = luaL_ref(L, LUA_REGISTRYINDEX);
|
|
|
|
uwsgi_register_signal(sig, (char *)who, (void *) lhandler, 6);
|
|
}
|
|
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
|
|
static int uwsgi_api_cache_get(lua_State *L) {
|
|
|
|
char *value ;
|
|
uint64_t valsize;
|
|
const char *key ;
|
|
|
|
lca(L, 1);
|
|
|
|
if (lua_isstring(L, 1)) {
|
|
|
|
key = lua_tolstring(L, 1, NULL);
|
|
value = uwsgi_cache_get((char *)key, strlen(key), &valsize);
|
|
|
|
if (value) {
|
|
lua_pushlstring(L, value, valsize);
|
|
return 1;
|
|
}
|
|
|
|
}
|
|
|
|
lua_pushnil(L);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
static int uwsgi_api_send_message(lua_State *L) {
|
|
|
|
int args = lua_gettop(L);
|
|
const char *host;
|
|
int uwsgi_fd;
|
|
uint8_t modifier1, modifier2;
|
|
char *pkt = NULL;
|
|
uint16_t pktsize = 0 ;
|
|
char buf[4096];
|
|
int rlen;
|
|
int items = 0;
|
|
int input_fd = -1, timeout = -1, input_size = 0;
|
|
|
|
// is this an fd ?
|
|
if (lua_isnumber(L, 1)) {
|
|
args = 1;
|
|
}
|
|
else if (lua_isstring(L, 1)) {
|
|
host = lua_tolstring(L, 1, NULL);
|
|
uwsgi_fd = uwsgi_connect((char *)host, timeout, 0);
|
|
modifier1 = lua_tonumber(L, 2);
|
|
modifier2 = lua_tonumber(L, 3);
|
|
if (args > 4) {
|
|
timeout = lua_tonumber(L, 5);
|
|
if (args == 7) {
|
|
input_fd = lua_tonumber(L, 6);
|
|
input_size = lua_tonumber(L, 7);
|
|
}
|
|
}
|
|
if (lua_istable(L,4)) {
|
|
// passed a table
|
|
pkt = encode_lua_table(L, 4, &pktsize);
|
|
}
|
|
if (uwsgi_send_message(uwsgi_fd, modifier1, modifier2, pkt, pktsize, input_fd, input_size, timeout) == -1) {
|
|
free(pkt);
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
free(pkt);
|
|
|
|
for(;;) {
|
|
rlen = uwsgi_waitfd(uwsgi_fd, timeout);
|
|
if (rlen > 0) {
|
|
rlen = read(uwsgi_fd, buf, 4096);
|
|
if (rlen < 0) {
|
|
uwsgi_error("read()");
|
|
break;
|
|
}
|
|
else if (rlen > 0) {
|
|
lua_pushlstring(L, buf, rlen);
|
|
items++;
|
|
}
|
|
else {
|
|
break;
|
|
}
|
|
}
|
|
else if (rlen == 0) {
|
|
uwsgi_log("uwsgi request timed out waiting for response\n");
|
|
break;
|
|
}
|
|
}
|
|
|
|
close(uwsgi_fd);
|
|
|
|
}
|
|
|
|
return items;
|
|
}
|
|
|
|
static int uwsgi_api_cl(lua_State *L) {
|
|
|
|
struct wsgi_request *wsgi_req = current_wsgi_req();
|
|
|
|
lua_pushnumber(L, wsgi_req->post_cl);
|
|
return 1;
|
|
}
|
|
|
|
static int uwsgi_api_req_fd(lua_State *L) {
|
|
|
|
struct wsgi_request *wsgi_req = current_wsgi_req();
|
|
|
|
lua_pushnumber(L, wsgi_req->fd);
|
|
return 1;
|
|
}
|
|
|
|
static int uwsgi_api_lock(lua_State *L) {
|
|
|
|
int lock_num = 0;
|
|
|
|
// the spooler cannot lock resources
|
|
if (uwsgi.i_am_a_spooler) {
|
|
lua_pushstring(L, "The spooler cannot lock/unlock resources");
|
|
lua_error(L);
|
|
}
|
|
|
|
if (lua_gettop(L) > 0) {
|
|
lock_num = lua_isnumber(L, 1) ? lua_tonumber(L, 1) : -1;
|
|
if (lock_num < 0 || lock_num > uwsgi.locks) {
|
|
lua_pushstring(L, "Invalid lock number");
|
|
lua_error(L);
|
|
}
|
|
}
|
|
|
|
uwsgi_lock(uwsgi.user_lock[lock_num]);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
static int uwsgi_api_unlock(lua_State *L) {
|
|
|
|
int lock_num = 0;
|
|
|
|
// the spooler cannot lock resources
|
|
if (uwsgi.i_am_a_spooler) {
|
|
lua_pushstring(L, "The spooler cannot lock/unlock resources");
|
|
lua_error(L);
|
|
}
|
|
|
|
if (lua_gettop(L) > 0) {
|
|
lock_num = lua_isnumber(L, 1) ? lua_tonumber(L, 1) : -1;
|
|
if (lock_num < 0 || lock_num > uwsgi.locks) {
|
|
lua_pushstring(L, "Invalid lock number");
|
|
lua_error(L);
|
|
}
|
|
}
|
|
|
|
uwsgi_unlock(uwsgi.user_lock[lock_num]);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static const luaL_reg uwsgi_api[] = {
|
|
{"log", uwsgi_api_log},
|
|
{"cl", uwsgi_api_cl},
|
|
{"req_fd", uwsgi_api_req_fd},
|
|
{"send_message", uwsgi_api_send_message},
|
|
{"cache_get", uwsgi_api_cache_get},
|
|
{"cache_set", uwsgi_api_cache_set},
|
|
{"register_signal", uwsgi_api_register_signal},
|
|
{"register_rpc", uwsgi_api_register_rpc},
|
|
{"lock", uwsgi_api_lock},
|
|
{"unlock", uwsgi_api_unlock},
|
|
{NULL, NULL}
|
|
};
|
|
|
|
|
|
|
|
static int uwsgi_lua_input(lua_State *L) {
|
|
|
|
struct wsgi_request *wsgi_req = current_wsgi_req();
|
|
ssize_t sum = 0;
|
|
|
|
int n = lua_gettop(L);
|
|
|
|
if (n > 1) {
|
|
sum = lua_tonumber(L, 2);
|
|
}
|
|
|
|
ssize_t rlen = 0;
|
|
|
|
char *buf = uwsgi_request_body_read(wsgi_req, sum, &rlen);
|
|
if (buf) {
|
|
lua_pushlstring(L, buf, rlen);
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int uwsgi_lua_init(){
|
|
|
|
uwsgi_log("Initializing Lua environment... (%d cores)\n", uwsgi.cores);
|
|
|
|
ulua.L = uwsgi_malloc( sizeof(lua_State*) * uwsgi.cores );
|
|
|
|
// ok the lua engine is ready
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
void uwsgi_lua_app() {
|
|
int i;
|
|
|
|
if (ulua.filename) {
|
|
for(i=0;i<uwsgi.cores;i++) {
|
|
ulua.L[i] = luaL_newstate();
|
|
luaL_openlibs(ulua.L[i]);
|
|
luaL_register(ulua.L[i], "uwsgi", uwsgi_api);
|
|
if (luaL_loadfile(ulua.L[i], ulua.filename)) {
|
|
uwsgi_log("unable to load file %s: %s\n", ulua.filename, lua_tostring(ulua.L[i], -1));
|
|
exit(1);
|
|
}
|
|
|
|
// use a pcall
|
|
//lua_call(ulua.L[i], 0, 1);
|
|
if (lua_pcall(ulua.L[i], 0, 1, 0) != 0) {
|
|
uwsgi_log("%s\n", lua_tostring(ulua.L[i], -1));
|
|
exit(1);
|
|
}
|
|
|
|
// if the loaded lua app returns as a table, fetch the
|
|
// run function.
|
|
if (lua_istable(ulua.L[i], 2)) {
|
|
lua_pushstring(ulua.L[i], "run" );
|
|
lua_gettable(ulua.L[i], 2);
|
|
lua_replace(ulua.L[i], 2);
|
|
}
|
|
|
|
if (! lua_isfunction(ulua.L[i], 2)) {
|
|
uwsgi_log("Can't find WSAPI entry point (no function, nor a table with function'run').\n");
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
int uwsgi_lua_request(struct wsgi_request *wsgi_req) {
|
|
|
|
int i;
|
|
const char *http, *http2;
|
|
size_t slen, slen2;
|
|
char *ptrbuf;
|
|
lua_State *L = ulua.L[wsgi_req->async_id];
|
|
|
|
if (wsgi_req->async_status == UWSGI_AGAIN) {
|
|
if ((i = lua_pcall(L, 0, 1, 0)) == 0) {
|
|
if (lua_type(L, -1) == LUA_TSTRING) {
|
|
http = lua_tolstring(L, -1, &slen);
|
|
uwsgi_response_write_body_do(wsgi_req, (char *)http, slen);
|
|
}
|
|
lua_pop(L, 1);
|
|
lua_pushvalue(L, -1);
|
|
return UWSGI_AGAIN;
|
|
}
|
|
goto clear;
|
|
}
|
|
|
|
/* Standard WSAPI request */
|
|
if (!wsgi_req->uh->pktsize) {
|
|
uwsgi_log( "Empty lua request. skip.\n");
|
|
return -1;
|
|
}
|
|
|
|
if (uwsgi_parse_vars(wsgi_req)) {
|
|
return -1;
|
|
}
|
|
|
|
// put function in the stack
|
|
//lua_getfield(L, LUA_GLOBALSINDEX, "run");
|
|
lua_pushvalue(L, -1);
|
|
|
|
// put cgi vars in the stack
|
|
|
|
lua_newtable(L);
|
|
lua_pushstring(L, "");
|
|
lua_setfield(L, -2, "CONTENT_TYPE");
|
|
for(i=0;i<wsgi_req->var_cnt;i++) {
|
|
lua_pushlstring(L, (char *)wsgi_req->hvec[i+1].iov_base, wsgi_req->hvec[i+1].iov_len);
|
|
// transform it in a valid c string TODO this is ugly
|
|
ptrbuf = wsgi_req->hvec[i].iov_base+wsgi_req->hvec[i].iov_len;
|
|
*ptrbuf = 0;
|
|
lua_setfield(L, -2, (char *)wsgi_req->hvec[i].iov_base);
|
|
i++;
|
|
}
|
|
|
|
|
|
// put "input" table
|
|
lua_newtable(L);
|
|
lua_pushcfunction(L, uwsgi_lua_input);
|
|
lua_setfield(L, -2, "read");
|
|
lua_setfield(L, -2, "input");
|
|
|
|
#ifdef UWSGI_DEBUG
|
|
uwsgi_log("stack pos %d\n", lua_gettop(L));
|
|
#endif
|
|
|
|
// call function
|
|
i = lua_pcall(L, 1, 3, 0);
|
|
if (i != 0) {
|
|
uwsgi_log("%s\n", lua_tostring(L, -1));
|
|
lua_pop(L, 1);
|
|
lua_pushvalue(L, -1);
|
|
goto clear;
|
|
}
|
|
|
|
//uwsgi_log("%d %s %s %s\n",i,lua_typename(L, lua_type(L, -3)), lua_typename(L, lua_type(L, -2)) , lua_typename(L, lua_type(L, -1)));
|
|
|
|
// send status
|
|
if (lua_type(L, -3) == LUA_TSTRING || lua_type(L, -3) == LUA_TNUMBER) {
|
|
http = lua_tolstring(L, -3, &slen);
|
|
uwsgi_response_prepare_headers(wsgi_req, (char *) http, slen);
|
|
}
|
|
else {
|
|
uwsgi_log("[uwsgi-lua] invalid response status !!!\n");
|
|
// let's continue
|
|
}
|
|
|
|
// send headers
|
|
|
|
lua_pushnil(L);
|
|
while(lua_next(L, -3) != 0) {
|
|
http = lua_tolstring(L, -2, &slen);
|
|
http2 = lua_tolstring(L, -1, &slen2);
|
|
uwsgi_response_add_header(wsgi_req, (char *) http, slen, (char *) http2, slen2);
|
|
lua_pop(L, 1);
|
|
}
|
|
|
|
// send body with coroutine
|
|
lua_pushvalue(L, -1);
|
|
|
|
while ( (i = lua_pcall(L, 0, 1, 0)) == 0) {
|
|
if (lua_type(L, -1) == LUA_TSTRING) {
|
|
http = lua_tolstring(L, -1, &slen);
|
|
uwsgi_response_write_body_do(wsgi_req, (char *)http, slen);
|
|
}
|
|
lua_pop(L, 1);
|
|
lua_pushvalue(L, -1);
|
|
if (uwsgi.async > 1) {
|
|
return UWSGI_AGAIN;
|
|
}
|
|
}
|
|
|
|
clear:
|
|
lua_pop(L, 4);
|
|
// set frequency
|
|
lua_gc(L, LUA_GCCOLLECT, 0);
|
|
|
|
return UWSGI_OK;
|
|
|
|
}
|
|
|
|
void uwsgi_lua_after_request(struct wsgi_request *wsgi_req) {
|
|
|
|
log_request(wsgi_req);
|
|
}
|
|
|
|
|
|
int uwsgi_lua_magic(char *mountpoint, char *lazy) {
|
|
|
|
if (!strcmp(lazy+strlen(lazy)-4, ".lua")) {
|
|
ulua.filename = lazy;
|
|
return 1;
|
|
}
|
|
else if (!strcmp(lazy+strlen(lazy)-3, ".ws")) {
|
|
ulua.filename = lazy;
|
|
return 1;
|
|
}
|
|
|
|
|
|
return 0;
|
|
}
|
|
|
|
char *uwsgi_lua_code_string(char *id, char *code, char *func, char *key, uint16_t keylen) {
|
|
|
|
static struct lua_State *L = NULL;
|
|
|
|
if (!L) {
|
|
L = luaL_newstate();
|
|
luaL_openlibs(L);
|
|
if (luaL_loadfile(L, code) || lua_pcall(L, 0, 0, 0)) {
|
|
uwsgi_log("unable to load file %s: %s\n", code, lua_tostring(L, -1));
|
|
lua_close(L);
|
|
L = NULL;
|
|
return NULL;
|
|
}
|
|
lua_getglobal(L, func);
|
|
if (!lua_isfunction(L,-1)) {
|
|
uwsgi_log("unable to find %s function in lua file %s\n", func, code);
|
|
lua_close(L);
|
|
L = NULL;
|
|
return NULL;
|
|
}
|
|
lua_pushnil(L);
|
|
}
|
|
|
|
|
|
lua_pop(L, 1);
|
|
|
|
lua_pushvalue(L, -1);
|
|
lua_pushlstring(L, key, keylen);
|
|
|
|
#ifdef UWSGI_DEBUG
|
|
uwsgi_log("stack pos %d %.*s\n", lua_gettop(L), keylen, key);
|
|
#endif
|
|
|
|
if (lua_pcall(L, 1, 1, 0) != 0) {
|
|
uwsgi_log("error running function `f': %s",
|
|
lua_tostring(L, -1));
|
|
return NULL;
|
|
|
|
}
|
|
|
|
if (lua_isstring(L, -1)) {
|
|
const char *ret = lua_tolstring(L, -1, NULL);
|
|
return (char *)ret;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
int uwsgi_lua_signal_handler(uint8_t sig, void *handler) {
|
|
|
|
struct wsgi_request *wsgi_req = current_wsgi_req();
|
|
|
|
lua_State *L = ulua.L[wsgi_req->async_id];
|
|
|
|
uwsgi_log("managing signal handler on core %d\n", wsgi_req->async_id);
|
|
|
|
lua_rawgeti(L, LUA_REGISTRYINDEX, (long) handler);
|
|
|
|
lua_pushnumber(L, sig);
|
|
|
|
if (lua_pcall(L, 1, 1, 0) != 0) {
|
|
uwsgi_log("error running function `f': %s",
|
|
lua_tostring(L, -1));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
uint16_t uwsgi_lua_rpc(void * func, uint8_t argc, char **argv, uint16_t argvs[], char *buffer) {
|
|
|
|
uint8_t i;
|
|
const char *sv;
|
|
size_t sl;
|
|
long lfunc = (long) func;
|
|
int ifunc = lfunc;
|
|
|
|
struct wsgi_request *wsgi_req = current_wsgi_req();
|
|
|
|
lua_State *L = ulua.L[wsgi_req->async_id];
|
|
|
|
uwsgi_log("get function %d\n", ifunc);
|
|
lua_rawgeti(L, LUA_REGISTRYINDEX, ifunc);
|
|
|
|
for(i=0;i<argc;i++) {
|
|
lua_pushlstring(L, argv[i], argvs[i]);
|
|
}
|
|
|
|
if (lua_pcall(L, argc, 1, 0) != 0) {
|
|
uwsgi_log("error running function `f': %s", lua_tostring(L, -1));
|
|
return 0;
|
|
}
|
|
|
|
|
|
sv = lua_tolstring(L, -1, &sl);
|
|
|
|
uwsgi_log("sv = %s sl = %lu\n", sv, (unsigned long) sl);
|
|
if (sl <= 0xffff) {
|
|
memcpy(buffer, sv, sl);
|
|
return sl;
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
struct uwsgi_plugin lua_plugin = {
|
|
|
|
.name = "lua",
|
|
.modifier1 = 6,
|
|
.init = uwsgi_lua_init,
|
|
.options = uwsgi_lua_options,
|
|
.request = uwsgi_lua_request,
|
|
.after_request = uwsgi_lua_after_request,
|
|
.init_apps = uwsgi_lua_app,
|
|
.magic = uwsgi_lua_magic,
|
|
.signal_handler = uwsgi_lua_signal_handler,
|
|
|
|
.code_string = uwsgi_lua_code_string,
|
|
.rpc = uwsgi_lua_rpc,
|
|
|
|
};
|
|
|