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