Previous 199869 Revisions Next

r32025 Tuesday 9th September, 2014 at 14:33:00 UTC by Miodrag Milanović
Added support for LUA server pages (nw)
[src/emu]webengine.c

trunk/src/emu/webengine.c
r32024r32025
1414#include "emuopts.h"
1515#include "ui/ui.h"
1616#include "webengine.h"
17#include "lua/lua.hpp"
1718
1819
20
1921//**************************************************************************
2022//  WEB ENGINE
2123//**************************************************************************
r32024r32025
130132   return MG_TRUE;
131133}
132134
135void reg_string(struct lua_State *L, const char *name, const char *val) {
136  lua_pushstring(L, name);
137  lua_pushstring(L, val);
138  lua_rawset(L, -3);
139}
140
141void reg_int(struct lua_State *L, const char *name, int val) {
142  lua_pushstring(L, name);
143  lua_pushinteger(L, val);
144  lua_rawset(L, -3);
145}
146
147void reg_function(struct lua_State *L, const char *name,
148                         lua_CFunction func, struct mg_connection *conn) {
149  lua_pushstring(L, name);
150  lua_pushlightuserdata(L, conn);
151  lua_pushcclosure(L, func, 1);
152  lua_rawset(L, -3);
153}
154
155static int lua_write(lua_State *L) {
156  int i, num_args;
157  const char *str;
158  size_t size;
159  struct mg_connection *conn = (struct mg_connection *)
160    lua_touserdata(L, lua_upvalueindex(1));
161
162  num_args = lua_gettop(L);
163  for (i = 1; i <= num_args; i++) {
164    if (lua_isstring(L, i)) {
165      str = lua_tolstring(L, i, &size);
166      mg_send_data(conn, str, size);
167    }
168  }
169
170  return 0;
171}
172
173static int lua_header(lua_State *L) {
174  struct mg_connection *conn = (struct mg_connection *)
175    lua_touserdata(L, lua_upvalueindex(1));
176
177  const char *header = luaL_checkstring(L,1);
178  const char *value  = luaL_checkstring(L,2);
179 
180  mg_send_header(conn, header, value);
181
182  return 0;
183}
184
185
186static void prepare_lua_environment(struct mg_connection *ri, lua_State *L) {
187  extern void luaL_openlibs(lua_State *);
188  int i;
189
190  luaL_openlibs(L);
191
192  if (ri == NULL) return;
193
194  // Register mg module
195  lua_newtable(L);
196  reg_function(L, "write", lua_write, ri);
197  reg_function(L, "header", lua_header, ri);
198
199  // Export request_info
200  lua_pushstring(L, "request_info");
201  lua_newtable(L);
202  reg_string(L, "request_method", ri->request_method);
203  reg_string(L, "uri", ri->uri);
204  reg_string(L, "http_version", ri->http_version);
205  reg_string(L, "query_string", ri->query_string);
206  reg_string(L, "remote_ip", ri->remote_ip);
207  reg_int(L, "remote_port", ri->remote_port);
208  reg_string(L, "local_ip", ri->local_ip);
209  reg_int(L, "local_port", ri->local_port);
210  lua_pushstring(L, "content");
211  lua_pushlstring(L, ri->content == NULL ? "" : ri->content, ri->content_len);
212  lua_rawset(L, -3);
213  reg_int(L, "num_headers", ri->num_headers);
214  lua_pushstring(L, "http_headers");
215  lua_newtable(L);
216  for (i = 0; i < ri->num_headers; i++) {
217    reg_string(L, ri->http_headers[i].name, ri->http_headers[i].value);
218  }
219  lua_rawset(L, -3);
220  lua_rawset(L, -3);
221
222  lua_setglobal(L, "mg");
223
224}
225
226
227static void lsp(struct mg_connection *conn, const char *p, int len, lua_State *L) {
228  int i, j, pos = 0;
229  for (i = 0; i < len; i++) {
230    if (p[i] == '<' && p[i + 1] == '?') {
231      for (j = i + 1; j < len ; j++) {
232        if (p[j] == '?' && p[j + 1] == '>') {     
233        if (i-pos!=0) mg_send_data(conn, p + pos, i - pos);       
234          if (luaL_loadbuffer(L, p + (i + 2), j - (i + 2), "") == 0) {
235            lua_pcall(L, 0, LUA_MULTRET, 0);
236          }
237          pos = j + 2;
238          i = pos - 1;
239          break;
240        }
241      }
242    }
243  }
244  if (i > pos) {
245   mg_send_data(conn, p + pos, i - pos);
246 }
247}
248
249static int filename_endswith(const char *str, const char *suffix)
250{
251    if (!str || !suffix)
252        return 0;
253    size_t lenstr = strlen(str);
254    size_t lensuffix = strlen(suffix);
255    if (lensuffix >  lenstr)
256        return 0;
257    return strncmp(str + lenstr - lensuffix, suffix, lensuffix) == 0;
258}
259
133260// This function will be called by mongoose on every new request.
134261int web_engine::begin_request_handler(struct mg_connection *conn)
135262{
136   if (!strncmp(conn->uri, "/json/",6))
263   astring file_path(mg_get_option(m_server, "document_root"), PATH_SEPARATOR, conn->uri);
264   if (filename_endswith(file_path,".lp"))
137265   {
266     FILE *fp = NULL;
267     if ((fp = fopen(file_path, "rb")) != NULL) {
268      fseek (fp, 0, SEEK_END);   
269      size_t size = ftell(fp);
270      fseek (fp, 0, SEEK_SET);   
271      char *data = (char*)mg_mmap(fp,size);
272
273      lua_State *L = luaL_newstate();
274       prepare_lua_environment(conn, L);
275      lsp(conn, data, (int) size, L);
276      if (L != NULL) lua_close(L);
277      mg_munmap(data,size);
278      fclose(fp);     
279      return MG_TRUE;   
280      } else {
281        return MG_FALSE;     
282     }
283   }
284   else if (!strncmp(conn->uri, "/json/",6))
285   {
138286      if (!strcmp(conn->uri, "/json/game"))
139287      {
140288         return json_game_handler(conn);

Previous 199869 Revisions Next


© 1997-2024 The MAME Team