lua plugin ported to the new api

This commit is contained in:
roberto@sirius
2010-10-24 08:28:47 +02:00
parent 6adca06764
commit c461d2e6b3
6 changed files with 227 additions and 101 deletions
+29
View File
@@ -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
+29
View File
@@ -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 =
+150 -95
View File
@@ -1,16 +1,29 @@
#include <uwsgi.h>
/* 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 <lua.h>
#include <lualib.h>
#include <lauxlib.h>
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;i<uwsgi.cores;i++) {
ulua.L[i] = lua_newstate(uwsgi_lua_alloc, NULL);
luaL_openlibs(ulua.L[i]);
if (luaL_loadfile(ulua.L[i], ulua.filename)) {
uwsgi_log("unable to load file %s\n", ulua.filename);
exit(1);
}
// use a pcall
lua_call(ulua.L[i], 0, 1);
}
// ok the lua engine is ready
return 0 ;
@@ -85,129 +85,184 @@ int uwsgi_init(struct uwsgi_server *uwsgi, char *args){
}
int uwsgi_request(struct uwsgi_server *uwsgi, struct wsgi_request *wsgi_req) {
int uwsgi_lua_request(struct wsgi_request *wsgi_req) {
int i;
const char *http ;
size_t slen ;
char *ptrbuf;
lua_State *L = ulua.L[wsgi_req->async_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;i<wsgi_req->var_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,
};
+4 -2
View File
@@ -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']
+4 -3
View File
@@ -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 {
+11 -1
View File
@@ -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)