1 #include <uwsgi.h>
2 
3 #include <lua.h>
4 #include <lualib.h>
5 #include <lauxlib.h>
6 
7 #if LUA_VERSION_NUM < 502
8 # define luaL_newuwsgilib(L,l) luaL_register(L, "uwsgi",l)
9 # define lua_rawlen lua_objlen
10 #else
11 # define luaL_newuwsgilib(L,l) lua_newtable(L);luaL_setfuncs (L, l, 0);lua_pushvalue(L,-1);lua_setglobal(L,"uwsgi")
12 #endif
13 
14 extern struct uwsgi_server uwsgi;
15 
16 struct uwsgi_lua {
17 	struct lua_State **L;
18 	char *shell;
19 	char *filename;
20 	struct uwsgi_string_list *load;
21 	int gc_freq;
22 } ulua;
23 
24 struct uwsgi_plugin lua_plugin;
25 
26 #define lca(L, n)		ulua_check_args(L, __FUNCTION__, n)
27 
uwsgi_opt_luashell(char * opt,char * value,void * foobar)28 static void uwsgi_opt_luashell(char *opt, char *value, void *foobar) {
29 
30         uwsgi.honour_stdin = 1;
31         if (value) {
32                 ulua.shell = value;
33         }
34         else {
35                 ulua.shell = "";
36         }
37 }
38 
39 
40 static struct uwsgi_option uwsgi_lua_options[] = {
41 
42 	{"lua", required_argument, 0, "load lua wsapi app", uwsgi_opt_set_str, &ulua.filename, 0},
43 	{"lua-load", required_argument, 0, "load a lua file", uwsgi_opt_add_string_list, &ulua.load, 0},
44 	{"lua-shell", no_argument, 0, "run the lua interactive shell (debug.debug())", uwsgi_opt_luashell, NULL, 0},
45 	{"luashell", no_argument, 0, "run the lua interactive shell (debug.debug())", uwsgi_opt_luashell, NULL, 0},
46 	{"lua-gc-freq", no_argument, 0, "set the lua gc frequency (default: 0, runs after every request)", uwsgi_opt_set_int, &ulua.gc_freq, 0},
47 
48 	{0, 0, 0, 0},
49 
50 };
51 
ulua_check_args(lua_State * L,const char * func,int n)52 static void ulua_check_args(lua_State *L, const char *func, int n) {
53 	int args = lua_gettop(L);
54 	char error[1024];
55 	if (args != n) {
56 		if (n == 1) {
57 			snprintf(error, 1024, "uwsgi.%s takes 1 parameter", func+10);
58 		}
59 		else {
60 			snprintf(error, 1024, "uwsgi.%s takes %d parameters", func+10, n);
61 		}
62 		lua_pushstring(L, error);
63         	lua_error(L);
64 	}
65 }
66 
uwsgi_api_log(lua_State * L)67 static int uwsgi_api_log(lua_State *L) {
68 
69 	const char *logline ;
70 
71 	lca(L, 1);
72 
73 	if (lua_isstring(L, 1)) {
74 		logline = lua_tolstring(L, 1, NULL);
75                 uwsgi_log( "%s\n", logline);
76 	}
77 
78 	return 0;
79 }
80 
uwsgi_api_register_rpc(lua_State * L)81 static int uwsgi_api_register_rpc(lua_State *L) {
82 
83         uint8_t argc = lua_gettop(L);
84 	const char *name;
85 	// a hack for 64bit;
86 	int func;
87 	long lfunc;
88 
89 	if (argc < 2) {
90 		lua_pushnil(L);
91 		return 1;
92 	}
93 
94 	name = lua_tolstring(L, 1, NULL);
95 
96 	lua_pushvalue(L, 2);
97         func = luaL_ref(L, LUA_REGISTRYINDEX);
98 
99 	uwsgi_log("registered function %d in Lua global table\n", func);
100 	lfunc = func;
101 
102         if (uwsgi_register_rpc((char *)name, &lua_plugin, 0, (void *) lfunc)) {
103 		lua_pushnil(L);
104         }
105 	else {
106 		lua_pushboolean(L, 1);
107 	}
108 
109 	return 1;
110 }
111 
uwsgi_api_cache_set(lua_State * L)112 static int uwsgi_api_cache_set(lua_State *L) {
113 
114 	uint8_t argc = lua_gettop(L);
115         const char *key ;
116         const char *value ;
117         uint64_t expires = 0;
118 	size_t vallen;
119 	size_t keylen;
120 	const char *cache = NULL;
121 
122 	if (argc < 2) goto error;
123 
124 	key = lua_tolstring(L, 1, &keylen);
125 	value = lua_tolstring(L, 2, &vallen);
126 	if (argc > 2) {
127 		expires = lua_tonumber(L, 3);
128 		if (argc > 3) {
129 			cache = lua_tolstring(L, 4, NULL);
130 		}
131 	}
132 
133         if (!uwsgi_cache_magic_set((char *)key, keylen, (char *)value, vallen, expires, 0, (char *) cache)) {
134 		lua_pushboolean(L, 1);
135 		return 1;
136 	}
137 error:
138 
139 	lua_pushnil(L);
140 	return 1;
141 
142 }
143 
uwsgi_api_cache_update(lua_State * L)144 static int uwsgi_api_cache_update(lua_State *L) {
145 
146         uint8_t argc = lua_gettop(L);
147         const char *key ;
148         const char *value ;
149         uint64_t expires = 0;
150         size_t vallen;
151         size_t keylen;
152         const char *cache = NULL;
153 
154         if (argc < 2) goto error;
155 
156         key = lua_tolstring(L, 1, &keylen);
157         value = lua_tolstring(L, 2, &vallen);
158         if (argc > 2) {
159                 expires = lua_tonumber(L, 3);
160                 if (argc > 3) {
161                         cache = lua_tolstring(L, 4, NULL);
162                 }
163         }
164 
165         if (!uwsgi_cache_magic_set((char *)key, keylen, (char *)value, vallen, expires, UWSGI_CACHE_FLAG_UPDATE, (char *)cache)) {
166                 lua_pushboolean(L, 1);
167                 return 1;
168         }
169 error:
170 
171         lua_pushnil(L);
172         return 1;
173 
174 }
175 
176 
uwsgi_api_register_signal(lua_State * L)177 static int uwsgi_api_register_signal(lua_State *L) {
178 
179 	int args = lua_gettop(L);
180 	uint8_t sig;
181 	long lhandler;
182 	const char *who;
183 
184 	if (args >= 3) {
185 
186 		sig = lua_tonumber(L, 1);
187 		who = lua_tostring(L, 2);
188 		lua_pushvalue(L, 3);
189 		lhandler = luaL_ref(L, LUA_REGISTRYINDEX);
190 
191 		uwsgi_register_signal(sig, (char *)who, (void *) lhandler, 6);
192 	}
193 
194 	lua_pushnil(L);
195         return 1;
196 }
197 
uwsgi_api_cache_clear(lua_State * L)198 static int uwsgi_api_cache_clear(lua_State *L) {
199 
200         const char *cache = NULL;
201         uint8_t argc = lua_gettop(L);
202 
203         if (argc > 0) {
204         	cache = lua_tolstring(L, 2, NULL);
205         }
206         if (!uwsgi_cache_magic_clear((char *)cache)) {
207         	lua_pushboolean(L, 1);
208                 return 1;
209         }
210 
211         lua_pushnil(L);
212         return 1;
213 
214 }
215 
216 
uwsgi_api_cache_del(lua_State * L)217 static int uwsgi_api_cache_del(lua_State *L) {
218 
219         size_t keylen;
220         const char *key ;
221         const char *cache = NULL;
222         uint8_t argc = lua_gettop(L);
223 
224         if (argc == 0) goto error;
225 
226         if (lua_isstring(L, 1)) {
227                 // get the key
228                 key = lua_tolstring(L, 1, &keylen);
229                 if (argc > 1) {
230                         cache = lua_tolstring(L, 2, NULL);
231                 }
232                 if (!uwsgi_cache_magic_del((char *)key, keylen, (char *)cache)) {
233                         lua_pushboolean(L, 1);
234                         return 1;
235                 }
236         }
237 
238 error:
239         lua_pushnil(L);
240         return 1;
241 
242 }
243 
244 
uwsgi_api_cache_exists(lua_State * L)245 static int uwsgi_api_cache_exists(lua_State *L) {
246 
247         size_t keylen;
248         const char *key ;
249         const char *cache = NULL;
250         uint8_t argc = lua_gettop(L);
251 
252         if (argc == 0) goto error;
253 
254         if (lua_isstring(L, 1)) {
255                 // get the key
256                 key = lua_tolstring(L, 1, &keylen);
257                 if (argc > 1) {
258                         cache = lua_tolstring(L, 2, NULL);
259                 }
260                 if (uwsgi_cache_magic_exists((char *)key, keylen,(char *)cache)) {
261 			lua_pushboolean(L, 1);
262                 	return 1;
263                 }
264         }
265 
266 error:
267         lua_pushnil(L);
268         return 1;
269 
270 }
271 
uwsgi_api_async_sleep(lua_State * L)272 static int uwsgi_api_async_sleep(lua_State *L) {
273 	uint8_t argc = lua_gettop(L);
274         if (argc == 0) goto end;
275 
276         struct wsgi_request *wsgi_req = current_wsgi_req();
277 
278         int timeout = lua_tonumber(L, 1);
279 
280         if (timeout >= 0) {
281                 async_add_timeout(wsgi_req, timeout);
282         }
283 end:
284 	lua_pushnil(L);
285         return 1;
286 }
287 
uwsgi_api_wait_fd_read(lua_State * L)288 static int uwsgi_api_wait_fd_read(lua_State *L) {
289         uint8_t argc = lua_gettop(L);
290         if (argc == 0) goto end;
291 
292         struct wsgi_request *wsgi_req = current_wsgi_req();
293 
294 	int fd = lua_tonumber(L, 1);
295 	int timeout = 0;
296 	if (argc > 1) {
297         	timeout = lua_tonumber(L, 2);
298 	}
299 
300 	if (async_add_fd_read(wsgi_req, fd, timeout)) {
301 		lua_pushstring(L, "unable to call async_add_fd_read()");
302         	lua_error(L);
303         	return 0;
304         }
305 end:
306         lua_pushnil(L);
307         return 1;
308 }
309 
uwsgi_api_wait_fd_write(lua_State * L)310 static int uwsgi_api_wait_fd_write(lua_State *L) {
311         uint8_t argc = lua_gettop(L);
312         if (argc == 0) goto end;
313 
314         struct wsgi_request *wsgi_req = current_wsgi_req();
315 
316         int fd = lua_tonumber(L, 1);
317         int timeout = 0;
318         if (argc > 1) {
319                 timeout = lua_tonumber(L, 2);
320         }
321 
322         if (async_add_fd_write(wsgi_req, fd, timeout)) {
323                 lua_pushstring(L, "unable to call async_add_fd_write()");
324                 lua_error(L);
325                 return 0;
326         }
327 end:
328         lua_pushnil(L);
329         return 1;
330 }
331 
uwsgi_api_async_connect(lua_State * L)332 static int uwsgi_api_async_connect(lua_State *L) {
333         uint8_t argc = lua_gettop(L);
334         if (argc == 0) goto end;
335 
336 	int fd = uwsgi_connect((char *)lua_tostring(L, 1), 0, 1);
337 	lua_pushnumber(L, fd);
338 	return 1;
339 end:
340         lua_pushnil(L);
341         return 1;
342 }
343 
uwsgi_api_is_connected(lua_State * L)344 static int uwsgi_api_is_connected(lua_State *L) {
345         uint8_t argc = lua_gettop(L);
346         if (argc == 0) goto end;
347 	int fd = lua_tonumber(L, 1);
348 	if (uwsgi_is_connected(fd)) {
349 		lua_pushboolean(L, 1);
350 		return 1;
351 	}
352 	lua_pushboolean(L, 0);
353         return 1;
354 end:
355         lua_pushnil(L);
356         return 1;
357 }
358 
uwsgi_api_close(lua_State * L)359 static int uwsgi_api_close(lua_State *L) {
360         uint8_t argc = lua_gettop(L);
361         if (argc == 0) goto end;
362         int fd = lua_tonumber(L, 1);
363 	close(fd);
364 end:
365         lua_pushnil(L);
366         return 1;
367 }
368 
369 
uwsgi_api_ready_fd(lua_State * L)370 static int uwsgi_api_ready_fd(lua_State *L) {
371 	struct wsgi_request *wsgi_req = current_wsgi_req();
372         int fd = uwsgi_ready_fd(wsgi_req);
373         lua_pushnumber(L, fd);
374         return 1;
375 }
376 
uwsgi_api_websocket_handshake(lua_State * L)377 static int uwsgi_api_websocket_handshake(lua_State *L) {
378 	uint8_t argc = lua_gettop(L);
379 
380 	const char *key = NULL, *origin = NULL, *proto = NULL;
381 	size_t key_len = 0, origin_len = 0, proto_len = 0;
382 
383 	if (argc > 0) {
384 		key = lua_tolstring(L, 1, &key_len);
385 		if (argc > 1) {
386 			origin = lua_tolstring(L, 2, &origin_len);
387 			if (argc > 2) {
388 				proto = lua_tolstring(L, 3, &proto_len);
389 			}
390 		}
391 	}
392 
393 	struct wsgi_request *wsgi_req = current_wsgi_req();
394 	if (uwsgi_websocket_handshake(wsgi_req, (char *)key, key_len, (char *)origin, origin_len, (char *) proto, proto_len)) {
395 		goto error;
396 	}
397 
398 	lua_pushnil(L);
399         return 1;
400 
401 error:
402 	lua_pushstring(L, "unable to complete websocket handshake");
403 	lua_error(L);
404 	return 0;
405 }
406 
uwsgi_api_websocket_send(lua_State * L)407 static int uwsgi_api_websocket_send(lua_State *L) {
408 	uint8_t argc = lua_gettop(L);
409         if (argc == 0) goto error;
410 
411 	size_t message_len = 0;
412 	const char *message = lua_tolstring(L, 1, &message_len);
413 	struct wsgi_request *wsgi_req = current_wsgi_req();
414 
415         if (uwsgi_websocket_send(wsgi_req, (char *) message, message_len)) {
416 		goto error;
417         }
418 	lua_pushnil(L);
419         return 1;
420 error:
421         lua_pushstring(L, "unable to send websocket message");
422         lua_error(L);
423         return 0;
424 }
425 
uwsgi_api_websocket_send_binary(lua_State * L)426 static int uwsgi_api_websocket_send_binary(lua_State *L) {
427         uint8_t argc = lua_gettop(L);
428         if (argc == 0) goto error;
429 
430         size_t message_len = 0;
431         const char *message = lua_tolstring(L, 1, &message_len);
432         struct wsgi_request *wsgi_req = current_wsgi_req();
433 
434         if (uwsgi_websocket_send_binary(wsgi_req, (char *) message, message_len)) {
435                 goto error;
436         }
437 	lua_pushnil(L);
438         return 1;
439 error:
440         lua_pushstring(L, "unable to send websocket binary message");
441         lua_error(L);
442         return 0;
443 }
444 
uwsgi_api_websocket_send_from_sharedarea(lua_State * L)445 static int uwsgi_api_websocket_send_from_sharedarea(lua_State *L) {
446         uint8_t argc = lua_gettop(L);
447         if (argc < 2) goto error;
448 
449 	int id = lua_tonumber(L, 1);
450 	uint64_t pos = lua_tonumber(L, 2);
451 	uint64_t len = 0;
452 	if (argc > 2) {
453 		len = lua_tonumber(L, 3);
454 	}
455         struct wsgi_request *wsgi_req = current_wsgi_req();
456 
457 	if (uwsgi_websocket_send_from_sharedarea(wsgi_req, id, pos, len)) {
458                 goto error;
459         }
460 	lua_pushnil(L);
461         return 1;
462 error:
463         lua_pushstring(L, "unable to send websocket message from sharedarea");
464         lua_error(L);
465         return 0;
466 }
467 
uwsgi_api_websocket_send_binary_from_sharedarea(lua_State * L)468 static int uwsgi_api_websocket_send_binary_from_sharedarea(lua_State *L) {
469         uint8_t argc = lua_gettop(L);
470         if (argc < 2) goto error;
471 
472         int id = lua_tonumber(L, 1);
473         uint64_t pos = lua_tonumber(L, 2);
474         uint64_t len = 0;
475         if (argc > 2) {
476                 len = lua_tonumber(L, 3);
477         }
478         struct wsgi_request *wsgi_req = current_wsgi_req();
479 
480         if (uwsgi_websocket_send_binary_from_sharedarea(wsgi_req, id, pos, len)) {
481                 goto error;
482         }
483         lua_pushnil(L);
484         return 1;
485 error:
486         lua_pushstring(L, "unable to send websocket message from sharedarea");
487         lua_error(L);
488         return 0;
489 }
490 
uwsgi_api_websocket_recv(lua_State * L)491 static int uwsgi_api_websocket_recv(lua_State *L) {
492 	struct wsgi_request *wsgi_req = current_wsgi_req();
493         struct uwsgi_buffer *ub = uwsgi_websocket_recv(wsgi_req);
494 	if (!ub) {
495         	lua_pushstring(L, "unable to receive websocket message");
496         	lua_error(L);
497         	return 0;
498 	}
499 	lua_pushlstring(L, ub->buf, ub->pos);
500 	uwsgi_buffer_destroy(ub);
501 	return 1;
502 }
503 
uwsgi_api_websocket_recv_nb(lua_State * L)504 static int uwsgi_api_websocket_recv_nb(lua_State *L) {
505         struct wsgi_request *wsgi_req = current_wsgi_req();
506         struct uwsgi_buffer *ub = uwsgi_websocket_recv_nb(wsgi_req);
507         if (!ub) {
508                 lua_pushstring(L, "unable to receive websocket message");
509                 lua_error(L);
510                 return 0;
511         }
512         lua_pushlstring(L, ub->buf, ub->pos);
513         uwsgi_buffer_destroy(ub);
514         return 1;
515 }
516 
uwsgi_api_cache_get(lua_State * L)517 static int uwsgi_api_cache_get(lua_State *L) {
518 
519         char *value ;
520         uint64_t valsize;
521 	size_t keylen;
522 	const char *key ;
523 	const char *cache = NULL;
524 	uint8_t argc = lua_gettop(L);
525 
526 	if (argc == 0) goto error;
527 
528 	if (lua_isstring(L, 1)) {
529 		// get the key
530 		key = lua_tolstring(L, 1, &keylen);
531 		if (argc > 1) {
532 			cache = lua_tolstring(L, 2, NULL);
533 		}
534         	value = uwsgi_cache_magic_get((char *)key, keylen, &valsize, NULL, (char *)cache);
535         	if (value) {
536                 	lua_pushlstring(L, value, valsize);
537 			free(value);
538 			return 1;
539         	}
540 	}
541 
542 error:
543 	lua_pushnil(L);
544         return 1;
545 
546 }
547 
uwsgi_api_req_fd(lua_State * L)548 static int uwsgi_api_req_fd(lua_State *L) {
549 
550 	struct wsgi_request *wsgi_req = current_wsgi_req();
551 
552 	lua_pushnumber(L, wsgi_req->fd);
553 	return 1;
554 }
555 
uwsgi_api_lock(lua_State * L)556 static int uwsgi_api_lock(lua_State *L) {
557 
558 	int lock_num = 0;
559 
560 	// the spooler cannot lock resources
561 	if (uwsgi.i_am_a_spooler) {
562 		lua_pushstring(L, "The spooler cannot lock/unlock resources");
563 		lua_error(L);
564 	}
565 
566 	if (lua_gettop(L) > 0) {
567 		lock_num = lua_isnumber(L, 1) ? lua_tonumber(L, 1) : -1;
568 		if (lock_num < 0 || lock_num > uwsgi.locks) {
569 			lua_pushstring(L, "Invalid lock number");
570 	    		lua_error(L);
571 	  	}
572 	}
573 
574 	uwsgi_lock(uwsgi.user_lock[lock_num]);
575 
576 	return 0;
577 }
578 
579 
uwsgi_api_unlock(lua_State * L)580 static int uwsgi_api_unlock(lua_State *L) {
581 
582 	int lock_num = 0;
583 
584 	// the spooler cannot lock resources
585 	if (uwsgi.i_am_a_spooler) {
586 		lua_pushstring(L, "The spooler cannot lock/unlock resources");
587 		lua_error(L);
588 	}
589 
590 	if (lua_gettop(L) > 0) {
591 		lock_num = lua_isnumber(L, 1) ? lua_tonumber(L, 1) : -1;
592 		if (lock_num < 0 || lock_num > uwsgi.locks) {
593 			lua_pushstring(L, "Invalid lock number");
594 	    		lua_error(L);
595 	  	}
596 	}
597 
598 	uwsgi_unlock(uwsgi.user_lock[lock_num]);
599 
600 	return 0;
601 }
602 
603 static const luaL_Reg uwsgi_api[] = {
604   {"log", uwsgi_api_log},
605   {"connection_fd", uwsgi_api_req_fd},
606 
607   {"cache_get", uwsgi_api_cache_get},
608   {"cache_set", uwsgi_api_cache_set},
609   {"cache_update", uwsgi_api_cache_update},
610   {"cache_del", uwsgi_api_cache_del},
611   {"cache_exists", uwsgi_api_cache_exists},
612   {"cache_clear", uwsgi_api_cache_clear},
613 
614   {"register_signal", uwsgi_api_register_signal},
615   {"register_rpc", uwsgi_api_register_rpc},
616 
617   {"websocket_handshake", uwsgi_api_websocket_handshake},
618   {"websocket_recv", uwsgi_api_websocket_recv},
619   {"websocket_recv_nb", uwsgi_api_websocket_recv_nb},
620   {"websocket_send", uwsgi_api_websocket_send},
621   {"websocket_send_from_sharedarea", uwsgi_api_websocket_send_from_sharedarea},
622   {"websocket_send_binary", uwsgi_api_websocket_send_binary},
623   {"websocket_send_binary_from_sharedarea", uwsgi_api_websocket_send_binary_from_sharedarea},
624 
625   {"lock", uwsgi_api_lock},
626   {"unlock", uwsgi_api_unlock},
627 
628   {"async_sleep", uwsgi_api_async_sleep},
629   {"async_connect", uwsgi_api_async_connect},
630   {"is_connected", uwsgi_api_is_connected},
631   {"close", uwsgi_api_close},
632   {"wait_fd_read", uwsgi_api_wait_fd_read},
633   {"wait_fd_write", uwsgi_api_wait_fd_write},
634   {"ready_fd", uwsgi_api_ready_fd},
635 
636   {NULL, NULL}
637 };
638 
639 
640 
uwsgi_lua_input(lua_State * L)641 static int uwsgi_lua_input(lua_State *L) {
642 
643 	struct wsgi_request *wsgi_req = current_wsgi_req();
644 	ssize_t sum = 0;
645 
646 	int n = lua_gettop(L);
647 
648 	if (n > 1) {
649 		sum = lua_tonumber(L, 2);
650 	}
651 
652 	ssize_t rlen = 0;
653 
654         char *buf = uwsgi_request_body_read(wsgi_req, sum, &rlen);
655         if (buf) {
656 		lua_pushlstring(L, buf, rlen);
657                 return 1;
658         }
659 
660 	return 0;
661 }
662 
uwsgi_lua_init()663 static int uwsgi_lua_init(){
664 
665 	uwsgi_log("Initializing Lua environment... (%d lua_States)\n", uwsgi.cores);
666 
667 	ulua.L = uwsgi_malloc( sizeof(lua_State*) * uwsgi.cores );
668 
669 	// ok the lua engine is ready
670 	return 0;
671 
672 
673 }
674 
uwsgi_lua_app()675 static void uwsgi_lua_app() {
676 	int i;
677 
678 	if (!ulua.filename && !ulua.load && !ulua.shell) return;
679 
680 		for(i=0;i<uwsgi.cores;i++) {
681 			ulua.L[i] = luaL_newstate();
682 			luaL_openlibs(ulua.L[i]);
683 			luaL_newuwsgilib(ulua.L[i], uwsgi_api);
684 
685 			lua_pushstring(ulua.L[i], UWSGI_VERSION);
686         		lua_setfield(ulua.L[i], -2, "version");
687 
688 			struct uwsgi_string_list *usl = ulua.load;
689 			while(usl) {
690 				if (luaL_dofile(ulua.L[i], usl->value)) {
691                                         uwsgi_log("unable to load Lua file %s: %s\n", usl->value, lua_tostring(ulua.L[i], -1));
692                                         exit(1);
693                                 }
694 				usl = usl->next;
695 			}
696 
697 			if (ulua.filename) {
698 				if (luaL_loadfile(ulua.L[i], ulua.filename)) {
699 					uwsgi_log("unable to load Lua file %s: %s\n", ulua.filename, lua_tostring(ulua.L[i], -1));
700 					exit(1);
701 				}
702 
703 				// use a pcall
704 				//lua_call(ulua.L[i], 0, 1);
705 				if (lua_pcall(ulua.L[i], 0, 1, 0) != 0) {
706 					uwsgi_log("%s\n", lua_tostring(ulua.L[i], -1));
707 					exit(1);
708 				}
709 
710 				// if the loaded lua app returns as a table, fetch the
711 				// run function.
712 				if (lua_istable(ulua.L[i], 2)) {
713 					lua_pushstring(ulua.L[i], "run" );
714 					lua_gettable(ulua.L[i], 2);
715 					lua_replace(ulua.L[i], 2);
716 				}
717 
718 				if (! lua_isfunction(ulua.L[i], 2))	{
719 					uwsgi_log("Can't find WSAPI entry point (no function, nor a table with function'run').\n");
720 					exit(1);
721 				}
722 			}
723 
724 	}
725 }
726 
uwsgi_lua_request(struct wsgi_request * wsgi_req)727 static int uwsgi_lua_request(struct wsgi_request *wsgi_req) {
728 
729 	int i;
730 	const char *http, *http2;
731 	size_t slen, slen2;
732 	char *ptrbuf;
733 	lua_State *L = ulua.L[wsgi_req->async_id];
734 
735 	if (wsgi_req->async_status == UWSGI_AGAIN) {
736 		if ((i = lua_pcall(L, 0, 1, 0)) == 0) {
737 			if (lua_type(L, -1) == LUA_TSTRING) {
738 				http = lua_tolstring(L, -1, &slen);
739 				uwsgi_response_write_body_do(wsgi_req, (char *)http, slen);
740 			}
741 			lua_pop(L, 1);
742 			lua_pushvalue(L, -1);
743 			return UWSGI_AGAIN;
744 		}
745 		goto clear;
746 	}
747 
748 	/* Standard WSAPI request */
749 	if (!wsgi_req->uh->pktsize) {
750 		uwsgi_log( "Empty lua request. skip.\n");
751 		return -1;
752 	}
753 
754 	if (uwsgi_parse_vars(wsgi_req)) {
755 		return -1;
756 	}
757 
758 	// put function in the stack
759 	//lua_getfield(L, LUA_GLOBALSINDEX, "run");
760 	lua_pushvalue(L, -1);
761 
762 	// put cgi vars in the stack
763 
764 	lua_newtable(L);
765 	lua_pushstring(L, "");
766 	lua_setfield(L, -2, "CONTENT_TYPE");
767 	for(i=0;i<wsgi_req->var_cnt;i+=2) {
768 		lua_pushlstring(L, (char *)wsgi_req->hvec[i+1].iov_base, wsgi_req->hvec[i+1].iov_len);
769 		// transform it in a valid c string TODO this is ugly
770 		ptrbuf = wsgi_req->hvec[i].iov_base+wsgi_req->hvec[i].iov_len;
771 		*ptrbuf = 0;
772 		lua_setfield(L, -2, (char *)wsgi_req->hvec[i].iov_base);
773 	}
774 
775 
776 	// put "input" table
777 	lua_newtable(L);
778 	lua_pushcfunction(L, uwsgi_lua_input);
779 	lua_setfield(L, -2, "read");
780 	lua_setfield(L, -2, "input");
781 
782 #ifdef UWSGI_DEBUG
783 	uwsgi_log("stack pos %d\n", lua_gettop(L));
784 #endif
785 
786 	// call function
787 	i = lua_pcall(L, 1, 3, 0);
788 	if (i != 0) {
789 		uwsgi_log("%s\n", lua_tostring(L, -1));
790 		lua_pop(L, 1);
791                 lua_pushvalue(L, -1);
792 		goto clear2;
793 	}
794 
795 	//uwsgi_log("%d %s %s %s\n",i,lua_typename(L, lua_type(L, -3)), lua_typename(L, lua_type(L, -2)) ,  lua_typename(L, lua_type(L, -1)));
796 
797 	// send status
798 	if (lua_type(L, -3) == LUA_TSTRING || lua_type(L, -3) == LUA_TNUMBER) {
799 		http = lua_tolstring(L, -3, &slen);
800 		if (uwsgi_response_prepare_headers(wsgi_req, (char *) http, slen))
801 			goto clear2;
802 	}
803 	else {
804 		uwsgi_log("[uwsgi-lua] invalid response status !!!\n");
805 		// let's continue
806 	}
807 
808 	// send headers
809 
810 	lua_pushnil(L);
811 	while(lua_next(L, -3) != 0) {
812 		http = lua_tolstring(L, -2, &slen);
813 
814 		if (lua_type(L, -1) == LUA_TTABLE) {
815 			for (i = 1; /*empty*/ ; ++i) {
816 				lua_rawgeti(L, -1, i);
817 
818 				if (lua_isnil(L, -1)) {
819 					lua_pop(L, 1);
820 					break;
821 				}
822 
823 				http2 = lua_tolstring(L, -1, &slen2);
824 				uwsgi_response_add_header(wsgi_req, (char *) http, slen, (char *) http2, slen2);
825 				lua_pop(L, 1);
826 			}
827 		}
828 		else {
829 			http2 = lua_tolstring(L, -1, &slen2);
830 			uwsgi_response_add_header(wsgi_req, (char *) http, slen, (char *) http2, slen2);
831 		}
832 		lua_pop(L, 1);
833 	}
834 
835 	// send body with coroutine
836 	lua_pushvalue(L, -1);
837 
838 	while ( (i = lua_pcall(L, 0, 1, 0)) == 0) {
839 		if (lua_type(L, -1) == LUA_TSTRING) {
840 			http = lua_tolstring(L, -1, &slen);
841 			uwsgi_response_write_body_do(wsgi_req, (char *)http, slen);
842 		}
843 		lua_pop(L, 1);
844 		lua_pushvalue(L, -1);
845 		if (uwsgi.async > 1) {
846 			return UWSGI_AGAIN;
847 		}
848 	}
849 clear:
850 	lua_pop(L, 4);
851 clear2:
852 	// set frequency
853 	if (!ulua.gc_freq || uwsgi.workers[uwsgi.mywid].cores[wsgi_req->async_id].requests % ulua.gc_freq == 0) {
854 		lua_gc(L, LUA_GCCOLLECT, 0);
855 	}
856 
857 	return UWSGI_OK;
858 
859 }
860 
uwsgi_lua_after_request(struct wsgi_request * wsgi_req)861 static void uwsgi_lua_after_request(struct wsgi_request *wsgi_req) {
862 
863 	log_request(wsgi_req);
864 }
865 
866 
uwsgi_lua_magic(char * mountpoint,char * lazy)867 static int uwsgi_lua_magic(char *mountpoint, char *lazy) {
868 
869 	if (!strcmp(lazy+strlen(lazy)-4, ".lua")) {
870                 ulua.filename = lazy;
871                 return 1;
872         }
873         else if (!strcmp(lazy+strlen(lazy)-3, ".ws")) {
874                 ulua.filename = lazy;
875                 return 1;
876         }
877 
878 
879 	return 0;
880 }
881 
uwsgi_lua_code_string(char * id,char * code,char * func,char * key,uint16_t keylen)882 static char *uwsgi_lua_code_string(char *id, char *code, char *func, char *key, uint16_t keylen) {
883 
884 	static struct lua_State *L = NULL;
885 
886 	if (!L) {
887 		L = luaL_newstate();
888                 luaL_openlibs(L);
889                 if (luaL_loadfile(L, code) || lua_pcall(L, 0, 0, 0)) {
890                 	uwsgi_log("unable to load file %s: %s\n", code, lua_tostring(L, -1));
891 			lua_close(L);
892 			L = NULL;
893 			return NULL;
894                 }
895 		lua_getglobal(L, func);
896 		if (!lua_isfunction(L,-1)) {
897 			uwsgi_log("unable to find %s function in lua file %s\n", func, code);
898 			lua_close(L);
899 			L = NULL;
900 			return NULL;
901 		}
902 		lua_pushnil(L);
903 	}
904 
905 
906 	lua_pop(L, 1);
907 
908 	lua_pushvalue(L, -1);
909 	lua_pushlstring(L, key, keylen);
910 
911 #ifdef UWSGI_DEBUG
912 	uwsgi_log("stack pos %d %.*s\n", lua_gettop(L), keylen, key);
913 #endif
914 
915         if (lua_pcall(L, 1, 1, 0) != 0) {
916                 uwsgi_log("error running function `f': %s",
917                  lua_tostring(L, -1));
918                 return NULL;
919 
920         }
921 
922 	if (lua_isstring(L, -1)) {
923                 const char *ret = lua_tolstring(L, -1, NULL);
924 		return (char *)ret;
925         }
926 
927         return NULL;
928 }
929 
uwsgi_lua_signal_handler(uint8_t sig,void * handler)930 static int uwsgi_lua_signal_handler(uint8_t sig, void *handler) {
931 
932 	struct wsgi_request *wsgi_req = current_wsgi_req();
933 
934 	lua_State *L = ulua.L[wsgi_req->async_id];
935 
936 #ifdef UWSGI_DEBUG
937 	uwsgi_log("managing signal handler on core %d\n", wsgi_req->async_id);
938 #endif
939 
940 	lua_rawgeti(L, LUA_REGISTRYINDEX, (long) handler);
941 
942 	lua_pushnumber(L, sig);
943 
944 	if (lua_pcall(L, 1, 1, 0) != 0) {
945 		uwsgi_log("error running function `f': %s",
946                  lua_tostring(L, -1));
947 
948 		return -1;
949 
950 	}
951 
952 	return 0;
953 
954 }
955 
uwsgi_lua_rpc(void * func,uint8_t argc,char ** argv,uint16_t argvs[],char ** buffer)956 static uint64_t uwsgi_lua_rpc(void * func, uint8_t argc, char **argv, uint16_t argvs[], char **buffer) {
957 
958         uint8_t i;
959         const char *sv;
960         size_t sl;
961 	long lfunc = (long) func;
962 	int ifunc = lfunc;
963 
964 	struct wsgi_request *wsgi_req = current_wsgi_req();
965 
966 	lua_State *L = ulua.L[wsgi_req->async_id];
967 
968 #ifdef UWSGI_DEBUG
969 	uwsgi_log("get function %d\n", ifunc);
970 #endif
971 	lua_rawgeti(L, LUA_REGISTRYINDEX, ifunc);
972 
973         for(i=0;i<argc;i++) {
974 		lua_pushlstring(L, argv[i], argvs[i]);
975         }
976 
977         if (lua_pcall(L, argc, 1, 0) != 0) {
978 		uwsgi_log("error running function `f': %s", lua_tostring(L, -1));
979 		return 0;
980         }
981 
982 
983 	sv = lua_tolstring(L, -1, &sl);
984 
985 #ifdef UWSGI_DEBUG
986 	uwsgi_log("sv = %s sl = %lu\n", sv, (unsigned long) sl);
987 #endif
988 	if (sl > 0) {
989 		*buffer = uwsgi_malloc(sl);
990 		memcpy(*buffer, sv, sl);
991 		lua_pop(L, 1);
992 		return sl;
993 	}
994 
995 	lua_pop(L, 1);
996         return 0;
997 
998 }
999 
uwsgi_lua_configurator_array(lua_State * L)1000 static void uwsgi_lua_configurator_array(lua_State *L) {
1001 
1002 	int i;
1003 	int n = lua_rawlen(L, -3);
1004 
1005 	for(i=1;i<=n;i++) {
1006 		lua_rawgeti(L, 1, i);
1007 		if (lua_istable(L, -1)) {
1008                 	lua_pushnil(L);
1009                         while (lua_next(L, -2) != 0) {
1010                         	char *key = uwsgi_str((char *)lua_tostring(L, -2));
1011                                 char *value = uwsgi_str((char *)lua_tostring(L, -1));
1012                                 add_exported_option(key, value, 0);
1013                                 lua_pop(L, 1);
1014                         }
1015                 }
1016 	}
1017 }
1018 
1019 
uwsgi_lua_configurator(char * filename,char * magic_table[])1020 static void uwsgi_lua_configurator(char *filename, char *magic_table[]) {
1021 	size_t len = 0;
1022 	uwsgi_log_initial("[uWSGI] getting Lua configuration from %s\n", filename);
1023 	char *code = uwsgi_open_and_read(filename, &len, 1, magic_table);
1024 	lua_State *L = luaL_newstate();
1025 	if (!L) {
1026 		uwsgi_log("unable to initialize Lua state for configuration\n");
1027 		exit(1);
1028 	}
1029         luaL_openlibs(L);
1030 	if (luaL_dostring(L, code) != 0) {
1031 		uwsgi_log("error running Lua configurator: %s\n", lua_tostring(L, -1));
1032 		exit(1);
1033 	}
1034 	free(code);
1035 
1036 	if (!lua_istable(L, -1)) {
1037 		uwsgi_log("Lua configurator has to return a table !!!\n");
1038 		exit(1);
1039 	}
1040 
1041 	lua_pushnil(L);
1042 	// we always use uwsgi_str to avoid GC destroying our strings
1043 	// and to be able to call lua_close at the end
1044 	while (lua_next(L, -2) != 0) {
1045 		// array ?
1046 		if (lua_isnumber(L, -2)) {
1047 			uwsgi_lua_configurator_array(L);
1048 			break;
1049 		}
1050 		// dictionary
1051 		else {
1052 			char *key = uwsgi_str((char *)lua_tostring(L, -2));
1053 			if (lua_istable(L, -1)) {
1054 				lua_pushnil(L);
1055 				while (lua_next(L, -2) != 0) {
1056 					char *value = uwsgi_str((char *)lua_tostring(L, -1));
1057 					add_exported_option(key, value, 0);
1058 					lua_pop(L, 1);
1059 				}
1060 			}
1061 			else {
1062 				char *value = uwsgi_str((char *)lua_tostring(L, -1));
1063 				add_exported_option(key, value, 0);
1064 			}
1065 		}
1066 		lua_pop(L, 1);
1067 	}
1068 
1069 	// this will destroy the whole Lua state
1070 	lua_close(L);
1071 }
1072 
uwsgi_register_lua_features()1073 static void uwsgi_register_lua_features() {
1074 	uwsgi_register_configurator(".lua", uwsgi_lua_configurator);
1075 }
1076 
uwsgi_lua_hijack(void)1077 static void uwsgi_lua_hijack(void) {
1078         if (ulua.shell && uwsgi.mywid == 1) {
1079                 uwsgi.workers[uwsgi.mywid].hijacked = 1;
1080                 uwsgi.workers[uwsgi.mywid].hijacked_count++;
1081                 // re-map stdin to stdout and stderr if we are logging to a file
1082                 if (uwsgi.logfile) {
1083                         if (dup2(0, 1) < 0) {
1084                                 uwsgi_error("dup2()");
1085                         }
1086                         if (dup2(0, 2) < 0) {
1087                                 uwsgi_error("dup2()");
1088                         }
1089                 }
1090                 int ret = -1;
1091 		// run in the first state
1092 		lua_State *L = ulua.L[0];
1093 		lua_getglobal(L, "debug");
1094 		lua_getfield(L, -1, "debug");
1095 		ret = lua_pcall(L, 0, 0, 0);
1096                 if (ret == 0) {
1097                         exit(UWSGI_QUIET_CODE);
1098                 }
1099                 exit(0);
1100         }
1101 
1102 }
1103 
1104 
1105 struct uwsgi_plugin lua_plugin = {
1106 
1107 	.name = "lua",
1108 	.modifier1 = 6,
1109 	.init = uwsgi_lua_init,
1110 	.options = uwsgi_lua_options,
1111 	.request = uwsgi_lua_request,
1112 	.after_request = uwsgi_lua_after_request,
1113 	.init_apps = uwsgi_lua_app,
1114 	.magic = uwsgi_lua_magic,
1115 	.signal_handler = uwsgi_lua_signal_handler,
1116 
1117 	.hijack_worker = uwsgi_lua_hijack,
1118 
1119 	.code_string = uwsgi_lua_code_string,
1120 	.rpc = uwsgi_lua_rpc,
1121 
1122 	.on_load = uwsgi_register_lua_features,
1123 };
1124 
1125