b2ca34e0c1108ed3b41bbcaaa0411b17d261cac4
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
);