#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
#include "sandbird.h"
/* Functions to be called from Lua */
static int l_sb_send_header(lua_State *L) {
sb_Event *e = lua_touserdata(L, 1);
const char *key = lua_tostring(L, 2);
const char *value = lua_tostring(L, 3);
sb_send_header(e->stream, key, value);
return 0; /* Number of return values */
}
static int l_sb_send_status(lua_State *L) {
sb_Event *e = lua_touserdata(L, 1);
int status = lua_tointeger(L, 2);
const char *message = lua_tostring(L, 3);
sb_send_status(e->stream, status, message);
return 0; /* Number of return values */
}
static int event_handler(sb_Event *e) {
if (e->type == SB_EV_REQUEST) {
printf("%s - %s %s\n", e->address, e->method, e->path);
lua_State *L = luaL_newstate(); /* create a new Lua state */
luaL_openlibs(L); /* load Lua libraries */
/* Expose our functions to Lua */
lua_pushcfunction(L, l_sb_send_header);
lua_setglobal(L, "sb_send_header");
lua_pushcfunction(L, l_sb_send_status);
lua_setglobal(L, "sb_send_status");
/* load and run the Lua script */
if (luaL_dofile(L, "route_handler.lua") != LUA_OK) {
fprintf(stderr, "Failed to load Lua script: %s\n", lua_tostring(L, -1));
lua_close(L);
return SB_RES_OK;
}
/* call the Lua function based on the request method */
if (strcmp(e->method, "POST") == 0) {
lua_getglobal(L, "HANDLE_POST_ROUTE");
} else {
lua_getglobal(L, "HANDLE_ROUTE");
}
lua_pushlightuserdata(L, e); /* Pass the event as userdata to Lua */
lua_pushstring(L, e->path); /* FIXME: find a way to use lua_pushstring to pass posted data into lua */
if (lua_pcall(L, 2, 1, 0) != LUA_OK) {
fprintf(stderr, "Failed to call Lua function: %s\n", lua_tostring(L, -1));
lua_close(L);
return SB_RES_OK;
}
/* get the result from the Lua function */
const char *response = lua_tostring(L, -1);
lua_pop(L, 1);
sb_writef(e->stream, response);
lua_close(L); /* close the Lua state */
}
return SB_RES_OK;
}
int main(void) {
sb_Options opt;
sb_Server *server;
memset(&opt, 0, sizeof(opt));
opt.port = "8000";
opt.handler = event_handler;
server = sb_new_server(&opt);
if (!server) {
fprintf(stderr, "failed to initialize server\n");
exit(EXIT_FAILURE);
}
printf("Server running at http://localhost:%s\n", opt.port);
for (;;) {
sb_poll_server(server, 1000);
}
sb_close_server(server);
return EXIT_SUCCESS;
}