diff --git a/buildconf/lua.ini b/buildconf/lua.ini new file mode 100644 index 00000000..11e19f1f --- /dev/null +++ b/buildconf/lua.ini @@ -0,0 +1,29 @@ +[uwsgi] +xml = true +ini = true +snmp = true +sctp = false +erlang = false +spooler = false +embedded = false +udp = true +multicast = false +threading = true +sendfile = true +nagios = true +proxy = true +minterpreters = true +async = true +ugreen = false +http = true +evdis = false +ldap = false +routing = false +stackless = false +debug = false +unbit = false +xml_implementation = libxml2 +plugins = +bin_name = uwsgi +plugin_dir = . +embedded_plugins = lua diff --git a/buildconf/luap.ini b/buildconf/luap.ini new file mode 100644 index 00000000..d1f16973 --- /dev/null +++ b/buildconf/luap.ini @@ -0,0 +1,29 @@ +[uwsgi] +xml = true +ini = true +snmp = true +sctp = false +erlang = false +spooler = false +embedded = false +udp = true +multicast = false +threading = true +sendfile = true +nagios = true +proxy = true +minterpreters = true +async = true +ugreen = false +http = true +evdis = false +ldap = false +routing = false +stackless = false +debug = false +unbit = false +xml_implementation = libxml2 +plugins = lua +bin_name = uwsgi +plugin_dir = . +embedded_plugins = diff --git a/plugins/lua/lua_plugin.c b/plugins/lua/lua_plugin.c index b2e64911..2a93d163 100644 --- a/plugins/lua/lua_plugin.c +++ b/plugins/lua/lua_plugin.c @@ -1,16 +1,29 @@ -#include - -/* gcc -fPIC -shared -o lua_plugin.so `python2.5-config --cflags` -I /usr/include/lua5.1 -llua5.1 lua_plugin.c */ +#include "../../uwsgi.h" #include #include +#include +extern struct uwsgi_server uwsgi; -static struct uwsgi_lua { - struct lua_State *L ; - struct uwsgi_server *uwsgi; +struct uwsgi_lua { + struct lua_State **L ; + + char *filename; } ulua; +#define LONG_ARGS_LUA_BASE 17000 + (6 * 100) +#define LONG_ARGS_LUA LONG_ARGS_LUA_BASE + 1 + +struct option uwsgi_lua_options[] = { + + {"lua", required_argument, 0, LONG_ARGS_LUA}, + + {0, 0, 0, 0}, + +}; + + static void *uwsgi_lua_alloc(void *ud, void *ptr, size_t osize, size_t nsize) { if(nsize == 0) { free(ptr); @@ -20,64 +33,51 @@ static void *uwsgi_lua_alloc(void *ud, void *ptr, size_t osize, size_t nsize) { return realloc(ptr, nsize); } -static const char *uwsgi_read_lua(lua_State *L, void *data, size_t *size) { - - int fd = *(int *)data; - static char buf[4096]; - - *size = read(fd, buf, 4096); - - if (size == 0) { - return NULL; - } - - return buf; -} - static int uwsgi_lua_input(lua_State *L) { + struct wsgi_request *wsgi_req = current_wsgi_req(); + ssize_t sum; + int n = lua_gettop(L); - static char *buf = "" ; + char *buf ; - fprintf(stderr,"richiesti %d bytes\n", n); + uwsgi_log("requested %d bytes\n", n); - //sum = read(ulua.uwsgi->poll.fd,); + buf = malloc(n); + if (!buf) { + uwsgi_error("malloc()"); + } + + sum = read(wsgi_req->poll.fd, buf, n); lua_pushlstring(L, buf, 0); return 1; } -int uwsgi_init(struct uwsgi_server *uwsgi, char *args){ +int uwsgi_lua_init(){ - int fd, i; + int i; - fprintf(stderr,"Initializing Lua environment...\n"); + uwsgi_log("Initializing Lua environment... (%d cores)\n", uwsgi.cores); - - - - ulua.L = lua_newstate(uwsgi_lua_alloc, NULL); - - luaL_openlibs(ulua.L); - - - fd = open(args, O_RDONLY) ; - if (fd < 0) { - perror("open()"); - return -1 ; + ulua.L = malloc( sizeof(lua_State*) * uwsgi.cores ); + if (!ulua.L) { + uwsgi_error("malloc()"); + exit(1); } - - i = lua_load(ulua.L, uwsgi_read_lua, &fd, "uwsgi"); - - fprintf(stderr,"lua_load: %d\n" ,i); - - // use a pcall - lua_call(ulua.L, 0, 1); - - fprintf(stderr,"%s\n", lua_typename(ulua.L, lua_type(ulua.L, -1))); + for(i=0;iasync_id]; + +#ifdef UWSGI_ASYNC + 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); + if (write(wsgi_req->poll.fd, http, slen) != (ssize_t) slen) { + perror("write()"); + return UWSGI_OK ; + } + } + lua_pop(L, 1); + lua_pushvalue(L, -1); + return UWSGI_AGAIN; + } + goto clear; + } +#endif /* Standard WSAPI request */ if (!wsgi_req->uh.pktsize) { - fprintf (stderr, "Invalid WSAPI request. skip.\n"); - return -1; + uwsgi_log( "Invalid WSAPI request. skip.\n"); + goto clear; } - if (uwsgi_parse_vars(uwsgi, wsgi_req)) { - fprintf(stderr,"Invalid WSAPI request. skip.\n"); - return -1; + if (uwsgi_parse_vars(wsgi_req)) { + uwsgi_log("Invalid WSAPI request. skip.\n"); + goto clear; } // put function in the stack - lua_getfield(ulua.L, LUA_GLOBALSINDEX, "run"); + //lua_getfield(L, LUA_GLOBALSINDEX, "run"); + lua_pushvalue(L, -1); // put cgi vars in the stack - lua_newtable(ulua.L); - lua_pushstring(ulua.L, ""); - lua_setfield(ulua.L, -2, "CONTENT_TYPE"); + + lua_newtable(L); + lua_pushstring(L, ""); + lua_setfield(L, -2, "CONTENT_TYPE"); for(i=0;ivar_cnt;i++) { - lua_pushlstring(ulua.L, (char *)wsgi_req->hvec[i+1].iov_base, wsgi_req->hvec[i+1].iov_len); + 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(ulua.L, -2, (char *)wsgi_req->hvec[i].iov_base); + lua_setfield(L, -2, (char *)wsgi_req->hvec[i].iov_base); i++; } // put "input" table - lua_newtable(ulua.L); - lua_pushcfunction(ulua.L, uwsgi_lua_input); - lua_setfield(ulua.L, -2, "read"); - lua_setfield(ulua.L, -2, "input"); + lua_newtable(L); + lua_pushcfunction(L, uwsgi_lua_input); + lua_setfield(L, -2, "read"); + lua_setfield(L, -2, "input"); // call function - i = lua_pcall(ulua.L, 1, 3, 0); + i = lua_pcall(L, 1, 3, 0); if (i != 0) { - fprintf(stderr,"%s\n", lua_tostring(ulua.L, -1)); - lua_pop(ulua.L, 1); - return -1 ; + uwsgi_log("%s\n", lua_tostring(L, -1)); + lua_pop(L, 1); + goto clear; } - fprintf(stderr,"%d %s %s %s\n",i,lua_typename(ulua.L, lua_type(ulua.L, -3)), lua_typename(ulua.L, lua_type(ulua.L, -2)) , lua_typename(ulua.L, lua_type(ulua.L, -1))); + //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(ulua.L, -3) == LUA_TSTRING || lua_type(ulua.L, -3) == LUA_TNUMBER) { - http = lua_tolstring(ulua.L, -3, &slen); + if (lua_type(L, -3) == LUA_TSTRING || lua_type(L, -3) == LUA_TNUMBER) { + http = lua_tolstring(L, -3, &slen); if (write(wsgi_req->poll.fd, "HTTP/1.1 ", 9) != 9) { perror("write()"); - return -1 ; + goto clear; } if (write(wsgi_req->poll.fd, http, slen) != (ssize_t) slen) { perror("write()"); - return -1 ; + goto clear; } if (write(wsgi_req->poll.fd, "\r\n", 2) != 2) { perror("write()"); - return -1 ; + goto clear; } } // send headers - lua_pushnil(ulua.L); - while(lua_next(ulua.L, -3) != 0) { - http = lua_tolstring(ulua.L, -2, &slen); + lua_pushnil(L); + while(lua_next(L, -3) != 0) { + http = lua_tolstring(L, -2, &slen); if (write(wsgi_req->poll.fd, http, slen) != (ssize_t) slen) { perror("write()"); - return -1 ; + goto clear; } if (write(wsgi_req->poll.fd, ": ", 2) != 2) { perror("write()"); - return -1 ; + goto clear; } - http = lua_tolstring(ulua.L, -1, &slen); + http = lua_tolstring(L, -1, &slen); if (write(wsgi_req->poll.fd, http, slen) != (ssize_t) slen) { perror("write()"); - return -1 ; + goto clear; } if (write(wsgi_req->poll.fd, "\r\n", 2) != 2) { perror("write()"); - return -1 ; + goto clear; } - lua_pop(ulua.L, 1); + lua_pop(L, 1); } if (write(wsgi_req->poll.fd, "\r\n", 2) != 2) { perror("write()"); - return -1 ; + goto clear; } // send body with coroutine - lua_pushvalue(ulua.L, -1); + lua_pushvalue(L, -1); - while ( (i = lua_pcall(ulua.L, 0, 1, 0)) == 0) { - if (lua_type(ulua.L, -1) == LUA_TSTRING) { - http = lua_tolstring(ulua.L, -1, &slen); + while ( (i = lua_pcall(L, 0, 1, 0)) == 0) { + if (lua_type(L, -1) == LUA_TSTRING) { + http = lua_tolstring(L, -1, &slen); if (write(wsgi_req->poll.fd, http, slen) != (ssize_t) slen) { perror("write()"); - return -1 ; + goto clear; } - //fprintf(stderr,"%.*s\n", slen, http); } - lua_pop(ulua.L, 1); - lua_pushvalue(ulua.L, -1); + lua_pop(L, 1); + lua_pushvalue(L, -1); +#ifdef UWSGI_ASYNC + if (uwsgi.async > 1) { + return UWSGI_AGAIN; + } +#endif } - lua_pop(ulua.L, 4); +clear: - return 0; + lua_pop(L, 4); + + // set frequency + lua_gc(L, LUA_GCCOLLECT, 0); + + return UWSGI_OK; } -void uwsgi_after_request(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req) { +void uwsgi_lua_after_request(struct wsgi_request *wsgi_req) { - if (uwsgi->shared->options[UWSGI_OPTION_LOGGING]) + if (uwsgi.shared->options[UWSGI_OPTION_LOGGING]) log_request(wsgi_req); } + +int uwsgi_lua_manage_options(int i, char *optarg) { + + switch(i) { + case LONG_ARGS_LUA: + ulua.filename = optarg; + return 1; + } + + return 0; +} + + +struct uwsgi_plugin lua_plugin = { + + .name = "lua", + .modifier1 = 6, + .init = uwsgi_lua_init, + .options = uwsgi_lua_options, + .manage_opt = uwsgi_lua_manage_options, + .request = uwsgi_lua_request, + .after_request = uwsgi_lua_after_request, + +}; + diff --git a/plugins/lua/uwsgiplugin.py b/plugins/lua/uwsgiplugin.py index 694da388..91ea6926 100644 --- a/plugins/lua/uwsgiplugin.py +++ b/plugins/lua/uwsgiplugin.py @@ -1,5 +1,7 @@ import os,sys NAME='lua' -CFLAGS = '-I /usr/include/lua5.1' -LDFLAGS = '-llua5.1' +CFLAGS = [] +LDFLAGS = [] +GCC_LIST = ['lua_plugin'] +LIBS = ['-llua'] diff --git a/plugins/rack/rack_plugin.c b/plugins/rack/rack_plugin.c index 53bebb5b..81e95dd3 100644 --- a/plugins/rack/rack_plugin.c +++ b/plugins/rack/rack_plugin.c @@ -5,9 +5,10 @@ extern char **environ; extern struct uwsgi_server uwsgi; -#define LONG_ARGS_RAILS 18001 -#define LONG_ARGS_RUBY_GC_FREQ 18002 -#define LONG_ARGS_RACK 18003 +#define LONG_ARGS_RACK_BASE 17000 + (7 * 100) +#define LONG_ARGS_RAILS LONG_ARGS_RACK_BASE + 1 +#define LONG_ARGS_RUBY_GC_FREQ LONG_ARGS_RACK_BASE + 2 +#define LONG_ARGS_RACK LONG_ARGS_RACK_BASE + 3 struct uwsgi_rack { diff --git a/uwsgiconfig.py b/uwsgiconfig.py index ea166f1a..805d1c61 100644 --- a/uwsgiconfig.py +++ b/uwsgiconfig.py @@ -391,7 +391,17 @@ if __name__ == "__main__": elif cmd == '--unbit': build_uwsgi(uConf('buildconf/unbit.ini')) elif cmd == '--plugin': - build_plugin(sys.argv[2], uConf('buildconf/unbit.ini')) + bconf = 'default.ini' + try: + bconf = sys.argv[3] + if not bconf.endswith('.ini'): + bconf += '.ini' + except: + pass + + uc = uConf('buildconf/%s' % bconf) + gcc_list, cflags, ldflags, libs = uc.get_gcll() + build_plugin(sys.argv[2], uc, cflags, ldflags, libs) else: print("unknown uwsgiconfig command") sys.exit(1)