various test for trying to allow pre-connected requests

This commit is contained in:
roberto@sirius
2010-12-11 20:08:23 +01:00
parent 96700a49e3
commit 245ab6d815
12 changed files with 320 additions and 16 deletions
+190 -3
View File
@@ -15,6 +15,8 @@ struct uwsgi_lua {
#define LONG_ARGS_LUA_BASE 17000 + (6 * 100)
#define LONG_ARGS_LUA LONG_ARGS_LUA_BASE + 1
#define lca(L, n) ulua_check_args(L, __FUNCTION__, n)
struct option uwsgi_lua_options[] = {
{"lua", required_argument, 0, LONG_ARGS_LUA},
@@ -23,6 +25,182 @@ struct option uwsgi_lua_options[] = {
};
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) {
time_t tt;
const char *logline ;
lca(L, 1);
if (lua_isstring(L, 1)) {
logline = lua_tolstring(L, 1, NULL);
tt = time(NULL);
if (logline[strlen(logline)] != '\n') {
uwsgi_log( UWSGI_LOGBASE " %.*s] %s\n", 24, ctime(&tt), logline);
}
else {
uwsgi_log( UWSGI_LOGBASE " %.*s] %s", 24, ctime(&tt), logline);
}
}
return 0;
}
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 = malloc(*size);
if (!buf) {
uwsgi_error("malloc()");
exit(1);
}
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_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);
}
uwsgi_send_message(uwsgi_fd, modifier1, modifier2, pkt, pktsize, input_fd, input_size, timeout);
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->poll.fd);
return 1;
}
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},
{NULL, NULL}
};
static void *uwsgi_lua_alloc(void *ud, void *ptr, size_t osize, size_t nsize) {
if(nsize == 0) {
@@ -95,6 +273,7 @@ void uwsgi_lua_app() {
for(i=0;i<uwsgi.cores;i++) {
ulua.L[i] = lua_newstate(uwsgi_lua_alloc, NULL);
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\n", ulua.filename);
exit(1);
@@ -113,6 +292,7 @@ void uwsgi_lua_app() {
int uwsgi_lua_request(struct wsgi_request *wsgi_req) {
int i;
int raw;
const char *http;
size_t slen;
ssize_t rlen;
@@ -185,6 +365,7 @@ int uwsgi_lua_request(struct wsgi_request *wsgi_req) {
//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)));
raw = 0;
// send status
if (lua_type(L, -3) == LUA_TSTRING || lua_type(L, -3) == LUA_TNUMBER) {
http = lua_tolstring(L, -3, &slen);
@@ -209,6 +390,10 @@ int uwsgi_lua_request(struct wsgi_request *wsgi_req) {
goto clear;
}
}
else {
raw = 1;
wsgi_req->status = -1;
}
// send headers
@@ -235,9 +420,11 @@ int uwsgi_lua_request(struct wsgi_request *wsgi_req) {
lua_pop(L, 1);
}
if (write(wsgi_req->poll.fd, "\r\n", 2) != 2) {
perror("write()");
goto clear;
if (!raw) {
if (write(wsgi_req->poll.fd, "\r\n", 2) != 2) {
perror("write()");
goto clear;
}
}
// send body with coroutine