2 #include "uhttpd-utils.h"
3 #include "uhttpd-lua.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 *prefix = cl->server->conf->lua_prefix;
200 const char *err_str = NULL;
202 /* put handler callback on stack */
203 lua_getglobal(L, UH_LUA_CALLBACK);
206 /* build env table */
210 lua_pushlightuserdata(L, (void *)cl);
211 lua_setfield(L, -2, "client");
216 case UH_HTTP_MSG_GET:
217 lua_pushstring(L, "get");
220 case UH_HTTP_MSG_HEAD:
221 lua_pushstring(L, "head");
224 case UH_HTTP_MSG_POST:
225 lua_pushstring(L, "post");
229 lua_setfield(L, -2, "request_method");
232 lua_pushstring(L, req->url);
233 lua_setfield(L, -2, "request_url");
235 /* query string, path info */
236 if( (query_string = strchr(req->url, '?')) != NULL )
238 lua_pushstring(L, query_string + 1);
239 lua_setfield(L, -2, "query_string");
241 if( (int)(query_string - req->url) > strlen(prefix) )
244 &req->url[strlen(prefix)],
245 (int)(query_string - req->url) - strlen(prefix)
248 lua_setfield(L, -2, "path_info");
251 else if( strlen(req->url) > strlen(prefix) )
253 lua_pushstring(L, &req->url[strlen(prefix)]);
254 lua_setfield(L, -2, "path_info");
257 /* http protcol version */
258 lua_pushnumber(L, floor(req->version * 10) / 10);
259 lua_setfield(L, -2, "http_version");
262 /* address information */
263 lua_pushstring(L, sa_straddr(&cl->peeraddr));
264 lua_setfield(L, -2, "remote_addr");
266 lua_pushinteger(L, sa_port(&cl->peeraddr));
267 lua_setfield(L, -2, "remote_port");
269 lua_pushstring(L, sa_straddr(&cl->servaddr));
270 lua_setfield(L, -2, "server_addr");
272 lua_pushinteger(L, sa_port(&cl->servaddr));
273 lua_setfield(L, -2, "server_port");
279 foreach_header(i, req->headers)
281 lua_pushstring(L, req->headers[i+1]);
282 lua_setfield(L, -2, req->headers[i]);
285 lua_setfield(L, -2, "headers");
289 switch( lua_pcall(L, 1, 0, 0) )
292 err_str = luaL_checkstring(L, -1);
293 uh_http_sendhf(cl, 500, "Lua runtime error",
294 "Lua raised an error:\n%s\n", err_str);
298 err_str = luaL_checkstring(L, -1);
299 uh_http_sendhf(cl, 500, "Lua out of memory",
300 "Lua raised an error:\n%s\n", err_str);