about summary refs log tree commit diff stats
path: root/lua/sandborb/src/sandborb.c
diff options
context:
space:
mode:
Diffstat (limited to 'lua/sandborb/src/sandborb.c')
-rw-r--r--lua/sandborb/src/sandborb.c97
1 files changed, 97 insertions, 0 deletions
diff --git a/lua/sandborb/src/sandborb.c b/lua/sandborb/src/sandborb.c
new file mode 100644
index 0000000..f63106d
--- /dev/null
+++ b/lua/sandborb/src/sandborb.c
@@ -0,0 +1,97 @@
+#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;
+}