2 #include "uhttpd-lua.h"
3 #include "uhttpd-utils.h"
6 static int uh_lua_recv(lua_State *L)
9 char buffer[UH_LIMIT_MSGHEAD];
12 struct timeval timeout;
15 luaL_checktype(L, 1, LUA_TLIGHTUSERDATA);
16 cl = (struct client *) lua_topointer(L, 1);
17 length = luaL_checknumber(L, 2);
19 if( (cl != NULL) && (length > 0) && (length <= sizeof(buffer)) )
22 FD_SET(cl->socket, &reader);
26 timeout.tv_usec = 100000;
28 /* first return stuff from peek buffer */
32 rlen = uh_tcp_recv(cl, buffer, min(cl->peeklen, length));
33 lua_pushnumber(L, rlen);
34 lua_pushlstring(L, buffer, rlen);
39 /* check whether fd is readable */
40 else if( select(cl->socket + 1, &reader, NULL, NULL, &timeout) > 0 )
43 rlen = uh_tcp_recv(cl, buffer, length);
44 lua_pushnumber(L, rlen);
48 lua_pushlstring(L, buffer, rlen);
55 /* no, timeout and actually no data */
56 lua_pushnumber(L, -2);
61 lua_pushnumber(L, -3);
65 static int uh_lua_send(lua_State *L)
72 luaL_checktype(L, 1, LUA_TLIGHTUSERDATA);
73 cl = (struct client *) lua_topointer(L, 1);
74 buffer = luaL_checklstring(L, 2, &length);
76 if( (cl != NULL) && (length > 0) )
78 slen = uh_tcp_send(cl, buffer, length);
79 lua_pushnumber(L, slen);
83 lua_pushnumber(L, -1);
87 static int uh_lua_urldecode(lua_State *L)
91 char outbuf[UH_LIMIT_MSGHEAD];
93 inbuf = luaL_checklstring(L, 1, &inlen);
94 outlen = uh_urldecode(outbuf, sizeof(outbuf), inbuf, inlen);
96 lua_pushlstring(L, outbuf, outlen);
101 lua_State * uh_lua_init(const char *handler)
103 lua_State *L = lua_open();
105 const char *err_str = NULL;
107 /* Declare the Lua libraries we wish to use. */
108 /* Note: If you are opening and running a file containing Lua code */
109 /* using 'lua_dofile(l, "myfile.lua") - you must delcare all the libraries */
110 /* used in that file here also. */
111 static const luaL_reg lualibs[] =
113 { "base", luaopen_base },
114 { "string", luaopen_string },
118 /* preload libraries */
119 for (lib = lualibs; lib->func != NULL; lib++)
125 /* register global send and receive functions */
126 lua_pushcfunction(L, uh_lua_recv);
127 lua_setfield(L, LUA_GLOBALSINDEX, "recv");
129 lua_pushcfunction(L, uh_lua_send);
130 lua_setfield(L, LUA_GLOBALSINDEX, "send");
132 lua_pushcfunction(L, uh_lua_urldecode);
133 lua_setfield(L, LUA_GLOBALSINDEX, "urldecode");
136 /* load Lua handler */
137 switch( luaL_loadfile(L, handler) )
141 "Lua handler contains syntax errors, unable to continue\n");
146 "Lua handler ran out of memory, unable to continue\n");
151 "Lua cannot open the handler script, unable to continue\n");
155 /* compile Lua handler */
156 switch( lua_pcall(L, 0, 0, 0) )
159 err_str = luaL_checkstring(L, -1);
161 "Lua handler had runtime error, unable to continue\n"
162 "Error: %s\n", err_str
167 err_str = luaL_checkstring(L, -1);
169 "Lua handler ran out of memory, unable to continue\n"
170 "Error: %s\n", err_str
175 /* test handler function */
176 lua_getglobal(L, UH_LUA_CALLBACK);
178 if( ! lua_isfunction(L, -1) )
181 "Lua handler provides no " UH_LUA_CALLBACK "(), unable to continue\n");
195 void uh_lua_request(struct client *cl, struct http_request *req, lua_State *L)
199 const char *err_str = NULL;
201 /* put handler callback on stack */
202 lua_getglobal(L, UH_LUA_CALLBACK);
205 /* build env table */
209 lua_pushlightuserdata(L, (void *)cl);
210 lua_setfield(L, -2, "client");
215 case UH_HTTP_MSG_GET:
216 lua_pushstring(L, "get");
219 case UH_HTTP_MSG_HEAD:
220 lua_pushstring(L, "head");
223 case UH_HTTP_MSG_POST:
224 lua_pushstring(L, "post");
228 lua_setfield(L, -2, "request_method");
231 lua_pushstring(L, req->url);
232 lua_setfield(L, -2, "request_url");
234 /* query string, path info */
235 if( (query_string = strchr(req->url, '?')) != NULL )
237 lua_pushstring(L, query_string + 1);
238 lua_setfield(L, -2, "query_string");
240 lua_pushlstring(L, req->url, (int)(query_string - req->url));
241 lua_setfield(L, -2, "path_info");
245 lua_pushstring(L, req->url);
246 lua_setfield(L, -2, "path_info");
249 /* http protcol version */
250 lua_pushnumber(L, floor(req->version * 10) / 10);
251 lua_setfield(L, -2, "http_version");
254 /* address information */
255 lua_pushstring(L, sa_straddr(&cl->peeraddr));
256 lua_setfield(L, -2, "remote_addr");
258 lua_pushinteger(L, sa_port(&cl->peeraddr));
259 lua_setfield(L, -2, "remote_port");
261 lua_pushstring(L, sa_straddr(&cl->servaddr));
262 lua_setfield(L, -2, "server_addr");
264 lua_pushinteger(L, sa_port(&cl->servaddr));
265 lua_setfield(L, -2, "server_port");
271 foreach_header(i, req->headers)
273 lua_pushstring(L, req->headers[i+1]);
274 lua_setfield(L, -2, req->headers[i]);
277 lua_setfield(L, -2, "headers");
281 switch( lua_pcall(L, 1, 0, 0) )
284 err_str = luaL_checkstring(L, -1);
285 uh_http_sendhf(cl, 500, "Lua runtime error",
286 "Lua raised an error:\n%s\n", err_str);
290 err_str = luaL_checkstring(L, -1);
291 uh_http_sendhf(cl, 500, "Lua out of memory",
292 "Lua raised an error:\n%s\n", err_str);