Added support for LUA server pages (nw)

This commit is contained in:
Miodrag Milanovic 2014-09-09 14:33:00 +00:00
parent 8e207529fe
commit 5033a590a3

View File

@ -14,6 +14,8 @@
#include "emuopts.h"
#include "ui/ui.h"
#include "webengine.h"
#include "lua/lua.hpp"
//**************************************************************************
@ -130,10 +132,156 @@ int web_engine::json_slider_handler(struct mg_connection *conn)
return MG_TRUE;
}
void reg_string(struct lua_State *L, const char *name, const char *val) {
lua_pushstring(L, name);
lua_pushstring(L, val);
lua_rawset(L, -3);
}
void reg_int(struct lua_State *L, const char *name, int val) {
lua_pushstring(L, name);
lua_pushinteger(L, val);
lua_rawset(L, -3);
}
void reg_function(struct lua_State *L, const char *name,
lua_CFunction func, struct mg_connection *conn) {
lua_pushstring(L, name);
lua_pushlightuserdata(L, conn);
lua_pushcclosure(L, func, 1);
lua_rawset(L, -3);
}
static int lua_write(lua_State *L) {
int i, num_args;
const char *str;
size_t size;
struct mg_connection *conn = (struct mg_connection *)
lua_touserdata(L, lua_upvalueindex(1));
num_args = lua_gettop(L);
for (i = 1; i <= num_args; i++) {
if (lua_isstring(L, i)) {
str = lua_tolstring(L, i, &size);
mg_send_data(conn, str, size);
}
}
return 0;
}
static int lua_header(lua_State *L) {
struct mg_connection *conn = (struct mg_connection *)
lua_touserdata(L, lua_upvalueindex(1));
const char *header = luaL_checkstring(L,1);
const char *value = luaL_checkstring(L,2);
mg_send_header(conn, header, value);
return 0;
}
static void prepare_lua_environment(struct mg_connection *ri, lua_State *L) {
extern void luaL_openlibs(lua_State *);
int i;
luaL_openlibs(L);
if (ri == NULL) return;
// Register mg module
lua_newtable(L);
reg_function(L, "write", lua_write, ri);
reg_function(L, "header", lua_header, ri);
// Export request_info
lua_pushstring(L, "request_info");
lua_newtable(L);
reg_string(L, "request_method", ri->request_method);
reg_string(L, "uri", ri->uri);
reg_string(L, "http_version", ri->http_version);
reg_string(L, "query_string", ri->query_string);
reg_string(L, "remote_ip", ri->remote_ip);
reg_int(L, "remote_port", ri->remote_port);
reg_string(L, "local_ip", ri->local_ip);
reg_int(L, "local_port", ri->local_port);
lua_pushstring(L, "content");
lua_pushlstring(L, ri->content == NULL ? "" : ri->content, ri->content_len);
lua_rawset(L, -3);
reg_int(L, "num_headers", ri->num_headers);
lua_pushstring(L, "http_headers");
lua_newtable(L);
for (i = 0; i < ri->num_headers; i++) {
reg_string(L, ri->http_headers[i].name, ri->http_headers[i].value);
}
lua_rawset(L, -3);
lua_rawset(L, -3);
lua_setglobal(L, "mg");
}
static void lsp(struct mg_connection *conn, const char *p, int len, lua_State *L) {
int i, j, pos = 0;
for (i = 0; i < len; i++) {
if (p[i] == '<' && p[i + 1] == '?') {
for (j = i + 1; j < len ; j++) {
if (p[j] == '?' && p[j + 1] == '>') {
if (i-pos!=0) mg_send_data(conn, p + pos, i - pos);
if (luaL_loadbuffer(L, p + (i + 2), j - (i + 2), "") == 0) {
lua_pcall(L, 0, LUA_MULTRET, 0);
}
pos = j + 2;
i = pos - 1;
break;
}
}
}
}
if (i > pos) {
mg_send_data(conn, p + pos, i - pos);
}
}
static int filename_endswith(const char *str, const char *suffix)
{
if (!str || !suffix)
return 0;
size_t lenstr = strlen(str);
size_t lensuffix = strlen(suffix);
if (lensuffix > lenstr)
return 0;
return strncmp(str + lenstr - lensuffix, suffix, lensuffix) == 0;
}
// This function will be called by mongoose on every new request.
int web_engine::begin_request_handler(struct mg_connection *conn)
{
if (!strncmp(conn->uri, "/json/",6))
astring file_path(mg_get_option(m_server, "document_root"), PATH_SEPARATOR, conn->uri);
if (filename_endswith(file_path,".lp"))
{
FILE *fp = NULL;
if ((fp = fopen(file_path, "rb")) != NULL) {
fseek (fp, 0, SEEK_END);
size_t size = ftell(fp);
fseek (fp, 0, SEEK_SET);
char *data = (char*)mg_mmap(fp,size);
lua_State *L = luaL_newstate();
prepare_lua_environment(conn, L);
lsp(conn, data, (int) size, L);
if (L != NULL) lua_close(L);
mg_munmap(data,size);
fclose(fp);
return MG_TRUE;
} else {
return MG_FALSE;
}
}
else if (!strncmp(conn->uri, "/json/",6))
{
if (!strcmp(conn->uri, "/json/game"))
{