mirror of
https://github.com/clearlinux/uwsgi.git
synced 2026-09-01 11:15:57 +00:00
lua plugin ported to the new api
This commit is contained in:
@@ -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
|
||||
@@ -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
@@ -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,
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -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']
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user