1 /*
2  * Lua unsafe core engine
3  *
4  * Copyright 2015-2016 Thierry Fournier <tfournier@arpalert.org>
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version
9  * 2 of the License, or (at your option) any later version.
10  *
11  */
12 
13 #define _GNU_SOURCE
14 
15 #include <ctype.h>
16 #include <limits.h>
17 #include <setjmp.h>
18 
19 #include <lauxlib.h>
20 #include <lua.h>
21 #include <lualib.h>
22 
23 #if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 503
24 #error "Requires Lua 5.3 or later."
25 #endif
26 
27 #include <ebpttree.h>
28 
29 #include <common/cfgparse.h>
30 #include <common/compiler.h>
31 #include <common/hathreads.h>
32 #include <common/initcall.h>
33 #include <common/xref.h>
34 #include <common/h1.h>
35 
36 #include <types/cli.h>
37 #include <types/hlua.h>
38 #include <types/proxy.h>
39 #include <types/stats.h>
40 
41 #include <proto/arg.h>
42 #include <proto/applet.h>
43 #include <proto/channel.h>
44 #include <proto/cli.h>
45 #include <proto/connection.h>
46 #include <proto/stats.h>
47 #include <proto/hdr_idx.h>
48 #include <proto/hlua.h>
49 #include <proto/hlua_fcn.h>
50 #include <proto/http_fetch.h>
51 #include <proto/http_htx.h>
52 #include <proto/http_rules.h>
53 #include <proto/map.h>
54 #include <proto/obj_type.h>
55 #include <proto/queue.h>
56 #include <proto/pattern.h>
57 #include <proto/payload.h>
58 #include <proto/proto_http.h>
59 #include <proto/sample.h>
60 #include <proto/server.h>
61 #include <proto/session.h>
62 #include <proto/stream.h>
63 #include <proto/stream_interface.h>
64 #include <proto/task.h>
65 #include <proto/tcp_rules.h>
66 #include <proto/vars.h>
67 
68 /* Lua uses longjmp to perform yield or throwing errors. This
69  * macro is used only for identifying the function that can
70  * not return because a longjmp is executed.
71  *   __LJMP marks a prototype of hlua file that can use longjmp.
72  *   WILL_LJMP() marks an lua function that will use longjmp.
73  *   MAY_LJMP() marks an lua function that may use longjmp.
74  */
75 #define __LJMP
76 #define WILL_LJMP(func) do { func; my_unreachable(); } while(0)
77 #define MAY_LJMP(func) func
78 
79 /* This couple of function executes securely some Lua calls outside of
80  * the lua runtime environment. Each Lua call can return a longjmp
81  * if it encounter a memory error.
82  *
83  * Lua documentation extract:
84  *
85  *   If an error happens outside any protected environment, Lua calls
86  *   a panic function (see lua_atpanic) and then calls abort, thus
87  *   exiting the host application. Your panic function can avoid this
88  *   exit by never returning (e.g., doing a long jump to your own
89  *   recovery point outside Lua).
90  *
91  *   The panic function runs as if it were a message handler (see
92  *   §2.3); in particular, the error message is at the top of the
93  *   stack. However, there is no guarantee about stack space. To push
94  *   anything on the stack, the panic function must first check the
95  *   available space (see §4.2).
96  *
97  * We must check all the Lua entry point. This includes:
98  *  - The include/proto/hlua.h exported functions
99  *  - the task wrapper function
100  *  - The action wrapper function
101  *  - The converters wrapper function
102  *  - The sample-fetch wrapper functions
103  *
104  * It is tolerated that the initilisation function returns an abort.
105  * Before each Lua abort, an error message is written on stderr.
106  *
107  * The macro SET_SAFE_LJMP initialise the longjmp. The Macro
108  * RESET_SAFE_LJMP reset the longjmp. These function must be macro
109  * because they must be exists in the program stack when the longjmp
110  * is called.
111  *
112  * Note that the Lua processing is not really thread safe. It provides
113  * heavy system which consists to add our own lock function in the Lua
114  * code and recompile the library. This system will probably not accepted
115  * by maintainers of various distribs.
116  *
117  * Our main excution point of the Lua is the function lua_resume(). A
118  * quick looking on the Lua sources displays a lua_lock() a the start
119  * of function and a lua_unlock() at the end of the function. So I
120  * conclude that the Lua thread safe mode just perform a mutex around
121  * all execution. So I prefer to do this in the HAProxy code, it will be
122  * easier for distro maintainers.
123  *
124  * Note that the HAProxy lua functions rounded by the macro SET_SAFE_LJMP
125  * and RESET_SAFE_LJMP manipulates the Lua stack, so it will be careful
126  * to set mutex around these functions.
127  */
128 __decl_spinlock(hlua_global_lock);
129 THREAD_LOCAL jmp_buf safe_ljmp_env;
hlua_panic_safe(lua_State * L)130 static int hlua_panic_safe(lua_State *L) { return 0; }
hlua_panic_ljmp(lua_State * L)131 static int hlua_panic_ljmp(lua_State *L) { longjmp(safe_ljmp_env, 1); }
132 
133 #define SET_SAFE_LJMP(__L) \
134 	({ \
135 		int ret; \
136 		HA_SPIN_LOCK(LUA_LOCK, &hlua_global_lock); \
137 		if (setjmp(safe_ljmp_env) != 0) { \
138 			lua_atpanic(__L, hlua_panic_safe); \
139 			ret = 0; \
140 			HA_SPIN_UNLOCK(LUA_LOCK, &hlua_global_lock); \
141 		} else { \
142 			lua_atpanic(__L, hlua_panic_ljmp); \
143 			ret = 1; \
144 		} \
145 		ret; \
146 	})
147 
148 /* If we are the last function catching Lua errors, we
149  * must reset the panic function.
150  */
151 #define RESET_SAFE_LJMP(__L) \
152 	do { \
153 		lua_atpanic(__L, hlua_panic_safe); \
154 		HA_SPIN_UNLOCK(LUA_LOCK, &hlua_global_lock); \
155 	} while(0)
156 
157 /* Applet status flags */
158 #define APPLET_DONE     0x01 /* applet processing is done. */
159 /* unused: 0x02 */
160 #define APPLET_HDR_SENT 0x04 /* Response header sent. */
161 #define APPLET_CHUNKED  0x08 /* Use transfer encoding chunked. */
162 #define APPLET_LAST_CHK 0x10 /* Last chunk sent. */
163 #define APPLET_HTTP11   0x20 /* Last chunk sent. */
164 #define APPLET_RSP_SENT 0x40 /* The response was fully sent */
165 
166 /* The main Lua execution context. */
167 struct hlua gL;
168 
169 /* This is the memory pool containing struct lua for applets
170  * (including cli).
171  */
172 DECLARE_STATIC_POOL(pool_head_hlua, "hlua", sizeof(struct hlua));
173 
174 /* Used for Socket connection. */
175 static struct proxy socket_proxy;
176 static struct server socket_tcp;
177 #ifdef USE_OPENSSL
178 static struct server socket_ssl;
179 #endif
180 
181 /* List head of the function called at the initialisation time. */
182 struct list hlua_init_functions = LIST_HEAD_INIT(hlua_init_functions);
183 
184 /* The following variables contains the reference of the different
185  * Lua classes. These references are useful for identify metadata
186  * associated with an object.
187  */
188 static int class_txn_ref;
189 static int class_socket_ref;
190 static int class_channel_ref;
191 static int class_fetches_ref;
192 static int class_converters_ref;
193 static int class_http_ref;
194 static int class_map_ref;
195 static int class_applet_tcp_ref;
196 static int class_applet_http_ref;
197 
198 /* Global Lua execution timeout. By default Lua, execution linked
199  * with stream (actions, sample-fetches and converters) have a
200  * short timeout. Lua linked with tasks doesn't have a timeout
201  * because a task may remain alive during all the haproxy execution.
202  */
203 static unsigned int hlua_timeout_session = 4000; /* session timeout. */
204 static unsigned int hlua_timeout_task = TICK_ETERNITY; /* task timeout. */
205 static unsigned int hlua_timeout_applet = 4000; /* applet timeout. */
206 
207 /* Interrupts the Lua processing each "hlua_nb_instruction" instructions.
208  * it is used for preventing infinite loops.
209  *
210  * I test the scheer with an infinite loop containing one incrementation
211  * and one test. I run this loop between 10 seconds, I raise a ceil of
212  * 710M loops from one interrupt each 9000 instructions, so I fix the value
213  * to one interrupt each 10 000 instructions.
214  *
215  *  configured    | Number of
216  *  instructions  | loops executed
217  *  between two   | in milions
218  *  forced yields |
219  * ---------------+---------------
220  *  10            | 160
221  *  500           | 670
222  *  1000          | 680
223  *  5000          | 700
224  *  7000          | 700
225  *  8000          | 700
226  *  9000          | 710 <- ceil
227  *  10000         | 710
228  *  100000        | 710
229  *  1000000       | 710
230  *
231  */
232 static unsigned int hlua_nb_instruction = 10000;
233 
234 /* Descriptor for the memory allocation state. If limit is not null, it will
235  * be enforced on any memory allocation.
236  */
237 struct hlua_mem_allocator {
238 	size_t allocated;
239 	size_t limit;
240 };
241 
242 static struct hlua_mem_allocator hlua_global_allocator;
243 
244 static const char error_500[] =
245 	"HTTP/1.0 500 Internal Server Error\r\n"
246 	"Cache-Control: no-cache\r\n"
247 	"Connection: close\r\n"
248 	"Content-Type: text/html\r\n"
249 	"\r\n"
250 	"<html><body><h1>500 Internal Server Error</h1>\nAn internal server error occurred.\n</body></html>\n";
251 
252 /* These functions converts types between HAProxy internal args or
253  * sample and LUA types. Another function permits to check if the
254  * LUA stack contains arguments according with an required ARG_T
255  * format.
256  */
257 static int hlua_arg2lua(lua_State *L, const struct arg *arg);
258 static int hlua_lua2arg(lua_State *L, int ud, struct arg *arg);
259 __LJMP static int hlua_lua2arg_check(lua_State *L, int first, struct arg *argp,
260                                      uint64_t mask, struct proxy *p);
261 static int hlua_smp2lua(lua_State *L, struct sample *smp);
262 static int hlua_smp2lua_str(lua_State *L, struct sample *smp);
263 static int hlua_lua2smp(lua_State *L, int ud, struct sample *smp);
264 
265 __LJMP static int hlua_http_get_headers(lua_State *L, struct hlua_txn *htxn, struct http_msg *msg);
266 
267 #define SEND_ERR(__be, __fmt, __args...) \
268 	do { \
269 		send_log(__be, LOG_ERR, __fmt, ## __args); \
270 		if (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE)) \
271 			ha_alert(__fmt, ## __args); \
272 	} while (0)
273 
274 /* Used to check an Lua function type in the stack. It creates and
275  * returns a reference of the function. This function throws an
276  * error if the rgument is not a "function".
277  */
hlua_checkfunction(lua_State * L,int argno)278 __LJMP unsigned int hlua_checkfunction(lua_State *L, int argno)
279 {
280 	if (!lua_isfunction(L, argno)) {
281 		const char *msg = lua_pushfstring(L, "function expected, got %s", luaL_typename(L, argno));
282 		WILL_LJMP(luaL_argerror(L, argno, msg));
283 	}
284 	lua_pushvalue(L, argno);
285 	return luaL_ref(L, LUA_REGISTRYINDEX);
286 }
287 
288 /* Return the string that is of the top of the stack. */
hlua_get_top_error_string(lua_State * L)289 const char *hlua_get_top_error_string(lua_State *L)
290 {
291 	if (lua_gettop(L) < 1)
292 		return "unknown error";
293 	if (lua_type(L, -1) != LUA_TSTRING)
294 		return "unknown error";
295 	return lua_tostring(L, -1);
296 }
297 
hlua_traceback(lua_State * L,const char * sep)298 __LJMP const char *hlua_traceback(lua_State *L, const char* sep)
299 {
300 	lua_Debug ar;
301 	int level = 0;
302 	struct buffer *msg = get_trash_chunk();
303 
304 	while (lua_getstack(L, level++, &ar)) {
305 
306 		/* Add separator */
307 		if (b_data(msg))
308 			chunk_appendf(msg, "%s", sep);
309 
310 		/* Fill fields:
311 		 * 'S': fills in the fields source, short_src, linedefined, lastlinedefined, and what;
312 		 * 'l': fills in the field currentline;
313 		 * 'n': fills in the field name and namewhat;
314 		 * 't': fills in the field istailcall;
315 		 */
316 		lua_getinfo(L, "Slnt", &ar);
317 
318 		/* Append code localisation */
319 		if (ar.currentline > 0)
320 			chunk_appendf(msg, "%s:%d: ", ar.short_src, ar.currentline);
321 		else
322 			chunk_appendf(msg, "%s: ", ar.short_src);
323 
324 		/*
325 		 * Get function name
326 		 *
327 		 * if namewhat is no empty, name is defined.
328 		 * what contains "Lua" for Lua function, "C" for C function,
329 		 * or "main" for main code.
330 		 */
331 		if (*ar.namewhat != '\0' && ar.name != NULL)  /* is there a name from code? */
332 			chunk_appendf(msg, "in %s '%s'", ar.namewhat, ar.name);  /* use it */
333 
334 		else if (*ar.what == 'm')  /* "main", the code is not executed in a function */
335 			chunk_appendf(msg, "in main chunk");
336 
337 		else if (*ar.what != 'C')  /* for Lua functions, use <file:line> */
338 			chunk_appendf(msg, "in function line %d", ar.linedefined);
339 
340 		else  /* nothing left... */
341 			chunk_appendf(msg, "?");
342 
343 
344 		/* Display tailed call */
345 		if (ar.istailcall)
346 			chunk_appendf(msg, " ...");
347 	}
348 
349 	return msg->area;
350 }
351 
352 
353 /* This function check the number of arguments available in the
354  * stack. If the number of arguments available is not the same
355  * then <nb> an error is throwed.
356  */
check_args(lua_State * L,int nb,char * fcn)357 __LJMP static inline void check_args(lua_State *L, int nb, char *fcn)
358 {
359 	if (lua_gettop(L) == nb)
360 		return;
361 	WILL_LJMP(luaL_error(L, "'%s' needs %d arguments", fcn, nb));
362 }
363 
364 /* This function pushes an error string prefixed by the file name
365  * and the line number where the error is encountered.
366  */
hlua_pusherror(lua_State * L,const char * fmt,...)367 static int hlua_pusherror(lua_State *L, const char *fmt, ...)
368 {
369 	va_list argp;
370 	va_start(argp, fmt);
371 	luaL_where(L, 1);
372 	lua_pushvfstring(L, fmt, argp);
373 	va_end(argp);
374 	lua_concat(L, 2);
375 	return 1;
376 }
377 
378 /* This functions is used with sample fetch and converters. It
379  * converts the HAProxy configuration argument in a lua stack
380  * values.
381  *
382  * It takes an array of "arg", and each entry of the array is
383  * converted and pushed in the LUA stack.
384  */
hlua_arg2lua(lua_State * L,const struct arg * arg)385 static int hlua_arg2lua(lua_State *L, const struct arg *arg)
386 {
387 	switch (arg->type) {
388 	case ARGT_SINT:
389 	case ARGT_TIME:
390 	case ARGT_SIZE:
391 		lua_pushinteger(L, arg->data.sint);
392 		break;
393 
394 	case ARGT_STR:
395 		lua_pushlstring(L, arg->data.str.area, arg->data.str.data);
396 		break;
397 
398 	case ARGT_IPV4:
399 	case ARGT_IPV6:
400 	case ARGT_MSK4:
401 	case ARGT_MSK6:
402 	case ARGT_FE:
403 	case ARGT_BE:
404 	case ARGT_TAB:
405 	case ARGT_SRV:
406 	case ARGT_USR:
407 	case ARGT_MAP:
408 	default:
409 		lua_pushnil(L);
410 		break;
411 	}
412 	return 1;
413 }
414 
415 /* This function take one entrie in an LUA stack at the index "ud",
416  * and try to convert it in an HAProxy argument entry. This is useful
417  * with sample fetch wrappers. The input arguments are gived to the
418  * lua wrapper and converted as arg list by thi function.
419  */
hlua_lua2arg(lua_State * L,int ud,struct arg * arg)420 static int hlua_lua2arg(lua_State *L, int ud, struct arg *arg)
421 {
422 	switch (lua_type(L, ud)) {
423 
424 	case LUA_TNUMBER:
425 	case LUA_TBOOLEAN:
426 		arg->type = ARGT_SINT;
427 		arg->data.sint = lua_tointeger(L, ud);
428 		break;
429 
430 	case LUA_TSTRING:
431 		arg->type = ARGT_STR;
432 		arg->data.str.area = (char *)lua_tolstring(L, ud, (size_t *)&arg->data.str.data);
433 		/* We don't know the actual size of the underlying allocation, so be conservative. */
434 		arg->data.str.size = arg->data.str.data;
435 		arg->data.str.head = 0;
436 		break;
437 
438 	case LUA_TUSERDATA:
439 	case LUA_TNIL:
440 	case LUA_TTABLE:
441 	case LUA_TFUNCTION:
442 	case LUA_TTHREAD:
443 	case LUA_TLIGHTUSERDATA:
444 		arg->type = ARGT_SINT;
445 		arg->data.sint = 0;
446 		break;
447 	}
448 	return 1;
449 }
450 
451 /* the following functions are used to convert a struct sample
452  * in Lua type. This useful to convert the return of the
453  * fetchs or converters.
454  */
hlua_smp2lua(lua_State * L,struct sample * smp)455 static int hlua_smp2lua(lua_State *L, struct sample *smp)
456 {
457 	switch (smp->data.type) {
458 	case SMP_T_SINT:
459 	case SMP_T_BOOL:
460 		lua_pushinteger(L, smp->data.u.sint);
461 		break;
462 
463 	case SMP_T_BIN:
464 	case SMP_T_STR:
465 		lua_pushlstring(L, smp->data.u.str.area, smp->data.u.str.data);
466 		break;
467 
468 	case SMP_T_METH:
469 		switch (smp->data.u.meth.meth) {
470 		case HTTP_METH_OPTIONS: lua_pushstring(L, "OPTIONS"); break;
471 		case HTTP_METH_GET:     lua_pushstring(L, "GET");     break;
472 		case HTTP_METH_HEAD:    lua_pushstring(L, "HEAD");    break;
473 		case HTTP_METH_POST:    lua_pushstring(L, "POST");    break;
474 		case HTTP_METH_PUT:     lua_pushstring(L, "PUT");     break;
475 		case HTTP_METH_DELETE:  lua_pushstring(L, "DELETE");  break;
476 		case HTTP_METH_TRACE:   lua_pushstring(L, "TRACE");   break;
477 		case HTTP_METH_CONNECT: lua_pushstring(L, "CONNECT"); break;
478 		case HTTP_METH_OTHER:
479 			lua_pushlstring(L, smp->data.u.meth.str.area, smp->data.u.meth.str.data);
480 			break;
481 		default:
482 			lua_pushnil(L);
483 			break;
484 		}
485 		break;
486 
487 	case SMP_T_IPV4:
488 	case SMP_T_IPV6:
489 	case SMP_T_ADDR: /* This type is never used to qualify a sample. */
490 		if (sample_casts[smp->data.type][SMP_T_STR] &&
491 		    sample_casts[smp->data.type][SMP_T_STR](smp))
492 			lua_pushlstring(L, smp->data.u.str.area, smp->data.u.str.data);
493 		else
494 			lua_pushnil(L);
495 		break;
496 	default:
497 		lua_pushnil(L);
498 		break;
499 	}
500 	return 1;
501 }
502 
503 /* the following functions are used to convert a struct sample
504  * in Lua strings. This is useful to convert the return of the
505  * fetchs or converters.
506  */
hlua_smp2lua_str(lua_State * L,struct sample * smp)507 static int hlua_smp2lua_str(lua_State *L, struct sample *smp)
508 {
509 	switch (smp->data.type) {
510 
511 	case SMP_T_BIN:
512 	case SMP_T_STR:
513 		lua_pushlstring(L, smp->data.u.str.area, smp->data.u.str.data);
514 		break;
515 
516 	case SMP_T_METH:
517 		switch (smp->data.u.meth.meth) {
518 		case HTTP_METH_OPTIONS: lua_pushstring(L, "OPTIONS"); break;
519 		case HTTP_METH_GET:     lua_pushstring(L, "GET");     break;
520 		case HTTP_METH_HEAD:    lua_pushstring(L, "HEAD");    break;
521 		case HTTP_METH_POST:    lua_pushstring(L, "POST");    break;
522 		case HTTP_METH_PUT:     lua_pushstring(L, "PUT");     break;
523 		case HTTP_METH_DELETE:  lua_pushstring(L, "DELETE");  break;
524 		case HTTP_METH_TRACE:   lua_pushstring(L, "TRACE");   break;
525 		case HTTP_METH_CONNECT: lua_pushstring(L, "CONNECT"); break;
526 		case HTTP_METH_OTHER:
527 			lua_pushlstring(L, smp->data.u.meth.str.area, smp->data.u.meth.str.data);
528 			break;
529 		default:
530 			lua_pushstring(L, "");
531 			break;
532 		}
533 		break;
534 
535 	case SMP_T_SINT:
536 	case SMP_T_BOOL:
537 	case SMP_T_IPV4:
538 	case SMP_T_IPV6:
539 	case SMP_T_ADDR: /* This type is never used to qualify a sample. */
540 		if (sample_casts[smp->data.type][SMP_T_STR] &&
541 		    sample_casts[smp->data.type][SMP_T_STR](smp))
542 			lua_pushlstring(L, smp->data.u.str.area, smp->data.u.str.data);
543 		else
544 			lua_pushstring(L, "");
545 		break;
546 	default:
547 		lua_pushstring(L, "");
548 		break;
549 	}
550 	return 1;
551 }
552 
553 /* the following functions are used to convert an Lua type in a
554  * struct sample. This is useful to provide data from a converter
555  * to the LUA code.
556  */
hlua_lua2smp(lua_State * L,int ud,struct sample * smp)557 static int hlua_lua2smp(lua_State *L, int ud, struct sample *smp)
558 {
559 	switch (lua_type(L, ud)) {
560 
561 	case LUA_TNUMBER:
562 		smp->data.type = SMP_T_SINT;
563 		smp->data.u.sint = lua_tointeger(L, ud);
564 		break;
565 
566 
567 	case LUA_TBOOLEAN:
568 		smp->data.type = SMP_T_BOOL;
569 		smp->data.u.sint = lua_toboolean(L, ud);
570 		break;
571 
572 	case LUA_TSTRING:
573 		smp->data.type = SMP_T_STR;
574 		smp->flags |= SMP_F_CONST;
575 		smp->data.u.str.area = (char *)lua_tolstring(L, ud, (size_t *)&smp->data.u.str.data);
576 		/* We don't know the actual size of the underlying allocation, so be conservative. */
577 		smp->data.u.str.size = smp->data.u.str.data;
578 		smp->data.u.str.head = 0;
579 		break;
580 
581 	case LUA_TUSERDATA:
582 	case LUA_TNIL:
583 	case LUA_TTABLE:
584 	case LUA_TFUNCTION:
585 	case LUA_TTHREAD:
586 	case LUA_TLIGHTUSERDATA:
587 	case LUA_TNONE:
588 	default:
589 		smp->data.type = SMP_T_BOOL;
590 		smp->data.u.sint = 0;
591 		break;
592 	}
593 	return 1;
594 }
595 
596 /* This function check the "argp" builded by another conversion function
597  * is in accord with the expected argp defined by the "mask". The function
598  * returns true or false. It can be adjust the types if there compatibles.
599  *
600  * This function assumes thant the argp argument contains ARGM_NBARGS + 1
601  * entries.
602  */
hlua_lua2arg_check(lua_State * L,int first,struct arg * argp,uint64_t mask,struct proxy * p)603 __LJMP int hlua_lua2arg_check(lua_State *L, int first, struct arg *argp,
604                               uint64_t mask, struct proxy *p)
605 {
606 	int min_arg;
607 	int idx;
608 	struct proxy *px;
609 	char *sname, *pname;
610 
611 	idx = 0;
612 	min_arg = ARGM(mask);
613 	mask >>= ARGM_BITS;
614 
615 	while (1) {
616 
617 		/* Check oversize. */
618 		if (idx >= ARGM_NBARGS && argp[idx].type != ARGT_STOP) {
619 			WILL_LJMP(luaL_argerror(L, first + idx, "Malformed argument mask"));
620 		}
621 
622 		/* Check for mandatory arguments. */
623 		if (argp[idx].type == ARGT_STOP) {
624 			if (idx < min_arg) {
625 
626 				/* If miss other argument than the first one, we return an error. */
627 				if (idx > 0)
628 					WILL_LJMP(luaL_argerror(L, first + idx, "Mandatory argument expected"));
629 
630 				/* If first argument have a certain type, some default values
631 				 * may be used. See the function smp_resolve_args().
632 				 */
633 				switch (mask & ARGT_MASK) {
634 
635 				case ARGT_FE:
636 					if (!(p->cap & PR_CAP_FE))
637 						WILL_LJMP(luaL_argerror(L, first + idx, "Mandatory argument expected"));
638 					argp[idx].data.prx = p;
639 					argp[idx].type = ARGT_FE;
640 					argp[idx+1].type = ARGT_STOP;
641 					break;
642 
643 				case ARGT_BE:
644 					if (!(p->cap & PR_CAP_BE))
645 						WILL_LJMP(luaL_argerror(L, first + idx, "Mandatory argument expected"));
646 					argp[idx].data.prx = p;
647 					argp[idx].type = ARGT_BE;
648 					argp[idx+1].type = ARGT_STOP;
649 					break;
650 
651 				case ARGT_TAB:
652 					argp[idx].data.prx = p;
653 					argp[idx].type = ARGT_TAB;
654 					argp[idx+1].type = ARGT_STOP;
655 					break;
656 
657 				default:
658 					WILL_LJMP(luaL_argerror(L, first + idx, "Mandatory argument expected"));
659 					break;
660 				}
661 			}
662 			return 0;
663 		}
664 
665 		/* Check for exceed the number of requiered argument. */
666 		if ((mask & ARGT_MASK) == ARGT_STOP &&
667 		    argp[idx].type != ARGT_STOP) {
668 			WILL_LJMP(luaL_argerror(L, first + idx, "Last argument expected"));
669 		}
670 
671 		if ((mask & ARGT_MASK) == ARGT_STOP &&
672 		    argp[idx].type == ARGT_STOP) {
673 			return 0;
674 		}
675 
676 		/* Convert some argument types. */
677 		switch (mask & ARGT_MASK) {
678 		case ARGT_SINT:
679 			if (argp[idx].type != ARGT_SINT)
680 				WILL_LJMP(luaL_argerror(L, first + idx, "integer expected"));
681 			argp[idx].type = ARGT_SINT;
682 			break;
683 
684 		case ARGT_TIME:
685 			if (argp[idx].type != ARGT_SINT)
686 				WILL_LJMP(luaL_argerror(L, first + idx, "integer expected"));
687 			argp[idx].type = ARGT_TIME;
688 			break;
689 
690 		case ARGT_SIZE:
691 			if (argp[idx].type != ARGT_SINT)
692 				WILL_LJMP(luaL_argerror(L, first + idx, "integer expected"));
693 			argp[idx].type = ARGT_SIZE;
694 			break;
695 
696 		case ARGT_FE:
697 			if (argp[idx].type != ARGT_STR)
698 				WILL_LJMP(luaL_argerror(L, first + idx, "string expected"));
699 			memcpy(trash.area, argp[idx].data.str.area,
700 			       argp[idx].data.str.data);
701 			trash.area[argp[idx].data.str.data] = 0;
702 			argp[idx].data.prx = proxy_fe_by_name(trash.area);
703 			if (!argp[idx].data.prx)
704 				WILL_LJMP(luaL_argerror(L, first + idx, "frontend doesn't exist"));
705 			argp[idx].type = ARGT_FE;
706 			break;
707 
708 		case ARGT_BE:
709 			if (argp[idx].type != ARGT_STR)
710 				WILL_LJMP(luaL_argerror(L, first + idx, "string expected"));
711 			memcpy(trash.area, argp[idx].data.str.area,
712 			       argp[idx].data.str.data);
713 			trash.area[argp[idx].data.str.data] = 0;
714 			argp[idx].data.prx = proxy_be_by_name(trash.area);
715 			if (!argp[idx].data.prx)
716 				WILL_LJMP(luaL_argerror(L, first + idx, "backend doesn't exist"));
717 			argp[idx].type = ARGT_BE;
718 			break;
719 
720 		case ARGT_TAB:
721 			if (argp[idx].type != ARGT_STR)
722 				WILL_LJMP(luaL_argerror(L, first + idx, "string expected"));
723 			memcpy(trash.area, argp[idx].data.str.area,
724 			       argp[idx].data.str.data);
725 			trash.area[argp[idx].data.str.data] = 0;
726 			argp[idx].data.t = stktable_find_by_name(trash.area);
727 			if (!argp[idx].data.t)
728 				WILL_LJMP(luaL_argerror(L, first + idx, "table doesn't exist"));
729 			argp[idx].type = ARGT_TAB;
730 			break;
731 
732 		case ARGT_SRV:
733 			if (argp[idx].type != ARGT_STR)
734 				WILL_LJMP(luaL_argerror(L, first + idx, "string expected"));
735 			memcpy(trash.area, argp[idx].data.str.area,
736 			       argp[idx].data.str.data);
737 			trash.area[argp[idx].data.str.data] = 0;
738 			sname = strrchr(trash.area, '/');
739 			if (sname) {
740 				*sname++ = '\0';
741 				pname = trash.area;
742 				px = proxy_be_by_name(pname);
743 				if (!px)
744 					WILL_LJMP(luaL_argerror(L, first + idx, "backend doesn't exist"));
745 			}
746 			else {
747 				sname = trash.area;
748 				px = p;
749 			}
750 			argp[idx].data.srv = findserver(px, sname);
751 			if (!argp[idx].data.srv)
752 				WILL_LJMP(luaL_argerror(L, first + idx, "server doesn't exist"));
753 			argp[idx].type = ARGT_SRV;
754 			break;
755 
756 		case ARGT_IPV4:
757 			if (argp[idx].type != ARGT_STR)
758 				WILL_LJMP(luaL_argerror(L, first + idx, "string expected"));
759 			memcpy(trash.area, argp[idx].data.str.area,
760 			       argp[idx].data.str.data);
761 			trash.area[argp[idx].data.str.data] = 0;
762 			if (inet_pton(AF_INET, trash.area, &argp[idx].data.ipv4))
763 				WILL_LJMP(luaL_argerror(L, first + idx, "invalid IPv4 address"));
764 			argp[idx].type = ARGT_IPV4;
765 			break;
766 
767 		case ARGT_MSK4:
768 			if (argp[idx].type == ARGT_SINT)
769 				len2mask4(argp[idx].data.sint, &argp[idx].data.ipv4);
770 			else if (argp[idx].type == ARGT_STR) {
771 				memcpy(trash.area, argp[idx].data.str.area,
772 				       argp[idx].data.str.data);
773 				trash.area[argp[idx].data.str.data] = 0;
774 				if (!str2mask(trash.area, &argp[idx].data.ipv4))
775 					WILL_LJMP(luaL_argerror(L, first + idx, "invalid IPv4 mask"));
776 			}
777 			else
778 				WILL_LJMP(luaL_argerror(L, first + idx, "integer or string expected"));
779 			argp[idx].type = ARGT_MSK4;
780 			break;
781 
782 		case ARGT_IPV6:
783 			if (argp[idx].type != ARGT_STR)
784 				WILL_LJMP(luaL_argerror(L, first + idx, "string expected"));
785 			memcpy(trash.area, argp[idx].data.str.area,
786 			       argp[idx].data.str.data);
787 			trash.area[argp[idx].data.str.data] = 0;
788 			if (inet_pton(AF_INET6, trash.area, &argp[idx].data.ipv6))
789 				WILL_LJMP(luaL_argerror(L, first + idx, "invalid IPv6 address"));
790 			argp[idx].type = ARGT_IPV6;
791 			break;
792 
793 		case ARGT_MSK6:
794 			if (argp[idx].type == ARGT_SINT)
795 				len2mask6(argp[idx].data.sint, &argp[idx].data.ipv6);
796 			else if (argp[idx].type == ARGT_STR) {
797 				memcpy(trash.area, argp[idx].data.str.area,
798 				       argp[idx].data.str.data);
799 				trash.area[argp[idx].data.str.data] = 0;
800 				if (!str2mask6(trash.area, &argp[idx].data.ipv6))
801 					WILL_LJMP(luaL_argerror(L, first + idx, "invalid IPv6 mask"));
802 			}
803 			else
804 				WILL_LJMP(luaL_argerror(L, first + idx, "integer or string expected"));
805 			argp[idx].type = ARGT_MSK6;
806 			break;
807 
808 		case ARGT_MAP:
809 		case ARGT_REG:
810 		case ARGT_USR:
811 			WILL_LJMP(luaL_argerror(L, first + idx, "type not yet supported"));
812 			break;
813 		}
814 
815 		/* Check for type of argument. */
816 		if ((mask & ARGT_MASK) != argp[idx].type) {
817 			const char *msg = lua_pushfstring(L, "'%s' expected, got '%s'",
818 			                                  arg_type_names[(mask & ARGT_MASK)],
819 			                                  arg_type_names[argp[idx].type & ARGT_MASK]);
820 			WILL_LJMP(luaL_argerror(L, first + idx, msg));
821 		}
822 
823 		/* Next argument. */
824 		mask >>= ARGT_BITS;
825 		idx++;
826 	}
827 }
828 
829 /*
830  * The following functions are used to make correspondance between the the
831  * executed lua pointer and the "struct hlua *" that contain the context.
832  *
833  *  - hlua_gethlua : return the hlua context associated with an lua_State.
834  *  - hlua_sethlua : create the association between hlua context and lua_state.
835  */
hlua_gethlua(lua_State * L)836 static inline struct hlua *hlua_gethlua(lua_State *L)
837 {
838 	struct hlua **hlua = lua_getextraspace(L);
839 	return *hlua;
840 }
hlua_sethlua(struct hlua * hlua)841 static inline void hlua_sethlua(struct hlua *hlua)
842 {
843 	struct hlua **hlua_store = lua_getextraspace(hlua->T);
844 	*hlua_store = hlua;
845 }
846 
847 /* This function is used to send logs. It try to send on screen (stderr)
848  * and on the default syslog server.
849  */
hlua_sendlog(struct proxy * px,int level,const char * msg)850 static inline void hlua_sendlog(struct proxy *px, int level, const char *msg)
851 {
852 	struct tm tm;
853 	char *p;
854 
855 	/* Cleanup the log message. */
856 	p = trash.area;
857 	for (; *msg != '\0'; msg++, p++) {
858 		if (p >= trash.area + trash.size - 1) {
859 			/* Break the message if exceed the buffer size. */
860 			*(p-4) = ' ';
861 			*(p-3) = '.';
862 			*(p-2) = '.';
863 			*(p-1) = '.';
864 			break;
865 		}
866 		if (isprint(*msg))
867 			*p = *msg;
868 		else
869 			*p = '.';
870 	}
871 	*p = '\0';
872 
873 	send_log(px, level, "%s\n", trash.area);
874 	if (!(global.mode & MODE_QUIET) || (global.mode & (MODE_VERBOSE | MODE_STARTING))) {
875 		if (level == LOG_DEBUG && !(global.mode & MODE_DEBUG))
876 			return;
877 
878 		get_localtime(date.tv_sec, &tm);
879 		fprintf(stderr, "[%s] %03d/%02d%02d%02d (%d) : %s\n",
880 		        log_levels[level], tm.tm_yday, tm.tm_hour, tm.tm_min, tm.tm_sec,
881 		        (int)getpid(), trash.area);
882 		fflush(stderr);
883 	}
884 }
885 
886 /* This function just ensure that the yield will be always
887  * returned with a timeout and permit to set some flags
888  */
hlua_yieldk(lua_State * L,int nresults,int ctx,lua_KFunction k,int timeout,unsigned int flags)889 __LJMP void hlua_yieldk(lua_State *L, int nresults, int ctx,
890                         lua_KFunction k, int timeout, unsigned int flags)
891 {
892 	struct hlua *hlua = hlua_gethlua(L);
893 
894 	/* Set the wake timeout. If timeout is required, we set
895 	 * the expiration time.
896 	 */
897 	hlua->wake_time = timeout;
898 
899 	hlua->flags |= flags;
900 
901 	/* Process the yield. */
902 	MAY_LJMP(lua_yieldk(L, nresults, ctx, k));
903 }
904 
905 /* This function initialises the Lua environment stored in the stream.
906  * It must be called at the start of the stream. This function creates
907  * an LUA coroutine. It can not be use to crete the main LUA context.
908  *
909  * This function is particular. it initialises a new Lua thread. If the
910  * initialisation fails (example: out of memory error), the lua function
911  * throws an error (longjmp).
912  *
913  * In some case (at least one), this function can be called from safe
914  * environement, so we must not initialise it. While the support of
915  * threads appear, the safe environment set a lock to ensure only one
916  * Lua execution at a time. If we initialize safe environment in another
917  * safe environmenet, we have a dead lock.
918  *
919  * set "already_safe" true if the context is initialized form safe
920  * Lua fonction.
921  *
922  * This function manipulates two Lua stacks: the main and the thread. Only
923  * the main stack can fail. The thread is not manipulated. This function
924  * MUST NOT manipulate the created thread stack state, because it is not
925  * proctected against errors thrown by the thread stack.
926  */
hlua_ctx_init(struct hlua * lua,struct task * task,int already_safe)927 int hlua_ctx_init(struct hlua *lua, struct task *task, int already_safe)
928 {
929 	if (!already_safe) {
930 		if (!SET_SAFE_LJMP(gL.T)) {
931 			lua->Tref = LUA_REFNIL;
932 			return 0;
933 		}
934 	}
935 	lua->Mref = LUA_REFNIL;
936 	lua->flags = 0;
937 	LIST_INIT(&lua->com);
938 	lua->T = lua_newthread(gL.T);
939 	if (!lua->T) {
940 		lua->Tref = LUA_REFNIL;
941 		if (!already_safe)
942 			RESET_SAFE_LJMP(gL.T);
943 		return 0;
944 	}
945 	hlua_sethlua(lua);
946 	lua->Tref = luaL_ref(gL.T, LUA_REGISTRYINDEX);
947 	lua->task = task;
948 	if (!already_safe)
949 		RESET_SAFE_LJMP(gL.T);
950 	return 1;
951 }
952 
953 /* Used to destroy the Lua coroutine when the attached stream or task
954  * is destroyed. The destroy also the memory context. The struct "lua"
955  * is not freed.
956  */
hlua_ctx_destroy(struct hlua * lua)957 void hlua_ctx_destroy(struct hlua *lua)
958 {
959 	if (!lua)
960 		return;
961 
962 	if (!lua->T)
963 		goto end;
964 
965 	/* Purge all the pending signals. */
966 	notification_purge(&lua->com);
967 
968 	if (!SET_SAFE_LJMP(lua->T))
969 		return;
970 	luaL_unref(lua->T, LUA_REGISTRYINDEX, lua->Mref);
971 	RESET_SAFE_LJMP(lua->T);
972 
973 	if (!SET_SAFE_LJMP(gL.T))
974 		return;
975 	luaL_unref(gL.T, LUA_REGISTRYINDEX, lua->Tref);
976 	RESET_SAFE_LJMP(gL.T);
977 	/* Forces a garbage collecting process. If the Lua program is finished
978 	 * without error, we run the GC on the thread pointer. Its freed all
979 	 * the unused memory.
980 	 * If the thread is finnish with an error or is currently yielded,
981 	 * it seems that the GC applied on the thread doesn't clean anything,
982 	 * so e run the GC on the main thread.
983 	 * NOTE: maybe this action locks all the Lua threads untiml the en of
984 	 * the garbage collection.
985 	 */
986 	if (lua->flags & HLUA_MUST_GC) {
987 		if (!SET_SAFE_LJMP(gL.T))
988 			return;
989 		lua_gc(gL.T, LUA_GCCOLLECT, 0);
990 		RESET_SAFE_LJMP(gL.T);
991 	}
992 
993 	lua->T = NULL;
994 
995 end:
996 	pool_free(pool_head_hlua, lua);
997 }
998 
999 /* This function is used to restore the Lua context when a coroutine
1000  * fails. This function copy the common memory between old coroutine
1001  * and the new coroutine. The old coroutine is destroyed, and its
1002  * replaced by the new coroutine.
1003  * If the flag "keep_msg" is set, the last entry of the old is assumed
1004  * as string error message and it is copied in the new stack.
1005  */
hlua_ctx_renew(struct hlua * lua,int keep_msg)1006 static int hlua_ctx_renew(struct hlua *lua, int keep_msg)
1007 {
1008 	lua_State *T;
1009 	int new_ref;
1010 
1011 	/* Renew the main LUA stack doesn't have sense. */
1012 	if (lua == &gL)
1013 		return 0;
1014 
1015 	/* New Lua coroutine. */
1016 	T = lua_newthread(gL.T);
1017 	if (!T)
1018 		return 0;
1019 
1020 	/* Copy last error message. */
1021 	if (keep_msg)
1022 		lua_xmove(lua->T, T, 1);
1023 
1024 	/* Copy data between the coroutines. */
1025 	lua_rawgeti(lua->T, LUA_REGISTRYINDEX, lua->Mref);
1026 	lua_xmove(lua->T, T, 1);
1027 	new_ref = luaL_ref(T, LUA_REGISTRYINDEX); /* Valur poped. */
1028 
1029 	/* Destroy old data. */
1030 	luaL_unref(lua->T, LUA_REGISTRYINDEX, lua->Mref);
1031 
1032 	/* The thread is garbage collected by Lua. */
1033 	luaL_unref(gL.T, LUA_REGISTRYINDEX, lua->Tref);
1034 
1035 	/* Fill the struct with the new coroutine values. */
1036 	lua->Mref = new_ref;
1037 	lua->T = T;
1038 	lua->Tref = luaL_ref(gL.T, LUA_REGISTRYINDEX);
1039 
1040 	/* Set context. */
1041 	hlua_sethlua(lua);
1042 
1043 	return 1;
1044 }
1045 
hlua_hook(lua_State * L,lua_Debug * ar)1046 void hlua_hook(lua_State *L, lua_Debug *ar)
1047 {
1048 	struct hlua *hlua = hlua_gethlua(L);
1049 
1050 	/* Lua cannot yield when its returning from a function,
1051 	 * so, we can fix the interrupt hook to 1 instruction,
1052 	 * expecting that the function is finnished.
1053 	 */
1054 	if (lua_gethookmask(L) & LUA_MASKRET) {
1055 		lua_sethook(hlua->T, hlua_hook, LUA_MASKCOUNT, 1);
1056 		return;
1057 	}
1058 
1059 	/* restore the interrupt condition. */
1060 	lua_sethook(hlua->T, hlua_hook, LUA_MASKCOUNT, hlua_nb_instruction);
1061 
1062 	/* If we interrupt the Lua processing in yieldable state, we yield.
1063 	 * If the state is not yieldable, trying yield causes an error.
1064 	 */
1065 	if (lua_isyieldable(L))
1066 		MAY_LJMP(hlua_yieldk(L, 0, 0, NULL, TICK_ETERNITY, HLUA_CTRLYIELD));
1067 
1068 	/* If we cannot yield, update the clock and check the timeout. */
1069 	tv_update_date(0, 1);
1070 	hlua->run_time += now_ms - hlua->start_time;
1071 	if (hlua->max_time && hlua->run_time >= hlua->max_time) {
1072 		lua_pushfstring(L, "execution timeout");
1073 		WILL_LJMP(lua_error(L));
1074 	}
1075 
1076 	/* Update the start time. */
1077 	hlua->start_time = now_ms;
1078 
1079 	/* Try to interrupt the process at the end of the current
1080 	 * unyieldable function.
1081 	 */
1082 	lua_sethook(hlua->T, hlua_hook, LUA_MASKRET|LUA_MASKCOUNT, hlua_nb_instruction);
1083 }
1084 
1085 /* This function start or resumes the Lua stack execution. If the flag
1086  * "yield_allowed" if no set and the  LUA stack execution returns a yield
1087  * The function return an error.
1088  *
1089  * The function can returns 4 values:
1090  *  - HLUA_E_OK     : The execution is terminated without any errors.
1091  *  - HLUA_E_AGAIN  : The execution must continue at the next associated
1092  *                    task wakeup.
1093  *  - HLUA_E_ERRMSG : An error has occurred, an error message is set in
1094  *                    the top of the stack.
1095  *  - HLUA_E_ERR    : An error has occurred without error message.
1096  *
1097  * If an error occurred, the stack is renewed and it is ready to run new
1098  * LUA code.
1099  */
hlua_ctx_resume(struct hlua * lua,int yield_allowed)1100 static enum hlua_exec hlua_ctx_resume(struct hlua *lua, int yield_allowed)
1101 {
1102 #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >= 504
1103 	int nres;
1104 #endif
1105 	int ret;
1106 	const char *msg;
1107 	const char *trace;
1108 
1109 	/* Initialise run time counter. */
1110 	if (!HLUA_IS_RUNNING(lua))
1111 		lua->run_time = 0;
1112 
1113 	/* Lock the whole Lua execution. This lock must be before the
1114 	 * label "resume_execution".
1115 	 */
1116 	HA_SPIN_LOCK(LUA_LOCK, &hlua_global_lock);
1117 
1118 resume_execution:
1119 
1120 	/* This hook interrupts the Lua processing each 'hlua_nb_instruction'
1121 	 * instructions. it is used for preventing infinite loops.
1122 	 */
1123 	lua_sethook(lua->T, hlua_hook, LUA_MASKCOUNT, hlua_nb_instruction);
1124 
1125 	/* Remove all flags except the running flags. */
1126 	HLUA_SET_RUN(lua);
1127 	HLUA_CLR_CTRLYIELD(lua);
1128 	HLUA_CLR_WAKERESWR(lua);
1129 	HLUA_CLR_WAKEREQWR(lua);
1130 
1131 	/* Update the start time. */
1132 	lua->start_time = now_ms;
1133 
1134 	/* Call the function. */
1135 #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >= 504
1136 	ret = lua_resume(lua->T, gL.T, lua->nargs, &nres);
1137 #else
1138 	ret = lua_resume(lua->T, gL.T, lua->nargs);
1139 #endif
1140 	switch (ret) {
1141 
1142 	case LUA_OK:
1143 		ret = HLUA_E_OK;
1144 		break;
1145 
1146 	case LUA_YIELD:
1147 		/* Check if the execution timeout is expired. It it is the case, we
1148 		 * break the Lua execution.
1149 		 */
1150 		tv_update_date(0, 1);
1151 		lua->run_time += now_ms - lua->start_time;
1152 		if (lua->max_time && lua->run_time > lua->max_time) {
1153 			lua_settop(lua->T, 0); /* Empty the stack. */
1154 			ret = HLUA_E_ETMOUT;
1155 			break;
1156 		}
1157 		/* Process the forced yield. if the general yield is not allowed or
1158 		 * if no task were associated this the current Lua execution
1159 		 * coroutine, we resume the execution. Else we want to return in the
1160 		 * scheduler and we want to be waked up again, to continue the
1161 		 * current Lua execution. So we schedule our own task.
1162 		 */
1163 		if (HLUA_IS_CTRLYIELDING(lua)) {
1164 			if (!yield_allowed || !lua->task)
1165 				goto resume_execution;
1166 			task_wakeup(lua->task, TASK_WOKEN_MSG);
1167 		}
1168 		if (!yield_allowed) {
1169 			lua_settop(lua->T, 0); /* Empty the stack. */
1170 			ret = HLUA_E_YIELD;
1171 			break;
1172 		}
1173 		ret = HLUA_E_AGAIN;
1174 		break;
1175 
1176 	case LUA_ERRRUN:
1177 
1178 		/* Special exit case. The traditional exit is returned as an error
1179 		 * because the errors ares the only one mean to return immediately
1180 		 * from and lua execution.
1181 		 */
1182 		if (lua->flags & HLUA_EXIT) {
1183 			ret = HLUA_E_OK;
1184 			hlua_ctx_renew(lua, 0);
1185 			break;
1186 		}
1187 
1188 		lua->wake_time = TICK_ETERNITY;
1189 		if (!lua_checkstack(lua->T, 1)) {
1190 			ret = HLUA_E_ERR;
1191 			break;
1192 		}
1193 		msg = lua_tostring(lua->T, -1);
1194 		lua_settop(lua->T, 0); /* Empty the stack. */
1195 		lua_pop(lua->T, 1);
1196 		trace = hlua_traceback(lua->T, ", ");
1197 		if (msg)
1198 			lua_pushfstring(lua->T, "runtime error: %s from %s", msg, trace);
1199 		else
1200 			lua_pushfstring(lua->T, "unknown runtime error from %s", trace);
1201 		ret = HLUA_E_ERRMSG;
1202 		break;
1203 
1204 	case LUA_ERRMEM:
1205 		lua->wake_time = TICK_ETERNITY;
1206 		lua_settop(lua->T, 0); /* Empty the stack. */
1207 		ret = HLUA_E_NOMEM;
1208 		break;
1209 
1210 	case LUA_ERRERR:
1211 		lua->wake_time = TICK_ETERNITY;
1212 		if (!lua_checkstack(lua->T, 1)) {
1213 			ret = HLUA_E_ERR;
1214 			break;
1215 		}
1216 		msg = lua_tostring(lua->T, -1);
1217 		lua_settop(lua->T, 0); /* Empty the stack. */
1218 		lua_pop(lua->T, 1);
1219 		if (msg)
1220 			lua_pushfstring(lua->T, "message handler error: %s", msg);
1221 		else
1222 			lua_pushfstring(lua->T, "message handler error");
1223 		ret = HLUA_E_ERRMSG;
1224 		break;
1225 
1226 	default:
1227 		lua->wake_time = TICK_ETERNITY;
1228 		lua_settop(lua->T, 0); /* Empty the stack. */
1229 		ret = HLUA_E_ERR;
1230 		break;
1231 	}
1232 
1233 	/* This GC permits to destroy some object when a Lua timeout strikes. */
1234 	if (lua->flags & HLUA_MUST_GC &&
1235 	    ret != HLUA_E_AGAIN)
1236 		lua_gc(lua->T, LUA_GCCOLLECT, 0);
1237 
1238 	switch (ret) {
1239 	case HLUA_E_AGAIN:
1240 		break;
1241 
1242 	case HLUA_E_ERRMSG:
1243 		notification_purge(&lua->com);
1244 		hlua_ctx_renew(lua, 1);
1245 		HLUA_CLR_RUN(lua);
1246 		break;
1247 
1248 	case HLUA_E_ETMOUT:
1249 	case HLUA_E_NOMEM:
1250 	case HLUA_E_YIELD:
1251 	case HLUA_E_ERR:
1252 		HLUA_CLR_RUN(lua);
1253 		notification_purge(&lua->com);
1254 		hlua_ctx_renew(lua, 0);
1255 		break;
1256 
1257 	case HLUA_E_OK:
1258 		HLUA_CLR_RUN(lua);
1259 		notification_purge(&lua->com);
1260 		break;
1261 	}
1262 
1263 	/* This is the main exit point, remove the Lua lock. */
1264 	HA_SPIN_UNLOCK(LUA_LOCK, &hlua_global_lock);
1265 
1266 	return ret;
1267 }
1268 
1269 /* This function exit the current code. */
hlua_done(lua_State * L)1270 __LJMP static int hlua_done(lua_State *L)
1271 {
1272 	struct hlua *hlua = hlua_gethlua(L);
1273 
1274 	hlua->flags |= HLUA_EXIT;
1275 	WILL_LJMP(lua_error(L));
1276 
1277 	return 0;
1278 }
1279 
1280 /* This function is an LUA binding. It provides a function
1281  * for deleting ACL from a referenced ACL file.
1282  */
hlua_del_acl(lua_State * L)1283 __LJMP static int hlua_del_acl(lua_State *L)
1284 {
1285 	const char *name;
1286 	const char *key;
1287 	struct pat_ref *ref;
1288 
1289 	MAY_LJMP(check_args(L, 2, "del_acl"));
1290 
1291 	name = MAY_LJMP(luaL_checkstring(L, 1));
1292 	key = MAY_LJMP(luaL_checkstring(L, 2));
1293 
1294 	ref = pat_ref_lookup(name);
1295 	if (!ref)
1296 		WILL_LJMP(luaL_error(L, "'del_acl': unknown acl file '%s'", name));
1297 
1298 	HA_SPIN_LOCK(PATREF_LOCK, &ref->lock);
1299 	pat_ref_delete(ref, key);
1300 	HA_SPIN_UNLOCK(PATREF_LOCK, &ref->lock);
1301 	return 0;
1302 }
1303 
1304 /* This function is an LUA binding. It provides a function
1305  * for deleting map entry from a referenced map file.
1306  */
hlua_del_map(lua_State * L)1307 static int hlua_del_map(lua_State *L)
1308 {
1309 	const char *name;
1310 	const char *key;
1311 	struct pat_ref *ref;
1312 
1313 	MAY_LJMP(check_args(L, 2, "del_map"));
1314 
1315 	name = MAY_LJMP(luaL_checkstring(L, 1));
1316 	key = MAY_LJMP(luaL_checkstring(L, 2));
1317 
1318 	ref = pat_ref_lookup(name);
1319 	if (!ref)
1320 		WILL_LJMP(luaL_error(L, "'del_map': unknown acl file '%s'", name));
1321 
1322 	HA_SPIN_LOCK(PATREF_LOCK, &ref->lock);
1323 	pat_ref_delete(ref, key);
1324 	HA_SPIN_UNLOCK(PATREF_LOCK, &ref->lock);
1325 	return 0;
1326 }
1327 
1328 /* This function is an LUA binding. It provides a function
1329  * for adding ACL pattern from a referenced ACL file.
1330  */
hlua_add_acl(lua_State * L)1331 static int hlua_add_acl(lua_State *L)
1332 {
1333 	const char *name;
1334 	const char *key;
1335 	struct pat_ref *ref;
1336 
1337 	MAY_LJMP(check_args(L, 2, "add_acl"));
1338 
1339 	name = MAY_LJMP(luaL_checkstring(L, 1));
1340 	key = MAY_LJMP(luaL_checkstring(L, 2));
1341 
1342 	ref = pat_ref_lookup(name);
1343 	if (!ref)
1344 		WILL_LJMP(luaL_error(L, "'add_acl': unknown acl file '%s'", name));
1345 
1346 	HA_SPIN_LOCK(PATREF_LOCK, &ref->lock);
1347 	if (pat_ref_find_elt(ref, key) == NULL)
1348 		pat_ref_add(ref, key, NULL, NULL);
1349 	HA_SPIN_UNLOCK(PATREF_LOCK, &ref->lock);
1350 	return 0;
1351 }
1352 
1353 /* This function is an LUA binding. It provides a function
1354  * for setting map pattern and sample from a referenced map
1355  * file.
1356  */
hlua_set_map(lua_State * L)1357 static int hlua_set_map(lua_State *L)
1358 {
1359 	const char *name;
1360 	const char *key;
1361 	const char *value;
1362 	struct pat_ref *ref;
1363 
1364 	MAY_LJMP(check_args(L, 3, "set_map"));
1365 
1366 	name = MAY_LJMP(luaL_checkstring(L, 1));
1367 	key = MAY_LJMP(luaL_checkstring(L, 2));
1368 	value = MAY_LJMP(luaL_checkstring(L, 3));
1369 
1370 	ref = pat_ref_lookup(name);
1371 	if (!ref)
1372 		WILL_LJMP(luaL_error(L, "'set_map': unknown map file '%s'", name));
1373 
1374 	HA_SPIN_LOCK(PATREF_LOCK, &ref->lock);
1375 	if (pat_ref_find_elt(ref, key) != NULL)
1376 		pat_ref_set(ref, key, value, NULL);
1377 	else
1378 		pat_ref_add(ref, key, value, NULL);
1379 	HA_SPIN_UNLOCK(PATREF_LOCK, &ref->lock);
1380 	return 0;
1381 }
1382 
1383 /* A class is a lot of memory that contain data. This data can be a table,
1384  * an integer or user data. This data is associated with a metatable. This
1385  * metatable have an original version registred in the global context with
1386  * the name of the object (_G[<name>] = <metable> ).
1387  *
1388  * A metable is a table that modify the standard behavior of a standard
1389  * access to the associated data. The entries of this new metatable are
1390  * defined as is:
1391  *
1392  * http://lua-users.org/wiki/MetatableEvents
1393  *
1394  *    __index
1395  *
1396  * we access an absent field in a table, the result is nil. This is
1397  * true, but it is not the whole truth. Actually, such access triggers
1398  * the interpreter to look for an __index metamethod: If there is no
1399  * such method, as usually happens, then the access results in nil;
1400  * otherwise, the metamethod will provide the result.
1401  *
1402  * Control 'prototype' inheritance. When accessing "myTable[key]" and
1403  * the key does not appear in the table, but the metatable has an __index
1404  * property:
1405  *
1406  * - if the value is a function, the function is called, passing in the
1407  *   table and the key; the return value of that function is returned as
1408  *   the result.
1409  *
1410  * - if the value is another table, the value of the key in that table is
1411  *   asked for and returned (and if it doesn't exist in that table, but that
1412  *   table's metatable has an __index property, then it continues on up)
1413  *
1414  * - Use "rawget(myTable,key)" to skip this metamethod.
1415  *
1416  * http://www.lua.org/pil/13.4.1.html
1417  *
1418  *    __newindex
1419  *
1420  * Like __index, but control property assignment.
1421  *
1422  *    __mode - Control weak references. A string value with one or both
1423  *             of the characters 'k' and 'v' which specifies that the the
1424  *             keys and/or values in the table are weak references.
1425  *
1426  *    __call - Treat a table like a function. When a table is followed by
1427  *             parenthesis such as "myTable( 'foo' )" and the metatable has
1428  *             a __call key pointing to a function, that function is invoked
1429  *             (passing any specified arguments) and the return value is
1430  *             returned.
1431  *
1432  *    __metatable - Hide the metatable. When "getmetatable( myTable )" is
1433  *                  called, if the metatable for myTable has a __metatable
1434  *                  key, the value of that key is returned instead of the
1435  *                  actual metatable.
1436  *
1437  *    __tostring - Control string representation. When the builtin
1438  *                 "tostring( myTable )" function is called, if the metatable
1439  *                 for myTable has a __tostring property set to a function,
1440  *                 that function is invoked (passing myTable to it) and the
1441  *                 return value is used as the string representation.
1442  *
1443  *    __len - Control table length. When the table length is requested using
1444  *            the length operator ( '#' ), if the metatable for myTable has
1445  *            a __len key pointing to a function, that function is invoked
1446  *            (passing myTable to it) and the return value used as the value
1447  *            of "#myTable".
1448  *
1449  *    __gc - Userdata finalizer code. When userdata is set to be garbage
1450  *           collected, if the metatable has a __gc field pointing to a
1451  *           function, that function is first invoked, passing the userdata
1452  *           to it. The __gc metamethod is not called for tables.
1453  *           (See http://lua-users.org/lists/lua-l/2006-11/msg00508.html)
1454  *
1455  * Special metamethods for redefining standard operators:
1456  * http://www.lua.org/pil/13.1.html
1457  *
1458  *    __add    "+"
1459  *    __sub    "-"
1460  *    __mul    "*"
1461  *    __div    "/"
1462  *    __unm    "!"
1463  *    __pow    "^"
1464  *    __concat ".."
1465  *
1466  * Special methods for redfining standar relations
1467  * http://www.lua.org/pil/13.2.html
1468  *
1469  *    __eq "=="
1470  *    __lt "<"
1471  *    __le "<="
1472  */
1473 
1474 /*
1475  *
1476  *
1477  * Class Map
1478  *
1479  *
1480  */
1481 
1482 /* Returns a struct hlua_map if the stack entry "ud" is
1483  * a class session, otherwise it throws an error.
1484  */
hlua_checkmap(lua_State * L,int ud)1485 __LJMP static struct map_descriptor *hlua_checkmap(lua_State *L, int ud)
1486 {
1487 	return MAY_LJMP(hlua_checkudata(L, ud, class_map_ref));
1488 }
1489 
1490 /* This function is the map constructor. It don't need
1491  * the class Map object. It creates and return a new Map
1492  * object. It must be called only during "body" or "init"
1493  * context because it process some filesystem accesses.
1494  */
hlua_map_new(struct lua_State * L)1495 __LJMP static int hlua_map_new(struct lua_State *L)
1496 {
1497 	const char *fn;
1498 	int match = PAT_MATCH_STR;
1499 	struct sample_conv conv;
1500 	const char *file = "";
1501 	int line = 0;
1502 	lua_Debug ar;
1503 	char *err = NULL;
1504 	struct arg args[2];
1505 
1506 	if (lua_gettop(L) < 1 || lua_gettop(L) > 2)
1507 		WILL_LJMP(luaL_error(L, "'new' needs at least 1 argument."));
1508 
1509 	fn = MAY_LJMP(luaL_checkstring(L, 1));
1510 
1511 	if (lua_gettop(L) >= 2) {
1512 		match = MAY_LJMP(luaL_checkinteger(L, 2));
1513 		if (match < 0 || match >= PAT_MATCH_NUM)
1514 			WILL_LJMP(luaL_error(L, "'new' needs a valid match method."));
1515 	}
1516 
1517 	/* Get Lua filename and line number. */
1518 	if (lua_getstack(L, 1, &ar)) {  /* check function at level */
1519 		lua_getinfo(L, "Sl", &ar);  /* get info about it */
1520 		if (ar.currentline > 0) {  /* is there info? */
1521 			file = ar.short_src;
1522 			line = ar.currentline;
1523 		}
1524 	}
1525 
1526 	/* fill fake sample_conv struct. */
1527 	conv.kw = ""; /* unused. */
1528 	conv.process = NULL; /* unused. */
1529 	conv.arg_mask = 0; /* unused. */
1530 	conv.val_args = NULL; /* unused. */
1531 	conv.out_type = SMP_T_STR;
1532 	conv.private = (void *)(long)match;
1533 	switch (match) {
1534 	case PAT_MATCH_STR: conv.in_type = SMP_T_STR;  break;
1535 	case PAT_MATCH_BEG: conv.in_type = SMP_T_STR;  break;
1536 	case PAT_MATCH_SUB: conv.in_type = SMP_T_STR;  break;
1537 	case PAT_MATCH_DIR: conv.in_type = SMP_T_STR;  break;
1538 	case PAT_MATCH_DOM: conv.in_type = SMP_T_STR;  break;
1539 	case PAT_MATCH_END: conv.in_type = SMP_T_STR;  break;
1540 	case PAT_MATCH_REG: conv.in_type = SMP_T_STR;  break;
1541 	case PAT_MATCH_INT: conv.in_type = SMP_T_SINT; break;
1542 	case PAT_MATCH_IP:  conv.in_type = SMP_T_ADDR; break;
1543 	default:
1544 		WILL_LJMP(luaL_error(L, "'new' doesn't support this match mode."));
1545 	}
1546 
1547 	/* fill fake args. */
1548 	args[0].type = ARGT_STR;
1549 	args[0].data.str.area = (char *)fn;
1550 	args[1].type = ARGT_STOP;
1551 
1552 	/* load the map. */
1553 	if (!sample_load_map(args, &conv, file, line, &err)) {
1554 		/* error case: we cant use luaL_error because we must
1555 		 * free the err variable.
1556 		 */
1557 		luaL_where(L, 1);
1558 		lua_pushfstring(L, "'new': %s.", err);
1559 		lua_concat(L, 2);
1560 		free(err);
1561 		WILL_LJMP(lua_error(L));
1562 	}
1563 
1564 	/* create the lua object. */
1565 	lua_newtable(L);
1566 	lua_pushlightuserdata(L, args[0].data.map);
1567 	lua_rawseti(L, -2, 0);
1568 
1569 	/* Pop a class Map metatable and affect it to the userdata. */
1570 	lua_rawgeti(L, LUA_REGISTRYINDEX, class_map_ref);
1571 	lua_setmetatable(L, -2);
1572 
1573 
1574 	return 1;
1575 }
1576 
_hlua_map_lookup(struct lua_State * L,int str)1577 __LJMP static inline int _hlua_map_lookup(struct lua_State *L, int str)
1578 {
1579 	struct map_descriptor *desc;
1580 	struct pattern *pat;
1581 	struct sample smp;
1582 
1583 	MAY_LJMP(check_args(L, 2, "lookup"));
1584 	desc = MAY_LJMP(hlua_checkmap(L, 1));
1585 	if (desc->pat.expect_type == SMP_T_SINT) {
1586 		smp.data.type = SMP_T_SINT;
1587 		smp.data.u.sint = MAY_LJMP(luaL_checkinteger(L, 2));
1588 	}
1589 	else {
1590 		smp.data.type = SMP_T_STR;
1591 		smp.flags = SMP_F_CONST;
1592 		smp.data.u.str.area = (char *)MAY_LJMP(luaL_checklstring(L, 2, (size_t *)&smp.data.u.str.data));
1593 		smp.data.u.str.size = smp.data.u.str.data + 1;
1594 	}
1595 
1596 	pat = pattern_exec_match(&desc->pat, &smp, 1);
1597 	if (!pat || !pat->data) {
1598 		if (str)
1599 			lua_pushstring(L, "");
1600 		else
1601 			lua_pushnil(L);
1602 		return 1;
1603 	}
1604 
1605 	/* The Lua pattern must return a string, so we can't check the returned type */
1606 	lua_pushlstring(L, pat->data->u.str.area, pat->data->u.str.data);
1607 	return 1;
1608 }
1609 
hlua_map_lookup(struct lua_State * L)1610 __LJMP static int hlua_map_lookup(struct lua_State *L)
1611 {
1612 	return _hlua_map_lookup(L, 0);
1613 }
1614 
hlua_map_slookup(struct lua_State * L)1615 __LJMP static int hlua_map_slookup(struct lua_State *L)
1616 {
1617 	return _hlua_map_lookup(L, 1);
1618 }
1619 
1620 /*
1621  *
1622  *
1623  * Class Socket
1624  *
1625  *
1626  */
1627 
hlua_checksocket(lua_State * L,int ud)1628 __LJMP static struct hlua_socket *hlua_checksocket(lua_State *L, int ud)
1629 {
1630 	return MAY_LJMP(hlua_checkudata(L, ud, class_socket_ref));
1631 }
1632 
1633 /* This function is the handler called for each I/O on the established
1634  * connection. It is used for notify space available to send or data
1635  * received.
1636  */
hlua_socket_handler(struct appctx * appctx)1637 static void hlua_socket_handler(struct appctx *appctx)
1638 {
1639 	struct stream_interface *si = appctx->owner;
1640 	struct connection *c = cs_conn(objt_cs(si_opposite(si)->end));
1641 
1642 	if (appctx->ctx.hlua_cosocket.die) {
1643 		si_shutw(si);
1644 		si_shutr(si);
1645 		si_ic(si)->flags |= CF_READ_NULL;
1646 		notification_wake(&appctx->ctx.hlua_cosocket.wake_on_read);
1647 		notification_wake(&appctx->ctx.hlua_cosocket.wake_on_write);
1648 		stream_shutdown(si_strm(si), SF_ERR_KILLED);
1649 	}
1650 
1651 	/* If the connection object is not available, close all the
1652 	 * streams and wakeup everything waiting for.
1653 	 */
1654 	if (!c) {
1655 		si_shutw(si);
1656 		si_shutr(si);
1657 		si_ic(si)->flags |= CF_READ_NULL;
1658 		notification_wake(&appctx->ctx.hlua_cosocket.wake_on_read);
1659 		notification_wake(&appctx->ctx.hlua_cosocket.wake_on_write);
1660 		return;
1661 	}
1662 
1663 	/* If we cant write, wakeup the pending write signals. */
1664 	if (channel_output_closed(si_ic(si)))
1665 		notification_wake(&appctx->ctx.hlua_cosocket.wake_on_write);
1666 
1667 	/* If we cant read, wakeup the pending read signals. */
1668 	if (channel_input_closed(si_oc(si)))
1669 		notification_wake(&appctx->ctx.hlua_cosocket.wake_on_read);
1670 
1671 	/* if the connection is not estabkished, inform the stream that we want
1672 	 * to be notified whenever the connection completes.
1673 	 */
1674 	if (!(c->flags & CO_FL_CONNECTED)) {
1675 		si_cant_get(si);
1676 		si_rx_conn_blk(si);
1677 		si_rx_endp_more(si);
1678 		return;
1679 	}
1680 
1681 	/* This function is called after the connect. */
1682 	appctx->ctx.hlua_cosocket.connected = 1;
1683 
1684 	/* Wake the tasks which wants to write if the buffer have available space. */
1685 	if (channel_may_recv(si_ic(si)))
1686 		notification_wake(&appctx->ctx.hlua_cosocket.wake_on_write);
1687 
1688 	/* Wake the tasks which wants to read if the buffer contains data. */
1689 	if (!channel_is_empty(si_oc(si)))
1690 		notification_wake(&appctx->ctx.hlua_cosocket.wake_on_read);
1691 
1692 	/* Some data were injected in the buffer, notify the stream
1693 	 * interface.
1694 	 */
1695 	if (!channel_is_empty(si_ic(si)))
1696 		si_update(si);
1697 
1698 	/* If write notifications are registered, we considers we want
1699 	 * to write, so we clear the blocking flag.
1700 	 */
1701 	if (notification_registered(&appctx->ctx.hlua_cosocket.wake_on_write))
1702 		si_rx_endp_more(si);
1703 }
1704 
1705 /* This function is called when the "struct stream" is destroyed.
1706  * Remove the link from the object to this stream.
1707  * Wake all the pending signals.
1708  */
hlua_socket_release(struct appctx * appctx)1709 static void hlua_socket_release(struct appctx *appctx)
1710 {
1711 	struct xref *peer;
1712 
1713 	/* Remove my link in the original object. */
1714 	peer = xref_get_peer_and_lock(&appctx->ctx.hlua_cosocket.xref);
1715 	if (peer)
1716 		xref_disconnect(&appctx->ctx.hlua_cosocket.xref, peer);
1717 
1718 	/* Wake all the task waiting for me. */
1719 	notification_wake(&appctx->ctx.hlua_cosocket.wake_on_read);
1720 	notification_wake(&appctx->ctx.hlua_cosocket.wake_on_write);
1721 }
1722 
1723 /* If the garbage collectio of the object is launch, nobody
1724  * uses this object. If the stream does not exists, just quit.
1725  * Send the shutdown signal to the stream. In some cases,
1726  * pending signal can rest in the read and write lists. destroy
1727  * it.
1728  */
hlua_socket_gc(lua_State * L)1729 __LJMP static int hlua_socket_gc(lua_State *L)
1730 {
1731 	struct hlua_socket *socket;
1732 	struct appctx *appctx;
1733 	struct xref *peer;
1734 
1735 	MAY_LJMP(check_args(L, 1, "__gc"));
1736 
1737 	socket = MAY_LJMP(hlua_checksocket(L, 1));
1738 	peer = xref_get_peer_and_lock(&socket->xref);
1739 	if (!peer)
1740 		return 0;
1741 	appctx = container_of(peer, struct appctx, ctx.hlua_cosocket.xref);
1742 
1743 	/* Set the flag which destroy the session. */
1744 	appctx->ctx.hlua_cosocket.die = 1;
1745 	appctx_wakeup(appctx);
1746 
1747 	/* Remove all reference between the Lua stack and the coroutine stream. */
1748 	xref_disconnect(&socket->xref, peer);
1749 	return 0;
1750 }
1751 
1752 /* The close function send shutdown signal and break the
1753  * links between the stream and the object.
1754  */
hlua_socket_close_helper(lua_State * L)1755 __LJMP static int hlua_socket_close_helper(lua_State *L)
1756 {
1757 	struct hlua_socket *socket;
1758 	struct appctx *appctx;
1759 	struct xref *peer;
1760 
1761 	socket = MAY_LJMP(hlua_checksocket(L, 1));
1762 
1763 	/* Check if we run on the same thread than the xreator thread.
1764 	 * We cannot access to the socket if the thread is different.
1765 	 */
1766 	if (socket->tid != tid)
1767 		WILL_LJMP(luaL_error(L, "connect: cannot use socket on other thread"));
1768 
1769 	peer = xref_get_peer_and_lock(&socket->xref);
1770 	if (!peer)
1771 		return 0;
1772 	appctx = container_of(peer, struct appctx, ctx.hlua_cosocket.xref);
1773 
1774 	/* Set the flag which destroy the session. */
1775 	appctx->ctx.hlua_cosocket.die = 1;
1776 	appctx_wakeup(appctx);
1777 
1778 	/* Remove all reference between the Lua stack and the coroutine stream. */
1779 	xref_disconnect(&socket->xref, peer);
1780 	return 0;
1781 }
1782 
1783 /* The close function calls close_helper.
1784  */
hlua_socket_close(lua_State * L)1785 __LJMP static int hlua_socket_close(lua_State *L)
1786 {
1787 	MAY_LJMP(check_args(L, 1, "close"));
1788 	return hlua_socket_close_helper(L);
1789 }
1790 
1791 /* This Lua function assumes that the stack contain three parameters.
1792  *  1 - USERDATA containing a struct socket
1793  *  2 - INTEGER with values of the macro defined below
1794  *      If the integer is -1, we must read at most one line.
1795  *      If the integer is -2, we ust read all the data until the
1796  *      end of the stream.
1797  *      If the integer is positive value, we must read a number of
1798  *      bytes corresponding to this value.
1799  */
1800 #define HLSR_READ_LINE (-1)
1801 #define HLSR_READ_ALL (-2)
hlua_socket_receive_yield(struct lua_State * L,int status,lua_KContext ctx)1802 __LJMP static int hlua_socket_receive_yield(struct lua_State *L, int status, lua_KContext ctx)
1803 {
1804 	struct hlua_socket *socket = MAY_LJMP(hlua_checksocket(L, 1));
1805 	int wanted = lua_tointeger(L, 2);
1806 	struct hlua *hlua = hlua_gethlua(L);
1807 	struct appctx *appctx;
1808 	size_t len;
1809 	int nblk;
1810 	const char *blk1;
1811 	size_t len1;
1812 	const char *blk2;
1813 	size_t len2;
1814 	int skip_at_end = 0;
1815 	struct channel *oc;
1816 	struct stream_interface *si;
1817 	struct stream *s;
1818 	struct xref *peer;
1819 	int missing_bytes;
1820 
1821 	/* Check if this lua stack is schedulable. */
1822 	if (!hlua || !hlua->task)
1823 		WILL_LJMP(luaL_error(L, "The 'receive' function is only allowed in "
1824 		                      "'frontend', 'backend' or 'task'"));
1825 
1826 	/* Check if we run on the same thread than the xreator thread.
1827 	 * We cannot access to the socket if the thread is different.
1828 	 */
1829 	if (socket->tid != tid)
1830 		WILL_LJMP(luaL_error(L, "connect: cannot use socket on other thread"));
1831 
1832 	/* check for connection break. If some data where read, return it. */
1833 	peer = xref_get_peer_and_lock(&socket->xref);
1834 	if (!peer)
1835 		goto no_peer;
1836 	appctx = container_of(peer, struct appctx, ctx.hlua_cosocket.xref);
1837 	si = appctx->owner;
1838 	s = si_strm(si);
1839 
1840 	oc = &s->res;
1841 	if (wanted == HLSR_READ_LINE) {
1842 		/* Read line. */
1843 		nblk = co_getline_nc(oc, &blk1, &len1, &blk2, &len2);
1844 		if (nblk < 0) /* Connection close. */
1845 			goto connection_closed;
1846 		if (nblk == 0) /* No data available. */
1847 			goto connection_empty;
1848 
1849 		/* remove final \r\n. */
1850 		if (nblk == 1) {
1851 			if (blk1[len1-1] == '\n') {
1852 				len1--;
1853 				skip_at_end++;
1854 				if (blk1[len1-1] == '\r') {
1855 					len1--;
1856 					skip_at_end++;
1857 				}
1858 			}
1859 		}
1860 		else {
1861 			if (blk2[len2-1] == '\n') {
1862 				len2--;
1863 				skip_at_end++;
1864 				if (blk2[len2-1] == '\r') {
1865 					len2--;
1866 					skip_at_end++;
1867 				}
1868 			}
1869 		}
1870 	}
1871 
1872 	else if (wanted == HLSR_READ_ALL) {
1873 		/* Read all the available data. */
1874 		nblk = co_getblk_nc(oc, &blk1, &len1, &blk2, &len2);
1875 		if (nblk < 0) /* Connection close. */
1876 			goto connection_closed;
1877 		if (nblk == 0) /* No data available. */
1878 			goto connection_empty;
1879 	}
1880 
1881 	else {
1882 		/* Read a block of data. */
1883 		nblk = co_getblk_nc(oc, &blk1, &len1, &blk2, &len2);
1884 		if (nblk < 0) /* Connection close. */
1885 			goto connection_closed;
1886 		if (nblk == 0) /* No data available. */
1887 			goto connection_empty;
1888 
1889 		missing_bytes = wanted - socket->b.n;
1890 		if (len1 > missing_bytes) {
1891 			nblk = 1;
1892 			len1 = missing_bytes;
1893 		} if (nblk == 2 && len1 + len2 > missing_bytes)
1894 			len2 = missing_bytes - len1;
1895 	}
1896 
1897 	len = len1;
1898 
1899 	luaL_addlstring(&socket->b, blk1, len1);
1900 	if (nblk == 2) {
1901 		len += len2;
1902 		luaL_addlstring(&socket->b, blk2, len2);
1903 	}
1904 
1905 	/* Consume data. */
1906 	co_skip(oc, len + skip_at_end);
1907 
1908 	/* Don't wait anything. */
1909 	appctx_wakeup(appctx);
1910 
1911 	/* If the pattern reclaim to read all the data
1912 	 * in the connection, got out.
1913 	 */
1914 	if (wanted == HLSR_READ_ALL)
1915 		goto connection_empty;
1916 	else if (wanted >= 0 && socket->b.n < wanted)
1917 		goto connection_empty;
1918 
1919 	/* Return result. */
1920 	luaL_pushresult(&socket->b);
1921 	xref_unlock(&socket->xref, peer);
1922 	return 1;
1923 
1924 connection_closed:
1925 
1926 	xref_unlock(&socket->xref, peer);
1927 
1928 no_peer:
1929 
1930 	/* If the buffer containds data. */
1931 	if (socket->b.n > 0) {
1932 		luaL_pushresult(&socket->b);
1933 		return 1;
1934 	}
1935 	lua_pushnil(L);
1936 	lua_pushstring(L, "connection closed.");
1937 	return 2;
1938 
1939 connection_empty:
1940 
1941 	if (!notification_new(&hlua->com, &appctx->ctx.hlua_cosocket.wake_on_read, hlua->task)) {
1942 		xref_unlock(&socket->xref, peer);
1943 		WILL_LJMP(luaL_error(L, "out of memory"));
1944 	}
1945 	xref_unlock(&socket->xref, peer);
1946 	MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_socket_receive_yield, TICK_ETERNITY, 0));
1947 	return 0;
1948 }
1949 
1950 /* This Lua function gets two parameters. The first one can be string
1951  * or a number. If the string is "*l", the user requires one line. If
1952  * the string is "*a", the user requires all the contents of the stream.
1953  * If the value is a number, the user require a number of bytes equal
1954  * to the value. The default value is "*l" (a line).
1955  *
1956  * This parameter with a variable type is converted in integer. This
1957  * integer takes this values:
1958  *  -1 : read a line
1959  *  -2 : read all the stream
1960  *  >0 : amount of bytes.
1961  *
1962  * The second parameter is optional. It contains a string that must be
1963  * concatenated with the read data.
1964  */
hlua_socket_receive(struct lua_State * L)1965 __LJMP static int hlua_socket_receive(struct lua_State *L)
1966 {
1967 	int wanted = HLSR_READ_LINE;
1968 	const char *pattern;
1969 	int lastarg, type;
1970 	char *error;
1971 	size_t len;
1972 	struct hlua_socket *socket;
1973 
1974 	if (lua_gettop(L) < 1 || lua_gettop(L) > 3)
1975 		WILL_LJMP(luaL_error(L, "The 'receive' function requires between 1 and 3 arguments."));
1976 
1977 	socket = MAY_LJMP(hlua_checksocket(L, 1));
1978 
1979 	/* Check if we run on the same thread than the xreator thread.
1980 	 * We cannot access to the socket if the thread is different.
1981 	 */
1982 	if (socket->tid != tid)
1983 		WILL_LJMP(luaL_error(L, "connect: cannot use socket on other thread"));
1984 
1985 	/* check for pattern. */
1986 	if (lua_gettop(L) >= 2) {
1987 		type = lua_type(L, 2);
1988 		if (type == LUA_TSTRING) {
1989 			pattern = lua_tostring(L, 2);
1990 			if (strcmp(pattern, "*a") == 0)
1991 				wanted = HLSR_READ_ALL;
1992 			else if (strcmp(pattern, "*l") == 0)
1993 				wanted = HLSR_READ_LINE;
1994 			else {
1995 				wanted = strtoll(pattern, &error, 10);
1996 				if (*error != '\0')
1997 					WILL_LJMP(luaL_error(L, "Unsupported pattern."));
1998 			}
1999 		}
2000 		else if (type == LUA_TNUMBER) {
2001 			wanted = lua_tointeger(L, 2);
2002 			if (wanted < 0)
2003 				WILL_LJMP(luaL_error(L, "Unsupported size."));
2004 		}
2005 	}
2006 
2007 	/* Set pattern. */
2008 	lua_pushinteger(L, wanted);
2009 
2010 	/* Check if we would replace the top by itself. */
2011 	if (lua_gettop(L) != 2)
2012 		lua_replace(L, 2);
2013 
2014 	/* Save index of the top of the stack because since buffers are used, it
2015 	 * may change
2016 	 */
2017 	lastarg = lua_gettop(L);
2018 
2019 	/* init buffer, and fill it with prefix. */
2020 	luaL_buffinit(L, &socket->b);
2021 
2022 	/* Check prefix. */
2023 	if (lastarg >= 3) {
2024 		if (lua_type(L, 3) != LUA_TSTRING)
2025 			WILL_LJMP(luaL_error(L, "Expect a 'string' for the prefix"));
2026 		pattern = lua_tolstring(L, 3, &len);
2027 		luaL_addlstring(&socket->b, pattern, len);
2028 	}
2029 
2030 	return __LJMP(hlua_socket_receive_yield(L, 0, 0));
2031 }
2032 
2033 /* Write the Lua input string in the output buffer.
2034  * This function returns a yield if no space is available.
2035  */
hlua_socket_write_yield(struct lua_State * L,int status,lua_KContext ctx)2036 static int hlua_socket_write_yield(struct lua_State *L,int status, lua_KContext ctx)
2037 {
2038 	struct hlua_socket *socket;
2039 	struct hlua *hlua = hlua_gethlua(L);
2040 	struct appctx *appctx;
2041 	size_t buf_len;
2042 	const char *buf;
2043 	int len;
2044 	int send_len;
2045 	int sent;
2046 	struct xref *peer;
2047 	struct stream_interface *si;
2048 	struct stream *s;
2049 
2050 	/* Check if this lua stack is schedulable. */
2051 	if (!hlua || !hlua->task)
2052 		WILL_LJMP(luaL_error(L, "The 'write' function is only allowed in "
2053 		                      "'frontend', 'backend' or 'task'"));
2054 
2055 	/* Get object */
2056 	socket = MAY_LJMP(hlua_checksocket(L, 1));
2057 	buf = MAY_LJMP(luaL_checklstring(L, 2, &buf_len));
2058 	sent = MAY_LJMP(luaL_checkinteger(L, 3));
2059 
2060 	/* Check if we run on the same thread than the xreator thread.
2061 	 * We cannot access to the socket if the thread is different.
2062 	 */
2063 	if (socket->tid != tid)
2064 		WILL_LJMP(luaL_error(L, "connect: cannot use socket on other thread"));
2065 
2066 	/* check for connection break. If some data where read, return it. */
2067 	peer = xref_get_peer_and_lock(&socket->xref);
2068 	if (!peer) {
2069 		lua_pushinteger(L, -1);
2070 		return 1;
2071 	}
2072 	appctx = container_of(peer, struct appctx, ctx.hlua_cosocket.xref);
2073 	si = appctx->owner;
2074 	s = si_strm(si);
2075 
2076 	/* Check for connection close. */
2077 	if (channel_output_closed(&s->req)) {
2078 		xref_unlock(&socket->xref, peer);
2079 		lua_pushinteger(L, -1);
2080 		return 1;
2081 	}
2082 
2083 	/* Update the input buffer data. */
2084 	buf += sent;
2085 	send_len = buf_len - sent;
2086 
2087 	/* All the data are sent. */
2088 	if (sent >= buf_len) {
2089 		xref_unlock(&socket->xref, peer);
2090 		return 1; /* Implicitly return the length sent. */
2091 	}
2092 
2093 	/* Check if the buffer is available because HAProxy doesn't allocate
2094 	 * the request buffer if its not required.
2095 	 */
2096 	if (s->req.buf.size == 0) {
2097 		if (!si_alloc_ibuf(si, &appctx->buffer_wait))
2098 			goto hlua_socket_write_yield_return;
2099 	}
2100 
2101 	/* Check for available space. */
2102 	len = b_room(&s->req.buf);
2103 	if (len <= 0) {
2104 		goto hlua_socket_write_yield_return;
2105 	}
2106 
2107 	/* send data */
2108 	if (len < send_len)
2109 		send_len = len;
2110 	len = ci_putblk(&s->req, buf, send_len);
2111 
2112 	/* "Not enough space" (-1), "Buffer too little to contain
2113 	 * the data" (-2) are not expected because the available length
2114 	 * is tested.
2115 	 * Other unknown error are also not expected.
2116 	 */
2117 	if (len <= 0) {
2118 		if (len == -1)
2119 			s->req.flags |= CF_WAKE_WRITE;
2120 
2121 		MAY_LJMP(hlua_socket_close_helper(L));
2122 		lua_pop(L, 1);
2123 		lua_pushinteger(L, -1);
2124 		xref_unlock(&socket->xref, peer);
2125 		return 1;
2126 	}
2127 
2128 	/* update buffers. */
2129 	appctx_wakeup(appctx);
2130 
2131 	s->req.rex = TICK_ETERNITY;
2132 	s->res.wex = TICK_ETERNITY;
2133 
2134 	/* Update length sent. */
2135 	lua_pop(L, 1);
2136 	lua_pushinteger(L, sent + len);
2137 
2138 	/* All the data buffer is sent ? */
2139 	if (sent + len >= buf_len) {
2140 		xref_unlock(&socket->xref, peer);
2141 		return 1;
2142 	}
2143 
2144 hlua_socket_write_yield_return:
2145 	if (!notification_new(&hlua->com, &appctx->ctx.hlua_cosocket.wake_on_write, hlua->task)) {
2146 		xref_unlock(&socket->xref, peer);
2147 		WILL_LJMP(luaL_error(L, "out of memory"));
2148 	}
2149 	xref_unlock(&socket->xref, peer);
2150 	MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_socket_write_yield, TICK_ETERNITY, 0));
2151 	return 0;
2152 }
2153 
2154 /* This function initiate the send of data. It just check the input
2155  * parameters and push an integer in the Lua stack that contain the
2156  * amount of data written to the buffer. This is used by the function
2157  * "hlua_socket_write_yield" that can yield.
2158  *
2159  * The Lua function gets between 3 and 4 parameters. The first one is
2160  * the associated object. The second is a string buffer. The third is
2161  * a facultative integer that represents where is the buffer position
2162  * of the start of the data that can send. The first byte is the
2163  * position "1". The default value is "1". The fourth argument is a
2164  * facultative integer that represents where is the buffer position
2165  * of the end of the data that can send. The default is the last byte.
2166  */
hlua_socket_send(struct lua_State * L)2167 static int hlua_socket_send(struct lua_State *L)
2168 {
2169 	int i;
2170 	int j;
2171 	const char *buf;
2172 	size_t buf_len;
2173 
2174 	/* Check number of arguments. */
2175 	if (lua_gettop(L) < 2 || lua_gettop(L) > 4)
2176 		WILL_LJMP(luaL_error(L, "'send' needs between 2 and 4 arguments"));
2177 
2178 	/* Get the string. */
2179 	buf = MAY_LJMP(luaL_checklstring(L, 2, &buf_len));
2180 
2181 	/* Get and check j. */
2182 	if (lua_gettop(L) == 4) {
2183 		j = MAY_LJMP(luaL_checkinteger(L, 4));
2184 		if (j < 0)
2185 			j = buf_len + j + 1;
2186 		if (j > buf_len)
2187 			j = buf_len + 1;
2188 		lua_pop(L, 1);
2189 	}
2190 	else
2191 		j = buf_len;
2192 
2193 	/* Get and check i. */
2194 	if (lua_gettop(L) == 3) {
2195 		i = MAY_LJMP(luaL_checkinteger(L, 3));
2196 		if (i < 0)
2197 			i = buf_len + i + 1;
2198 		if (i > buf_len)
2199 			i = buf_len + 1;
2200 		lua_pop(L, 1);
2201 	} else
2202 		i = 1;
2203 
2204 	/* Check bth i and j. */
2205 	if (i > j) {
2206 		lua_pushinteger(L, 0);
2207 		return 1;
2208 	}
2209 	if (i == 0 && j == 0) {
2210 		lua_pushinteger(L, 0);
2211 		return 1;
2212 	}
2213 	if (i == 0)
2214 		i = 1;
2215 	if (j == 0)
2216 		j = 1;
2217 
2218 	/* Pop the string. */
2219 	lua_pop(L, 1);
2220 
2221 	/* Update the buffer length. */
2222 	buf += i - 1;
2223 	buf_len = j - i + 1;
2224 	lua_pushlstring(L, buf, buf_len);
2225 
2226 	/* This unsigned is used to remember the amount of sent data. */
2227 	lua_pushinteger(L, 0);
2228 
2229 	return MAY_LJMP(hlua_socket_write_yield(L, 0, 0));
2230 }
2231 
2232 #define SOCKET_INFO_MAX_LEN sizeof("[0000:0000:0000:0000:0000:0000:0000:0000]:12345")
hlua_socket_info(struct lua_State * L,struct sockaddr_storage * addr)2233 __LJMP static inline int hlua_socket_info(struct lua_State *L, struct sockaddr_storage *addr)
2234 {
2235 	static char buffer[SOCKET_INFO_MAX_LEN];
2236 	int ret;
2237 	int len;
2238 	char *p;
2239 
2240 	ret = addr_to_str(addr, buffer+1, SOCKET_INFO_MAX_LEN-1);
2241 	if (ret <= 0) {
2242 		lua_pushnil(L);
2243 		return 1;
2244 	}
2245 
2246 	if (ret == AF_UNIX) {
2247 		lua_pushstring(L, buffer+1);
2248 		return 1;
2249 	}
2250 	else if (ret == AF_INET6) {
2251 		buffer[0] = '[';
2252 		len = strlen(buffer);
2253 		buffer[len] = ']';
2254 		len++;
2255 		buffer[len] = ':';
2256 		len++;
2257 		p = buffer;
2258 	}
2259 	else if (ret == AF_INET) {
2260 		p = buffer + 1;
2261 		len = strlen(p);
2262 		p[len] = ':';
2263 		len++;
2264 	}
2265 	else {
2266 		lua_pushnil(L);
2267 		return 1;
2268 	}
2269 
2270 	if (port_to_str(addr, p + len, SOCKET_INFO_MAX_LEN-1 - len) <= 0) {
2271 		lua_pushnil(L);
2272 		return 1;
2273 	}
2274 
2275 	lua_pushstring(L, p);
2276 	return 1;
2277 }
2278 
2279 /* Returns information about the peer of the connection. */
hlua_socket_getpeername(struct lua_State * L)2280 __LJMP static int hlua_socket_getpeername(struct lua_State *L)
2281 {
2282 	struct hlua_socket *socket;
2283 	struct connection *conn;
2284 	struct xref *peer;
2285 	struct appctx *appctx;
2286 	struct stream_interface *si;
2287 	struct stream *s;
2288 	int ret;
2289 
2290 	MAY_LJMP(check_args(L, 1, "getpeername"));
2291 
2292 	socket = MAY_LJMP(hlua_checksocket(L, 1));
2293 
2294 	/* Check if we run on the same thread than the xreator thread.
2295 	 * We cannot access to the socket if the thread is different.
2296 	 */
2297 	if (socket->tid != tid)
2298 		WILL_LJMP(luaL_error(L, "connect: cannot use socket on other thread"));
2299 
2300 	/* check for connection break. If some data where read, return it. */
2301 	peer = xref_get_peer_and_lock(&socket->xref);
2302 	if (!peer) {
2303 		lua_pushnil(L);
2304 		return 1;
2305 	}
2306 	appctx = container_of(peer, struct appctx, ctx.hlua_cosocket.xref);
2307 	si = appctx->owner;
2308 	s = si_strm(si);
2309 
2310 	conn = cs_conn(objt_cs(s->si[1].end));
2311 	if (!conn) {
2312 		xref_unlock(&socket->xref, peer);
2313 		lua_pushnil(L);
2314 		return 1;
2315 	}
2316 
2317 	conn_get_to_addr(conn);
2318 	if (!(conn->flags & CO_FL_ADDR_TO_SET)) {
2319 		xref_unlock(&socket->xref, peer);
2320 		lua_pushnil(L);
2321 		return 1;
2322 	}
2323 
2324 	ret = MAY_LJMP(hlua_socket_info(L, &conn->addr.to));
2325 	xref_unlock(&socket->xref, peer);
2326 	return ret;
2327 }
2328 
2329 /* Returns information about my connection side. */
hlua_socket_getsockname(struct lua_State * L)2330 static int hlua_socket_getsockname(struct lua_State *L)
2331 {
2332 	struct hlua_socket *socket;
2333 	struct connection *conn;
2334 	struct appctx *appctx;
2335 	struct xref *peer;
2336 	struct stream_interface *si;
2337 	struct stream *s;
2338 	int ret;
2339 
2340 	MAY_LJMP(check_args(L, 1, "getsockname"));
2341 
2342 	socket = MAY_LJMP(hlua_checksocket(L, 1));
2343 
2344 	/* Check if we run on the same thread than the xreator thread.
2345 	 * We cannot access to the socket if the thread is different.
2346 	 */
2347 	if (socket->tid != tid)
2348 		WILL_LJMP(luaL_error(L, "connect: cannot use socket on other thread"));
2349 
2350 	/* check for connection break. If some data where read, return it. */
2351 	peer = xref_get_peer_and_lock(&socket->xref);
2352 	if (!peer) {
2353 		lua_pushnil(L);
2354 		return 1;
2355 	}
2356 	appctx = container_of(peer, struct appctx, ctx.hlua_cosocket.xref);
2357 	si = appctx->owner;
2358 	s = si_strm(si);
2359 
2360 	conn = cs_conn(objt_cs(s->si[1].end));
2361 	if (!conn) {
2362 		xref_unlock(&socket->xref, peer);
2363 		lua_pushnil(L);
2364 		return 1;
2365 	}
2366 
2367 	conn_get_from_addr(conn);
2368 	if (!(conn->flags & CO_FL_ADDR_FROM_SET)) {
2369 		xref_unlock(&socket->xref, peer);
2370 		lua_pushnil(L);
2371 		return 1;
2372 	}
2373 
2374 	ret = hlua_socket_info(L, &conn->addr.from);
2375 	xref_unlock(&socket->xref, peer);
2376 	return ret;
2377 }
2378 
2379 /* This struct define the applet. */
2380 static struct applet update_applet = {
2381 	.obj_type = OBJ_TYPE_APPLET,
2382 	.name = "<LUA_TCP>",
2383 	.fct = hlua_socket_handler,
2384 	.release = hlua_socket_release,
2385 };
2386 
hlua_socket_connect_yield(struct lua_State * L,int status,lua_KContext ctx)2387 __LJMP static int hlua_socket_connect_yield(struct lua_State *L, int status, lua_KContext ctx)
2388 {
2389 	struct hlua_socket *socket = MAY_LJMP(hlua_checksocket(L, 1));
2390 	struct hlua *hlua = hlua_gethlua(L);
2391 	struct xref *peer;
2392 	struct appctx *appctx;
2393 	struct stream_interface *si;
2394 	struct stream *s;
2395 
2396 	/* Check if we run on the same thread than the xreator thread.
2397 	 * We cannot access to the socket if the thread is different.
2398 	 */
2399 	if (socket->tid != tid)
2400 		WILL_LJMP(luaL_error(L, "connect: cannot use socket on other thread"));
2401 
2402 	/* check for connection break. If some data where read, return it. */
2403 	peer = xref_get_peer_and_lock(&socket->xref);
2404 	if (!peer) {
2405 		lua_pushnil(L);
2406 		lua_pushstring(L, "Can't connect");
2407 		return 2;
2408 	}
2409 	appctx = container_of(peer, struct appctx, ctx.hlua_cosocket.xref);
2410 	si = appctx->owner;
2411 	s = si_strm(si);
2412 
2413 	/* Check if we run on the same thread than the xreator thread.
2414 	 * We cannot access to the socket if the thread is different.
2415 	 */
2416 	if (socket->tid != tid) {
2417 		xref_unlock(&socket->xref, peer);
2418 		WILL_LJMP(luaL_error(L, "connect: cannot use socket on other thread"));
2419 	}
2420 
2421 	/* Check for connection close. */
2422 	if (!hlua || channel_output_closed(&s->req)) {
2423 		xref_unlock(&socket->xref, peer);
2424 		lua_pushnil(L);
2425 		lua_pushstring(L, "Can't connect");
2426 		return 2;
2427 	}
2428 
2429 	appctx = __objt_appctx(s->si[0].end);
2430 
2431 	/* Check for connection established. */
2432 	if (appctx->ctx.hlua_cosocket.connected) {
2433 		xref_unlock(&socket->xref, peer);
2434 		lua_pushinteger(L, 1);
2435 		return 1;
2436 	}
2437 
2438 	if (!notification_new(&hlua->com, &appctx->ctx.hlua_cosocket.wake_on_write, hlua->task)) {
2439 		xref_unlock(&socket->xref, peer);
2440 		WILL_LJMP(luaL_error(L, "out of memory error"));
2441 	}
2442 	xref_unlock(&socket->xref, peer);
2443 	MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_socket_connect_yield, TICK_ETERNITY, 0));
2444 	return 0;
2445 }
2446 
2447 /* This function fail or initite the connection. */
hlua_socket_connect(struct lua_State * L)2448 __LJMP static int hlua_socket_connect(struct lua_State *L)
2449 {
2450 	struct hlua_socket *socket;
2451 	int port = -1;
2452 	const char *ip;
2453 	struct connection *conn;
2454 	struct hlua *hlua;
2455 	struct appctx *appctx;
2456 	int low, high;
2457 	struct sockaddr_storage *addr;
2458 	struct xref *peer;
2459 	struct stream_interface *si;
2460 	struct stream *s;
2461 
2462 	if (lua_gettop(L) < 2)
2463 		WILL_LJMP(luaL_error(L, "connect: need at least 2 arguments"));
2464 
2465 	/* Get args. */
2466 	socket  = MAY_LJMP(hlua_checksocket(L, 1));
2467 
2468 	/* Check if we run on the same thread than the xreator thread.
2469 	 * We cannot access to the socket if the thread is different.
2470 	 */
2471 	if (socket->tid != tid)
2472 		WILL_LJMP(luaL_error(L, "connect: cannot use socket on other thread"));
2473 
2474 	ip      = MAY_LJMP(luaL_checkstring(L, 2));
2475 	if (lua_gettop(L) >= 3) {
2476 		luaL_Buffer b;
2477 		port = MAY_LJMP(luaL_checkinteger(L, 3));
2478 
2479 		/* Force the ip to end with a colon, to support IPv6 addresses
2480 		 * that are not enclosed within square brackets.
2481 		 */
2482 		if (port > 0) {
2483 			luaL_buffinit(L, &b);
2484 			luaL_addstring(&b, ip);
2485 			luaL_addchar(&b, ':');
2486 			luaL_pushresult(&b);
2487 			ip = lua_tolstring(L, lua_gettop(L), NULL);
2488 		}
2489 	}
2490 
2491 	/* check for connection break. If some data where read, return it. */
2492 	peer = xref_get_peer_and_lock(&socket->xref);
2493 	if (!peer) {
2494 		lua_pushnil(L);
2495 		return 1;
2496 	}
2497 	appctx = container_of(peer, struct appctx, ctx.hlua_cosocket.xref);
2498 	si = appctx->owner;
2499 	s = si_strm(si);
2500 
2501 	/* Initialise connection. */
2502 	conn = cs_conn(si_alloc_cs(&s->si[1], NULL));
2503 	if (!conn) {
2504 		xref_unlock(&socket->xref, peer);
2505 		WILL_LJMP(luaL_error(L, "connect: internal error"));
2506 	}
2507 
2508 	/* needed for the connection not to be closed */
2509 	conn->target = s->target;
2510 
2511 	/* Parse ip address. */
2512 	addr = str2sa_range(ip, NULL, &low, &high, NULL, NULL, NULL, 0);
2513 	if (!addr) {
2514 		xref_unlock(&socket->xref, peer);
2515 		WILL_LJMP(luaL_error(L, "connect: cannot parse destination address '%s'", ip));
2516 	}
2517 	if (low != high) {
2518 		xref_unlock(&socket->xref, peer);
2519 		WILL_LJMP(luaL_error(L, "connect: port ranges not supported : address '%s'", ip));
2520 	}
2521 	memcpy(&conn->addr.to, addr, sizeof(struct sockaddr_storage));
2522 
2523 	/* Set port. */
2524 	if (low == 0) {
2525 		if (conn->addr.to.ss_family == AF_INET) {
2526 			if (port == -1) {
2527 				xref_unlock(&socket->xref, peer);
2528 				WILL_LJMP(luaL_error(L, "connect: port missing"));
2529 			}
2530 			((struct sockaddr_in *)&conn->addr.to)->sin_port = htons(port);
2531 		} else if (conn->addr.to.ss_family == AF_INET6) {
2532 			if (port == -1) {
2533 				xref_unlock(&socket->xref, peer);
2534 				WILL_LJMP(luaL_error(L, "connect: port missing"));
2535 			}
2536 			((struct sockaddr_in6 *)&conn->addr.to)->sin6_port = htons(port);
2537 		}
2538 	}
2539 
2540 	hlua = hlua_gethlua(L);
2541 	appctx = __objt_appctx(s->si[0].end);
2542 
2543 	/* inform the stream that we want to be notified whenever the
2544 	 * connection completes.
2545 	 */
2546 	si_cant_get(&s->si[0]);
2547 	si_rx_endp_more(&s->si[0]);
2548 	appctx_wakeup(appctx);
2549 
2550 	hlua->flags |= HLUA_MUST_GC;
2551 
2552 	if (!notification_new(&hlua->com, &appctx->ctx.hlua_cosocket.wake_on_write, hlua->task)) {
2553 		xref_unlock(&socket->xref, peer);
2554 		WILL_LJMP(luaL_error(L, "out of memory"));
2555 	}
2556 	xref_unlock(&socket->xref, peer);
2557 
2558 	task_wakeup(s->task, TASK_WOKEN_INIT);
2559 	/* Return yield waiting for connection. */
2560 
2561 	MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_socket_connect_yield, TICK_ETERNITY, 0));
2562 
2563 	return 0;
2564 }
2565 
2566 #ifdef USE_OPENSSL
hlua_socket_connect_ssl(struct lua_State * L)2567 __LJMP static int hlua_socket_connect_ssl(struct lua_State *L)
2568 {
2569 	struct hlua_socket *socket;
2570 	struct xref *peer;
2571 	struct appctx *appctx;
2572 	struct stream_interface *si;
2573 	struct stream *s;
2574 
2575 	MAY_LJMP(check_args(L, 3, "connect_ssl"));
2576 	socket  = MAY_LJMP(hlua_checksocket(L, 1));
2577 
2578 	/* check for connection break. If some data where read, return it. */
2579 	peer = xref_get_peer_and_lock(&socket->xref);
2580 	if (!peer) {
2581 		lua_pushnil(L);
2582 		return 1;
2583 	}
2584 	appctx = container_of(peer, struct appctx, ctx.hlua_cosocket.xref);
2585 	si = appctx->owner;
2586 	s = si_strm(si);
2587 
2588 	s->target = &socket_ssl.obj_type;
2589 	xref_unlock(&socket->xref, peer);
2590 	return MAY_LJMP(hlua_socket_connect(L));
2591 }
2592 #endif
2593 
hlua_socket_setoption(struct lua_State * L)2594 __LJMP static int hlua_socket_setoption(struct lua_State *L)
2595 {
2596 	return 0;
2597 }
2598 
hlua_socket_settimeout(struct lua_State * L)2599 __LJMP static int hlua_socket_settimeout(struct lua_State *L)
2600 {
2601 	struct hlua_socket *socket;
2602 	int tmout;
2603 	double dtmout;
2604 	struct xref *peer;
2605 	struct appctx *appctx;
2606 	struct stream_interface *si;
2607 	struct stream *s;
2608 
2609 	MAY_LJMP(check_args(L, 2, "settimeout"));
2610 
2611 	socket = MAY_LJMP(hlua_checksocket(L, 1));
2612 
2613 	/* convert the timeout to millis */
2614 	dtmout = MAY_LJMP(luaL_checknumber(L, 2)) * 1000;
2615 
2616 	/* Check for negative values */
2617 	if (dtmout < 0)
2618 		WILL_LJMP(luaL_error(L, "settimeout: cannot set negatives values"));
2619 
2620 	if (dtmout > INT_MAX) /* overflow check */
2621 		WILL_LJMP(luaL_error(L, "settimeout: cannot set values larger than %d ms", INT_MAX));
2622 
2623 	tmout = MS_TO_TICKS((int)dtmout);
2624 	if (tmout == 0)
2625 		tmout++; /* very small timeouts are adjusted to a minium of 1ms */
2626 
2627 	/* Check if we run on the same thread than the xreator thread.
2628 	 * We cannot access to the socket if the thread is different.
2629 	 */
2630 	if (socket->tid != tid)
2631 		WILL_LJMP(luaL_error(L, "connect: cannot use socket on other thread"));
2632 
2633 	/* check for connection break. If some data were read, return it. */
2634 	peer = xref_get_peer_and_lock(&socket->xref);
2635 	if (!peer) {
2636 		hlua_pusherror(L, "socket: not yet initialised, you can't set timeouts.");
2637 		WILL_LJMP(lua_error(L));
2638 		return 0;
2639 	}
2640 	appctx = container_of(peer, struct appctx, ctx.hlua_cosocket.xref);
2641 	si = appctx->owner;
2642 	s = si_strm(si);
2643 
2644 	s->sess->fe->timeout.connect = tmout;
2645 	s->req.rto = tmout;
2646 	s->req.wto = tmout;
2647 	s->res.rto = tmout;
2648 	s->res.wto = tmout;
2649 	s->req.rex = tick_add_ifset(now_ms, tmout);
2650 	s->req.wex = tick_add_ifset(now_ms, tmout);
2651 	s->res.rex = tick_add_ifset(now_ms, tmout);
2652 	s->res.wex = tick_add_ifset(now_ms, tmout);
2653 
2654 	s->task->expire = tick_add_ifset(now_ms, tmout);
2655 	task_queue(s->task);
2656 
2657 	xref_unlock(&socket->xref, peer);
2658 
2659 	lua_pushinteger(L, 1);
2660 	return 1;
2661 }
2662 
hlua_socket_new(lua_State * L)2663 __LJMP static int hlua_socket_new(lua_State *L)
2664 {
2665 	struct hlua_socket *socket;
2666 	struct appctx *appctx;
2667 	struct session *sess;
2668 	struct stream *strm;
2669 
2670 	/* Check stack size. */
2671 	if (!lua_checkstack(L, 3)) {
2672 		hlua_pusherror(L, "socket: full stack");
2673 		goto out_fail_conf;
2674 	}
2675 
2676 	/* Create the object: obj[0] = userdata. */
2677 	lua_newtable(L);
2678 	socket = MAY_LJMP(lua_newuserdata(L, sizeof(*socket)));
2679 	lua_rawseti(L, -2, 0);
2680 	memset(socket, 0, sizeof(*socket));
2681 	socket->tid = tid;
2682 
2683 	/* Check if the various memory pools are intialized. */
2684 	if (!pool_head_stream || !pool_head_buffer) {
2685 		hlua_pusherror(L, "socket: uninitialized pools.");
2686 		goto out_fail_conf;
2687 	}
2688 
2689 	/* Pop a class stream metatable and affect it to the userdata. */
2690 	lua_rawgeti(L, LUA_REGISTRYINDEX, class_socket_ref);
2691 	lua_setmetatable(L, -2);
2692 
2693 	/* Create the applet context */
2694 	appctx = appctx_new(&update_applet, tid_bit);
2695 	if (!appctx) {
2696 		hlua_pusherror(L, "socket: out of memory");
2697 		goto out_fail_conf;
2698 	}
2699 
2700 	appctx->ctx.hlua_cosocket.connected = 0;
2701 	appctx->ctx.hlua_cosocket.die = 0;
2702 	LIST_INIT(&appctx->ctx.hlua_cosocket.wake_on_write);
2703 	LIST_INIT(&appctx->ctx.hlua_cosocket.wake_on_read);
2704 
2705 	/* Now create a session, task and stream for this applet */
2706 	sess = session_new(&socket_proxy, NULL, &appctx->obj_type);
2707 	if (!sess) {
2708 		hlua_pusherror(L, "socket: out of memory");
2709 		goto out_fail_sess;
2710 	}
2711 
2712 	strm = stream_new(sess, &appctx->obj_type);
2713 	if (!strm) {
2714 		hlua_pusherror(L, "socket: out of memory");
2715 		goto out_fail_stream;
2716 	}
2717 
2718 	/* Initialise cross reference between stream and Lua socket object. */
2719 	xref_create(&socket->xref, &appctx->ctx.hlua_cosocket.xref);
2720 
2721 	/* Configure "right" stream interface. this "si" is used to connect
2722 	 * and retrieve data from the server. The connection is initialized
2723 	 * with the "struct server".
2724 	 */
2725 	si_set_state(&strm->si[1], SI_ST_ASS);
2726 
2727 	/* Force destination server. */
2728 	strm->flags |= SF_DIRECT | SF_ASSIGNED | SF_ADDR_SET | SF_BE_ASSIGNED;
2729 	strm->target = &socket_tcp.obj_type;
2730 
2731 	return 1;
2732 
2733  out_fail_stream:
2734 	session_free(sess);
2735  out_fail_sess:
2736 	appctx_free(appctx);
2737  out_fail_conf:
2738 	WILL_LJMP(lua_error(L));
2739 	return 0;
2740 }
2741 
2742 /*
2743  *
2744  *
2745  * Class Channel
2746  *
2747  *
2748  */
2749 
2750 /* This function is called before the Lua execution. It stores
2751  * the differents parsers state before executing some Lua code.
2752  */
consistency_set(struct stream * stream,int opt,struct hlua_consistency * c)2753 static inline void consistency_set(struct stream *stream, int opt, struct hlua_consistency *c)
2754 {
2755 	c->mode = stream->be->mode;
2756 	switch (c->mode) {
2757 	case PR_MODE_HTTP:
2758 		c->data.http.dir = opt & SMP_OPT_DIR;
2759 		if (c->data.http.dir == SMP_OPT_DIR_REQ)
2760 			c->data.http.state = stream->txn->req.msg_state;
2761 		else
2762 			c->data.http.state = stream->txn->rsp.msg_state;
2763 		break;
2764 	default:
2765 		break;
2766 	}
2767 }
2768 
2769 /* This function is called after the Lua execution. it
2770  * returns true if the parser state is consistent, otherwise,
2771  * it return false.
2772  *
2773  * In HTTP mode, the parser state must be in the same state
2774  * or greater when we exit the function. Even if we do a
2775  * control yield. This prevent to break the HTTP message
2776  * from the Lua code.
2777  */
consistency_check(struct stream * stream,int opt,struct hlua_consistency * c)2778 static inline int consistency_check(struct stream *stream, int opt, struct hlua_consistency *c)
2779 {
2780 	if (c->mode != stream->be->mode)
2781 		return 0;
2782 
2783 	switch (c->mode) {
2784 	case PR_MODE_HTTP:
2785 		if (c->data.http.dir != (opt & SMP_OPT_DIR))
2786 			return 0;
2787 		if (c->data.http.dir == SMP_OPT_DIR_REQ)
2788 			return stream->txn->req.msg_state >= c->data.http.state;
2789 		else
2790 			return stream->txn->rsp.msg_state >= c->data.http.state;
2791 	default:
2792 		return 1;
2793 	}
2794 	return 1;
2795 }
2796 
2797 /* Returns the struct hlua_channel join to the class channel in the
2798  * stack entry "ud" or throws an argument error.
2799  */
hlua_checkchannel(lua_State * L,int ud)2800 __LJMP static struct channel *hlua_checkchannel(lua_State *L, int ud)
2801 {
2802 	return MAY_LJMP(hlua_checkudata(L, ud, class_channel_ref));
2803 }
2804 
2805 /* Pushes the channel onto the top of the stack. If the stask does not have a
2806  * free slots, the function fails and returns 0;
2807  */
hlua_channel_new(lua_State * L,struct channel * channel)2808 static int hlua_channel_new(lua_State *L, struct channel *channel)
2809 {
2810 	/* Check stack size. */
2811 	if (!lua_checkstack(L, 3))
2812 		return 0;
2813 
2814 	lua_newtable(L);
2815 	lua_pushlightuserdata(L, channel);
2816 	lua_rawseti(L, -2, 0);
2817 
2818 	/* Pop a class sesison metatable and affect it to the userdata. */
2819 	lua_rawgeti(L, LUA_REGISTRYINDEX, class_channel_ref);
2820 	lua_setmetatable(L, -2);
2821 	return 1;
2822 }
2823 
2824 /* Duplicate all the data present in the input channel and put it
2825  * in a string LUA variables. Returns -1 and push a nil value in
2826  * the stack if the channel is closed and all the data are consumed,
2827  * returns 0 if no data are available, otherwise it returns the length
2828  * of the builded string.
2829  */
_hlua_channel_dup(struct channel * chn,lua_State * L)2830 static inline int _hlua_channel_dup(struct channel *chn, lua_State *L)
2831 {
2832 	char *blk1;
2833 	char *blk2;
2834 	size_t len1;
2835 	size_t len2;
2836 	int ret;
2837 	luaL_Buffer b;
2838 
2839 	ret = ci_getblk_nc(chn, &blk1, &len1, &blk2, &len2);
2840 	if (unlikely(ret == 0))
2841 		return 0;
2842 
2843 	if (unlikely(ret < 0)) {
2844 		lua_pushnil(L);
2845 		return -1;
2846 	}
2847 
2848 	luaL_buffinit(L, &b);
2849 	luaL_addlstring(&b, blk1, len1);
2850 	if (unlikely(ret == 2))
2851 		luaL_addlstring(&b, blk2, len2);
2852 	luaL_pushresult(&b);
2853 
2854 	if (unlikely(ret == 2))
2855 		return len1 + len2;
2856 	return len1;
2857 }
2858 
2859 /* "_hlua_channel_dup" wrapper. If no data are available, it returns
2860  * a yield. This function keep the data in the buffer.
2861  */
hlua_channel_dup_yield(lua_State * L,int status,lua_KContext ctx)2862 __LJMP static int hlua_channel_dup_yield(lua_State *L, int status, lua_KContext ctx)
2863 {
2864 	struct channel *chn;
2865 
2866 	chn = MAY_LJMP(hlua_checkchannel(L, 1));
2867 
2868 	if (chn_strm(chn)->be->mode == PR_MODE_HTTP) {
2869 		lua_pushfstring(L, "Cannot manipulate HAProxy channels in HTTP mode.");
2870 		WILL_LJMP(lua_error(L));
2871 	}
2872 
2873 	if (_hlua_channel_dup(chn, L) == 0)
2874 		MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_channel_dup_yield, TICK_ETERNITY, 0));
2875 	return 1;
2876 }
2877 
2878 /* Check arguments for the function "hlua_channel_dup_yield". */
hlua_channel_dup(lua_State * L)2879 __LJMP static int hlua_channel_dup(lua_State *L)
2880 {
2881 	MAY_LJMP(check_args(L, 1, "dup"));
2882 	MAY_LJMP(hlua_checkchannel(L, 1));
2883 	return MAY_LJMP(hlua_channel_dup_yield(L, 0, 0));
2884 }
2885 
2886 /* "_hlua_channel_dup" wrapper. If no data are available, it returns
2887  * a yield. This function consumes the data in the buffer. It returns
2888  * a string containing the data or a nil pointer if no data are available
2889  * and the channel is closed.
2890  */
hlua_channel_get_yield(lua_State * L,int status,lua_KContext ctx)2891 __LJMP static int hlua_channel_get_yield(lua_State *L, int status, lua_KContext ctx)
2892 {
2893 	struct channel *chn;
2894 	int ret;
2895 
2896 	chn = MAY_LJMP(hlua_checkchannel(L, 1));
2897 
2898 	if (chn_strm(chn)->be->mode == PR_MODE_HTTP) {
2899 		lua_pushfstring(L, "Cannot manipulate HAProxy channels in HTTP mode.");
2900 		WILL_LJMP(lua_error(L));
2901 	}
2902 
2903 	ret = _hlua_channel_dup(chn, L);
2904 	if (unlikely(ret == 0))
2905 		MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_channel_get_yield, TICK_ETERNITY, 0));
2906 
2907 	if (unlikely(ret == -1))
2908 		return 1;
2909 
2910 	b_sub(&chn->buf, ret);
2911 	return 1;
2912 }
2913 
2914 /* Check arguments for the function "hlua_channel_get_yield". */
hlua_channel_get(lua_State * L)2915 __LJMP static int hlua_channel_get(lua_State *L)
2916 {
2917 	MAY_LJMP(check_args(L, 1, "get"));
2918 	MAY_LJMP(hlua_checkchannel(L, 1));
2919 	return MAY_LJMP(hlua_channel_get_yield(L, 0, 0));
2920 }
2921 
2922 /* This functions consumes and returns one line. If the channel is closed,
2923  * and the last data does not contains a final '\n', the data are returned
2924  * without the final '\n'. When no more data are available, it returns nil
2925  * value.
2926  */
hlua_channel_getline_yield(lua_State * L,int status,lua_KContext ctx)2927 __LJMP static int hlua_channel_getline_yield(lua_State *L, int status, lua_KContext ctx)
2928 {
2929 	char *blk1;
2930 	char *blk2;
2931 	size_t len1;
2932 	size_t len2;
2933 	size_t len;
2934 	struct channel *chn;
2935 	int ret;
2936 	luaL_Buffer b;
2937 
2938 	chn = MAY_LJMP(hlua_checkchannel(L, 1));
2939 
2940 	if (chn_strm(chn)->be->mode == PR_MODE_HTTP) {
2941 		lua_pushfstring(L, "Cannot manipulate HAProxy channels in HTTP mode.");
2942 		WILL_LJMP(lua_error(L));
2943 	}
2944 
2945 	ret = ci_getline_nc(chn, &blk1, &len1, &blk2, &len2);
2946 	if (ret == 0)
2947 		MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_channel_getline_yield, TICK_ETERNITY, 0));
2948 
2949 	if (ret == -1) {
2950 		lua_pushnil(L);
2951 		return 1;
2952 	}
2953 
2954 	luaL_buffinit(L, &b);
2955 	luaL_addlstring(&b, blk1, len1);
2956 	len = len1;
2957 	if (unlikely(ret == 2)) {
2958 		luaL_addlstring(&b, blk2, len2);
2959 		len += len2;
2960 	}
2961 	luaL_pushresult(&b);
2962 	b_rep_blk(&chn->buf, ci_head(chn), ci_head(chn) + len,  NULL, 0);
2963 	return 1;
2964 }
2965 
2966 /* Check arguments for the function "hlua_channel_getline_yield". */
hlua_channel_getline(lua_State * L)2967 __LJMP static int hlua_channel_getline(lua_State *L)
2968 {
2969 	MAY_LJMP(check_args(L, 1, "getline"));
2970 	MAY_LJMP(hlua_checkchannel(L, 1));
2971 	return MAY_LJMP(hlua_channel_getline_yield(L, 0, 0));
2972 }
2973 
2974 /* This function takes a string as input, and append it at the
2975  * input side of channel. If the data is too big, but a space
2976  * is probably available after sending some data, the function
2977  * yields. If the data is bigger than the buffer, or if the
2978  * channel is closed, it returns -1. Otherwise, it returns the
2979  * amount of data written.
2980  */
hlua_channel_append_yield(lua_State * L,int status,lua_KContext ctx)2981 __LJMP static int hlua_channel_append_yield(lua_State *L, int status, lua_KContext ctx)
2982 {
2983 	struct channel *chn = MAY_LJMP(hlua_checkchannel(L, 1));
2984 	size_t len;
2985 	const char *str = MAY_LJMP(luaL_checklstring(L, 2, &len));
2986 	int l = MAY_LJMP(luaL_checkinteger(L, 3));
2987 	int ret;
2988 	int max;
2989 
2990 	if (chn_strm(chn)->be->mode == PR_MODE_HTTP) {
2991 		lua_pushfstring(L, "Cannot manipulate HAProxy channels in HTTP mode.");
2992 		WILL_LJMP(lua_error(L));
2993 	}
2994 
2995 	/* Check if the buffer is available because HAProxy doesn't allocate
2996 	 * the request buffer if its not required.
2997 	 */
2998 	if (chn->buf.size == 0) {
2999 		si_rx_buff_blk(chn_prod(chn));
3000 		MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_channel_append_yield, TICK_ETERNITY, 0));
3001 	}
3002 
3003 	max = channel_recv_limit(chn) - b_data(&chn->buf);
3004 	if (max > len - l)
3005 		max = len - l;
3006 
3007 	ret = ci_putblk(chn, str + l, max);
3008 	if (ret == -2 || ret == -3) {
3009 		lua_pushinteger(L, -1);
3010 		return 1;
3011 	}
3012 	if (ret == -1) {
3013 		chn->flags |= CF_WAKE_WRITE;
3014 		MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_channel_append_yield, TICK_ETERNITY, 0));
3015 	}
3016 	l += ret;
3017 	lua_pop(L, 1);
3018 	lua_pushinteger(L, l);
3019 
3020 	max = channel_recv_limit(chn) - b_data(&chn->buf);
3021 	if (max == 0 && co_data(chn) == 0) {
3022 		/* There are no space available, and the output buffer is empty.
3023 		 * in this case, we cannot add more data, so we cannot yield,
3024 		 * we return the amount of copyied data.
3025 		 */
3026 		return 1;
3027 	}
3028 	if (l < len)
3029 		MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_channel_append_yield, TICK_ETERNITY, 0));
3030 	return 1;
3031 }
3032 
3033 /* Just a wrapper of "hlua_channel_append_yield". It returns the length
3034  * of the written string, or -1 if the channel is closed or if the
3035  * buffer size is too little for the data.
3036  */
hlua_channel_append(lua_State * L)3037 __LJMP static int hlua_channel_append(lua_State *L)
3038 {
3039 	size_t len;
3040 
3041 	MAY_LJMP(check_args(L, 2, "append"));
3042 	MAY_LJMP(hlua_checkchannel(L, 1));
3043 	MAY_LJMP(luaL_checklstring(L, 2, &len));
3044 	MAY_LJMP(luaL_checkinteger(L, 3));
3045 	lua_pushinteger(L, 0);
3046 
3047 	return MAY_LJMP(hlua_channel_append_yield(L, 0, 0));
3048 }
3049 
3050 /* Just a wrapper of "hlua_channel_append_yield". This wrapper starts
3051  * his process by cleaning the buffer. The result is a replacement
3052  * of the current data. It returns the length of the written string,
3053  * or -1 if the channel is closed or if the buffer size is too
3054  * little for the data.
3055  */
hlua_channel_set(lua_State * L)3056 __LJMP static int hlua_channel_set(lua_State *L)
3057 {
3058 	struct channel *chn;
3059 
3060 	MAY_LJMP(check_args(L, 2, "set"));
3061 	chn = MAY_LJMP(hlua_checkchannel(L, 1));
3062 	lua_pushinteger(L, 0);
3063 
3064 	if (chn_strm(chn)->be->mode == PR_MODE_HTTP) {
3065 		lua_pushfstring(L, "Cannot manipulate HAProxy channels in HTTP mode.");
3066 		WILL_LJMP(lua_error(L));
3067 	}
3068 
3069 	b_set_data(&chn->buf, co_data(chn));
3070 
3071 	return MAY_LJMP(hlua_channel_append_yield(L, 0, 0));
3072 }
3073 
3074 /* Append data in the output side of the buffer. This data is immediately
3075  * sent. The function returns the amount of data written. If the buffer
3076  * cannot contain the data, the function yields. The function returns -1
3077  * if the channel is closed.
3078  */
hlua_channel_send_yield(lua_State * L,int status,lua_KContext ctx)3079 __LJMP static int hlua_channel_send_yield(lua_State *L, int status, lua_KContext ctx)
3080 {
3081 	struct channel *chn = MAY_LJMP(hlua_checkchannel(L, 1));
3082 	size_t len;
3083 	const char *str = MAY_LJMP(luaL_checklstring(L, 2, &len));
3084 	int l = MAY_LJMP(luaL_checkinteger(L, 3));
3085 	int max;
3086 	struct hlua *hlua = hlua_gethlua(L);
3087 
3088 	if (chn_strm(chn)->be->mode == PR_MODE_HTTP) {
3089 		lua_pushfstring(L, "Cannot manipulate HAProxy channels in HTTP mode.");
3090 		WILL_LJMP(lua_error(L));
3091 	}
3092 
3093 	if (unlikely(channel_output_closed(chn))) {
3094 		lua_pushinteger(L, -1);
3095 		return 1;
3096 	}
3097 
3098 	/* Check if the buffer is available because HAProxy doesn't allocate
3099 	 * the request buffer if its not required.
3100 	 */
3101 	if (chn->buf.size == 0) {
3102 		si_rx_buff_blk(chn_prod(chn));
3103 		MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_channel_send_yield, TICK_ETERNITY, 0));
3104 	}
3105 
3106 	/* The written data will be immediately sent, so we can check
3107 	 * the available space without taking in account the reserve.
3108 	 * The reserve is guaranteed for the processing of incoming
3109 	 * data, because the buffer will be flushed.
3110 	 */
3111 	max = b_room(&chn->buf);
3112 
3113 	/* If there is no space available, and the output buffer is empty.
3114 	 * in this case, we cannot add more data, so we cannot yield,
3115 	 * we return the amount of copyied data.
3116 	 */
3117 	if (max == 0 && co_data(chn) == 0)
3118 		return 1;
3119 
3120 	/* Adjust the real required length. */
3121 	if (max > len - l)
3122 		max = len - l;
3123 
3124 	/* The buffer available size may be not contiguous. This test
3125 	 * detects a non contiguous buffer and realign it.
3126 	 */
3127 	if (ci_space_for_replace(chn) < max)
3128 		channel_slow_realign(chn, trash.area);
3129 
3130 	/* Copy input data in the buffer. */
3131 	max = b_rep_blk(&chn->buf, ci_head(chn), ci_head(chn), str + l, max);
3132 
3133 	/* buffer replace considers that the input part is filled.
3134 	 * so, I must forward these new data in the output part.
3135 	 */
3136 	c_adv(chn, max);
3137 
3138 	l += max;
3139 	lua_pop(L, 1);
3140 	lua_pushinteger(L, l);
3141 
3142 	/* If there is no space available, and the output buffer is empty.
3143 	 * in this case, we cannot add more data, so we cannot yield,
3144 	 * we return the amount of copyied data.
3145 	 */
3146 	max = b_room(&chn->buf);
3147 	if (max == 0 && co_data(chn) == 0)
3148 		return 1;
3149 
3150 	if (l < len) {
3151 		/* If we are waiting for space in the response buffer, we
3152 		 * must set the flag WAKERESWR. This flag required the task
3153 		 * wake up if any activity is detected on the response buffer.
3154 		 */
3155 		if (chn->flags & CF_ISRESP)
3156 			HLUA_SET_WAKERESWR(hlua);
3157 		else
3158 			HLUA_SET_WAKEREQWR(hlua);
3159 		MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_channel_send_yield, TICK_ETERNITY, 0));
3160 	}
3161 
3162 	return 1;
3163 }
3164 
3165 /* Just a wraper of "_hlua_channel_send". This wrapper permits
3166  * yield the LUA process, and resume it without checking the
3167  * input arguments.
3168  */
hlua_channel_send(lua_State * L)3169 __LJMP static int hlua_channel_send(lua_State *L)
3170 {
3171 	MAY_LJMP(check_args(L, 2, "send"));
3172 	lua_pushinteger(L, 0);
3173 
3174 	return MAY_LJMP(hlua_channel_send_yield(L, 0, 0));
3175 }
3176 
3177 /* This function forward and amount of butes. The data pass from
3178  * the input side of the buffer to the output side, and can be
3179  * forwarded. This function never fails.
3180  *
3181  * The Lua function takes an amount of bytes to be forwarded in
3182  * imput. It returns the number of bytes forwarded.
3183  */
hlua_channel_forward_yield(lua_State * L,int status,lua_KContext ctx)3184 __LJMP static int hlua_channel_forward_yield(lua_State *L, int status, lua_KContext ctx)
3185 {
3186 	struct channel *chn;
3187 	int len;
3188 	int l;
3189 	int max;
3190 	struct hlua *hlua = hlua_gethlua(L);
3191 
3192 	chn = MAY_LJMP(hlua_checkchannel(L, 1));
3193 
3194 	if (chn_strm(chn)->be->mode == PR_MODE_HTTP) {
3195 		lua_pushfstring(L, "Cannot manipulate HAProxy channels in HTTP mode.");
3196 		WILL_LJMP(lua_error(L));
3197 	}
3198 
3199 	len = MAY_LJMP(luaL_checkinteger(L, 2));
3200 	l = MAY_LJMP(luaL_checkinteger(L, -1));
3201 
3202 	max = len - l;
3203 	if (max > ci_data(chn))
3204 		max = ci_data(chn);
3205 	channel_forward(chn, max);
3206 	l += max;
3207 
3208 	lua_pop(L, 1);
3209 	lua_pushinteger(L, l);
3210 
3211 	/* Check if it miss bytes to forward. */
3212 	if (l < len) {
3213 		/* The the input channel or the output channel are closed, we
3214 		 * must return the amount of data forwarded.
3215 		 */
3216 		if (channel_input_closed(chn) || channel_output_closed(chn))
3217 			return 1;
3218 
3219 		/* If we are waiting for space data in the response buffer, we
3220 		 * must set the flag WAKERESWR. This flag required the task
3221 		 * wake up if any activity is detected on the response buffer.
3222 		 */
3223 		if (chn->flags & CF_ISRESP)
3224 			HLUA_SET_WAKERESWR(hlua);
3225 		else
3226 			HLUA_SET_WAKEREQWR(hlua);
3227 
3228 		/* Otherwise, we can yield waiting for new data in the inpout side. */
3229 		MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_channel_forward_yield, TICK_ETERNITY, 0));
3230 	}
3231 
3232 	return 1;
3233 }
3234 
3235 /* Just check the input and prepare the stack for the previous
3236  * function "hlua_channel_forward_yield"
3237  */
hlua_channel_forward(lua_State * L)3238 __LJMP static int hlua_channel_forward(lua_State *L)
3239 {
3240 	MAY_LJMP(check_args(L, 2, "forward"));
3241 	MAY_LJMP(hlua_checkchannel(L, 1));
3242 	MAY_LJMP(luaL_checkinteger(L, 2));
3243 
3244 	lua_pushinteger(L, 0);
3245 	return MAY_LJMP(hlua_channel_forward_yield(L, 0, 0));
3246 }
3247 
3248 /* Just returns the number of bytes available in the input
3249  * side of the buffer. This function never fails.
3250  */
hlua_channel_get_in_len(lua_State * L)3251 __LJMP static int hlua_channel_get_in_len(lua_State *L)
3252 {
3253 	struct channel *chn;
3254 
3255 	MAY_LJMP(check_args(L, 1, "get_in_len"));
3256 	chn = MAY_LJMP(hlua_checkchannel(L, 1));
3257 	if (IS_HTX_STRM(chn_strm(chn))) {
3258 		struct htx *htx = htxbuf(&chn->buf);
3259 		lua_pushinteger(L, htx->data - co_data(chn));
3260 	}
3261 	else
3262 		lua_pushinteger(L, ci_data(chn));
3263 	return 1;
3264 }
3265 
3266 /* Returns true if the channel is full. */
hlua_channel_is_full(lua_State * L)3267 __LJMP static int hlua_channel_is_full(lua_State *L)
3268 {
3269 	struct channel *chn;
3270 
3271 	MAY_LJMP(check_args(L, 1, "is_full"));
3272 	chn = MAY_LJMP(hlua_checkchannel(L, 1));
3273 	/* ignore the reserve, we are not on a producer side (ie in an
3274 	 * applet).
3275 	 */
3276 	lua_pushboolean(L, channel_full(chn, 0));
3277 	return 1;
3278 }
3279 
3280 /* Just returns the number of bytes available in the output
3281  * side of the buffer. This function never fails.
3282  */
hlua_channel_get_out_len(lua_State * L)3283 __LJMP static int hlua_channel_get_out_len(lua_State *L)
3284 {
3285 	struct channel *chn;
3286 
3287 	MAY_LJMP(check_args(L, 1, "get_out_len"));
3288 	chn = MAY_LJMP(hlua_checkchannel(L, 1));
3289 	lua_pushinteger(L, co_data(chn));
3290 	return 1;
3291 }
3292 
3293 /*
3294  *
3295  *
3296  * Class Fetches
3297  *
3298  *
3299  */
3300 
3301 /* Returns a struct hlua_session if the stack entry "ud" is
3302  * a class stream, otherwise it throws an error.
3303  */
hlua_checkfetches(lua_State * L,int ud)3304 __LJMP static struct hlua_smp *hlua_checkfetches(lua_State *L, int ud)
3305 {
3306 	return MAY_LJMP(hlua_checkudata(L, ud, class_fetches_ref));
3307 }
3308 
3309 /* This function creates and push in the stack a fetch object according
3310  * with a current TXN.
3311  */
hlua_fetches_new(lua_State * L,struct hlua_txn * txn,unsigned int flags)3312 static int hlua_fetches_new(lua_State *L, struct hlua_txn *txn, unsigned int flags)
3313 {
3314 	struct hlua_smp *hsmp;
3315 
3316 	/* Check stack size. */
3317 	if (!lua_checkstack(L, 3))
3318 		return 0;
3319 
3320 	/* Create the object: obj[0] = userdata.
3321 	 * Note that the base of the Fetches object is the
3322 	 * transaction object.
3323 	 */
3324 	lua_newtable(L);
3325 	hsmp = lua_newuserdata(L, sizeof(*hsmp));
3326 	lua_rawseti(L, -2, 0);
3327 
3328 	hsmp->s = txn->s;
3329 	hsmp->p = txn->p;
3330 	hsmp->dir = txn->dir;
3331 	hsmp->flags = flags;
3332 
3333 	/* Pop a class sesison metatable and affect it to the userdata. */
3334 	lua_rawgeti(L, LUA_REGISTRYINDEX, class_fetches_ref);
3335 	lua_setmetatable(L, -2);
3336 
3337 	return 1;
3338 }
3339 
3340 /* This function is an LUA binding. It is called with each sample-fetch.
3341  * It uses closure argument to store the associated sample-fetch. It
3342  * returns only one argument or throws an error. An error is thrown
3343  * only if an error is encountered during the argument parsing. If
3344  * the "sample-fetch" function fails, nil is returned.
3345  */
hlua_run_sample_fetch(lua_State * L)3346 __LJMP static int hlua_run_sample_fetch(lua_State *L)
3347 {
3348 	struct hlua_smp *hsmp;
3349 	struct sample_fetch *f;
3350 	struct arg args[ARGM_NBARGS + 1] = {{0}};
3351 	int i;
3352 	struct sample smp;
3353 
3354 	/* Get closure arguments. */
3355 	f = lua_touserdata(L, lua_upvalueindex(1));
3356 
3357 	/* Get traditional arguments. */
3358 	hsmp = MAY_LJMP(hlua_checkfetches(L, 1));
3359 
3360 	/* Check execution authorization. */
3361 	if (f->use & SMP_USE_HTTP_ANY &&
3362 	    !(hsmp->flags & HLUA_F_MAY_USE_HTTP)) {
3363 		lua_pushfstring(L, "the sample-fetch '%s' needs an HTTP parser which "
3364 		                   "is not available in Lua services", f->kw);
3365 		WILL_LJMP(lua_error(L));
3366 	}
3367 
3368 	/* Get extra arguments. */
3369 	for (i = 0; i < lua_gettop(L) - 1; i++) {
3370 		if (i >= ARGM_NBARGS)
3371 			break;
3372 		hlua_lua2arg(L, i + 2, &args[i]);
3373 	}
3374 	args[i].type = ARGT_STOP;
3375 	args[i].data.str.area = NULL;
3376 
3377 	/* Check arguments. */
3378 	MAY_LJMP(hlua_lua2arg_check(L, 2, args, f->arg_mask, hsmp->p));
3379 
3380 	/* Run the special args checker. */
3381 	if (f->val_args && !f->val_args(args, NULL)) {
3382 		lua_pushfstring(L, "error in arguments");
3383 		WILL_LJMP(lua_error(L));
3384 	}
3385 
3386 	/* Initialise the sample. */
3387 	memset(&smp, 0, sizeof(smp));
3388 
3389 	/* Run the sample fetch process. */
3390 	smp_set_owner(&smp, hsmp->p, hsmp->s->sess, hsmp->s, hsmp->dir & SMP_OPT_DIR);
3391 	if (!f->process(args, &smp, f->kw, f->private)) {
3392 		if (hsmp->flags & HLUA_F_AS_STRING)
3393 			lua_pushstring(L, "");
3394 		else
3395 			lua_pushnil(L);
3396 		return 1;
3397 	}
3398 
3399 	/* Convert the returned sample in lua value. */
3400 	if (hsmp->flags & HLUA_F_AS_STRING)
3401 		hlua_smp2lua_str(L, &smp);
3402 	else
3403 		hlua_smp2lua(L, &smp);
3404 	return 1;
3405 }
3406 
3407 /*
3408  *
3409  *
3410  * Class Converters
3411  *
3412  *
3413  */
3414 
3415 /* Returns a struct hlua_session if the stack entry "ud" is
3416  * a class stream, otherwise it throws an error.
3417  */
hlua_checkconverters(lua_State * L,int ud)3418 __LJMP static struct hlua_smp *hlua_checkconverters(lua_State *L, int ud)
3419 {
3420 	return MAY_LJMP(hlua_checkudata(L, ud, class_converters_ref));
3421 }
3422 
3423 /* This function creates and push in the stack a Converters object
3424  * according with a current TXN.
3425  */
hlua_converters_new(lua_State * L,struct hlua_txn * txn,unsigned int flags)3426 static int hlua_converters_new(lua_State *L, struct hlua_txn *txn, unsigned int flags)
3427 {
3428 	struct hlua_smp *hsmp;
3429 
3430 	/* Check stack size. */
3431 	if (!lua_checkstack(L, 3))
3432 		return 0;
3433 
3434 	/* Create the object: obj[0] = userdata.
3435 	 * Note that the base of the Converters object is the
3436 	 * same than the TXN object.
3437 	 */
3438 	lua_newtable(L);
3439 	hsmp = lua_newuserdata(L, sizeof(*hsmp));
3440 	lua_rawseti(L, -2, 0);
3441 
3442 	hsmp->s = txn->s;
3443 	hsmp->p = txn->p;
3444 	hsmp->dir = txn->dir;
3445 	hsmp->flags = flags;
3446 
3447 	/* Pop a class stream metatable and affect it to the table. */
3448 	lua_rawgeti(L, LUA_REGISTRYINDEX, class_converters_ref);
3449 	lua_setmetatable(L, -2);
3450 
3451 	return 1;
3452 }
3453 
3454 /* This function is an LUA binding. It is called with each converter.
3455  * It uses closure argument to store the associated converter. It
3456  * returns only one argument or throws an error. An error is thrown
3457  * only if an error is encountered during the argument parsing. If
3458  * the converter function function fails, nil is returned.
3459  */
hlua_run_sample_conv(lua_State * L)3460 __LJMP static int hlua_run_sample_conv(lua_State *L)
3461 {
3462 	struct hlua_smp *hsmp;
3463 	struct sample_conv *conv;
3464 	struct arg args[ARGM_NBARGS + 1] = {{0}};
3465 	int i;
3466 	struct sample smp;
3467 
3468 	/* Get closure arguments. */
3469 	conv = lua_touserdata(L, lua_upvalueindex(1));
3470 
3471 	/* Get traditional arguments. */
3472 	hsmp = MAY_LJMP(hlua_checkconverters(L, 1));
3473 
3474 	/* Get extra arguments. */
3475 	for (i = 0; i < lua_gettop(L) - 2; i++) {
3476 		if (i >= ARGM_NBARGS)
3477 			break;
3478 		hlua_lua2arg(L, i + 3, &args[i]);
3479 	}
3480 	args[i].type = ARGT_STOP;
3481 	args[i].data.str.area = NULL;
3482 
3483 	/* Check arguments. */
3484 	MAY_LJMP(hlua_lua2arg_check(L, 3, args, conv->arg_mask, hsmp->p));
3485 
3486 	/* Run the special args checker. */
3487 	if (conv->val_args && !conv->val_args(args, conv, "", 0, NULL)) {
3488 		hlua_pusherror(L, "error in arguments");
3489 		WILL_LJMP(lua_error(L));
3490 	}
3491 
3492 	/* Initialise the sample. */
3493 	memset(&smp, 0, sizeof(smp));
3494 	if (!hlua_lua2smp(L, 2, &smp)) {
3495 		hlua_pusherror(L, "error in the input argument");
3496 		WILL_LJMP(lua_error(L));
3497 	}
3498 
3499 	smp_set_owner(&smp, hsmp->p, hsmp->s->sess, hsmp->s, hsmp->dir & SMP_OPT_DIR);
3500 
3501 	/* Apply expected cast. */
3502 	if (!sample_casts[smp.data.type][conv->in_type]) {
3503 		hlua_pusherror(L, "invalid input argument: cannot cast '%s' to '%s'",
3504 		               smp_to_type[smp.data.type], smp_to_type[conv->in_type]);
3505 		WILL_LJMP(lua_error(L));
3506 	}
3507 	if (sample_casts[smp.data.type][conv->in_type] != c_none &&
3508 	    !sample_casts[smp.data.type][conv->in_type](&smp)) {
3509 		hlua_pusherror(L, "error during the input argument casting");
3510 		WILL_LJMP(lua_error(L));
3511 	}
3512 
3513 	/* Run the sample conversion process. */
3514 	if (!conv->process(args, &smp, conv->private)) {
3515 		if (hsmp->flags & HLUA_F_AS_STRING)
3516 			lua_pushstring(L, "");
3517 		else
3518 			lua_pushnil(L);
3519 		return 1;
3520 	}
3521 
3522 	/* Convert the returned sample in lua value. */
3523 	if (hsmp->flags & HLUA_F_AS_STRING)
3524 		hlua_smp2lua_str(L, &smp);
3525 	else
3526 		hlua_smp2lua(L, &smp);
3527 	return 1;
3528 }
3529 
3530 /*
3531  *
3532  *
3533  * Class AppletTCP
3534  *
3535  *
3536  */
3537 
3538 /* Returns a struct hlua_txn if the stack entry "ud" is
3539  * a class stream, otherwise it throws an error.
3540  */
hlua_checkapplet_tcp(lua_State * L,int ud)3541 __LJMP static struct hlua_appctx *hlua_checkapplet_tcp(lua_State *L, int ud)
3542 {
3543 	return MAY_LJMP(hlua_checkudata(L, ud, class_applet_tcp_ref));
3544 }
3545 
3546 /* This function creates and push in the stack an Applet object
3547  * according with a current TXN.
3548  */
hlua_applet_tcp_new(lua_State * L,struct appctx * ctx)3549 static int hlua_applet_tcp_new(lua_State *L, struct appctx *ctx)
3550 {
3551 	struct hlua_appctx *appctx;
3552 	struct stream_interface *si = ctx->owner;
3553 	struct stream *s = si_strm(si);
3554 	struct proxy *p = s->be;
3555 
3556 	/* Check stack size. */
3557 	if (!lua_checkstack(L, 3))
3558 		return 0;
3559 
3560 	/* Create the object: obj[0] = userdata.
3561 	 * Note that the base of the Converters object is the
3562 	 * same than the TXN object.
3563 	 */
3564 	lua_newtable(L);
3565 	appctx = lua_newuserdata(L, sizeof(*appctx));
3566 	lua_rawseti(L, -2, 0);
3567 	appctx->appctx = ctx;
3568 	appctx->htxn.s = s;
3569 	appctx->htxn.p = p;
3570 
3571 	/* Create the "f" field that contains a list of fetches. */
3572 	lua_pushstring(L, "f");
3573 	if (!hlua_fetches_new(L, &appctx->htxn, 0))
3574 		return 0;
3575 	lua_settable(L, -3);
3576 
3577 	/* Create the "sf" field that contains a list of stringsafe fetches. */
3578 	lua_pushstring(L, "sf");
3579 	if (!hlua_fetches_new(L, &appctx->htxn, HLUA_F_AS_STRING))
3580 		return 0;
3581 	lua_settable(L, -3);
3582 
3583 	/* Create the "c" field that contains a list of converters. */
3584 	lua_pushstring(L, "c");
3585 	if (!hlua_converters_new(L, &appctx->htxn, 0))
3586 		return 0;
3587 	lua_settable(L, -3);
3588 
3589 	/* Create the "sc" field that contains a list of stringsafe converters. */
3590 	lua_pushstring(L, "sc");
3591 	if (!hlua_converters_new(L, &appctx->htxn, HLUA_F_AS_STRING))
3592 		return 0;
3593 	lua_settable(L, -3);
3594 
3595 	/* Pop a class stream metatable and affect it to the table. */
3596 	lua_rawgeti(L, LUA_REGISTRYINDEX, class_applet_tcp_ref);
3597 	lua_setmetatable(L, -2);
3598 
3599 	return 1;
3600 }
3601 
hlua_applet_tcp_set_var(lua_State * L)3602 __LJMP static int hlua_applet_tcp_set_var(lua_State *L)
3603 {
3604 	struct hlua_appctx *appctx;
3605 	struct stream *s;
3606 	const char *name;
3607 	size_t len;
3608 	struct sample smp;
3609 
3610 	MAY_LJMP(check_args(L, 3, "set_var"));
3611 
3612 	/* It is useles to retrieve the stream, but this function
3613 	 * runs only in a stream context.
3614 	 */
3615 	appctx = MAY_LJMP(hlua_checkapplet_tcp(L, 1));
3616 	name = MAY_LJMP(luaL_checklstring(L, 2, &len));
3617 	s = appctx->htxn.s;
3618 
3619 	/* Converts the third argument in a sample. */
3620 	memset(&smp, 0, sizeof(smp));
3621 	hlua_lua2smp(L, 3, &smp);
3622 
3623 	/* Store the sample in a variable. */
3624 	smp_set_owner(&smp, s->be, s->sess, s, 0);
3625 	vars_set_by_name(name, len, &smp);
3626 	return 0;
3627 }
3628 
hlua_applet_tcp_unset_var(lua_State * L)3629 __LJMP static int hlua_applet_tcp_unset_var(lua_State *L)
3630 {
3631 	struct hlua_appctx *appctx;
3632 	struct stream *s;
3633 	const char *name;
3634 	size_t len;
3635 	struct sample smp;
3636 
3637 	MAY_LJMP(check_args(L, 2, "unset_var"));
3638 
3639 	/* It is useles to retrieve the stream, but this function
3640 	 * runs only in a stream context.
3641 	 */
3642 	appctx = MAY_LJMP(hlua_checkapplet_tcp(L, 1));
3643 	name = MAY_LJMP(luaL_checklstring(L, 2, &len));
3644 	s = appctx->htxn.s;
3645 
3646 	/* Unset the variable. */
3647 	smp_set_owner(&smp, s->be, s->sess, s, 0);
3648 	vars_unset_by_name(name, len, &smp);
3649 	return 0;
3650 }
3651 
hlua_applet_tcp_get_var(lua_State * L)3652 __LJMP static int hlua_applet_tcp_get_var(lua_State *L)
3653 {
3654 	struct hlua_appctx *appctx;
3655 	struct stream *s;
3656 	const char *name;
3657 	size_t len;
3658 	struct sample smp;
3659 
3660 	MAY_LJMP(check_args(L, 2, "get_var"));
3661 
3662 	/* It is useles to retrieve the stream, but this function
3663 	 * runs only in a stream context.
3664 	 */
3665 	appctx = MAY_LJMP(hlua_checkapplet_tcp(L, 1));
3666 	name = MAY_LJMP(luaL_checklstring(L, 2, &len));
3667 	s = appctx->htxn.s;
3668 
3669 	smp_set_owner(&smp, s->be, s->sess, s, 0);
3670 	if (!vars_get_by_name(name, len, &smp)) {
3671 		lua_pushnil(L);
3672 		return 1;
3673 	}
3674 
3675 	return hlua_smp2lua(L, &smp);
3676 }
3677 
hlua_applet_tcp_set_priv(lua_State * L)3678 __LJMP static int hlua_applet_tcp_set_priv(lua_State *L)
3679 {
3680 	struct hlua_appctx *appctx = MAY_LJMP(hlua_checkapplet_tcp(L, 1));
3681 	struct stream *s = appctx->htxn.s;
3682 	struct hlua *hlua;
3683 
3684 	/* Note that this hlua struct is from the session and not from the applet. */
3685 	if (!s->hlua)
3686 		return 0;
3687 	hlua = s->hlua;
3688 
3689 	MAY_LJMP(check_args(L, 2, "set_priv"));
3690 
3691 	/* Remove previous value. */
3692 	luaL_unref(L, LUA_REGISTRYINDEX, hlua->Mref);
3693 
3694 	/* Get and store new value. */
3695 	lua_pushvalue(L, 2); /* Copy the element 2 at the top of the stack. */
3696 	hlua->Mref = luaL_ref(L, LUA_REGISTRYINDEX); /* pop the previously pushed value. */
3697 
3698 	return 0;
3699 }
3700 
hlua_applet_tcp_get_priv(lua_State * L)3701 __LJMP static int hlua_applet_tcp_get_priv(lua_State *L)
3702 {
3703 	struct hlua_appctx *appctx = MAY_LJMP(hlua_checkapplet_tcp(L, 1));
3704 	struct stream *s = appctx->htxn.s;
3705 	struct hlua *hlua;
3706 
3707 	/* Note that this hlua struct is from the session and not from the applet. */
3708 	if (!s->hlua) {
3709 		lua_pushnil(L);
3710 		return 1;
3711 	}
3712 	hlua = s->hlua;
3713 
3714 	/* Push configuration index in the stack. */
3715 	lua_rawgeti(L, LUA_REGISTRYINDEX, hlua->Mref);
3716 
3717 	return 1;
3718 }
3719 
3720 /* If expected data not yet available, it returns a yield. This function
3721  * consumes the data in the buffer. It returns a string containing the
3722  * data. This string can be empty.
3723  */
hlua_applet_tcp_getline_yield(lua_State * L,int status,lua_KContext ctx)3724 __LJMP static int hlua_applet_tcp_getline_yield(lua_State *L, int status, lua_KContext ctx)
3725 {
3726 	struct hlua_appctx *appctx = MAY_LJMP(hlua_checkapplet_tcp(L, 1));
3727 	struct stream_interface *si = appctx->appctx->owner;
3728 	int ret;
3729 	const char *blk1;
3730 	size_t len1;
3731 	const char *blk2;
3732 	size_t len2;
3733 
3734 	/* Read the maximum amount of data available. */
3735 	ret = co_getline_nc(si_oc(si), &blk1, &len1, &blk2, &len2);
3736 
3737 	/* Data not yet available. return yield. */
3738 	if (ret == 0) {
3739 		si_cant_get(si);
3740 		MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_applet_tcp_getline_yield, TICK_ETERNITY, 0));
3741 	}
3742 
3743 	/* End of data: commit the total strings and return. */
3744 	if (ret < 0) {
3745 		luaL_pushresult(&appctx->b);
3746 		return 1;
3747 	}
3748 
3749 	/* Ensure that the block 2 length is usable. */
3750 	if (ret == 1)
3751 		len2 = 0;
3752 
3753 	/* dont check the max length read and dont check. */
3754 	luaL_addlstring(&appctx->b, blk1, len1);
3755 	luaL_addlstring(&appctx->b, blk2, len2);
3756 
3757 	/* Consume input channel output buffer data. */
3758 	co_skip(si_oc(si), len1 + len2);
3759 	luaL_pushresult(&appctx->b);
3760 	return 1;
3761 }
3762 
3763 /* Check arguments for the function "hlua_channel_get_yield". */
hlua_applet_tcp_getline(lua_State * L)3764 __LJMP static int hlua_applet_tcp_getline(lua_State *L)
3765 {
3766 	struct hlua_appctx *appctx = MAY_LJMP(hlua_checkapplet_tcp(L, 1));
3767 
3768 	/* Initialise the string catenation. */
3769 	luaL_buffinit(L, &appctx->b);
3770 
3771 	return MAY_LJMP(hlua_applet_tcp_getline_yield(L, 0, 0));
3772 }
3773 
3774 /* If expected data not yet available, it returns a yield. This function
3775  * consumes the data in the buffer. It returns a string containing the
3776  * data. This string can be empty.
3777  */
hlua_applet_tcp_recv_yield(lua_State * L,int status,lua_KContext ctx)3778 __LJMP static int hlua_applet_tcp_recv_yield(lua_State *L, int status, lua_KContext ctx)
3779 {
3780 	struct hlua_appctx *appctx = MAY_LJMP(hlua_checkapplet_tcp(L, 1));
3781 	struct stream_interface *si = appctx->appctx->owner;
3782 	size_t len = MAY_LJMP(luaL_checkinteger(L, 2));
3783 	int ret;
3784 	const char *blk1;
3785 	size_t len1;
3786 	const char *blk2;
3787 	size_t len2;
3788 
3789 	/* Read the maximum amount of data available. */
3790 	ret = co_getblk_nc(si_oc(si), &blk1, &len1, &blk2, &len2);
3791 
3792 	/* Data not yet available. return yield. */
3793 	if (ret == 0) {
3794 		si_cant_get(si);
3795 		MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_applet_tcp_recv_yield, TICK_ETERNITY, 0));
3796 	}
3797 
3798 	/* End of data: commit the total strings and return. */
3799 	if (ret < 0) {
3800 		luaL_pushresult(&appctx->b);
3801 		return 1;
3802 	}
3803 
3804 	/* Ensure that the block 2 length is usable. */
3805 	if (ret == 1)
3806 		len2 = 0;
3807 
3808 	if (len == -1) {
3809 
3810 		/* If len == -1, catenate all the data avalaile and
3811 		 * yield because we want to get all the data until
3812 		 * the end of data stream.
3813 		 */
3814 		luaL_addlstring(&appctx->b, blk1, len1);
3815 		luaL_addlstring(&appctx->b, blk2, len2);
3816 		co_skip(si_oc(si), len1 + len2);
3817 		si_cant_get(si);
3818 		MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_applet_tcp_recv_yield, TICK_ETERNITY, 0));
3819 
3820 	} else {
3821 
3822 		/* Copy the fisrt block caping to the length required. */
3823 		if (len1 > len)
3824 			len1 = len;
3825 		luaL_addlstring(&appctx->b, blk1, len1);
3826 		len -= len1;
3827 
3828 		/* Copy the second block. */
3829 		if (len2 > len)
3830 			len2 = len;
3831 		luaL_addlstring(&appctx->b, blk2, len2);
3832 		len -= len2;
3833 
3834 		/* Consume input channel output buffer data. */
3835 		co_skip(si_oc(si), len1 + len2);
3836 
3837 		/* If there is no other data available, yield waiting for new data. */
3838 		if (len > 0) {
3839 			lua_pushinteger(L, len);
3840 			lua_replace(L, 2);
3841 			si_cant_get(si);
3842 			MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_applet_tcp_recv_yield, TICK_ETERNITY, 0));
3843 		}
3844 
3845 		/* return the result. */
3846 		luaL_pushresult(&appctx->b);
3847 		return 1;
3848 	}
3849 
3850 	/* we never execute this */
3851 	hlua_pusherror(L, "Lua: internal error");
3852 	WILL_LJMP(lua_error(L));
3853 	return 0;
3854 }
3855 
3856 /* Check arguments for the function "hlua_channel_get_yield". */
hlua_applet_tcp_recv(lua_State * L)3857 __LJMP static int hlua_applet_tcp_recv(lua_State *L)
3858 {
3859 	struct hlua_appctx *appctx = MAY_LJMP(hlua_checkapplet_tcp(L, 1));
3860 	int len = -1;
3861 
3862 	if (lua_gettop(L) > 2)
3863 		WILL_LJMP(luaL_error(L, "The 'recv' function requires between 1 and 2 arguments."));
3864 	if (lua_gettop(L) >= 2) {
3865 		len = MAY_LJMP(luaL_checkinteger(L, 2));
3866 		lua_pop(L, 1);
3867 	}
3868 
3869 	/* Confirm or set the required length */
3870 	lua_pushinteger(L, len);
3871 
3872 	/* Initialise the string catenation. */
3873 	luaL_buffinit(L, &appctx->b);
3874 
3875 	return MAY_LJMP(hlua_applet_tcp_recv_yield(L, 0, 0));
3876 }
3877 
3878 /* Append data in the output side of the buffer. This data is immediately
3879  * sent. The function returns the amount of data written. If the buffer
3880  * cannot contain the data, the function yields. The function returns -1
3881  * if the channel is closed.
3882  */
hlua_applet_tcp_send_yield(lua_State * L,int status,lua_KContext ctx)3883 __LJMP static int hlua_applet_tcp_send_yield(lua_State *L, int status, lua_KContext ctx)
3884 {
3885 	size_t len;
3886 	struct hlua_appctx *appctx = MAY_LJMP(hlua_checkapplet_tcp(L, 1));
3887 	const char *str = MAY_LJMP(luaL_checklstring(L, 2, &len));
3888 	int l = MAY_LJMP(luaL_checkinteger(L, 3));
3889 	struct stream_interface *si = appctx->appctx->owner;
3890 	struct channel *chn = si_ic(si);
3891 	int max;
3892 
3893 	/* Get the max amount of data which can write as input in the channel. */
3894 	max = channel_recv_max(chn);
3895 	if (max > (len - l))
3896 		max = len - l;
3897 
3898 	/* Copy data. */
3899 	ci_putblk(chn, str + l, max);
3900 
3901 	/* update counters. */
3902 	l += max;
3903 	lua_pop(L, 1);
3904 	lua_pushinteger(L, l);
3905 
3906 	/* If some data is not send, declares the situation to the
3907 	 * applet, and returns a yield.
3908 	 */
3909 	if (l < len) {
3910 		si_rx_room_blk(si);
3911 		MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_applet_tcp_send_yield, TICK_ETERNITY, 0));
3912 	}
3913 
3914 	return 1;
3915 }
3916 
3917 /* Just a wraper of "hlua_applet_tcp_send_yield". This wrapper permits
3918  * yield the LUA process, and resume it without checking the
3919  * input arguments.
3920  */
hlua_applet_tcp_send(lua_State * L)3921 __LJMP static int hlua_applet_tcp_send(lua_State *L)
3922 {
3923 	MAY_LJMP(check_args(L, 2, "send"));
3924 	lua_pushinteger(L, 0);
3925 
3926 	return MAY_LJMP(hlua_applet_tcp_send_yield(L, 0, 0));
3927 }
3928 
3929 /*
3930  *
3931  *
3932  * Class AppletHTTP
3933  *
3934  *
3935  */
3936 
3937 /* Returns a struct hlua_txn if the stack entry "ud" is
3938  * a class stream, otherwise it throws an error.
3939  */
hlua_checkapplet_http(lua_State * L,int ud)3940 __LJMP static struct hlua_appctx *hlua_checkapplet_http(lua_State *L, int ud)
3941 {
3942 	return MAY_LJMP(hlua_checkudata(L, ud, class_applet_http_ref));
3943 }
3944 
3945 /* This function creates and push in the stack an Applet object
3946  * according with a current TXN.
3947  */
hlua_applet_http_new(lua_State * L,struct appctx * ctx)3948 static int hlua_applet_http_new(lua_State *L, struct appctx *ctx)
3949 {
3950 	struct hlua_appctx *appctx;
3951 	struct hlua_txn htxn;
3952 	struct stream_interface *si = ctx->owner;
3953 	struct stream *s = si_strm(si);
3954 	struct proxy *px = s->be;
3955 
3956 	/* Check stack size. */
3957 	if (!lua_checkstack(L, 3))
3958 		return 0;
3959 
3960 	/* Create the object: obj[0] = userdata.
3961 	 * Note that the base of the Converters object is the
3962 	 * same than the TXN object.
3963 	 */
3964 	lua_newtable(L);
3965 	appctx = lua_newuserdata(L, sizeof(*appctx));
3966 	lua_rawseti(L, -2, 0);
3967 	appctx->appctx = ctx;
3968 	appctx->appctx->ctx.hlua_apphttp.status = 200; /* Default status code returned. */
3969 	appctx->appctx->ctx.hlua_apphttp.reason = NULL; /* Use default reason based on status */
3970 	appctx->htxn.s = s;
3971 	appctx->htxn.p = px;
3972 
3973 	/* Create the "f" field that contains a list of fetches. */
3974 	lua_pushstring(L, "f");
3975 	if (!hlua_fetches_new(L, &appctx->htxn, 0))
3976 		return 0;
3977 	lua_settable(L, -3);
3978 
3979 	/* Create the "sf" field that contains a list of stringsafe fetches. */
3980 	lua_pushstring(L, "sf");
3981 	if (!hlua_fetches_new(L, &appctx->htxn, HLUA_F_AS_STRING))
3982 		return 0;
3983 	lua_settable(L, -3);
3984 
3985 	/* Create the "c" field that contains a list of converters. */
3986 	lua_pushstring(L, "c");
3987 	if (!hlua_converters_new(L, &appctx->htxn, 0))
3988 		return 0;
3989 	lua_settable(L, -3);
3990 
3991 	/* Create the "sc" field that contains a list of stringsafe converters. */
3992 	lua_pushstring(L, "sc");
3993 	if (!hlua_converters_new(L, &appctx->htxn, HLUA_F_AS_STRING))
3994 		return 0;
3995 	lua_settable(L, -3);
3996 
3997 	if (IS_HTX_STRM(s)) {
3998 		/* HTX version */
3999 		struct htx *htx = htxbuf(&s->req.buf);
4000 		struct htx_blk *blk;
4001 		struct htx_sl *sl;
4002 		struct ist path;
4003 		unsigned long long len = 0;
4004 		int32_t pos;
4005 
4006 		blk = htx_get_first_blk(htx);
4007 		BUG_ON(!blk || htx_get_blk_type(blk) != HTX_BLK_REQ_SL);
4008 		sl = htx_get_blk_ptr(htx, blk);
4009 
4010 		/* Stores the request method. */
4011 		lua_pushstring(L, "method");
4012 		lua_pushlstring(L, HTX_SL_REQ_MPTR(sl), HTX_SL_REQ_MLEN(sl));
4013 		lua_settable(L, -3);
4014 
4015 		/* Stores the http version. */
4016 		lua_pushstring(L, "version");
4017 		lua_pushlstring(L, HTX_SL_REQ_VPTR(sl), HTX_SL_REQ_VLEN(sl));
4018 		lua_settable(L, -3);
4019 
4020 		/* creates an array of headers. hlua_http_get_headers() crates and push
4021 		 * the array on the top of the stack.
4022 		 */
4023 		lua_pushstring(L, "headers");
4024 		htxn.s = s;
4025 		htxn.p = px;
4026 		htxn.dir = SMP_OPT_DIR_REQ;
4027 		if (!hlua_http_get_headers(L, &htxn, &htxn.s->txn->req))
4028 			return 0;
4029 		lua_settable(L, -3);
4030 
4031 		path = http_get_path(htx_sl_req_uri(sl));
4032 		if (path.ptr) {
4033 			char *p, *q, *end;
4034 
4035 			p = path.ptr;
4036 			end = path.ptr + path.len;
4037 			q = p;
4038 			while (q < end && *q != '?')
4039 				q++;
4040 
4041 			/* Stores the request path. */
4042 			lua_pushstring(L, "path");
4043 			lua_pushlstring(L, p, q - p);
4044 			lua_settable(L, -3);
4045 
4046 			/* Stores the query string. */
4047 			lua_pushstring(L, "qs");
4048 			if (*q == '?')
4049 				q++;
4050 			lua_pushlstring(L, q, end - q);
4051 			lua_settable(L, -3);
4052 		}
4053 
4054 		for (pos = htx_get_first(htx); pos != -1; pos = htx_get_next(htx, pos)) {
4055 			struct htx_blk *blk = htx_get_blk(htx, pos);
4056 			enum htx_blk_type type = htx_get_blk_type(blk);
4057 
4058 			if (type == HTX_BLK_EOM || type == HTX_BLK_TLR || type == HTX_BLK_EOT)
4059 				break;
4060 			if (type == HTX_BLK_DATA)
4061 				len += htx_get_blksz(blk);
4062 		}
4063 		if (htx->extra != ULLONG_MAX)
4064 			len += htx->extra;
4065 
4066 		/* Stores the request path. */
4067 		lua_pushstring(L, "length");
4068 		lua_pushinteger(L, len);
4069 		lua_settable(L, -3);
4070 	}
4071 	else {
4072 		/* Legacy HTTP version */
4073 		struct http_txn *txn = s->txn;
4074 		const char *path;
4075 		const char *end;
4076 		const char *p;
4077 
4078 		/* Stores the request method. */
4079 		lua_pushstring(L, "method");
4080 		lua_pushlstring(L, ci_head(txn->req.chn), txn->req.sl.rq.m_l);
4081 		lua_settable(L, -3);
4082 
4083 		/* Stores the http version. */
4084 		lua_pushstring(L, "version");
4085 		lua_pushlstring(L, ci_head(txn->req.chn) + txn->req.sl.rq.v, txn->req.sl.rq.v_l);
4086 		lua_settable(L, -3);
4087 
4088 		/* creates an array of headers. hlua_http_get_headers() crates and push
4089 		 * the array on the top of the stack.
4090 		 */
4091 		lua_pushstring(L, "headers");
4092 		htxn.s = s;
4093 		htxn.p = px;
4094 		htxn.dir = SMP_OPT_DIR_REQ;
4095 		if (!hlua_http_get_headers(L, &htxn, &htxn.s->txn->req))
4096 			return 0;
4097 		lua_settable(L, -3);
4098 
4099 		/* Get path and qs */
4100 		path = http_txn_get_path(txn);
4101 		if (path) {
4102 			end = ci_head(txn->req.chn) + txn->req.sl.rq.u + txn->req.sl.rq.u_l;
4103 			p = path;
4104 			while (p < end && *p != '?')
4105 				p++;
4106 
4107 			/* Stores the request path. */
4108 			lua_pushstring(L, "path");
4109 			lua_pushlstring(L, path, p - path);
4110 			lua_settable(L, -3);
4111 
4112 			/* Stores the query string. */
4113 			lua_pushstring(L, "qs");
4114 			if (*p == '?')
4115 				p++;
4116 			lua_pushlstring(L, p, end - p);
4117 			lua_settable(L, -3);
4118 		}
4119 
4120 		/* Stores the request path. */
4121 		lua_pushstring(L, "length");
4122 		lua_pushinteger(L, txn->req.body_len);
4123 		lua_settable(L, -3);
4124 	}
4125 
4126 	/* Create an empty array of HTTP request headers. */
4127 	lua_pushstring(L, "response");
4128 	lua_newtable(L);
4129 	lua_settable(L, -3);
4130 
4131 	/* Pop a class stream metatable and affect it to the table. */
4132 	lua_rawgeti(L, LUA_REGISTRYINDEX, class_applet_http_ref);
4133 	lua_setmetatable(L, -2);
4134 
4135 	return 1;
4136 }
4137 
hlua_applet_http_set_var(lua_State * L)4138 __LJMP static int hlua_applet_http_set_var(lua_State *L)
4139 {
4140 	struct hlua_appctx *appctx;
4141 	struct stream *s;
4142 	const char *name;
4143 	size_t len;
4144 	struct sample smp;
4145 
4146 	MAY_LJMP(check_args(L, 3, "set_var"));
4147 
4148 	/* It is useles to retrieve the stream, but this function
4149 	 * runs only in a stream context.
4150 	 */
4151 	appctx = MAY_LJMP(hlua_checkapplet_http(L, 1));
4152 	name = MAY_LJMP(luaL_checklstring(L, 2, &len));
4153 	s = appctx->htxn.s;
4154 
4155 	/* Converts the third argument in a sample. */
4156 	memset(&smp, 0, sizeof(smp));
4157 	hlua_lua2smp(L, 3, &smp);
4158 
4159 	/* Store the sample in a variable. */
4160 	smp_set_owner(&smp, s->be, s->sess, s, 0);
4161 	vars_set_by_name(name, len, &smp);
4162 	return 0;
4163 }
4164 
hlua_applet_http_unset_var(lua_State * L)4165 __LJMP static int hlua_applet_http_unset_var(lua_State *L)
4166 {
4167 	struct hlua_appctx *appctx;
4168 	struct stream *s;
4169 	const char *name;
4170 	size_t len;
4171 	struct sample smp;
4172 
4173 	MAY_LJMP(check_args(L, 2, "unset_var"));
4174 
4175 	/* It is useles to retrieve the stream, but this function
4176 	 * runs only in a stream context.
4177 	 */
4178 	appctx = MAY_LJMP(hlua_checkapplet_http(L, 1));
4179 	name = MAY_LJMP(luaL_checklstring(L, 2, &len));
4180 	s = appctx->htxn.s;
4181 
4182 	/* Unset the variable. */
4183 	smp_set_owner(&smp, s->be, s->sess, s, 0);
4184 	vars_unset_by_name(name, len, &smp);
4185 	return 0;
4186 }
4187 
hlua_applet_http_get_var(lua_State * L)4188 __LJMP static int hlua_applet_http_get_var(lua_State *L)
4189 {
4190 	struct hlua_appctx *appctx;
4191 	struct stream *s;
4192 	const char *name;
4193 	size_t len;
4194 	struct sample smp;
4195 
4196 	MAY_LJMP(check_args(L, 2, "get_var"));
4197 
4198 	/* It is useles to retrieve the stream, but this function
4199 	 * runs only in a stream context.
4200 	 */
4201 	appctx = MAY_LJMP(hlua_checkapplet_http(L, 1));
4202 	name = MAY_LJMP(luaL_checklstring(L, 2, &len));
4203 	s = appctx->htxn.s;
4204 
4205 	smp_set_owner(&smp, s->be, s->sess, s, 0);
4206 	if (!vars_get_by_name(name, len, &smp)) {
4207 		lua_pushnil(L);
4208 		return 1;
4209 	}
4210 
4211 	return hlua_smp2lua(L, &smp);
4212 }
4213 
hlua_applet_http_set_priv(lua_State * L)4214 __LJMP static int hlua_applet_http_set_priv(lua_State *L)
4215 {
4216 	struct hlua_appctx *appctx = MAY_LJMP(hlua_checkapplet_http(L, 1));
4217 	struct stream *s = appctx->htxn.s;
4218 	struct hlua *hlua;
4219 
4220 	/* Note that this hlua struct is from the session and not from the applet. */
4221 	if (!s->hlua)
4222 		return 0;
4223 	hlua = s->hlua;
4224 
4225 	MAY_LJMP(check_args(L, 2, "set_priv"));
4226 
4227 	/* Remove previous value. */
4228 	luaL_unref(L, LUA_REGISTRYINDEX, hlua->Mref);
4229 
4230 	/* Get and store new value. */
4231 	lua_pushvalue(L, 2); /* Copy the element 2 at the top of the stack. */
4232 	hlua->Mref = luaL_ref(L, LUA_REGISTRYINDEX); /* pop the previously pushed value. */
4233 
4234 	return 0;
4235 }
4236 
hlua_applet_http_get_priv(lua_State * L)4237 __LJMP static int hlua_applet_http_get_priv(lua_State *L)
4238 {
4239 	struct hlua_appctx *appctx = MAY_LJMP(hlua_checkapplet_http(L, 1));
4240 	struct stream *s = appctx->htxn.s;
4241 	struct hlua *hlua;
4242 
4243 	/* Note that this hlua struct is from the session and not from the applet. */
4244 	if (!s->hlua) {
4245 		lua_pushnil(L);
4246 		return 1;
4247 	}
4248 	hlua = s->hlua;
4249 
4250 	/* Push configuration index in the stack. */
4251 	lua_rawgeti(L, LUA_REGISTRYINDEX, hlua->Mref);
4252 
4253 	return 1;
4254 }
4255 
4256 /* If expected data not yet available, it returns a yield. This function
4257  * consumes the data in the buffer. It returns a string containing the
4258  * data. This string can be empty.
4259  */
hlua_applet_htx_getline_yield(lua_State * L,int status,lua_KContext ctx)4260 __LJMP static int hlua_applet_htx_getline_yield(lua_State *L, int status, lua_KContext ctx)
4261 {
4262 	struct hlua_appctx *appctx = MAY_LJMP(hlua_checkapplet_http(L, 1));
4263 	struct stream_interface *si = appctx->appctx->owner;
4264 	struct channel *req = si_oc(si);
4265 	struct htx *htx;
4266 	struct htx_blk *blk;
4267 	size_t count;
4268 	int stop = 0;
4269 
4270 	htx = htx_from_buf(&req->buf);
4271 	count = co_data(req);
4272 	blk = htx_get_first_blk(htx);
4273 
4274 	while (count && !stop && blk) {
4275 		enum htx_blk_type type = htx_get_blk_type(blk);
4276 		uint32_t sz = htx_get_blksz(blk);
4277 		struct ist v;
4278 		uint32_t vlen;
4279 		char *nl;
4280 
4281 		if (type == HTX_BLK_EOM) {
4282 			stop = 1;
4283 			break;
4284 		}
4285 
4286 		vlen = sz;
4287 		if (vlen > count) {
4288 			if (type != HTX_BLK_DATA)
4289 				break;
4290 			vlen = count;
4291 		}
4292 
4293 		switch (type) {
4294 			case HTX_BLK_UNUSED:
4295 				break;
4296 
4297 			case HTX_BLK_DATA:
4298 				v = htx_get_blk_value(htx, blk);
4299 				v.len = vlen;
4300 				nl = istchr(v, '\n');
4301 				if (nl != NULL) {
4302 					stop = 1;
4303 					vlen = nl - v.ptr + 1;
4304 				}
4305 				luaL_addlstring(&appctx->b, v.ptr, vlen);
4306 				break;
4307 
4308 			case HTX_BLK_TLR:
4309 			case HTX_BLK_EOM:
4310 				stop = 1;
4311 				break;
4312 
4313 			default:
4314 				break;
4315 		}
4316 
4317 		co_set_data(req, co_data(req) - vlen);
4318 		count -= vlen;
4319 		if (sz == vlen)
4320 			blk = htx_remove_blk(htx, blk);
4321 		else {
4322 			htx_cut_data_blk(htx, blk, vlen);
4323 			break;
4324 		}
4325 	}
4326 
4327 	htx_to_buf(htx, &req->buf);
4328 	if (!stop) {
4329 		si_cant_get(si);
4330 		MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_applet_htx_getline_yield, TICK_ETERNITY, 0));
4331 	}
4332 
4333 	/* return the result. */
4334 	luaL_pushresult(&appctx->b);
4335 	return 1;
4336 }
4337 
4338 
4339 /* If expected data not yet available, it returns a yield. This function
4340  * consumes the data in the buffer. It returns a string containing the
4341  * data. This string can be empty.
4342  */
hlua_applet_http_getline_yield(lua_State * L,int status,lua_KContext ctx)4343 __LJMP static int hlua_applet_http_getline_yield(lua_State *L, int status, lua_KContext ctx)
4344 {
4345 	struct hlua_appctx *appctx = MAY_LJMP(hlua_checkapplet_http(L, 1));
4346 	struct stream_interface *si = appctx->appctx->owner;
4347 	int ret;
4348 	const char *blk1;
4349 	size_t len1;
4350 	const char *blk2;
4351 	size_t len2;
4352 
4353 	/* Check for the end of the data. */
4354 	if (appctx->appctx->ctx.hlua_apphttp.left_bytes <= 0) {
4355 		luaL_pushresult(&appctx->b);
4356 		return 1;
4357 	}
4358 
4359 	/* Read the maximum amount of data available. */
4360 	ret = co_getline_nc(si_oc(si), &blk1, &len1, &blk2, &len2);
4361 
4362 	/* Data not yet available. return yield. */
4363 	if (ret == 0) {
4364 		si_cant_get(si);
4365 		MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_applet_http_getline_yield, TICK_ETERNITY, 0));
4366 	}
4367 
4368 	/* End of data: commit the total strings and return. */
4369 	if (ret < 0) {
4370 		luaL_pushresult(&appctx->b);
4371 		return 1;
4372 	}
4373 
4374 	/* Ensure that the block 2 length is usable. */
4375 	if (ret == 1)
4376 		len2 = 0;
4377 
4378 	/* Copy the fisrt block caping to the length required. */
4379 	if (len1 > appctx->appctx->ctx.hlua_apphttp.left_bytes)
4380 		len1 = appctx->appctx->ctx.hlua_apphttp.left_bytes;
4381 	luaL_addlstring(&appctx->b, blk1, len1);
4382 	appctx->appctx->ctx.hlua_apphttp.left_bytes -= len1;
4383 
4384 	/* Copy the second block. */
4385 	if (len2 > appctx->appctx->ctx.hlua_apphttp.left_bytes)
4386 		len2 = appctx->appctx->ctx.hlua_apphttp.left_bytes;
4387 	luaL_addlstring(&appctx->b, blk2, len2);
4388 	appctx->appctx->ctx.hlua_apphttp.left_bytes -= len2;
4389 
4390 	/* Consume input channel output buffer data. */
4391 	co_skip(si_oc(si), len1 + len2);
4392 	luaL_pushresult(&appctx->b);
4393 	return 1;
4394 }
4395 
4396 /* Check arguments for the function "hlua_channel_get_yield". */
hlua_applet_http_getline(lua_State * L)4397 __LJMP static int hlua_applet_http_getline(lua_State *L)
4398 {
4399 	struct hlua_appctx *appctx = MAY_LJMP(hlua_checkapplet_http(L, 1));
4400 
4401 	/* Initialise the string catenation. */
4402 	luaL_buffinit(L, &appctx->b);
4403 
4404 	if (IS_HTX_STRM(si_strm(appctx->appctx->owner)))
4405 		return MAY_LJMP(hlua_applet_htx_getline_yield(L, 0, 0));
4406 	else
4407 		return MAY_LJMP(hlua_applet_http_getline_yield(L, 0, 0));
4408 }
4409 
4410 /* If expected data not yet available, it returns a yield. This function
4411  * consumes the data in the buffer. It returns a string containing the
4412  * data. This string can be empty.
4413  */
hlua_applet_htx_recv_yield(lua_State * L,int status,lua_KContext ctx)4414 __LJMP static int hlua_applet_htx_recv_yield(lua_State *L, int status, lua_KContext ctx)
4415 {
4416 	struct hlua_appctx *appctx = MAY_LJMP(hlua_checkapplet_http(L, 1));
4417 	struct stream_interface *si = appctx->appctx->owner;
4418 	struct channel *req = si_oc(si);
4419 	struct htx *htx;
4420 	struct htx_blk *blk;
4421 	size_t count;
4422 	int len;
4423 
4424 	htx = htx_from_buf(&req->buf);
4425 	len = MAY_LJMP(luaL_checkinteger(L, 2));
4426 	count = co_data(req);
4427 	blk = htx_get_head_blk(htx);
4428 	while (count && len && blk) {
4429 		enum htx_blk_type type = htx_get_blk_type(blk);
4430 		uint32_t sz = htx_get_blksz(blk);
4431 		struct ist v;
4432 		uint32_t vlen;
4433 
4434 		if (type == HTX_BLK_EOM) {
4435 			len = 0;
4436 			break;
4437 		}
4438 
4439 		vlen = sz;
4440 		if (len > 0 && vlen > len)
4441 			vlen = len;
4442 		if (vlen > count) {
4443 			if (type != HTX_BLK_DATA)
4444 				break;
4445 			vlen = count;
4446 		}
4447 
4448 		switch (type) {
4449 			case HTX_BLK_UNUSED:
4450 				break;
4451 
4452 			case HTX_BLK_DATA:
4453 				v = htx_get_blk_value(htx, blk);
4454 				luaL_addlstring(&appctx->b, v.ptr, vlen);
4455 				break;
4456 
4457 			case HTX_BLK_TLR:
4458 			case HTX_BLK_EOM:
4459 				len = 0;
4460 				break;
4461 
4462 			default:
4463 				break;
4464 		}
4465 
4466 		co_set_data(req, co_data(req) - vlen);
4467 		count -= vlen;
4468 		if (len > 0)
4469 			len -= vlen;
4470 		if (sz == vlen)
4471 			blk = htx_remove_blk(htx, blk);
4472 		else {
4473 			htx_cut_data_blk(htx, blk, vlen);
4474 			break;
4475 		}
4476 	}
4477 
4478 	htx_to_buf(htx, &req->buf);
4479 
4480 	/* If we are no other data available, yield waiting for new data. */
4481 	if (len) {
4482 		if (len > 0) {
4483 			lua_pushinteger(L, len);
4484 			lua_replace(L, 2);
4485 		}
4486 		si_cant_get(si);
4487 		MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_applet_htx_recv_yield, TICK_ETERNITY, 0));
4488 	}
4489 
4490 	/* return the result. */
4491 	luaL_pushresult(&appctx->b);
4492 	return 1;
4493 }
4494 
4495 /* If expected data not yet available, it returns a yield. This function
4496  * consumes the data in the buffer. It returns a string containing the
4497  * data. This string can be empty.
4498  */
hlua_applet_http_recv_yield(lua_State * L,int status,lua_KContext ctx)4499 __LJMP static int hlua_applet_http_recv_yield(lua_State *L, int status, lua_KContext ctx)
4500 {
4501 	struct hlua_appctx *appctx = MAY_LJMP(hlua_checkapplet_http(L, 1));
4502 	struct stream_interface *si = appctx->appctx->owner;
4503 	int len = MAY_LJMP(luaL_checkinteger(L, 2));
4504 	int ret;
4505 	const char *blk1;
4506 	size_t len1;
4507 	const char *blk2;
4508 	size_t len2;
4509 
4510 	/* Read the maximum amount of data available. */
4511 	ret = co_getblk_nc(si_oc(si), &blk1, &len1, &blk2, &len2);
4512 
4513 	/* Data not yet available. return yield. */
4514 	if (ret == 0) {
4515 		si_cant_get(si);
4516 		MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_applet_http_recv_yield, TICK_ETERNITY, 0));
4517 	}
4518 
4519 	/* End of data: commit the total strings and return. */
4520 	if (ret < 0) {
4521 		luaL_pushresult(&appctx->b);
4522 		return 1;
4523 	}
4524 
4525 	/* Ensure that the block 2 length is usable. */
4526 	if (ret == 1)
4527 		len2 = 0;
4528 
4529 	/* Copy the fisrt block caping to the length required. */
4530 	if (len1 > len)
4531 		len1 = len;
4532 	luaL_addlstring(&appctx->b, blk1, len1);
4533 	len -= len1;
4534 
4535 	/* Copy the second block. */
4536 	if (len2 > len)
4537 		len2 = len;
4538 	luaL_addlstring(&appctx->b, blk2, len2);
4539 	len -= len2;
4540 
4541 	/* Consume input channel output buffer data. */
4542 	co_skip(si_oc(si), len1 + len2);
4543 	if (appctx->appctx->ctx.hlua_apphttp.left_bytes != -1)
4544 		appctx->appctx->ctx.hlua_apphttp.left_bytes -= len;
4545 
4546 	/* If we are no other data available, yield waiting for new data. */
4547 	if (len > 0) {
4548 		lua_pushinteger(L, len);
4549 		lua_replace(L, 2);
4550 		si_cant_get(si);
4551 		MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_applet_http_recv_yield, TICK_ETERNITY, 0));
4552 	}
4553 
4554 	/* return the result. */
4555 	luaL_pushresult(&appctx->b);
4556 	return 1;
4557 }
4558 
4559 /* Check arguments for the function "hlua_channel_get_yield". */
hlua_applet_http_recv(lua_State * L)4560 __LJMP static int hlua_applet_http_recv(lua_State *L)
4561 {
4562 	struct hlua_appctx *appctx = MAY_LJMP(hlua_checkapplet_http(L, 1));
4563 	int len = -1;
4564 
4565 	/* Check arguments. */
4566 	if (lua_gettop(L) > 2)
4567 		WILL_LJMP(luaL_error(L, "The 'recv' function requires between 1 and 2 arguments."));
4568 	if (lua_gettop(L) >= 2) {
4569 		len = MAY_LJMP(luaL_checkinteger(L, 2));
4570 		lua_pop(L, 1);
4571 	}
4572 
4573 	if (IS_HTX_STRM(si_strm(appctx->appctx->owner))) {
4574 		/* HTX version */
4575 		lua_pushinteger(L, len);
4576 
4577 		/* Initialise the string catenation. */
4578 		luaL_buffinit(L, &appctx->b);
4579 
4580 		return MAY_LJMP(hlua_applet_htx_recv_yield(L, 0, 0));
4581 	}
4582 	else {
4583 		/* Legacy HTTP version */
4584 		/* Check the required length */
4585 		if (len == -1 || len > appctx->appctx->ctx.hlua_apphttp.left_bytes)
4586 			len = appctx->appctx->ctx.hlua_apphttp.left_bytes;
4587 		lua_pushinteger(L, len);
4588 
4589 		/* Initialise the string catenation. */
4590 		luaL_buffinit(L, &appctx->b);
4591 
4592 		return MAY_LJMP(hlua_applet_http_recv_yield(L, 0, 0));
4593 	}
4594 }
4595 
4596 /* Append data in the output side of the buffer. This data is immediately
4597  * sent. The function returns the amount of data written. If the buffer
4598  * cannot contain the data, the function yields. The function returns -1
4599  * if the channel is closed.
4600  */
hlua_applet_htx_send_yield(lua_State * L,int status,lua_KContext ctx)4601 __LJMP static int hlua_applet_htx_send_yield(lua_State *L, int status, lua_KContext ctx)
4602 {
4603 	struct hlua_appctx *appctx = MAY_LJMP(hlua_checkapplet_http(L, 1));
4604 	struct stream_interface *si = appctx->appctx->owner;
4605 	struct channel *res = si_ic(si);
4606 	struct htx *htx = htx_from_buf(&res->buf);
4607 	const char *data;
4608 	size_t len;
4609 	int l = MAY_LJMP(luaL_checkinteger(L, 3));
4610 	int max;
4611 
4612 	max = htx_get_max_blksz(htx, channel_htx_recv_max(res, htx));
4613 	if (!max)
4614 		goto snd_yield;
4615 
4616 	data = MAY_LJMP(luaL_checklstring(L, 2, &len));
4617 
4618 	/* Get the max amount of data which can write as input in the channel. */
4619 	if (max > (len - l))
4620 		max = len - l;
4621 
4622 	/* Copy data. */
4623 	max = htx_add_data(htx, ist2(data + l, max));
4624 	channel_add_input(res, max);
4625 
4626 	/* update counters. */
4627 	l += max;
4628 	lua_pop(L, 1);
4629 	lua_pushinteger(L, l);
4630 
4631 	/* If some data is not send, declares the situation to the
4632 	 * applet, and returns a yield.
4633 	 */
4634 	if (l < len) {
4635 	  snd_yield:
4636 		htx_to_buf(htx, &res->buf);
4637 		si_rx_room_blk(si);
4638 		MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_applet_htx_send_yield, TICK_ETERNITY, 0));
4639 	}
4640 
4641 	htx_to_buf(htx, &res->buf);
4642 	return 1;
4643 }
4644 
4645 /* Append data in the output side of the buffer. This data is immediately
4646  * sent. The function returns the amount of data written. If the buffer
4647  * cannot contain the data, the function yields. The function returns -1
4648  * if the channel is closed.
4649  */
hlua_applet_http_send_yield(lua_State * L,int status,lua_KContext ctx)4650 __LJMP static int hlua_applet_http_send_yield(lua_State *L, int status, lua_KContext ctx)
4651 {
4652 	size_t len;
4653 	struct hlua_appctx *appctx = MAY_LJMP(hlua_checkapplet_http(L, 1));
4654 	const char *str = MAY_LJMP(luaL_checklstring(L, 2, &len));
4655 	int l = MAY_LJMP(luaL_checkinteger(L, 3));
4656 	struct stream_interface *si = appctx->appctx->owner;
4657 	struct channel *chn = si_ic(si);
4658 	int max;
4659 
4660 	/* Get the max amount of data which can write as input in the channel. */
4661 	max = channel_recv_max(chn);
4662 	if (max > (len - l))
4663 		max = len - l;
4664 
4665 	/* Copy data. */
4666 	ci_putblk(chn, str + l, max);
4667 
4668 	/* update counters. */
4669 	l += max;
4670 	lua_pop(L, 1);
4671 	lua_pushinteger(L, l);
4672 
4673 	/* If some data is not send, declares the situation to the
4674 	 * applet, and returns a yield.
4675 	 */
4676 	if (l < len) {
4677 		si_rx_room_blk(si);
4678 		MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_applet_http_send_yield, TICK_ETERNITY, 0));
4679 	}
4680 
4681 	return 1;
4682 }
4683 
4684 /* Just a wraper of "hlua_applet_send_yield". This wrapper permits
4685  * yield the LUA process, and resume it without checking the
4686  * input arguments.
4687  */
hlua_applet_http_send(lua_State * L)4688 __LJMP static int hlua_applet_http_send(lua_State *L)
4689 {
4690 	struct hlua_appctx *appctx = MAY_LJMP(hlua_checkapplet_http(L, 1));
4691 
4692 	/* We want to send some data. Headers must be sent. */
4693 	if (!(appctx->appctx->ctx.hlua_apphttp.flags & APPLET_HDR_SENT)) {
4694 		hlua_pusherror(L, "Lua: 'send' you must call start_response() before sending data.");
4695 		WILL_LJMP(lua_error(L));
4696 	}
4697 
4698 	if (IS_HTX_STRM(si_strm(appctx->appctx->owner))) {
4699 		/* HTX version */
4700 		/* This interger is used for followinf the amount of data sent. */
4701 		lua_pushinteger(L, 0);
4702 
4703 		return MAY_LJMP(hlua_applet_htx_send_yield(L, 0, 0));
4704 	}
4705 	else {
4706 		/* Legacy HTTP version */
4707 		size_t len;
4708 		char hex[10];
4709 
4710 		MAY_LJMP(luaL_checklstring(L, 2, &len));
4711 
4712 		/* If transfer encoding chunked is selected, we surround the data
4713 		 * by chunk data.
4714 		 */
4715 		if (appctx->appctx->ctx.hlua_apphttp.flags & APPLET_CHUNKED) {
4716 			snprintf(hex, 9, "%x", (unsigned int)len);
4717 			lua_pushfstring(L, "%s\r\n", hex);
4718 			lua_insert(L, 2); /* swap the last 2 entries. */
4719 			lua_pushstring(L, "\r\n");
4720 			lua_concat(L, 3);
4721 		}
4722 
4723 		/* This interger is used for followinf the amount of data sent. */
4724 		lua_pushinteger(L, 0);
4725 
4726 		return MAY_LJMP(hlua_applet_http_send_yield(L, 0, 0));
4727 	}
4728 }
4729 
hlua_applet_http_addheader(lua_State * L)4730 __LJMP static int hlua_applet_http_addheader(lua_State *L)
4731 {
4732 	const char *name;
4733 	int ret;
4734 
4735 	MAY_LJMP(hlua_checkapplet_http(L, 1));
4736 	name = MAY_LJMP(luaL_checkstring(L, 2));
4737 	MAY_LJMP(luaL_checkstring(L, 3));
4738 
4739 	/* Push in the stack the "response" entry. */
4740 	ret = lua_getfield(L, 1, "response");
4741 	if (ret != LUA_TTABLE) {
4742 		hlua_pusherror(L, "Lua: 'add_header' internal error: AppletHTTP['response'] "
4743 		                  "is expected as an array. %s found", lua_typename(L, ret));
4744 		WILL_LJMP(lua_error(L));
4745 	}
4746 
4747 	/* check if the header is already registered if it is not
4748 	 * the case, register it.
4749 	 */
4750 	ret = lua_getfield(L, -1, name);
4751 	if (ret == LUA_TNIL) {
4752 
4753 		/* Entry not found. */
4754 		lua_pop(L, 1); /* remove the nil. The "response" table is the top of the stack. */
4755 
4756 		/* Insert the new header name in the array in the top of the stack.
4757 		 * It left the new array in the top of the stack.
4758 		 */
4759 		lua_newtable(L);
4760 		lua_pushvalue(L, 2);
4761 		lua_pushvalue(L, -2);
4762 		lua_settable(L, -4);
4763 
4764 	} else if (ret != LUA_TTABLE) {
4765 
4766 		/* corruption error. */
4767 		hlua_pusherror(L, "Lua: 'add_header' internal error: AppletHTTP['response']['%s'] "
4768 		                  "is expected as an array. %s found", name, lua_typename(L, ret));
4769 		WILL_LJMP(lua_error(L));
4770 	}
4771 
4772 	/* Now the top od thestack is an array of values. We push
4773 	 * the header value as new entry.
4774 	 */
4775 	lua_pushvalue(L, 3);
4776 	ret = lua_rawlen(L, -2);
4777 	lua_rawseti(L, -2, ret + 1);
4778 	lua_pushboolean(L, 1);
4779 	return 1;
4780 }
4781 
hlua_applet_http_status(lua_State * L)4782 __LJMP static int hlua_applet_http_status(lua_State *L)
4783 {
4784 	struct hlua_appctx *appctx = MAY_LJMP(hlua_checkapplet_http(L, 1));
4785 	int status = MAY_LJMP(luaL_checkinteger(L, 2));
4786 	const char *reason = MAY_LJMP(luaL_optlstring(L, 3, NULL, NULL));
4787 
4788 	if (status < 100 || status > 599) {
4789 		lua_pushboolean(L, 0);
4790 		return 1;
4791 	}
4792 
4793 	appctx->appctx->ctx.hlua_apphttp.status = status;
4794 	appctx->appctx->ctx.hlua_apphttp.reason = reason;
4795 	lua_pushboolean(L, 1);
4796 	return 1;
4797 }
4798 
4799 
hlua_applet_htx_send_response(lua_State * L)4800 __LJMP static int hlua_applet_htx_send_response(lua_State *L)
4801 {
4802 	struct hlua_appctx *appctx = MAY_LJMP(hlua_checkapplet_http(L, 1));
4803 	struct stream_interface *si = appctx->appctx->owner;
4804 	struct channel *res = si_ic(si);
4805 	struct htx *htx;
4806 	struct htx_sl *sl;
4807 	struct h1m h1m;
4808 	const char *status, *reason;
4809 	const char *name, *value;
4810 	size_t nlen, vlen;
4811         unsigned int flags;
4812 
4813 	/* Send the message at once. */
4814 	htx = htx_from_buf(&res->buf);
4815 	h1m_init_res(&h1m);
4816 
4817 	/* Use the same http version than the request. */
4818 	status = ultoa_r(appctx->appctx->ctx.hlua_apphttp.status, trash.area, trash.size);
4819 	reason = appctx->appctx->ctx.hlua_apphttp.reason;
4820 	if (reason == NULL)
4821 		reason = http_get_reason(appctx->appctx->ctx.hlua_apphttp.status);
4822 	if (appctx->appctx->ctx.hlua_apphttp.flags & APPLET_HTTP11) {
4823 		flags = (HTX_SL_F_IS_RESP|HTX_SL_F_VER_11);
4824 		sl = htx_add_stline(htx, HTX_BLK_RES_SL, flags, ist("HTTP/1.1"), ist(status), ist(reason));
4825 	}
4826 	else {
4827 		flags = HTX_SL_F_IS_RESP;
4828 		sl = htx_add_stline(htx, HTX_BLK_RES_SL, flags, ist("HTTP/1.0"), ist(status), ist(reason));
4829 	}
4830 	if (!sl) {
4831 		hlua_pusherror(L, "Lua applet http '%s': Failed to create response.\n",
4832 		               appctx->appctx->rule->arg.hlua_rule->fcn.name);
4833 		WILL_LJMP(lua_error(L));
4834 	}
4835 	sl->info.res.status = appctx->appctx->ctx.hlua_apphttp.status;
4836 
4837 	/* Get the array associated to the field "response" in the object AppletHTTP. */
4838 	lua_pushvalue(L, 0);
4839 	if (lua_getfield(L, 1, "response") != LUA_TTABLE) {
4840 		hlua_pusherror(L, "Lua applet http '%s': AppletHTTP['response'] missing.\n",
4841 		               appctx->appctx->rule->arg.hlua_rule->fcn.name);
4842 		WILL_LJMP(lua_error(L));
4843 	}
4844 
4845 	/* Browse the list of headers. */
4846 	lua_pushnil(L);
4847 	while(lua_next(L, -2) != 0) {
4848 		/* We expect a string as -2. */
4849 		if (lua_type(L, -2) != LUA_TSTRING) {
4850 			hlua_pusherror(L, "Lua applet http '%s': AppletHTTP['response'][] element must be a string. got %s.\n",
4851 				       appctx->appctx->rule->arg.hlua_rule->fcn.name,
4852 			               lua_typename(L, lua_type(L, -2)));
4853 			WILL_LJMP(lua_error(L));
4854 		}
4855 		name = lua_tolstring(L, -2, &nlen);
4856 
4857 		/* We expect an array as -1. */
4858 		if (lua_type(L, -1) != LUA_TTABLE) {
4859 			hlua_pusherror(L, "Lua applet http '%s': AppletHTTP['response']['%s'] element must be an table. got %s.\n",
4860 				       appctx->appctx->rule->arg.hlua_rule->fcn.name,
4861 				       name,
4862 			               lua_typename(L, lua_type(L, -1)));
4863 			WILL_LJMP(lua_error(L));
4864 		}
4865 
4866 		/* Browse the table who is on the top of the stack. */
4867 		lua_pushnil(L);
4868 		while(lua_next(L, -2) != 0) {
4869 			int id;
4870 
4871 			/* We expect a number as -2. */
4872 			if (lua_type(L, -2) != LUA_TNUMBER) {
4873 				hlua_pusherror(L, "Lua applet http '%s': AppletHTTP['response']['%s'][] element must be a number. got %s.\n",
4874 					       appctx->appctx->rule->arg.hlua_rule->fcn.name,
4875 					       name,
4876 				               lua_typename(L, lua_type(L, -2)));
4877 				WILL_LJMP(lua_error(L));
4878 			}
4879 			id = lua_tointeger(L, -2);
4880 
4881 			/* We expect a string as -2. */
4882 			if (lua_type(L, -1) != LUA_TSTRING) {
4883 				hlua_pusherror(L, "Lua applet http '%s': AppletHTTP['response']['%s'][%d] element must be a string. got %s.\n",
4884 					       appctx->appctx->rule->arg.hlua_rule->fcn.name,
4885 					       name, id,
4886 				               lua_typename(L, lua_type(L, -1)));
4887 				WILL_LJMP(lua_error(L));
4888 			}
4889 			value = lua_tolstring(L, -1, &vlen);
4890 
4891 			/* Simple Protocol checks. */
4892 			if (isteqi(ist2(name, nlen), ist("transfer-encoding")))
4893 				h1_parse_xfer_enc_header(&h1m, ist2(name, nlen));
4894 			else if (isteqi(ist2(name, nlen), ist("content-length"))) {
4895 				struct ist v = ist2(value, vlen);
4896 				int ret;
4897 
4898 				ret = h1_parse_cont_len_header(&h1m, &v);
4899 				if (ret < 0) {
4900 					hlua_pusherror(L, "Lua applet http '%s': Invalid '%s' header.\n",
4901 						       appctx->appctx->rule->arg.hlua_rule->fcn.name,
4902 						       name);
4903 					WILL_LJMP(lua_error(L));
4904 				}
4905 				else if (ret == 0)
4906 					goto next; /* Skip it */
4907 			}
4908 
4909 			/* Add a new header */
4910 			if (!htx_add_header(htx, ist2(name, nlen), ist2(value, vlen))) {
4911 				hlua_pusherror(L, "Lua applet http '%s': Failed to add header '%s' in the response.\n",
4912 					       appctx->appctx->rule->arg.hlua_rule->fcn.name,
4913 					       name);
4914 				WILL_LJMP(lua_error(L));
4915 			}
4916 		  next:
4917 			/* Remove the array from the stack, and get next element with a remaining string. */
4918 			lua_pop(L, 1);
4919 		}
4920 
4921 		/* Remove the array from the stack, and get next element with a remaining string. */
4922 		lua_pop(L, 1);
4923 	}
4924 
4925 	if (h1m.flags & H1_MF_CHNK)
4926 		h1m.flags &= ~H1_MF_CLEN;
4927 	if (h1m.flags & (H1_MF_CLEN|H1_MF_CHNK))
4928 		h1m.flags |= H1_MF_XFER_LEN;
4929 
4930 	/* Uset HTX start-line flags */
4931 	if (h1m.flags & H1_MF_XFER_ENC)
4932 		flags |= HTX_SL_F_XFER_ENC;
4933 	if (h1m.flags & H1_MF_XFER_LEN) {
4934 		flags |= HTX_SL_F_XFER_LEN;
4935 		if (h1m.flags & H1_MF_CHNK)
4936 			flags |= HTX_SL_F_CHNK;
4937 		else if (h1m.flags & H1_MF_CLEN)
4938 			flags |= HTX_SL_F_CLEN;
4939 		if (h1m.body_len == 0)
4940 			flags |= HTX_SL_F_BODYLESS;
4941 	}
4942 	sl->flags |= flags;
4943 
4944 	/* If we dont have a content-length set, and the HTTP version is 1.1
4945 	 * and the status code implies the presence of a message body, we must
4946 	 * announce a transfer encoding chunked. This is required by haproxy
4947 	 * for the keepalive compliance. If the applet annouces a transfer-encoding
4948 	 * chunked itslef, don't do anything.
4949 	 */
4950 	if ((flags & (HTX_SL_F_VER_11|HTX_SL_F_XFER_LEN)) == HTX_SL_F_VER_11 &&
4951 	    appctx->appctx->ctx.hlua_apphttp.status >= 200 &&
4952 	    appctx->appctx->ctx.hlua_apphttp.status != 204 &&
4953 	    appctx->appctx->ctx.hlua_apphttp.status != 304) {
4954 		/* Add a new header */
4955 		sl->flags |= (HTX_SL_F_XFER_ENC|H1_MF_CHNK|H1_MF_XFER_LEN);
4956 		if (!htx_add_header(htx, ist("transfer-encoding"), ist("chunked"))) {
4957 			hlua_pusherror(L, "Lua applet http '%s': Failed to add header 'transfer-encoding' in the response.\n",
4958 				       appctx->appctx->rule->arg.hlua_rule->fcn.name);
4959 			WILL_LJMP(lua_error(L));
4960 		}
4961 	}
4962 
4963 	/* Finalize headers. */
4964 	if (!htx_add_endof(htx, HTX_BLK_EOH)) {
4965 		hlua_pusherror(L, "Lua applet http '%s': Failed create the response.\n",
4966 			       appctx->appctx->rule->arg.hlua_rule->fcn.name);
4967 		WILL_LJMP(lua_error(L));
4968 	}
4969 
4970 	if (htx_used_space(htx) > b_size(&res->buf) - global.tune.maxrewrite) {
4971 		b_reset(&res->buf);
4972 		hlua_pusherror(L, "Lua: 'start_response': response header block too big");
4973 		WILL_LJMP(lua_error(L));
4974 	}
4975 
4976 	htx_to_buf(htx, &res->buf);
4977 	channel_add_input(res, htx->data);
4978 
4979 	/* Headers sent, set the flag. */
4980 	appctx->appctx->ctx.hlua_apphttp.flags |= APPLET_HDR_SENT;
4981 	return 0;
4982 
4983 }
4984 /* We will build the status line and the headers of the HTTP response.
4985  * We will try send at once if its not possible, we give back the hand
4986  * waiting for more room.
4987  */
hlua_applet_htx_start_response_yield(lua_State * L,int status,lua_KContext ctx)4988 __LJMP static int hlua_applet_htx_start_response_yield(lua_State *L, int status, lua_KContext ctx)
4989 {
4990 	struct hlua_appctx *appctx = MAY_LJMP(hlua_checkapplet_http(L, 1));
4991 	struct stream_interface *si = appctx->appctx->owner;
4992 	struct channel *res = si_ic(si);
4993 
4994 	if (co_data(res)) {
4995 		si_rx_room_blk(si);
4996 		MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_applet_htx_start_response_yield, TICK_ETERNITY, 0));
4997 	}
4998 	return MAY_LJMP(hlua_applet_htx_send_response(L));
4999 }
5000 
5001 
hlua_applet_htx_start_response(lua_State * L)5002 __LJMP static int hlua_applet_htx_start_response(lua_State *L)
5003 {
5004 	return MAY_LJMP(hlua_applet_htx_start_response_yield(L, 0, 0));
5005 }
5006 
5007 /* We will build the status line and the headers of the HTTP response.
5008  * We will try send at once if its not possible, we give back the hand
5009  * waiting for more room.
5010  */
hlua_applet_http_start_response_yield(lua_State * L,int status,lua_KContext ctx)5011 __LJMP static int hlua_applet_http_start_response_yield(lua_State *L, int status, lua_KContext ctx)
5012 {
5013 	struct hlua_appctx *appctx = MAY_LJMP(hlua_checkapplet_http(L, 1));
5014 	struct stream_interface *si = appctx->appctx->owner;
5015 	struct channel *chn = si_ic(si);
5016 	int ret;
5017 	size_t len;
5018 	const char *msg;
5019 
5020 	/* Get the message as the first argument on the stack. */
5021 	msg = MAY_LJMP(luaL_checklstring(L, 2, &len));
5022 
5023 	/* Send the message at once. */
5024 	ret = ci_putblk(chn, msg, len);
5025 
5026 	/* if ret == -2 or -3 the channel closed or the message si too
5027 	 * big for the buffers.
5028 	 */
5029 	if (ret == -2 || ret == -3) {
5030 		hlua_pusherror(L, "Lua: 'start_response': response header block too big");
5031 		WILL_LJMP(lua_error(L));
5032 	}
5033 
5034 	/* If ret is -1, we dont have room in the buffer, so we yield. */
5035 	if (ret == -1) {
5036 		si_rx_room_blk(si);
5037 		MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_applet_http_start_response_yield, TICK_ETERNITY, 0));
5038 	}
5039 
5040 	/* Headers sent, set the flag. */
5041 	appctx->appctx->ctx.hlua_apphttp.flags |= APPLET_HDR_SENT;
5042 	return 0;
5043 }
5044 
hlua_applet_http_start_response(lua_State * L)5045 __LJMP static int hlua_applet_http_start_response(lua_State *L)
5046 {
5047 	struct buffer *tmp;
5048 	struct hlua_appctx *appctx = MAY_LJMP(hlua_checkapplet_http(L, 1));
5049 	const char *name;
5050 	size_t name_len;
5051 	const char *value;
5052 	size_t value_len;
5053 	int id;
5054 	long long hdr_contentlength = -1;
5055 	int hdr_chunked = 0;
5056 	const char *reason;
5057 
5058 	if (IS_HTX_STRM(si_strm(appctx->appctx->owner)))
5059 		return MAY_LJMP(hlua_applet_htx_start_response(L));
5060 
5061 	reason = appctx->appctx->ctx.hlua_apphttp.reason;
5062 	if (reason == NULL)
5063 		reason = http_get_reason(appctx->appctx->ctx.hlua_apphttp.status);
5064 
5065 	tmp = get_trash_chunk();
5066 
5067 	/* Use the same http version than the request. */
5068 	chunk_appendf(tmp, "HTTP/1.%c %d %s\r\n",
5069 	              appctx->appctx->ctx.hlua_apphttp.flags & APPLET_HTTP11 ? '1' : '0',
5070 	              appctx->appctx->ctx.hlua_apphttp.status,
5071 	              reason);
5072 
5073 	/* Get the array associated to the field "response" in the object AppletHTTP. */
5074 	lua_pushvalue(L, 0);
5075 	if (lua_getfield(L, 1, "response") != LUA_TTABLE) {
5076 		hlua_pusherror(L, "Lua applet http '%s': AppletHTTP['response'] missing.\n",
5077 		               appctx->appctx->rule->arg.hlua_rule->fcn.name);
5078 		WILL_LJMP(lua_error(L));
5079 	}
5080 
5081 	/* Browse the list of headers. */
5082 	lua_pushnil(L);
5083 	while(lua_next(L, -2) != 0) {
5084 
5085 		/* We expect a string as -2. */
5086 		if (lua_type(L, -2) != LUA_TSTRING) {
5087 			hlua_pusherror(L, "Lua applet http '%s': AppletHTTP['response'][] element must be a string. got %s.\n",
5088 								appctx->appctx->rule->arg.hlua_rule->fcn.name,
5089 			               lua_typename(L, lua_type(L, -2)));
5090 			WILL_LJMP(lua_error(L));
5091 		}
5092 		name = lua_tolstring(L, -2, &name_len);
5093 
5094 		/* We expect an array as -1. */
5095 		if (lua_type(L, -1) != LUA_TTABLE) {
5096 			hlua_pusherror(L, "Lua applet http '%s': AppletHTTP['response']['%s'] element must be an table. got %s.\n",
5097 								appctx->appctx->rule->arg.hlua_rule->fcn.name,
5098 								name,
5099 			               lua_typename(L, lua_type(L, -1)));
5100 			WILL_LJMP(lua_error(L));
5101 		}
5102 
5103 		/* Browse the table who is on the top of the stack. */
5104 		lua_pushnil(L);
5105 		while(lua_next(L, -2) != 0) {
5106 
5107 			/* We expect a number as -2. */
5108 			if (lua_type(L, -2) != LUA_TNUMBER) {
5109 				hlua_pusherror(L, "Lua applet http '%s': AppletHTTP['response']['%s'][] element must be a number. got %s.\n",
5110 									appctx->appctx->rule->arg.hlua_rule->fcn.name,
5111 									name,
5112 				               lua_typename(L, lua_type(L, -2)));
5113 				WILL_LJMP(lua_error(L));
5114 			}
5115 			id = lua_tointeger(L, -2);
5116 
5117 			/* We expect a string as -2. */
5118 			if (lua_type(L, -1) != LUA_TSTRING) {
5119 				hlua_pusherror(L, "Lua applet http '%s': AppletHTTP['response']['%s'][%d] element must be a string. got %s.\n",
5120 									appctx->appctx->rule->arg.hlua_rule->fcn.name,
5121 									name, id,
5122 				               lua_typename(L, lua_type(L, -1)));
5123 				WILL_LJMP(lua_error(L));
5124 			}
5125 			value = lua_tolstring(L, -1, &value_len);
5126 
5127 			/* Catenate a new header. */
5128 			if (tmp->data + name_len + 2 + value_len + 2 < tmp->size) {
5129 				memcpy(tmp->area + tmp->data, name, name_len);
5130 				tmp->data += name_len;
5131 				tmp->area[tmp->data++] = ':';
5132 				tmp->area[tmp->data++] = ' ';
5133 
5134 				memcpy(tmp->area + tmp->data, value,
5135 				       value_len);
5136 				tmp->data += value_len;
5137 				tmp->area[tmp->data++] = '\r';
5138 				tmp->area[tmp->data++] = '\n';
5139 			}
5140 
5141 			/* Protocol checks. */
5142 
5143 			/* Copy the header content length. The length conversion
5144 			 * is done without control. If it contains a bad value,
5145 			 * the content-length remains negative so that we can
5146 			 * switch to either chunked encoding or close.
5147 			 */
5148 			if (name_len == 14 && strcasecmp("content-length", name) == 0)
5149 				strl2llrc(value, strlen(value), &hdr_contentlength);
5150 
5151 			/* Check if the client annouces a transfer-encoding chunked it self. */
5152 			if (name_len == 17 && value_len == 7 &&
5153 			    strcasecmp("transfer-encoding", name) == 0 &&
5154 			    strcasecmp("chunked", value) == 0)
5155 				hdr_chunked = 1;
5156 
5157 			/* Remove the array from the stack, and get next element with a remaining string. */
5158 			lua_pop(L, 1);
5159 		}
5160 
5161 		/* Remove the array from the stack, and get next element with a remaining string. */
5162 		lua_pop(L, 1);
5163 	}
5164 
5165 	/* If we dont have a content-length set, and the HTTP version is 1.1
5166 	 * and the status code implies the presence of a message body, we must
5167 	 * announce a transfer encoding chunked. This is required by haproxy
5168 	 * for the keepalive compliance. If the applet annouces a transfer-encoding
5169 	 * chunked itslef, don't do anything.
5170 	 */
5171 	if (hdr_contentlength < 0 && hdr_chunked == 0 &&
5172 	    (appctx->appctx->ctx.hlua_apphttp.flags & APPLET_HTTP11) &&
5173 	    appctx->appctx->ctx.hlua_apphttp.status >= 200 &&
5174 	    appctx->appctx->ctx.hlua_apphttp.status != 204 &&
5175 	    appctx->appctx->ctx.hlua_apphttp.status != 304) {
5176 		chunk_appendf(tmp, "Transfer-encoding: chunked\r\n");
5177 		appctx->appctx->ctx.hlua_apphttp.flags |= APPLET_CHUNKED;
5178 	}
5179 
5180 	/* Finalize headers. */
5181 	chunk_appendf(tmp, "\r\n");
5182 
5183 	/* Remove the last entry and the array of headers */
5184 	lua_pop(L, 2);
5185 
5186 	/* Push the headers block. */
5187 	lua_pushlstring(L, tmp->area, tmp->data);
5188 
5189 	return MAY_LJMP(hlua_applet_http_start_response_yield(L, 0, 0));
5190 }
5191 
5192 /*
5193  *
5194  *
5195  * Class HTTP
5196  *
5197  *
5198  */
5199 
5200 /* Returns a struct hlua_txn if the stack entry "ud" is
5201  * a class stream, otherwise it throws an error.
5202  */
hlua_checkhttp(lua_State * L,int ud)5203 __LJMP static struct hlua_txn *hlua_checkhttp(lua_State *L, int ud)
5204 {
5205 	return MAY_LJMP(hlua_checkudata(L, ud, class_http_ref));
5206 }
5207 
5208 /* This function creates and push in the stack a HTTP object
5209  * according with a current TXN.
5210  */
hlua_http_new(lua_State * L,struct hlua_txn * txn)5211 static int hlua_http_new(lua_State *L, struct hlua_txn *txn)
5212 {
5213 	struct hlua_txn *htxn;
5214 
5215 	/* Check stack size. */
5216 	if (!lua_checkstack(L, 3))
5217 		return 0;
5218 
5219 	/* Create the object: obj[0] = userdata.
5220 	 * Note that the base of the Converters object is the
5221 	 * same than the TXN object.
5222 	 */
5223 	lua_newtable(L);
5224 	htxn = lua_newuserdata(L, sizeof(*htxn));
5225 	lua_rawseti(L, -2, 0);
5226 
5227 	htxn->s = txn->s;
5228 	htxn->p = txn->p;
5229 	htxn->dir = txn->dir;
5230 	htxn->flags = txn->flags;
5231 
5232 	/* Pop a class stream metatable and affect it to the table. */
5233 	lua_rawgeti(L, LUA_REGISTRYINDEX, class_http_ref);
5234 	lua_setmetatable(L, -2);
5235 
5236 	return 1;
5237 }
5238 
5239 /* This function creates ans returns an array of HTTP headers.
5240  * This function does not fails. It is used as wrapper with the
5241  * 2 following functions.
5242  */
hlua_http_get_headers(lua_State * L,struct hlua_txn * htxn,struct http_msg * msg)5243 __LJMP static int hlua_http_get_headers(lua_State *L, struct hlua_txn *htxn, struct http_msg *msg)
5244 {
5245 	/* Create the table. */
5246 	lua_newtable(L);
5247 
5248 	if (!htxn->s->txn)
5249 		return 1;
5250 
5251 	if (IS_HTX_STRM(htxn->s)) {
5252 		/* HTX version */
5253 		struct htx *htx = htxbuf(&msg->chn->buf);
5254 		int32_t pos;
5255 
5256 		for (pos = htx_get_first(htx); pos != -1; pos = htx_get_next(htx, pos)) {
5257 			struct htx_blk *blk = htx_get_blk(htx, pos);
5258 			enum htx_blk_type type = htx_get_blk_type(blk);
5259 			struct ist n, v;
5260 			int len;
5261 
5262 			if (type == HTX_BLK_HDR) {
5263 				n = htx_get_blk_name(htx,blk);
5264 				v = htx_get_blk_value(htx, blk);
5265 			}
5266 			else if (type == HTX_BLK_EOH)
5267 				break;
5268 			else
5269 				continue;
5270 
5271 			/* Check for existing entry:
5272 			 * assume that the table is on the top of the stack, and
5273 			 * push the key in the stack, the function lua_gettable()
5274 			 * perform the lookup.
5275 			 */
5276 			lua_pushlstring(L, n.ptr, n.len);
5277 			lua_gettable(L, -2);
5278 
5279 			switch (lua_type(L, -1)) {
5280 				case LUA_TNIL:
5281 					/* Table not found, create it. */
5282 					lua_pop(L, 1); /* remove the nil value. */
5283 					lua_pushlstring(L, n.ptr, n.len);  /* push the header name as key. */
5284 					lua_newtable(L); /* create and push empty table. */
5285 					lua_pushlstring(L, v.ptr, v.len); /* push header value. */
5286 					lua_rawseti(L, -2, 0); /* index header value (pop it). */
5287 					lua_rawset(L, -3); /* index new table with header name (pop the values). */
5288 					break;
5289 
5290 				case LUA_TTABLE:
5291 					/* Entry found: push the value in the table. */
5292 					len = lua_rawlen(L, -1);
5293 					lua_pushlstring(L, v.ptr, v.len); /* push header value. */
5294 					lua_rawseti(L, -2, len+1); /* index header value (pop it). */
5295 					lua_pop(L, 1); /* remove the table (it is stored in the main table). */
5296 					break;
5297 
5298 				default:
5299 					/* Other cases are errors. */
5300 					hlua_pusherror(L, "internal error during the parsing of headers.");
5301 					WILL_LJMP(lua_error(L));
5302 			}
5303 		}
5304 	}
5305 	else {
5306 		/* Legacy HTTP version */
5307 		const char *cur_ptr, *cur_next, *p;
5308 		int old_idx, cur_idx;
5309 		struct hdr_idx_elem *cur_hdr;
5310 		const char *hn, *hv;
5311 		int hnl, hvl;
5312 		const char *in;
5313 		char *out;
5314 		int len;
5315 
5316 		/* Build array of headers. */
5317 		old_idx = 0;
5318 		cur_next = ci_head(msg->chn) + hdr_idx_first_pos(&htxn->s->txn->hdr_idx);
5319 
5320 		while (1) {
5321 			cur_idx = htxn->s->txn->hdr_idx.v[old_idx].next;
5322 			if (!cur_idx)
5323 				break;
5324 			old_idx = cur_idx;
5325 
5326 			cur_hdr  = &htxn->s->txn->hdr_idx.v[cur_idx];
5327 			cur_ptr  = cur_next;
5328 			cur_next = cur_ptr + cur_hdr->len + cur_hdr->cr + 1;
5329 
5330 			/* Now we have one full header at cur_ptr of len cur_hdr->len,
5331 			 * and the next header starts at cur_next. We'll check
5332 			 * this header in the list as well as against the default
5333 			 * rule.
5334 			 */
5335 
5336 			/* look for ': *'. */
5337 			hn = cur_ptr;
5338 			for (p = cur_ptr; p < cur_ptr + cur_hdr->len && *p != ':'; p++);
5339 			if (p >= cur_ptr+cur_hdr->len)
5340 				continue;
5341 			hnl = p - hn;
5342 			p++;
5343 			while (p < cur_ptr+cur_hdr->len && ( *p == ' ' || *p == '\t' ))
5344 				p++;
5345 			if (p >= cur_ptr+cur_hdr->len)
5346 				continue;
5347 			hv = p;
5348 			hvl = cur_ptr+cur_hdr->len-p;
5349 
5350 			/* Lowercase the key. Don't check the size of trash, it have
5351 			 * the size of one buffer and the input data contains in one
5352 			 * buffer.
5353 			 */
5354 			out = trash.area;
5355 			for (in=hn; in<hn+hnl; in++, out++)
5356 				*out = tolower(*in);
5357 			*out = '\0';
5358 
5359 			/* Check for existing entry:
5360 			 * assume that the table is on the top of the stack, and
5361 			 * push the key in the stack, the function lua_gettable()
5362 			 * perform the lookup.
5363 			 */
5364 			lua_pushlstring(L, trash.area, hnl);
5365 			lua_gettable(L, -2);
5366 
5367 			switch (lua_type(L, -1)) {
5368 				case LUA_TNIL:
5369 					/* Table not found, create it. */
5370 					lua_pop(L, 1); /* remove the nil value. */
5371 					lua_pushlstring(L, trash.area, hnl);  /* push the header name as key. */
5372 					lua_newtable(L); /* create and push empty table. */
5373 					lua_pushlstring(L, hv, hvl); /* push header value. */
5374 					lua_rawseti(L, -2, 0); /* index header value (pop it). */
5375 					lua_rawset(L, -3); /* index new table with header name (pop the values). */
5376 					break;
5377 
5378 				case LUA_TTABLE:
5379 					/* Entry found: push the value in the table. */
5380 					len = lua_rawlen(L, -1);
5381 					lua_pushlstring(L, hv, hvl); /* push header value. */
5382 					lua_rawseti(L, -2, len+1); /* index header value (pop it). */
5383 					lua_pop(L, 1); /* remove the table (it is stored in the main table). */
5384 					break;
5385 
5386 				default:
5387 					/* Other cases are errors. */
5388 					hlua_pusherror(L, "internal error during the parsing of headers.");
5389 					WILL_LJMP(lua_error(L));
5390 			}
5391 		}
5392 	}
5393 	return 1;
5394 }
5395 
hlua_http_req_get_headers(lua_State * L)5396 __LJMP static int hlua_http_req_get_headers(lua_State *L)
5397 {
5398 	struct hlua_txn *htxn;
5399 
5400 	MAY_LJMP(check_args(L, 1, "req_get_headers"));
5401 	htxn = MAY_LJMP(hlua_checkhttp(L, 1));
5402 
5403 	if (htxn->dir != SMP_OPT_DIR_REQ || !(htxn->flags & HLUA_TXN_HTTP_RDY))
5404 		WILL_LJMP(lua_error(L));
5405 
5406 	return hlua_http_get_headers(L, htxn, &htxn->s->txn->req);
5407 }
5408 
hlua_http_res_get_headers(lua_State * L)5409 __LJMP static int hlua_http_res_get_headers(lua_State *L)
5410 {
5411 	struct hlua_txn *htxn;
5412 
5413 	MAY_LJMP(check_args(L, 1, "res_get_headers"));
5414 	htxn = MAY_LJMP(hlua_checkhttp(L, 1));
5415 
5416 	if (htxn->dir != SMP_OPT_DIR_RES || !(htxn->flags & HLUA_TXN_HTTP_RDY))
5417 		WILL_LJMP(lua_error(L));
5418 
5419 	return hlua_http_get_headers(L, htxn, &htxn->s->txn->rsp);
5420 }
5421 
5422 /* This function replace full header, or just a value in
5423  * the request or in the response. It is a wrapper fir the
5424  * 4 following functions.
5425  */
hlua_http_rep_hdr(lua_State * L,struct hlua_txn * htxn,struct http_msg * msg,int action)5426 __LJMP static inline int hlua_http_rep_hdr(lua_State *L, struct hlua_txn *htxn,
5427                                            struct http_msg *msg, int action)
5428 {
5429 	size_t name_len;
5430 	const char *name = MAY_LJMP(luaL_checklstring(L, 2, &name_len));
5431 	const char *reg = MAY_LJMP(luaL_checkstring(L, 3));
5432 	const char *value = MAY_LJMP(luaL_checkstring(L, 4));
5433 	struct my_regex *re;
5434 
5435 	if (!(re = regex_comp(reg, 1, 1, NULL)))
5436 		WILL_LJMP(luaL_argerror(L, 3, "invalid regex"));
5437 
5438 	if (IS_HTX_STRM(htxn->s)) {
5439 		struct htx *htx = htxbuf(&msg->chn->buf);
5440 
5441 		htx_transform_header_str(htxn->s, msg->chn, htx, ist2(name, name_len), value, re, action);
5442 	}
5443 	else
5444 		http_transform_header_str(htxn->s, msg, name, name_len, value, re, action);
5445 	regex_free(re);
5446 	return 0;
5447 }
5448 
hlua_http_req_rep_hdr(lua_State * L)5449 __LJMP static int hlua_http_req_rep_hdr(lua_State *L)
5450 {
5451 	struct hlua_txn *htxn;
5452 
5453 	MAY_LJMP(check_args(L, 4, "req_rep_hdr"));
5454 	htxn = MAY_LJMP(hlua_checkhttp(L, 1));
5455 
5456 	if (htxn->dir != SMP_OPT_DIR_REQ || !(htxn->flags & HLUA_TXN_HTTP_RDY))
5457 		WILL_LJMP(lua_error(L));
5458 
5459 	return MAY_LJMP(hlua_http_rep_hdr(L, htxn, &htxn->s->txn->req, ACT_HTTP_REPLACE_HDR));
5460 }
5461 
hlua_http_res_rep_hdr(lua_State * L)5462 __LJMP static int hlua_http_res_rep_hdr(lua_State *L)
5463 {
5464 	struct hlua_txn *htxn;
5465 
5466 	MAY_LJMP(check_args(L, 4, "res_rep_hdr"));
5467 	htxn = MAY_LJMP(hlua_checkhttp(L, 1));
5468 
5469 	if (htxn->dir != SMP_OPT_DIR_RES || !(htxn->flags & HLUA_TXN_HTTP_RDY))
5470 		WILL_LJMP(lua_error(L));
5471 
5472 	return MAY_LJMP(hlua_http_rep_hdr(L, htxn, &htxn->s->txn->rsp, ACT_HTTP_REPLACE_HDR));
5473 }
5474 
hlua_http_req_rep_val(lua_State * L)5475 __LJMP static int hlua_http_req_rep_val(lua_State *L)
5476 {
5477 	struct hlua_txn *htxn;
5478 
5479 	MAY_LJMP(check_args(L, 4, "req_rep_hdr"));
5480 	htxn = MAY_LJMP(hlua_checkhttp(L, 1));
5481 
5482 	if (htxn->dir != SMP_OPT_DIR_REQ || !(htxn->flags & HLUA_TXN_HTTP_RDY))
5483 		WILL_LJMP(lua_error(L));
5484 
5485 	return MAY_LJMP(hlua_http_rep_hdr(L, htxn, &htxn->s->txn->req, ACT_HTTP_REPLACE_VAL));
5486 }
5487 
hlua_http_res_rep_val(lua_State * L)5488 __LJMP static int hlua_http_res_rep_val(lua_State *L)
5489 {
5490 	struct hlua_txn *htxn;
5491 
5492 	MAY_LJMP(check_args(L, 4, "res_rep_val"));
5493 	htxn = MAY_LJMP(hlua_checkhttp(L, 1));
5494 
5495 	if (htxn->dir != SMP_OPT_DIR_RES || !(htxn->flags & HLUA_TXN_HTTP_RDY))
5496 		WILL_LJMP(lua_error(L));
5497 
5498 	return MAY_LJMP(hlua_http_rep_hdr(L, htxn, &htxn->s->txn->rsp, ACT_HTTP_REPLACE_VAL));
5499 }
5500 
5501 /* This function deletes all the occurrences of an header.
5502  * It is a wrapper for the 2 following functions.
5503  */
hlua_http_del_hdr(lua_State * L,struct hlua_txn * htxn,struct http_msg * msg)5504 __LJMP static inline int hlua_http_del_hdr(lua_State *L, struct hlua_txn *htxn, struct http_msg *msg)
5505 {
5506 	size_t len;
5507 	const char *name = MAY_LJMP(luaL_checklstring(L, 2, &len));
5508 
5509 	if (IS_HTX_STRM(htxn->s)) {
5510 		/* HTX version */
5511 		struct htx *htx = htxbuf(&msg->chn->buf);
5512 		struct http_hdr_ctx ctx;
5513 
5514 		ctx.blk = NULL;
5515 		while (http_find_header(htx, ist2(name, len), &ctx, 1))
5516 			http_remove_header(htx, &ctx);
5517 	}
5518 	else {
5519 		/* Legacy HTTP version */
5520 		struct hdr_ctx ctx;
5521 		struct http_txn *txn = htxn->s->txn;
5522 
5523 		ctx.idx = 0;
5524 		while (http_find_header2(name, len, ci_head(msg->chn), &txn->hdr_idx, &ctx))
5525 			http_remove_header2(msg, &txn->hdr_idx, &ctx);
5526 	}
5527 	return 0;
5528 }
5529 
hlua_http_req_del_hdr(lua_State * L)5530 __LJMP static int hlua_http_req_del_hdr(lua_State *L)
5531 {
5532 	struct hlua_txn *htxn;
5533 
5534 	MAY_LJMP(check_args(L, 2, "req_del_hdr"));
5535 	htxn = MAY_LJMP(hlua_checkhttp(L, 1));
5536 
5537 	if (htxn->dir != SMP_OPT_DIR_REQ || !(htxn->flags & HLUA_TXN_HTTP_RDY))
5538 		WILL_LJMP(lua_error(L));
5539 
5540 	return hlua_http_del_hdr(L, htxn, &htxn->s->txn->req);
5541 }
5542 
hlua_http_res_del_hdr(lua_State * L)5543 __LJMP static int hlua_http_res_del_hdr(lua_State *L)
5544 {
5545 	struct hlua_txn *htxn;
5546 
5547 	MAY_LJMP(check_args(L, 2, "res_del_hdr"));
5548 	htxn = MAY_LJMP(hlua_checkhttp(L, 1));
5549 
5550 	if (htxn->dir != SMP_OPT_DIR_RES || !(htxn->flags & HLUA_TXN_HTTP_RDY))
5551 		WILL_LJMP(lua_error(L));
5552 
5553 	return hlua_http_del_hdr(L, htxn, &htxn->s->txn->rsp);
5554 }
5555 
5556 /* This function adds an header. It is a wrapper used by
5557  * the 2 following functions.
5558  */
hlua_http_add_hdr(lua_State * L,struct hlua_txn * htxn,struct http_msg * msg)5559 __LJMP static inline int hlua_http_add_hdr(lua_State *L, struct hlua_txn *htxn, struct http_msg *msg)
5560 {
5561 	size_t name_len;
5562 	const char *name = MAY_LJMP(luaL_checklstring(L, 2, &name_len));
5563 	size_t value_len;
5564 	const char *value = MAY_LJMP(luaL_checklstring(L, 3, &value_len));
5565 	char *p;
5566 
5567 	if (IS_HTX_STRM(htxn->s)) {
5568 		/* HTX version */
5569 		struct htx *htx = htxbuf(&msg->chn->buf);
5570 
5571 		lua_pushboolean(L, http_add_header(htx, ist2(name, name_len),
5572 						   ist2(value, value_len)));
5573 	}
5574 	else {
5575 		/* Legacy HTTP version */
5576 		/* Check length. */
5577 		trash.data = value_len + name_len + 2;
5578 		if (trash.data > trash.size)
5579 			return 0;
5580 
5581 		/* Creates the header string. */
5582 		p = trash.area;
5583 		memcpy(p, name, name_len);
5584 		p += name_len;
5585 		*p = ':';
5586 		p++;
5587 		*p = ' ';
5588 		p++;
5589 		memcpy(p, value, value_len);
5590 
5591 		lua_pushboolean(L, http_header_add_tail2(msg, &htxn->s->txn->hdr_idx,
5592 							 trash.area, trash.data) != 0);
5593 	}
5594 	return 0;
5595 }
5596 
hlua_http_req_add_hdr(lua_State * L)5597 __LJMP static int hlua_http_req_add_hdr(lua_State *L)
5598 {
5599 	struct hlua_txn *htxn;
5600 
5601 	MAY_LJMP(check_args(L, 3, "req_add_hdr"));
5602 	htxn = MAY_LJMP(hlua_checkhttp(L, 1));
5603 
5604 	if (htxn->dir != SMP_OPT_DIR_REQ || !(htxn->flags & HLUA_TXN_HTTP_RDY))
5605 		WILL_LJMP(lua_error(L));
5606 
5607 	return hlua_http_add_hdr(L, htxn, &htxn->s->txn->req);
5608 }
5609 
hlua_http_res_add_hdr(lua_State * L)5610 __LJMP static int hlua_http_res_add_hdr(lua_State *L)
5611 {
5612 	struct hlua_txn *htxn;
5613 
5614 	MAY_LJMP(check_args(L, 3, "res_add_hdr"));
5615 	htxn = MAY_LJMP(hlua_checkhttp(L, 1));
5616 
5617 	if (htxn->dir != SMP_OPT_DIR_RES || !(htxn->flags & HLUA_TXN_HTTP_RDY))
5618 		WILL_LJMP(lua_error(L));
5619 
5620 	return hlua_http_add_hdr(L, htxn, &htxn->s->txn->rsp);
5621 }
5622 
hlua_http_req_set_hdr(lua_State * L)5623 static int hlua_http_req_set_hdr(lua_State *L)
5624 {
5625 	struct hlua_txn *htxn;
5626 
5627 	MAY_LJMP(check_args(L, 3, "req_set_hdr"));
5628 	htxn = MAY_LJMP(hlua_checkhttp(L, 1));
5629 
5630 	if (htxn->dir != SMP_OPT_DIR_REQ || !(htxn->flags & HLUA_TXN_HTTP_RDY))
5631 		WILL_LJMP(lua_error(L));
5632 
5633 	hlua_http_del_hdr(L, htxn, &htxn->s->txn->req);
5634 	return hlua_http_add_hdr(L, htxn, &htxn->s->txn->req);
5635 }
5636 
hlua_http_res_set_hdr(lua_State * L)5637 static int hlua_http_res_set_hdr(lua_State *L)
5638 {
5639 	struct hlua_txn *htxn;
5640 
5641 	MAY_LJMP(check_args(L, 3, "res_set_hdr"));
5642 	htxn = MAY_LJMP(hlua_checkhttp(L, 1));
5643 
5644 	if (htxn->dir != SMP_OPT_DIR_RES || !(htxn->flags & HLUA_TXN_HTTP_RDY))
5645 		WILL_LJMP(lua_error(L));
5646 
5647 	hlua_http_del_hdr(L, htxn, &htxn->s->txn->rsp);
5648 	return hlua_http_add_hdr(L, htxn, &htxn->s->txn->rsp);
5649 }
5650 
5651 /* This function set the method. */
hlua_http_req_set_meth(lua_State * L)5652 static int hlua_http_req_set_meth(lua_State *L)
5653 {
5654 	struct hlua_txn *htxn = MAY_LJMP(hlua_checkhttp(L, 1));
5655 	size_t name_len;
5656 	const char *name = MAY_LJMP(luaL_checklstring(L, 2, &name_len));
5657 
5658 	if (htxn->dir != SMP_OPT_DIR_REQ || !(htxn->flags & HLUA_TXN_HTTP_RDY))
5659 		WILL_LJMP(lua_error(L));
5660 
5661 	lua_pushboolean(L, http_replace_req_line(0, name, name_len, htxn->p, htxn->s) != -1);
5662 	return 1;
5663 }
5664 
5665 /* This function set the method. */
hlua_http_req_set_path(lua_State * L)5666 static int hlua_http_req_set_path(lua_State *L)
5667 {
5668 	struct hlua_txn *htxn = MAY_LJMP(hlua_checkhttp(L, 1));
5669 	size_t name_len;
5670 	const char *name = MAY_LJMP(luaL_checklstring(L, 2, &name_len));
5671 
5672 	if (htxn->dir != SMP_OPT_DIR_REQ || !(htxn->flags & HLUA_TXN_HTTP_RDY))
5673 		WILL_LJMP(lua_error(L));
5674 
5675 	lua_pushboolean(L, http_replace_req_line(1, name, name_len, htxn->p, htxn->s) != -1);
5676 	return 1;
5677 }
5678 
5679 /* This function set the query-string. */
hlua_http_req_set_query(lua_State * L)5680 static int hlua_http_req_set_query(lua_State *L)
5681 {
5682 	struct hlua_txn *htxn = MAY_LJMP(hlua_checkhttp(L, 1));
5683 	size_t name_len;
5684 	const char *name = MAY_LJMP(luaL_checklstring(L, 2, &name_len));
5685 
5686 	if (htxn->dir != SMP_OPT_DIR_REQ || !(htxn->flags & HLUA_TXN_HTTP_RDY))
5687 		WILL_LJMP(lua_error(L));
5688 
5689 	/* Check length. */
5690 	if (name_len > trash.size - 1) {
5691 		lua_pushboolean(L, 0);
5692 		return 1;
5693 	}
5694 
5695 	/* Add the mark question as prefix. */
5696 	chunk_reset(&trash);
5697 	trash.area[trash.data++] = '?';
5698 	memcpy(trash.area + trash.data, name, name_len);
5699 	trash.data += name_len;
5700 
5701 	lua_pushboolean(L,
5702 			http_replace_req_line(2, trash.area, trash.data, htxn->p, htxn->s) != -1);
5703 	return 1;
5704 }
5705 
5706 /* This function set the uri. */
hlua_http_req_set_uri(lua_State * L)5707 static int hlua_http_req_set_uri(lua_State *L)
5708 {
5709 	struct hlua_txn *htxn = MAY_LJMP(hlua_checkhttp(L, 1));
5710 	size_t name_len;
5711 	const char *name = MAY_LJMP(luaL_checklstring(L, 2, &name_len));
5712 
5713 	if (htxn->dir != SMP_OPT_DIR_REQ || !(htxn->flags & HLUA_TXN_HTTP_RDY))
5714 		WILL_LJMP(lua_error(L));
5715 
5716 	lua_pushboolean(L, http_replace_req_line(3, name, name_len, htxn->p, htxn->s) != -1);
5717 	return 1;
5718 }
5719 
5720 /* This function set the response code & optionally reason. */
hlua_http_res_set_status(lua_State * L)5721 static int hlua_http_res_set_status(lua_State *L)
5722 {
5723 	struct hlua_txn *htxn = MAY_LJMP(hlua_checkhttp(L, 1));
5724 	unsigned int code = MAY_LJMP(luaL_checkinteger(L, 2));
5725 	const char *reason = MAY_LJMP(luaL_optlstring(L, 3, NULL, NULL));
5726 
5727 	if (htxn->dir != SMP_OPT_DIR_RES || !(htxn->flags & HLUA_TXN_HTTP_RDY))
5728 		WILL_LJMP(lua_error(L));
5729 
5730 	http_set_status(code, reason, htxn->s);
5731 	return 0;
5732 }
5733 
5734 /*
5735  *
5736  *
5737  * Class TXN
5738  *
5739  *
5740  */
5741 
5742 /* Returns a struct hlua_session if the stack entry "ud" is
5743  * a class stream, otherwise it throws an error.
5744  */
hlua_checktxn(lua_State * L,int ud)5745 __LJMP static struct hlua_txn *hlua_checktxn(lua_State *L, int ud)
5746 {
5747 	return MAY_LJMP(hlua_checkudata(L, ud, class_txn_ref));
5748 }
5749 
hlua_set_var(lua_State * L)5750 __LJMP static int hlua_set_var(lua_State *L)
5751 {
5752 	struct hlua_txn *htxn;
5753 	const char *name;
5754 	size_t len;
5755 	struct sample smp;
5756 
5757 	MAY_LJMP(check_args(L, 3, "set_var"));
5758 
5759 	/* It is useles to retrieve the stream, but this function
5760 	 * runs only in a stream context.
5761 	 */
5762 	htxn = MAY_LJMP(hlua_checktxn(L, 1));
5763 	name = MAY_LJMP(luaL_checklstring(L, 2, &len));
5764 
5765 	/* Converts the third argument in a sample. */
5766 	memset(&smp, 0, sizeof(smp));
5767 	hlua_lua2smp(L, 3, &smp);
5768 
5769 	/* Store the sample in a variable. */
5770 	smp_set_owner(&smp, htxn->p, htxn->s->sess, htxn->s, htxn->dir & SMP_OPT_DIR);
5771 	vars_set_by_name(name, len, &smp);
5772 	return 0;
5773 }
5774 
hlua_unset_var(lua_State * L)5775 __LJMP static int hlua_unset_var(lua_State *L)
5776 {
5777 	struct hlua_txn *htxn;
5778 	const char *name;
5779 	size_t len;
5780 	struct sample smp;
5781 
5782 	MAY_LJMP(check_args(L, 2, "unset_var"));
5783 
5784 	/* It is useles to retrieve the stream, but this function
5785 	 * runs only in a stream context.
5786 	 */
5787 	htxn = MAY_LJMP(hlua_checktxn(L, 1));
5788 	name = MAY_LJMP(luaL_checklstring(L, 2, &len));
5789 
5790 	/* Unset the variable. */
5791 	smp_set_owner(&smp, htxn->p, htxn->s->sess, htxn->s, htxn->dir & SMP_OPT_DIR);
5792 	vars_unset_by_name(name, len, &smp);
5793 	return 0;
5794 }
5795 
hlua_get_var(lua_State * L)5796 __LJMP static int hlua_get_var(lua_State *L)
5797 {
5798 	struct hlua_txn *htxn;
5799 	const char *name;
5800 	size_t len;
5801 	struct sample smp;
5802 
5803 	MAY_LJMP(check_args(L, 2, "get_var"));
5804 
5805 	/* It is useles to retrieve the stream, but this function
5806 	 * runs only in a stream context.
5807 	 */
5808 	htxn = MAY_LJMP(hlua_checktxn(L, 1));
5809 	name = MAY_LJMP(luaL_checklstring(L, 2, &len));
5810 
5811 	smp_set_owner(&smp, htxn->p, htxn->s->sess, htxn->s, htxn->dir & SMP_OPT_DIR);
5812 	if (!vars_get_by_name(name, len, &smp)) {
5813 		lua_pushnil(L);
5814 		return 1;
5815 	}
5816 
5817 	return hlua_smp2lua(L, &smp);
5818 }
5819 
hlua_set_priv(lua_State * L)5820 __LJMP static int hlua_set_priv(lua_State *L)
5821 {
5822 	struct hlua *hlua;
5823 
5824 	MAY_LJMP(check_args(L, 2, "set_priv"));
5825 
5826 	/* It is useles to retrieve the stream, but this function
5827 	 * runs only in a stream context.
5828 	 */
5829 	MAY_LJMP(hlua_checktxn(L, 1));
5830 	hlua = hlua_gethlua(L);
5831 
5832 	/* Remove previous value. */
5833 	luaL_unref(L, LUA_REGISTRYINDEX, hlua->Mref);
5834 
5835 	/* Get and store new value. */
5836 	lua_pushvalue(L, 2); /* Copy the element 2 at the top of the stack. */
5837 	hlua->Mref = luaL_ref(L, LUA_REGISTRYINDEX); /* pop the previously pushed value. */
5838 
5839 	return 0;
5840 }
5841 
hlua_get_priv(lua_State * L)5842 __LJMP static int hlua_get_priv(lua_State *L)
5843 {
5844 	struct hlua *hlua;
5845 
5846 	MAY_LJMP(check_args(L, 1, "get_priv"));
5847 
5848 	/* It is useles to retrieve the stream, but this function
5849 	 * runs only in a stream context.
5850 	 */
5851 	MAY_LJMP(hlua_checktxn(L, 1));
5852 	hlua = hlua_gethlua(L);
5853 
5854 	/* Push configuration index in the stack. */
5855 	lua_rawgeti(L, LUA_REGISTRYINDEX, hlua->Mref);
5856 
5857 	return 1;
5858 }
5859 
5860 /* Create stack entry containing a class TXN. This function
5861  * return 0 if the stack does not contains free slots,
5862  * otherwise it returns 1.
5863  */
hlua_txn_new(lua_State * L,struct stream * s,struct proxy * p,int dir,int flags)5864 static int hlua_txn_new(lua_State *L, struct stream *s, struct proxy *p, int dir, int flags)
5865 {
5866 	struct hlua_txn *htxn;
5867 
5868 	/* Check stack size. */
5869 	if (!lua_checkstack(L, 3))
5870 		return 0;
5871 
5872 	/* NOTE: The allocation never fails. The failure
5873 	 * throw an error, and the function never returns.
5874 	 * if the throw is not available, the process is aborted.
5875 	 */
5876 	/* Create the object: obj[0] = userdata. */
5877 	lua_newtable(L);
5878 	htxn = lua_newuserdata(L, sizeof(*htxn));
5879 	lua_rawseti(L, -2, 0);
5880 
5881 	htxn->s = s;
5882 	htxn->p = p;
5883 	htxn->dir = dir;
5884 	htxn->flags = flags;
5885 
5886 	/* Create the "f" field that contains a list of fetches. */
5887 	lua_pushstring(L, "f");
5888 	if (!hlua_fetches_new(L, htxn, HLUA_F_MAY_USE_HTTP))
5889 		return 0;
5890 	lua_rawset(L, -3);
5891 
5892 	/* Create the "sf" field that contains a list of stringsafe fetches. */
5893 	lua_pushstring(L, "sf");
5894 	if (!hlua_fetches_new(L, htxn, HLUA_F_MAY_USE_HTTP | HLUA_F_AS_STRING))
5895 		return 0;
5896 	lua_rawset(L, -3);
5897 
5898 	/* Create the "c" field that contains a list of converters. */
5899 	lua_pushstring(L, "c");
5900 	if (!hlua_converters_new(L, htxn, 0))
5901 		return 0;
5902 	lua_rawset(L, -3);
5903 
5904 	/* Create the "sc" field that contains a list of stringsafe converters. */
5905 	lua_pushstring(L, "sc");
5906 	if (!hlua_converters_new(L, htxn, HLUA_F_AS_STRING))
5907 		return 0;
5908 	lua_rawset(L, -3);
5909 
5910 	/* Create the "req" field that contains the request channel object. */
5911 	lua_pushstring(L, "req");
5912 	if (!hlua_channel_new(L, &s->req))
5913 		return 0;
5914 	lua_rawset(L, -3);
5915 
5916 	/* Create the "res" field that contains the response channel object. */
5917 	lua_pushstring(L, "res");
5918 	if (!hlua_channel_new(L, &s->res))
5919 		return 0;
5920 	lua_rawset(L, -3);
5921 
5922 	/* Creates the HTTP object is the current proxy allows http. */
5923 	lua_pushstring(L, "http");
5924 	if (p->mode == PR_MODE_HTTP) {
5925 		if (!hlua_http_new(L, htxn))
5926 			return 0;
5927 	}
5928 	else
5929 		lua_pushnil(L);
5930 	lua_rawset(L, -3);
5931 
5932 	/* Pop a class sesison metatable and affect it to the userdata. */
5933 	lua_rawgeti(L, LUA_REGISTRYINDEX, class_txn_ref);
5934 	lua_setmetatable(L, -2);
5935 
5936 	return 1;
5937 }
5938 
hlua_txn_deflog(lua_State * L)5939 __LJMP static int hlua_txn_deflog(lua_State *L)
5940 {
5941 	const char *msg;
5942 	struct hlua_txn *htxn;
5943 
5944 	MAY_LJMP(check_args(L, 2, "deflog"));
5945 	htxn = MAY_LJMP(hlua_checktxn(L, 1));
5946 	msg = MAY_LJMP(luaL_checkstring(L, 2));
5947 
5948 	hlua_sendlog(htxn->s->be, htxn->s->logs.level, msg);
5949 	return 0;
5950 }
5951 
hlua_txn_log(lua_State * L)5952 __LJMP static int hlua_txn_log(lua_State *L)
5953 {
5954 	int level;
5955 	const char *msg;
5956 	struct hlua_txn *htxn;
5957 
5958 	MAY_LJMP(check_args(L, 3, "log"));
5959 	htxn = MAY_LJMP(hlua_checktxn(L, 1));
5960 	level = MAY_LJMP(luaL_checkinteger(L, 2));
5961 	msg = MAY_LJMP(luaL_checkstring(L, 3));
5962 
5963 	if (level < 0 || level >= NB_LOG_LEVELS)
5964 		WILL_LJMP(luaL_argerror(L, 1, "Invalid loglevel."));
5965 
5966 	hlua_sendlog(htxn->s->be, level, msg);
5967 	return 0;
5968 }
5969 
hlua_txn_log_debug(lua_State * L)5970 __LJMP static int hlua_txn_log_debug(lua_State *L)
5971 {
5972 	const char *msg;
5973 	struct hlua_txn *htxn;
5974 
5975 	MAY_LJMP(check_args(L, 2, "Debug"));
5976 	htxn = MAY_LJMP(hlua_checktxn(L, 1));
5977 	msg = MAY_LJMP(luaL_checkstring(L, 2));
5978 	hlua_sendlog(htxn->s->be, LOG_DEBUG, msg);
5979 	return 0;
5980 }
5981 
hlua_txn_log_info(lua_State * L)5982 __LJMP static int hlua_txn_log_info(lua_State *L)
5983 {
5984 	const char *msg;
5985 	struct hlua_txn *htxn;
5986 
5987 	MAY_LJMP(check_args(L, 2, "Info"));
5988 	htxn = MAY_LJMP(hlua_checktxn(L, 1));
5989 	msg = MAY_LJMP(luaL_checkstring(L, 2));
5990 	hlua_sendlog(htxn->s->be, LOG_INFO, msg);
5991 	return 0;
5992 }
5993 
hlua_txn_log_warning(lua_State * L)5994 __LJMP static int hlua_txn_log_warning(lua_State *L)
5995 {
5996 	const char *msg;
5997 	struct hlua_txn *htxn;
5998 
5999 	MAY_LJMP(check_args(L, 2, "Warning"));
6000 	htxn = MAY_LJMP(hlua_checktxn(L, 1));
6001 	msg = MAY_LJMP(luaL_checkstring(L, 2));
6002 	hlua_sendlog(htxn->s->be, LOG_WARNING, msg);
6003 	return 0;
6004 }
6005 
hlua_txn_log_alert(lua_State * L)6006 __LJMP static int hlua_txn_log_alert(lua_State *L)
6007 {
6008 	const char *msg;
6009 	struct hlua_txn *htxn;
6010 
6011 	MAY_LJMP(check_args(L, 2, "Alert"));
6012 	htxn = MAY_LJMP(hlua_checktxn(L, 1));
6013 	msg = MAY_LJMP(luaL_checkstring(L, 2));
6014 	hlua_sendlog(htxn->s->be, LOG_ALERT, msg);
6015 	return 0;
6016 }
6017 
hlua_txn_set_loglevel(lua_State * L)6018 __LJMP static int hlua_txn_set_loglevel(lua_State *L)
6019 {
6020 	struct hlua_txn *htxn;
6021 	int ll;
6022 
6023 	MAY_LJMP(check_args(L, 2, "set_loglevel"));
6024 	htxn = MAY_LJMP(hlua_checktxn(L, 1));
6025 	ll = MAY_LJMP(luaL_checkinteger(L, 2));
6026 
6027 	if (ll < 0 || ll > 7)
6028 		WILL_LJMP(luaL_argerror(L, 2, "Bad log level. It must be between 0 and 7"));
6029 
6030 	htxn->s->logs.level = ll;
6031 	return 0;
6032 }
6033 
hlua_txn_set_tos(lua_State * L)6034 __LJMP static int hlua_txn_set_tos(lua_State *L)
6035 {
6036 	struct hlua_txn *htxn;
6037 	int tos;
6038 
6039 	MAY_LJMP(check_args(L, 2, "set_tos"));
6040 	htxn = MAY_LJMP(hlua_checktxn(L, 1));
6041 	tos = MAY_LJMP(luaL_checkinteger(L, 2));
6042 
6043 	conn_set_tos(objt_conn(htxn->s->sess->origin), tos);
6044 	return 0;
6045 }
6046 
hlua_txn_set_mark(lua_State * L)6047 __LJMP static int hlua_txn_set_mark(lua_State *L)
6048 {
6049 	struct hlua_txn *htxn;
6050 	int mark;
6051 
6052 	MAY_LJMP(check_args(L, 2, "set_mark"));
6053 	htxn = MAY_LJMP(hlua_checktxn(L, 1));
6054 	mark = MAY_LJMP(luaL_checkinteger(L, 2));
6055 
6056 	conn_set_mark(objt_conn(htxn->s->sess->origin), mark);
6057 	return 0;
6058 }
6059 
hlua_txn_set_priority_class(lua_State * L)6060 __LJMP static int hlua_txn_set_priority_class(lua_State *L)
6061 {
6062 	struct hlua_txn *htxn;
6063 
6064 	MAY_LJMP(check_args(L, 2, "set_priority_class"));
6065 	htxn = MAY_LJMP(hlua_checktxn(L, 1));
6066 	htxn->s->priority_class = queue_limit_class(MAY_LJMP(luaL_checkinteger(L, 2)));
6067 	return 0;
6068 }
6069 
hlua_txn_set_priority_offset(lua_State * L)6070 __LJMP static int hlua_txn_set_priority_offset(lua_State *L)
6071 {
6072 	struct hlua_txn *htxn;
6073 
6074 	MAY_LJMP(check_args(L, 2, "set_priority_offset"));
6075 	htxn = MAY_LJMP(hlua_checktxn(L, 1));
6076 	htxn->s->priority_offset = queue_limit_offset(MAY_LJMP(luaL_checkinteger(L, 2)));
6077 	return 0;
6078 }
6079 
6080 /* This function is an Lua binding that send pending data
6081  * to the client, and close the stream interface.
6082  */
hlua_txn_done(lua_State * L)6083 __LJMP static int hlua_txn_done(lua_State *L)
6084 {
6085 	struct hlua_txn *htxn;
6086 	struct hlua *hlua;
6087 	struct channel *ic, *oc;
6088 
6089 	MAY_LJMP(check_args(L, 1, "close"));
6090 	htxn = MAY_LJMP(hlua_checktxn(L, 1));
6091 	hlua = hlua_gethlua(L);
6092 
6093 	/* If the flags NOTERM is set, we cannot terminate the http
6094 	 * session, so we just end the execution of the current
6095 	 * lua code.
6096 	 */
6097 	if (htxn->flags & HLUA_TXN_NOTERM) {
6098 		WILL_LJMP(hlua_done(L));
6099 		return 0;
6100 	}
6101 
6102 	ic = &htxn->s->req;
6103 	oc = &htxn->s->res;
6104 
6105 	if (IS_HTX_STRM(htxn->s)) {
6106 		htxn->s->txn->status = 0;
6107 		http_reply_and_close(htxn->s, 0, NULL);
6108 		ic->analysers &= AN_REQ_FLT_END;
6109 		oc->analysers &= AN_RES_FLT_END;
6110 	}
6111 	else {
6112 		if (htxn->s->txn) {
6113 			/* HTTP mode, let's stay in sync with the stream */
6114 			b_del(&ic->buf, htxn->s->txn->req.sov);
6115 			htxn->s->txn->req.next -= htxn->s->txn->req.sov;
6116 			htxn->s->txn->req.sov = 0;
6117 
6118 			ic->analysers &= AN_REQ_HTTP_XFER_BODY;
6119 			oc->analysers = AN_RES_HTTP_XFER_BODY;
6120 			htxn->s->txn->req.msg_state = HTTP_MSG_CLOSED;
6121 			htxn->s->txn->rsp.msg_state = HTTP_MSG_DONE;
6122 
6123 		/* Note that if we want to support keep-alive, we need
6124 		 * to bypass the close/shutr_now calls below, but that
6125 		 * may only be done if the HTTP request was already
6126 		 * processed and the connection header is known (ie
6127 		 * not during TCP rules).
6128 		 */
6129 		}
6130 
6131 		channel_auto_read(ic);
6132 		channel_abort(ic);
6133 		channel_auto_close(ic);
6134 		channel_erase(ic);
6135 
6136 		oc->wex = tick_add_ifset(now_ms, oc->wto);
6137 		channel_auto_read(oc);
6138 		channel_auto_close(oc);
6139 		channel_shutr_now(oc);
6140 
6141 		ic->analysers = 0;
6142 	}
6143 
6144 	if (!(htxn->s->flags & SF_ERR_MASK))      // this is not really an error but it is
6145 		htxn->s->flags |= SF_ERR_LOCAL;   // to mark that it comes from the proxy
6146 
6147 	hlua->flags |= HLUA_STOP;
6148 	WILL_LJMP(hlua_done(L));
6149 	return 0;
6150 }
6151 
hlua_log(lua_State * L)6152 __LJMP static int hlua_log(lua_State *L)
6153 {
6154 	int level;
6155 	const char *msg;
6156 
6157 	MAY_LJMP(check_args(L, 2, "log"));
6158 	level = MAY_LJMP(luaL_checkinteger(L, 1));
6159 	msg = MAY_LJMP(luaL_checkstring(L, 2));
6160 
6161 	if (level < 0 || level >= NB_LOG_LEVELS)
6162 		WILL_LJMP(luaL_argerror(L, 1, "Invalid loglevel."));
6163 
6164 	hlua_sendlog(NULL, level, msg);
6165 	return 0;
6166 }
6167 
hlua_log_debug(lua_State * L)6168 __LJMP static int hlua_log_debug(lua_State *L)
6169 {
6170 	const char *msg;
6171 
6172 	MAY_LJMP(check_args(L, 1, "debug"));
6173 	msg = MAY_LJMP(luaL_checkstring(L, 1));
6174 	hlua_sendlog(NULL, LOG_DEBUG, msg);
6175 	return 0;
6176 }
6177 
hlua_log_info(lua_State * L)6178 __LJMP static int hlua_log_info(lua_State *L)
6179 {
6180 	const char *msg;
6181 
6182 	MAY_LJMP(check_args(L, 1, "info"));
6183 	msg = MAY_LJMP(luaL_checkstring(L, 1));
6184 	hlua_sendlog(NULL, LOG_INFO, msg);
6185 	return 0;
6186 }
6187 
hlua_log_warning(lua_State * L)6188 __LJMP static int hlua_log_warning(lua_State *L)
6189 {
6190 	const char *msg;
6191 
6192 	MAY_LJMP(check_args(L, 1, "warning"));
6193 	msg = MAY_LJMP(luaL_checkstring(L, 1));
6194 	hlua_sendlog(NULL, LOG_WARNING, msg);
6195 	return 0;
6196 }
6197 
hlua_log_alert(lua_State * L)6198 __LJMP static int hlua_log_alert(lua_State *L)
6199 {
6200 	const char *msg;
6201 
6202 	MAY_LJMP(check_args(L, 1, "alert"));
6203 	msg = MAY_LJMP(luaL_checkstring(L, 1));
6204 	hlua_sendlog(NULL, LOG_ALERT, msg);
6205 	return 0;
6206 }
6207 
hlua_sleep_yield(lua_State * L,int status,lua_KContext ctx)6208 __LJMP static int hlua_sleep_yield(lua_State *L, int status, lua_KContext ctx)
6209 {
6210 	int wakeup_ms = lua_tointeger(L, -1);
6211 	if (!tick_is_expired(wakeup_ms, now_ms))
6212 		MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_sleep_yield, wakeup_ms, 0));
6213 	return 0;
6214 }
6215 
hlua_sleep(lua_State * L)6216 __LJMP static int hlua_sleep(lua_State *L)
6217 {
6218 	unsigned int delay;
6219 	unsigned int wakeup_ms;
6220 
6221 	MAY_LJMP(check_args(L, 1, "sleep"));
6222 
6223 	delay = MAY_LJMP(luaL_checkinteger(L, 1)) * 1000;
6224 	wakeup_ms = tick_add(now_ms, delay);
6225 	lua_pushinteger(L, wakeup_ms);
6226 
6227 	MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_sleep_yield, wakeup_ms, 0));
6228 	return 0;
6229 }
6230 
hlua_msleep(lua_State * L)6231 __LJMP static int hlua_msleep(lua_State *L)
6232 {
6233 	unsigned int delay;
6234 	unsigned int wakeup_ms;
6235 
6236 	MAY_LJMP(check_args(L, 1, "msleep"));
6237 
6238 	delay = MAY_LJMP(luaL_checkinteger(L, 1));
6239 	wakeup_ms = tick_add(now_ms, delay);
6240 	lua_pushinteger(L, wakeup_ms);
6241 
6242 	MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_sleep_yield, wakeup_ms, 0));
6243 	return 0;
6244 }
6245 
6246 /* This functionis an LUA binding. it permits to give back
6247  * the hand at the HAProxy scheduler. It is used when the
6248  * LUA processing consumes a lot of time.
6249  */
hlua_yield_yield(lua_State * L,int status,lua_KContext ctx)6250 __LJMP static int hlua_yield_yield(lua_State *L, int status, lua_KContext ctx)
6251 {
6252 	return 0;
6253 }
6254 
hlua_yield(lua_State * L)6255 __LJMP static int hlua_yield(lua_State *L)
6256 {
6257 	MAY_LJMP(hlua_yieldk(L, 0, 0, hlua_yield_yield, TICK_ETERNITY, HLUA_CTRLYIELD));
6258 	return 0;
6259 }
6260 
6261 /* This function change the nice of the currently executed
6262  * task. It is used set low or high priority at the current
6263  * task.
6264  */
hlua_set_nice(lua_State * L)6265 __LJMP static int hlua_set_nice(lua_State *L)
6266 {
6267 	struct hlua *hlua;
6268 	int nice;
6269 
6270 	MAY_LJMP(check_args(L, 1, "set_nice"));
6271 	hlua = hlua_gethlua(L);
6272 	nice = MAY_LJMP(luaL_checkinteger(L, 1));
6273 
6274 	/* If he task is not set, I'm in a start mode. */
6275 	if (!hlua || !hlua->task)
6276 		return 0;
6277 
6278 	if (nice < -1024)
6279 		nice = -1024;
6280 	else if (nice > 1024)
6281 		nice = 1024;
6282 
6283 	hlua->task->nice = nice;
6284 	return 0;
6285 }
6286 
6287 /* This function is used as a callback of a task. It is called by the
6288  * HAProxy task subsystem when the task is awaked. The LUA runtime can
6289  * return an E_AGAIN signal, the emmiter of this signal must set a
6290  * signal to wake the task.
6291  *
6292  * Task wrapper are longjmp safe because the only one Lua code
6293  * executed is the safe hlua_ctx_resume();
6294  */
hlua_process_task(struct task * task,void * context,unsigned short state)6295 struct task *hlua_process_task(struct task *task, void *context, unsigned short state)
6296 {
6297 	struct hlua *hlua = context;
6298 	enum hlua_exec status;
6299 
6300 	if (task->thread_mask == MAX_THREADS_MASK)
6301 		task_set_affinity(task, tid_bit);
6302 
6303 	/* If it is the first call to the task, we must initialize the
6304 	 * execution timeouts.
6305 	 */
6306 	if (!HLUA_IS_RUNNING(hlua))
6307 		hlua->max_time = hlua_timeout_task;
6308 
6309 	/* Execute the Lua code. */
6310 	status = hlua_ctx_resume(hlua, 1);
6311 
6312 	switch (status) {
6313 	/* finished or yield */
6314 	case HLUA_E_OK:
6315 		hlua_ctx_destroy(hlua);
6316 		task_destroy(task);
6317 		task = NULL;
6318 		break;
6319 
6320 	case HLUA_E_AGAIN: /* co process or timeout wake me later. */
6321 		notification_gc(&hlua->com);
6322 		task->expire = hlua->wake_time;
6323 		break;
6324 
6325 	/* finished with error. */
6326 	case HLUA_E_ERRMSG:
6327 		SEND_ERR(NULL, "Lua task: %s.\n", lua_tostring(hlua->T, -1));
6328 		hlua_ctx_destroy(hlua);
6329 		task_destroy(task);
6330 		task = NULL;
6331 		break;
6332 
6333 	case HLUA_E_ERR:
6334 	default:
6335 		SEND_ERR(NULL, "Lua task: unknown error.\n");
6336 		hlua_ctx_destroy(hlua);
6337 		task_destroy(task);
6338 		task = NULL;
6339 		break;
6340 	}
6341 	return task;
6342 }
6343 
6344 /* This function is an LUA binding that register LUA function to be
6345  * executed after the HAProxy configuration parsing and before the
6346  * HAProxy scheduler starts. This function expect only one LUA
6347  * argument that is a function. This function returns nothing, but
6348  * throws if an error is encountered.
6349  */
hlua_register_init(lua_State * L)6350 __LJMP static int hlua_register_init(lua_State *L)
6351 {
6352 	struct hlua_init_function *init;
6353 	int ref;
6354 
6355 	MAY_LJMP(check_args(L, 1, "register_init"));
6356 
6357 	ref = MAY_LJMP(hlua_checkfunction(L, 1));
6358 
6359 	init = calloc(1, sizeof(*init));
6360 	if (!init)
6361 		WILL_LJMP(luaL_error(L, "Lua out of memory error."));
6362 
6363 	init->function_ref = ref;
6364 	LIST_ADDQ(&hlua_init_functions, &init->l);
6365 	return 0;
6366 }
6367 
6368 /* This functio is an LUA binding. It permits to register a task
6369  * executed in parallel of the main HAroxy activity. The task is
6370  * created and it is set in the HAProxy scheduler. It can be called
6371  * from the "init" section, "post init" or during the runtime.
6372  *
6373  * Lua prototype:
6374  *
6375  *   <none> core.register_task(<function>)
6376  */
hlua_register_task(lua_State * L)6377 static int hlua_register_task(lua_State *L)
6378 {
6379 	struct hlua *hlua;
6380 	struct task *task;
6381 	int ref;
6382 
6383 	MAY_LJMP(check_args(L, 1, "register_task"));
6384 
6385 	ref = MAY_LJMP(hlua_checkfunction(L, 1));
6386 
6387 	hlua = pool_alloc(pool_head_hlua);
6388 	if (!hlua)
6389 		WILL_LJMP(luaL_error(L, "Lua out of memory error."));
6390 	HLUA_INIT(hlua);
6391 
6392 	task = task_new(MAX_THREADS_MASK);
6393 	if (!task)
6394 		WILL_LJMP(luaL_error(L, "Lua out of memory error."));
6395 
6396 	task->context = hlua;
6397 	task->process = hlua_process_task;
6398 
6399 	if (!hlua_ctx_init(hlua, task, 1))
6400 		WILL_LJMP(luaL_error(L, "Lua out of memory error."));
6401 
6402 	/* Restore the function in the stack. */
6403 	lua_rawgeti(hlua->T, LUA_REGISTRYINDEX, ref);
6404 	hlua->nargs = 0;
6405 
6406 	/* Schedule task. */
6407 	task_wakeup(task, TASK_WOKEN_INIT);
6408 
6409 	return 0;
6410 }
6411 
6412 /* Wrapper called by HAProxy to execute an LUA converter. This wrapper
6413  * doesn't allow "yield" functions because the HAProxy engine cannot
6414  * resume converters.
6415  */
hlua_sample_conv_wrapper(const struct arg * arg_p,struct sample * smp,void * private)6416 static int hlua_sample_conv_wrapper(const struct arg *arg_p, struct sample *smp, void *private)
6417 {
6418 	struct hlua_function *fcn = private;
6419 	struct stream *stream = smp->strm;
6420 	const char *error;
6421 
6422 	if (!stream)
6423 		return 0;
6424 
6425 	/* In the execution wrappers linked with a stream, the
6426 	 * Lua context can be not initialized. This behavior
6427 	 * permits to save performances because a systematic
6428 	 * Lua initialization cause 5% performances loss.
6429 	 */
6430 	if (!stream->hlua) {
6431 		struct hlua *hlua;
6432 
6433 		hlua = pool_alloc(pool_head_hlua);
6434 		if (!hlua) {
6435 			SEND_ERR(stream->be, "Lua converter '%s': can't initialize Lua context.\n", fcn->name);
6436 			return 0;
6437 		}
6438 		HLUA_INIT(hlua);
6439 		stream->hlua = hlua;
6440 		if (!hlua_ctx_init(stream->hlua, stream->task, 0)) {
6441 			SEND_ERR(stream->be, "Lua converter '%s': can't initialize Lua context.\n", fcn->name);
6442 			return 0;
6443 		}
6444 	}
6445 
6446 	/* If it is the first run, initialize the data for the call. */
6447 	if (!HLUA_IS_RUNNING(stream->hlua)) {
6448 
6449 		/* The following Lua calls can fail. */
6450 		if (!SET_SAFE_LJMP(stream->hlua->T)) {
6451 			if (lua_type(stream->hlua->T, -1) == LUA_TSTRING)
6452 				error = lua_tostring(stream->hlua->T, -1);
6453 			else
6454 				error = "critical error";
6455 			SEND_ERR(stream->be, "Lua converter '%s': %s.\n", fcn->name, error);
6456 			return 0;
6457 		}
6458 
6459 		/* Check stack available size. */
6460 		if (!lua_checkstack(stream->hlua->T, 1)) {
6461 			SEND_ERR(stream->be, "Lua converter '%s': full stack.\n", fcn->name);
6462 			RESET_SAFE_LJMP(stream->hlua->T);
6463 			return 0;
6464 		}
6465 
6466 		/* Restore the function in the stack. */
6467 		lua_rawgeti(stream->hlua->T, LUA_REGISTRYINDEX, fcn->function_ref);
6468 
6469 		/* convert input sample and pust-it in the stack. */
6470 		if (!lua_checkstack(stream->hlua->T, 1)) {
6471 			SEND_ERR(stream->be, "Lua converter '%s': full stack.\n", fcn->name);
6472 			RESET_SAFE_LJMP(stream->hlua->T);
6473 			return 0;
6474 		}
6475 		hlua_smp2lua(stream->hlua->T, smp);
6476 		stream->hlua->nargs = 1;
6477 
6478 		/* push keywords in the stack. */
6479 		if (arg_p) {
6480 			for (; arg_p->type != ARGT_STOP; arg_p++) {
6481 				if (!lua_checkstack(stream->hlua->T, 1)) {
6482 					SEND_ERR(stream->be, "Lua converter '%s': full stack.\n", fcn->name);
6483 					RESET_SAFE_LJMP(stream->hlua->T);
6484 					return 0;
6485 				}
6486 				hlua_arg2lua(stream->hlua->T, arg_p);
6487 				stream->hlua->nargs++;
6488 			}
6489 		}
6490 
6491 		/* We must initialize the execution timeouts. */
6492 		stream->hlua->max_time = hlua_timeout_session;
6493 
6494 		/* At this point the execution is safe. */
6495 		RESET_SAFE_LJMP(stream->hlua->T);
6496 	}
6497 
6498 	/* Execute the function. */
6499 	switch (hlua_ctx_resume(stream->hlua, 0)) {
6500 	/* finished. */
6501 	case HLUA_E_OK:
6502 		/* If the stack is empty, the function fails. */
6503 		if (lua_gettop(stream->hlua->T) <= 0)
6504 			return 0;
6505 
6506 		/* Convert the returned value in sample. */
6507 		hlua_lua2smp(stream->hlua->T, -1, smp);
6508 		lua_pop(stream->hlua->T, 1);
6509 		return 1;
6510 
6511 	/* yield. */
6512 	case HLUA_E_AGAIN:
6513 		SEND_ERR(stream->be, "Lua converter '%s': cannot use yielded functions.\n", fcn->name);
6514 		return 0;
6515 
6516 	/* finished with error. */
6517 	case HLUA_E_ERRMSG:
6518 		/* Display log. */
6519 		SEND_ERR(stream->be, "Lua converter '%s': %s.\n",
6520 		         fcn->name, lua_tostring(stream->hlua->T, -1));
6521 		lua_pop(stream->hlua->T, 1);
6522 		return 0;
6523 
6524 	case HLUA_E_ETMOUT:
6525 		SEND_ERR(stream->be, "Lua converter '%s': execution timeout.\n", fcn->name);
6526 		return 0;
6527 
6528 	case HLUA_E_NOMEM:
6529 		SEND_ERR(stream->be, "Lua converter '%s': out of memory error.\n", fcn->name);
6530 		return 0;
6531 
6532 	case HLUA_E_YIELD:
6533 		SEND_ERR(stream->be, "Lua converter '%s': yield functions like core.tcp() or core.sleep() are not allowed.\n", fcn->name);
6534 		return 0;
6535 
6536 	case HLUA_E_ERR:
6537 		/* Display log. */
6538 		SEND_ERR(stream->be, "Lua converter '%s' returns an unknown error.\n", fcn->name);
6539 
6540 	default:
6541 		return 0;
6542 	}
6543 }
6544 
6545 /* Wrapper called by HAProxy to execute a sample-fetch. this wrapper
6546  * doesn't allow "yield" functions because the HAProxy engine cannot
6547  * resume sample-fetches. This function will be called by the sample
6548  * fetch engine to call lua-based fetch operations.
6549  */
hlua_sample_fetch_wrapper(const struct arg * arg_p,struct sample * smp,const char * kw,void * private)6550 static int hlua_sample_fetch_wrapper(const struct arg *arg_p, struct sample *smp,
6551                                      const char *kw, void *private)
6552 {
6553 	struct hlua_function *fcn = private;
6554 	struct stream *stream = smp->strm;
6555 	const char *error;
6556 	const struct buffer msg = { };
6557 	unsigned int hflags = HLUA_TXN_NOTERM;
6558 
6559 	if (!stream)
6560 		return 0;
6561 
6562 	/* In the execution wrappers linked with a stream, the
6563 	 * Lua context can be not initialized. This behavior
6564 	 * permits to save performances because a systematic
6565 	 * Lua initialization cause 5% performances loss.
6566 	 */
6567 	if (!stream->hlua) {
6568 		struct hlua *hlua;
6569 
6570 		hlua = pool_alloc(pool_head_hlua);
6571 		if (!hlua) {
6572 			SEND_ERR(stream->be, "Lua sample-fetch '%s': can't initialize Lua context.\n", fcn->name);
6573 			return 0;
6574 		}
6575 		hlua->T = NULL;
6576 		stream->hlua = hlua;
6577 		if (!hlua_ctx_init(stream->hlua, stream->task, 0)) {
6578 			SEND_ERR(stream->be, "Lua sample-fetch '%s': can't initialize Lua context.\n", fcn->name);
6579 			return 0;
6580 		}
6581 	}
6582 
6583 	consistency_set(stream, smp->opt, &stream->hlua->cons);
6584 
6585 	if (stream->be->mode == PR_MODE_HTTP) {
6586 		if ((smp->opt & SMP_OPT_DIR) == SMP_OPT_DIR_REQ)
6587 			hflags |= ((stream->txn->req.msg_state < HTTP_MSG_BODY) ? 0 : HLUA_TXN_HTTP_RDY);
6588 		else
6589 			hflags |= ((stream->txn->rsp.msg_state < HTTP_MSG_BODY) ? 0 : HLUA_TXN_HTTP_RDY);
6590 	}
6591 
6592 	/* If it is the first run, initialize the data for the call. */
6593 	if (!HLUA_IS_RUNNING(stream->hlua)) {
6594 
6595 		/* The following Lua calls can fail. */
6596 		if (!SET_SAFE_LJMP(stream->hlua->T)) {
6597 			if (lua_type(stream->hlua->T, -1) == LUA_TSTRING)
6598 				error = lua_tostring(stream->hlua->T, -1);
6599 			else
6600 				error = "critical error";
6601 			SEND_ERR(smp->px, "Lua sample-fetch '%s': %s.\n", fcn->name, error);
6602 			return 0;
6603 		}
6604 
6605 		/* Check stack available size. */
6606 		if (!lua_checkstack(stream->hlua->T, 2)) {
6607 			SEND_ERR(smp->px, "Lua sample-fetch '%s': full stack.\n", fcn->name);
6608 			RESET_SAFE_LJMP(stream->hlua->T);
6609 			return 0;
6610 		}
6611 
6612 		/* Restore the function in the stack. */
6613 		lua_rawgeti(stream->hlua->T, LUA_REGISTRYINDEX, fcn->function_ref);
6614 
6615 		/* push arguments in the stack. */
6616 		if (!hlua_txn_new(stream->hlua->T, stream, smp->px, smp->opt & SMP_OPT_DIR, hflags)) {
6617 			SEND_ERR(smp->px, "Lua sample-fetch '%s': full stack.\n", fcn->name);
6618 			RESET_SAFE_LJMP(stream->hlua->T);
6619 			return 0;
6620 		}
6621 		stream->hlua->nargs = 1;
6622 
6623 		/* push keywords in the stack. */
6624 		for (; arg_p && arg_p->type != ARGT_STOP; arg_p++) {
6625 			/* Check stack available size. */
6626 			if (!lua_checkstack(stream->hlua->T, 1)) {
6627 				SEND_ERR(smp->px, "Lua sample-fetch '%s': full stack.\n", fcn->name);
6628 				RESET_SAFE_LJMP(stream->hlua->T);
6629 				return 0;
6630 			}
6631 			hlua_arg2lua(stream->hlua->T, arg_p);
6632 			stream->hlua->nargs++;
6633 		}
6634 
6635 		/* We must initialize the execution timeouts. */
6636 		stream->hlua->max_time = hlua_timeout_session;
6637 
6638 		/* At this point the execution is safe. */
6639 		RESET_SAFE_LJMP(stream->hlua->T);
6640 	}
6641 
6642 	/* Execute the function. */
6643 	switch (hlua_ctx_resume(stream->hlua, 0)) {
6644 	/* finished. */
6645 	case HLUA_E_OK:
6646 		if (!consistency_check(stream, smp->opt, &stream->hlua->cons)) {
6647 			si_retnclose(&stream->si[0], &msg);
6648 			return 0;
6649 		}
6650 		/* If the stack is empty, the function fails. */
6651 		if (lua_gettop(stream->hlua->T) <= 0)
6652 			return 0;
6653 
6654 		/* Convert the returned value in sample. */
6655 		hlua_lua2smp(stream->hlua->T, -1, smp);
6656 		lua_pop(stream->hlua->T, 1);
6657 
6658 		/* Set the end of execution flag. */
6659 		smp->flags &= ~SMP_F_MAY_CHANGE;
6660 		return 1;
6661 
6662 	/* yield. */
6663 	case HLUA_E_AGAIN:
6664 		if (!consistency_check(stream, smp->opt, &stream->hlua->cons))
6665 			si_retnclose(&stream->si[0], &msg);
6666 		SEND_ERR(smp->px, "Lua sample-fetch '%s': cannot use yielded functions.\n", fcn->name);
6667 		return 0;
6668 
6669 	/* finished with error. */
6670 	case HLUA_E_ERRMSG:
6671 		if (!consistency_check(stream, smp->opt, &stream->hlua->cons))
6672 			si_retnclose(&stream->si[0], &msg);
6673 		/* Display log. */
6674 		SEND_ERR(smp->px, "Lua sample-fetch '%s': %s.\n",
6675 		         fcn->name, lua_tostring(stream->hlua->T, -1));
6676 		lua_pop(stream->hlua->T, 1);
6677 		return 0;
6678 
6679 	case HLUA_E_ETMOUT:
6680 		if (!consistency_check(stream, smp->opt, &stream->hlua->cons))
6681 			si_retnclose(&stream->si[0], &msg);
6682 		SEND_ERR(smp->px, "Lua sample-fetch '%s': execution timeout.\n", fcn->name);
6683 		return 0;
6684 
6685 	case HLUA_E_NOMEM:
6686 		if (!consistency_check(stream, smp->opt, &stream->hlua->cons))
6687 			si_retnclose(&stream->si[0], &msg);
6688 		SEND_ERR(smp->px, "Lua sample-fetch '%s': out of memory error.\n", fcn->name);
6689 		return 0;
6690 
6691 	case HLUA_E_YIELD:
6692 		if (!consistency_check(stream, smp->opt, &stream->hlua->cons))
6693 			si_retnclose(&stream->si[0], &msg);
6694 		SEND_ERR(smp->px, "Lua sample-fetch '%s': yield not allowed.\n", fcn->name);
6695 		return 0;
6696 
6697 	case HLUA_E_ERR:
6698 		if (!consistency_check(stream, smp->opt, &stream->hlua->cons))
6699 			si_retnclose(&stream->si[0], &msg);
6700 		/* Display log. */
6701 		SEND_ERR(smp->px, "Lua sample-fetch '%s' returns an unknown error.\n", fcn->name);
6702 
6703 	default:
6704 		return 0;
6705 	}
6706 }
6707 
6708 /* This function is an LUA binding used for registering
6709  * "sample-conv" functions. It expects a converter name used
6710  * in the haproxy configuration file, and an LUA function.
6711  */
hlua_register_converters(lua_State * L)6712 __LJMP static int hlua_register_converters(lua_State *L)
6713 {
6714 	struct sample_conv_kw_list *sck;
6715 	const char *name;
6716 	int ref;
6717 	int len;
6718 	struct hlua_function *fcn;
6719 	struct sample_conv *sc;
6720 	struct buffer *trash;
6721 
6722 	MAY_LJMP(check_args(L, 2, "register_converters"));
6723 
6724 	/* First argument : converter name. */
6725 	name = MAY_LJMP(luaL_checkstring(L, 1));
6726 
6727 	/* Second argument : lua function. */
6728 	ref = MAY_LJMP(hlua_checkfunction(L, 2));
6729 
6730 	/* Check if the converter is already registered */
6731 	trash = get_trash_chunk();
6732 	chunk_printf(trash, "lua.%s", name);
6733 	sc = find_sample_conv(trash->area, trash->data);
6734 	if (sc != NULL) {
6735 		ha_warning("Trying to register converter 'lua.%s' more than once. "
6736 		           "This will become a hard error in version 2.5.\n", name);
6737 	}
6738 
6739 	/* Allocate and fill the sample fetch keyword struct. */
6740 	sck = calloc(1, sizeof(*sck) + sizeof(struct sample_conv) * 2);
6741 	if (!sck)
6742 		WILL_LJMP(luaL_error(L, "Lua out of memory error."));
6743 	fcn = calloc(1, sizeof(*fcn));
6744 	if (!fcn)
6745 		WILL_LJMP(luaL_error(L, "Lua out of memory error."));
6746 
6747 	/* Fill fcn. */
6748 	fcn->name = strdup(name);
6749 	if (!fcn->name)
6750 		WILL_LJMP(luaL_error(L, "Lua out of memory error."));
6751 	fcn->function_ref = ref;
6752 
6753 	/* List head */
6754 	sck->list.n = sck->list.p = NULL;
6755 
6756 	/* converter keyword. */
6757 	len = strlen("lua.") + strlen(name) + 1;
6758 	sck->kw[0].kw = calloc(1, len);
6759 	if (!sck->kw[0].kw)
6760 		WILL_LJMP(luaL_error(L, "Lua out of memory error."));
6761 
6762 	snprintf((char *)sck->kw[0].kw, len, "lua.%s", name);
6763 	sck->kw[0].process = hlua_sample_conv_wrapper;
6764 	sck->kw[0].arg_mask = ARG12(0,STR,STR,STR,STR,STR,STR,STR,STR,STR,STR,STR,STR);
6765 	sck->kw[0].val_args = NULL;
6766 	sck->kw[0].in_type = SMP_T_STR;
6767 	sck->kw[0].out_type = SMP_T_STR;
6768 	sck->kw[0].private = fcn;
6769 
6770 	/* Register this new converter */
6771 	sample_register_convs(sck);
6772 
6773 	return 0;
6774 }
6775 
6776 /* This function is an LUA binding used for registering
6777  * "sample-fetch" functions. It expects a converter name used
6778  * in the haproxy configuration file, and an LUA function.
6779  */
hlua_register_fetches(lua_State * L)6780 __LJMP static int hlua_register_fetches(lua_State *L)
6781 {
6782 	const char *name;
6783 	int ref;
6784 	int len;
6785 	struct sample_fetch_kw_list *sfk;
6786 	struct hlua_function *fcn;
6787 	struct sample_fetch *sf;
6788 	struct buffer *trash;
6789 
6790 	MAY_LJMP(check_args(L, 2, "register_fetches"));
6791 
6792 	/* First argument : sample-fetch name. */
6793 	name = MAY_LJMP(luaL_checkstring(L, 1));
6794 
6795 	/* Second argument : lua function. */
6796 	ref = MAY_LJMP(hlua_checkfunction(L, 2));
6797 
6798 	/* Check if the sample-fetch is already registered */
6799 	trash = get_trash_chunk();
6800 	chunk_printf(trash, "lua.%s", name);
6801 	sf = find_sample_fetch(trash->area, trash->data);
6802 	if (sf != NULL) {
6803 		ha_warning("Trying to register sample-fetch 'lua.%s' more than once. "
6804 		           "This will become a hard error in version 2.5.\n", name);
6805 	}
6806 
6807 	/* Allocate and fill the sample fetch keyword struct. */
6808 	sfk = calloc(1, sizeof(*sfk) + sizeof(struct sample_fetch) * 2);
6809 	if (!sfk)
6810 		WILL_LJMP(luaL_error(L, "Lua out of memory error."));
6811 	fcn = calloc(1, sizeof(*fcn));
6812 	if (!fcn)
6813 		WILL_LJMP(luaL_error(L, "Lua out of memory error."));
6814 
6815 	/* Fill fcn. */
6816 	fcn->name = strdup(name);
6817 	if (!fcn->name)
6818 		WILL_LJMP(luaL_error(L, "Lua out of memory error."));
6819 	fcn->function_ref = ref;
6820 
6821 	/* List head */
6822 	sfk->list.n = sfk->list.p = NULL;
6823 
6824 	/* sample-fetch keyword. */
6825 	len = strlen("lua.") + strlen(name) + 1;
6826 	sfk->kw[0].kw = calloc(1, len);
6827 	if (!sfk->kw[0].kw)
6828 		return luaL_error(L, "Lua out of memory error.");
6829 
6830 	snprintf((char *)sfk->kw[0].kw, len, "lua.%s", name);
6831 	sfk->kw[0].process = hlua_sample_fetch_wrapper;
6832 	sfk->kw[0].arg_mask = ARG12(0,STR,STR,STR,STR,STR,STR,STR,STR,STR,STR,STR,STR);
6833 	sfk->kw[0].val_args = NULL;
6834 	sfk->kw[0].out_type = SMP_T_STR;
6835 	sfk->kw[0].use = SMP_USE_HTTP_ANY;
6836 	sfk->kw[0].val = 0;
6837 	sfk->kw[0].private = fcn;
6838 
6839 	/* Register this new fetch. */
6840 	sample_register_fetches(sfk);
6841 
6842 	return 0;
6843 }
6844 
6845 /* This function is a wrapper to execute each LUA function declared
6846  * as an action wrapper during the initialisation period. This function
6847  * return ACT_RET_CONT if the processing is finished (with or without
6848  * error) and return ACT_RET_YIELD if the function must be called again
6849  * because the LUA returns a yield.
6850  */
hlua_action(struct act_rule * rule,struct proxy * px,struct session * sess,struct stream * s,int flags)6851 static enum act_return hlua_action(struct act_rule *rule, struct proxy *px,
6852                                    struct session *sess, struct stream *s, int flags)
6853 {
6854 	char **arg;
6855 	unsigned int hflags = 0;
6856 	int dir;
6857 	const char *error;
6858 	const struct buffer msg = { };
6859 
6860 	switch (rule->from) {
6861 	case ACT_F_TCP_REQ_CNT:                            ; dir = SMP_OPT_DIR_REQ; break;
6862 	case ACT_F_TCP_RES_CNT:                            ; dir = SMP_OPT_DIR_RES; break;
6863 	case ACT_F_HTTP_REQ:    hflags = HLUA_TXN_HTTP_RDY ; dir = SMP_OPT_DIR_REQ; break;
6864 	case ACT_F_HTTP_RES:    hflags = HLUA_TXN_HTTP_RDY ; dir = SMP_OPT_DIR_RES; break;
6865 	default:
6866 		SEND_ERR(px, "Lua: internal error while execute action.\n");
6867 		return ACT_RET_CONT;
6868 	}
6869 
6870 	/* In the execution wrappers linked with a stream, the
6871 	 * Lua context can be not initialized. This behavior
6872 	 * permits to save performances because a systematic
6873 	 * Lua initialization cause 5% performances loss.
6874 	 */
6875 	if (!s->hlua) {
6876 		struct hlua *hlua;
6877 
6878 		hlua = pool_alloc(pool_head_hlua);
6879 		if (!hlua) {
6880 			SEND_ERR(px, "Lua action '%s': can't initialize Lua context.\n",
6881 			         rule->arg.hlua_rule->fcn.name);
6882 			return ACT_RET_CONT;
6883 		}
6884 		HLUA_INIT(hlua);
6885 		s->hlua = hlua;
6886 		if (!hlua_ctx_init(s->hlua, s->task, 0)) {
6887 			SEND_ERR(px, "Lua action '%s': can't initialize Lua context.\n",
6888 			         rule->arg.hlua_rule->fcn.name);
6889 			return ACT_RET_CONT;
6890 		}
6891 	}
6892 
6893 	consistency_set(s, dir, &s->hlua->cons);
6894 
6895 	/* If it is the first run, initialize the data for the call. */
6896 	if (!HLUA_IS_RUNNING(s->hlua)) {
6897 
6898 		/* The following Lua calls can fail. */
6899 		if (!SET_SAFE_LJMP(s->hlua->T)) {
6900 			if (lua_type(s->hlua->T, -1) == LUA_TSTRING)
6901 				error = lua_tostring(s->hlua->T, -1);
6902 			else
6903 				error = "critical error";
6904 			SEND_ERR(px, "Lua function '%s': %s.\n",
6905 			         rule->arg.hlua_rule->fcn.name, error);
6906 			return ACT_RET_CONT;
6907 		}
6908 
6909 		/* Check stack available size. */
6910 		if (!lua_checkstack(s->hlua->T, 1)) {
6911 			SEND_ERR(px, "Lua function '%s': full stack.\n",
6912 			         rule->arg.hlua_rule->fcn.name);
6913 			RESET_SAFE_LJMP(s->hlua->T);
6914 			return ACT_RET_CONT;
6915 		}
6916 
6917 		/* Restore the function in the stack. */
6918 		lua_rawgeti(s->hlua->T, LUA_REGISTRYINDEX, rule->arg.hlua_rule->fcn.function_ref);
6919 
6920 		/* Create and and push object stream in the stack. */
6921 		if (!hlua_txn_new(s->hlua->T, s, px, dir, hflags)) {
6922 			SEND_ERR(px, "Lua function '%s': full stack.\n",
6923 			         rule->arg.hlua_rule->fcn.name);
6924 			RESET_SAFE_LJMP(s->hlua->T);
6925 			return ACT_RET_CONT;
6926 		}
6927 		s->hlua->nargs = 1;
6928 
6929 		/* push keywords in the stack. */
6930 		for (arg = rule->arg.hlua_rule->args; arg && *arg; arg++) {
6931 			if (!lua_checkstack(s->hlua->T, 1)) {
6932 				SEND_ERR(px, "Lua function '%s': full stack.\n",
6933 				         rule->arg.hlua_rule->fcn.name);
6934 				RESET_SAFE_LJMP(s->hlua->T);
6935 				return ACT_RET_CONT;
6936 			}
6937 			lua_pushstring(s->hlua->T, *arg);
6938 			s->hlua->nargs++;
6939 		}
6940 
6941 		/* Now the execution is safe. */
6942 		RESET_SAFE_LJMP(s->hlua->T);
6943 
6944 		/* We must initialize the execution timeouts. */
6945 		s->hlua->max_time = hlua_timeout_session;
6946 	}
6947 
6948 	/* Always reset the analyse expiration timeout for the corresponding
6949 	 * channel in case the lua script yield, to be sure to not keep an
6950 	 * expired timeout.
6951 	 */
6952 	if (dir == SMP_OPT_DIR_REQ)
6953 		s->req.analyse_exp = TICK_ETERNITY;
6954 	else
6955 		s->res.analyse_exp = TICK_ETERNITY;
6956 
6957 	/* Execute the function. */
6958 	switch (hlua_ctx_resume(s->hlua, !(flags & ACT_FLAG_FINAL))) {
6959 	/* finished. */
6960 	case HLUA_E_OK:
6961 		if (!consistency_check(s, dir, &s->hlua->cons)) {
6962 			si_retnclose(&s->si[0], &msg);
6963 			return ACT_RET_ERR;
6964 		}
6965 		if (s->hlua->flags & HLUA_STOP)
6966 			return ACT_RET_DONE;
6967 		return ACT_RET_CONT;
6968 
6969 	/* yield. */
6970 	case HLUA_E_AGAIN:
6971 		/* Set timeout in the required channel. */
6972 		if (s->hlua->wake_time != TICK_ETERNITY) {
6973 			if (dir == SMP_OPT_DIR_REQ)
6974 				s->req.analyse_exp = s->hlua->wake_time;
6975 			else
6976 				s->res.analyse_exp = s->hlua->wake_time;
6977 		}
6978 		/* Some actions can be wake up when a "write" event
6979 		 * is detected on a response channel. This is useful
6980 		 * only for actions targeted on the requests.
6981 		 */
6982 		if (HLUA_IS_WAKERESWR(s->hlua))
6983 			s->res.flags |= CF_WAKE_WRITE;
6984 		if (HLUA_IS_WAKEREQWR(s->hlua))
6985 			s->req.flags |= CF_WAKE_WRITE;
6986 		/* We can quit the function without consistency check
6987 		 * because HAProxy is not able to manipulate data, it
6988 		 * is only allowed to call me again. */
6989 		return ACT_RET_YIELD;
6990 
6991 	/* finished with error. */
6992 	case HLUA_E_ERRMSG:
6993 		if (!consistency_check(s, dir, &s->hlua->cons)) {
6994 			si_retnclose(&s->si[0], &msg);
6995 			return ACT_RET_ERR;
6996 		}
6997 		/* Display log. */
6998 		SEND_ERR(px, "Lua function '%s': %s.\n",
6999 		         rule->arg.hlua_rule->fcn.name, lua_tostring(s->hlua->T, -1));
7000 		lua_pop(s->hlua->T, 1);
7001 		return ACT_RET_CONT;
7002 
7003 	case HLUA_E_ETMOUT:
7004 		if (!consistency_check(s, dir, &s->hlua->cons)) {
7005 			si_retnclose(&s->si[0], &msg);
7006 			return ACT_RET_ERR;
7007 		}
7008 		SEND_ERR(px, "Lua function '%s': execution timeout.\n", rule->arg.hlua_rule->fcn.name);
7009 		return 0;
7010 
7011 	case HLUA_E_NOMEM:
7012 		if (!consistency_check(s, dir, &s->hlua->cons)) {
7013 			si_retnclose(&s->si[0], &msg);
7014 			return ACT_RET_ERR;
7015 		}
7016 		SEND_ERR(px, "Lua function '%s': out of memory error.\n", rule->arg.hlua_rule->fcn.name);
7017 		return 0;
7018 
7019 	case HLUA_E_YIELD:
7020 		if (!consistency_check(s, dir, &s->hlua->cons)) {
7021 			si_retnclose(&s->si[0], &msg);
7022 			return ACT_RET_ERR;
7023 		}
7024 		SEND_ERR(px, "Lua function '%s': aborting Lua processing on expired timeout.\n",
7025 		         rule->arg.hlua_rule->fcn.name);
7026 		return 0;
7027 
7028 	case HLUA_E_ERR:
7029 		if (!consistency_check(s, dir, &s->hlua->cons)) {
7030 			si_retnclose(&s->si[0], &msg);
7031 			return ACT_RET_ERR;
7032 		}
7033 		/* Display log. */
7034 		SEND_ERR(px, "Lua function '%s' return an unknown error.\n",
7035 		         rule->arg.hlua_rule->fcn.name);
7036 
7037 	default:
7038 		return ACT_RET_CONT;
7039 	}
7040 }
7041 
hlua_applet_wakeup(struct task * t,void * context,unsigned short state)7042 struct task *hlua_applet_wakeup(struct task *t, void *context, unsigned short state)
7043 {
7044 	struct appctx *ctx = context;
7045 
7046 	appctx_wakeup(ctx);
7047 	t->expire = TICK_ETERNITY;
7048 	return t;
7049 }
7050 
hlua_applet_tcp_init(struct appctx * ctx,struct proxy * px,struct stream * strm)7051 static int hlua_applet_tcp_init(struct appctx *ctx, struct proxy *px, struct stream *strm)
7052 {
7053 	struct stream_interface *si = ctx->owner;
7054 	struct hlua *hlua;
7055 	struct task *task;
7056 	char **arg;
7057 	const char *error;
7058 
7059 	hlua = pool_alloc(pool_head_hlua);
7060 	if (!hlua) {
7061 		SEND_ERR(px, "Lua applet tcp '%s': out of memory.\n",
7062 		         ctx->rule->arg.hlua_rule->fcn.name);
7063 		return 0;
7064 	}
7065 	HLUA_INIT(hlua);
7066 	ctx->ctx.hlua_apptcp.hlua = hlua;
7067 	ctx->ctx.hlua_apptcp.flags = 0;
7068 
7069 	/* Create task used by signal to wakeup applets. */
7070 	task = task_new(tid_bit);
7071 	if (!task) {
7072 		SEND_ERR(px, "Lua applet tcp '%s': out of memory.\n",
7073 		         ctx->rule->arg.hlua_rule->fcn.name);
7074 		return 0;
7075 	}
7076 	task->nice = 0;
7077 	task->context = ctx;
7078 	task->process = hlua_applet_wakeup;
7079 	ctx->ctx.hlua_apptcp.task = task;
7080 
7081 	/* In the execution wrappers linked with a stream, the
7082 	 * Lua context can be not initialized. This behavior
7083 	 * permits to save performances because a systematic
7084 	 * Lua initialization cause 5% performances loss.
7085 	 */
7086 	if (!hlua_ctx_init(hlua, task, 0)) {
7087 		SEND_ERR(px, "Lua applet tcp '%s': can't initialize Lua context.\n",
7088 		         ctx->rule->arg.hlua_rule->fcn.name);
7089 		return 0;
7090 	}
7091 
7092 	/* Set timeout according with the applet configuration. */
7093 	hlua->max_time = ctx->applet->timeout;
7094 
7095 	/* The following Lua calls can fail. */
7096 	if (!SET_SAFE_LJMP(hlua->T)) {
7097 		if (lua_type(hlua->T, -1) == LUA_TSTRING)
7098 			error = lua_tostring(hlua->T, -1);
7099 		else
7100 			error = "critical error";
7101 		SEND_ERR(px, "Lua applet tcp '%s': %s.\n",
7102 		         ctx->rule->arg.hlua_rule->fcn.name, error);
7103 		return 0;
7104 	}
7105 
7106 	/* Check stack available size. */
7107 	if (!lua_checkstack(hlua->T, 1)) {
7108 		SEND_ERR(px, "Lua applet tcp '%s': full stack.\n",
7109 		         ctx->rule->arg.hlua_rule->fcn.name);
7110 		RESET_SAFE_LJMP(hlua->T);
7111 		return 0;
7112 	}
7113 
7114 	/* Restore the function in the stack. */
7115 	lua_rawgeti(hlua->T, LUA_REGISTRYINDEX, ctx->rule->arg.hlua_rule->fcn.function_ref);
7116 
7117 	/* Create and and push object stream in the stack. */
7118 	if (!hlua_applet_tcp_new(hlua->T, ctx)) {
7119 		SEND_ERR(px, "Lua applet tcp '%s': full stack.\n",
7120 		         ctx->rule->arg.hlua_rule->fcn.name);
7121 		RESET_SAFE_LJMP(hlua->T);
7122 		return 0;
7123 	}
7124 	hlua->nargs = 1;
7125 
7126 	/* push keywords in the stack. */
7127 	for (arg = ctx->rule->arg.hlua_rule->args; arg && *arg; arg++) {
7128 		if (!lua_checkstack(hlua->T, 1)) {
7129 			SEND_ERR(px, "Lua applet tcp '%s': full stack.\n",
7130 			         ctx->rule->arg.hlua_rule->fcn.name);
7131 			RESET_SAFE_LJMP(hlua->T);
7132 			return 0;
7133 		}
7134 		lua_pushstring(hlua->T, *arg);
7135 		hlua->nargs++;
7136 	}
7137 
7138 	RESET_SAFE_LJMP(hlua->T);
7139 
7140 	/* Wakeup the applet ASAP. */
7141 	si_cant_get(si);
7142 	si_rx_endp_more(si);
7143 
7144 	return 1;
7145 }
7146 
hlua_applet_tcp_fct(struct appctx * ctx)7147 void hlua_applet_tcp_fct(struct appctx *ctx)
7148 {
7149 	struct stream_interface *si = ctx->owner;
7150 	struct stream *strm = si_strm(si);
7151 	struct channel *res = si_ic(si);
7152 	struct act_rule *rule = ctx->rule;
7153 	struct proxy *px = strm->be;
7154 	struct hlua *hlua = ctx->ctx.hlua_apptcp.hlua;
7155 
7156 	/* The applet execution is already done. */
7157 	if (ctx->ctx.hlua_apptcp.flags & APPLET_DONE) {
7158 		/* eat the whole request */
7159 		co_skip(si_oc(si), co_data(si_oc(si)));
7160 		return;
7161 	}
7162 
7163 	/* If the stream is disconnect or closed, ldo nothing. */
7164 	if (unlikely(si->state == SI_ST_DIS || si->state == SI_ST_CLO))
7165 		return;
7166 
7167 	/* Execute the function. */
7168 	switch (hlua_ctx_resume(hlua, 1)) {
7169 	/* finished. */
7170 	case HLUA_E_OK:
7171 		ctx->ctx.hlua_apptcp.flags |= APPLET_DONE;
7172 
7173 		/* eat the whole request */
7174 		co_skip(si_oc(si), co_data(si_oc(si)));
7175 		res->flags |= CF_READ_NULL;
7176 		si_shutr(si);
7177 		return;
7178 
7179 	/* yield. */
7180 	case HLUA_E_AGAIN:
7181 		if (hlua->wake_time != TICK_ETERNITY)
7182 			task_schedule(ctx->ctx.hlua_apptcp.task, hlua->wake_time);
7183 		return;
7184 
7185 	/* finished with error. */
7186 	case HLUA_E_ERRMSG:
7187 		/* Display log. */
7188 		SEND_ERR(px, "Lua applet tcp '%s': %s.\n",
7189 		         rule->arg.hlua_rule->fcn.name, lua_tostring(hlua->T, -1));
7190 		lua_pop(hlua->T, 1);
7191 		goto error;
7192 
7193 	case HLUA_E_ETMOUT:
7194 		SEND_ERR(px, "Lua applet tcp '%s': execution timeout.\n",
7195 		         rule->arg.hlua_rule->fcn.name);
7196 		goto error;
7197 
7198 	case HLUA_E_NOMEM:
7199 		SEND_ERR(px, "Lua applet tcp '%s': out of memory error.\n",
7200 		         rule->arg.hlua_rule->fcn.name);
7201 		goto error;
7202 
7203 	case HLUA_E_YIELD: /* unexpected */
7204 		SEND_ERR(px, "Lua applet tcp '%s': yield not allowed.\n",
7205 		         rule->arg.hlua_rule->fcn.name);
7206 		goto error;
7207 
7208 	case HLUA_E_ERR:
7209 		/* Display log. */
7210 		SEND_ERR(px, "Lua applet tcp '%s' return an unknown error.\n",
7211 		         rule->arg.hlua_rule->fcn.name);
7212 		goto error;
7213 
7214 	default:
7215 		goto error;
7216 	}
7217 
7218 error:
7219 
7220 	/* For all other cases, just close the stream. */
7221 	si_shutw(si);
7222 	si_shutr(si);
7223 	ctx->ctx.hlua_apptcp.flags |= APPLET_DONE;
7224 }
7225 
hlua_applet_tcp_release(struct appctx * ctx)7226 static void hlua_applet_tcp_release(struct appctx *ctx)
7227 {
7228 	task_destroy(ctx->ctx.hlua_apptcp.task);
7229 	ctx->ctx.hlua_apptcp.task = NULL;
7230 	hlua_ctx_destroy(ctx->ctx.hlua_apptcp.hlua);
7231 	ctx->ctx.hlua_apptcp.hlua = NULL;
7232 }
7233 
7234 /* The function returns 1 if the initialisation is complete, 0 if
7235  * an errors occurs and -1 if more data are required for initializing
7236  * the applet.
7237  */
hlua_applet_http_init(struct appctx * ctx,struct proxy * px,struct stream * strm)7238 static int hlua_applet_http_init(struct appctx *ctx, struct proxy *px, struct stream *strm)
7239 {
7240 	struct stream_interface *si = ctx->owner;
7241 	struct http_txn *txn;
7242 	struct hlua *hlua;
7243 	char **arg;
7244 	struct task *task;
7245 	const char *error;
7246 
7247 	txn = strm->txn;
7248 
7249 	/* We want two things in HTTP mode :
7250 	 *  - enforce server-close mode if we were in keep-alive, so that the
7251 	 *    applet is released after each response ;
7252 	 *  - enable request body transfer to the applet in order to resync
7253 	 *    with the response body.
7254 	 */
7255 	if ((txn->flags & TX_CON_WANT_MSK) == TX_CON_WANT_KAL)
7256 		txn->flags = (txn->flags & ~TX_CON_WANT_MSK) | TX_CON_WANT_SCL;
7257 
7258 	hlua = pool_alloc(pool_head_hlua);
7259 	if (!hlua) {
7260 		SEND_ERR(px, "Lua applet http '%s': out of memory.\n",
7261 		         ctx->rule->arg.hlua_rule->fcn.name);
7262 		return 0;
7263 	}
7264 	HLUA_INIT(hlua);
7265 	ctx->ctx.hlua_apphttp.hlua = hlua;
7266 	ctx->ctx.hlua_apphttp.left_bytes = -1;
7267 	ctx->ctx.hlua_apphttp.flags = 0;
7268 
7269 	if (txn->req.flags & HTTP_MSGF_VER_11)
7270 		ctx->ctx.hlua_apphttp.flags |= APPLET_HTTP11;
7271 
7272 	/* Create task used by signal to wakeup applets. */
7273 	task = task_new(tid_bit);
7274 	if (!task) {
7275 		SEND_ERR(px, "Lua applet http '%s': out of memory.\n",
7276 		         ctx->rule->arg.hlua_rule->fcn.name);
7277 		return 0;
7278 	}
7279 	task->nice = 0;
7280 	task->context = ctx;
7281 	task->process = hlua_applet_wakeup;
7282 	ctx->ctx.hlua_apphttp.task = task;
7283 
7284 	/* In the execution wrappers linked with a stream, the
7285 	 * Lua context can be not initialized. This behavior
7286 	 * permits to save performances because a systematic
7287 	 * Lua initialization cause 5% performances loss.
7288 	 */
7289 	if (!hlua_ctx_init(hlua, task, 0)) {
7290 		SEND_ERR(px, "Lua applet http '%s': can't initialize Lua context.\n",
7291 		         ctx->rule->arg.hlua_rule->fcn.name);
7292 		return 0;
7293 	}
7294 
7295 	/* Set timeout according with the applet configuration. */
7296 	hlua->max_time = ctx->applet->timeout;
7297 
7298 	/* The following Lua calls can fail. */
7299 	if (!SET_SAFE_LJMP(hlua->T)) {
7300 		if (lua_type(hlua->T, -1) == LUA_TSTRING)
7301 			error = lua_tostring(hlua->T, -1);
7302 		else
7303 			error = "critical error";
7304 		SEND_ERR(px, "Lua applet http '%s': %s.\n",
7305 		         ctx->rule->arg.hlua_rule->fcn.name, error);
7306 		return 0;
7307 	}
7308 
7309 	/* Check stack available size. */
7310 	if (!lua_checkstack(hlua->T, 1)) {
7311 		SEND_ERR(px, "Lua applet http '%s': full stack.\n",
7312 		         ctx->rule->arg.hlua_rule->fcn.name);
7313 		RESET_SAFE_LJMP(hlua->T);
7314 		return 0;
7315 	}
7316 
7317 	/* Restore the function in the stack. */
7318 	lua_rawgeti(hlua->T, LUA_REGISTRYINDEX, ctx->rule->arg.hlua_rule->fcn.function_ref);
7319 
7320 	/* Create and and push object stream in the stack. */
7321 	if (!hlua_applet_http_new(hlua->T, ctx)) {
7322 		SEND_ERR(px, "Lua applet http '%s': full stack.\n",
7323 		         ctx->rule->arg.hlua_rule->fcn.name);
7324 		RESET_SAFE_LJMP(hlua->T);
7325 		return 0;
7326 	}
7327 	hlua->nargs = 1;
7328 
7329 	/* push keywords in the stack. */
7330 	for (arg = ctx->rule->arg.hlua_rule->args; arg && *arg; arg++) {
7331 		if (!lua_checkstack(hlua->T, 1)) {
7332 			SEND_ERR(px, "Lua applet http '%s': full stack.\n",
7333 			         ctx->rule->arg.hlua_rule->fcn.name);
7334 			RESET_SAFE_LJMP(hlua->T);
7335 			return 0;
7336 		}
7337 		lua_pushstring(hlua->T, *arg);
7338 		hlua->nargs++;
7339 	}
7340 
7341 	RESET_SAFE_LJMP(hlua->T);
7342 
7343 	/* Wakeup the applet when data is ready for read. */
7344 	si_cant_get(si);
7345 
7346 	return 1;
7347 }
7348 
hlua_applet_htx_fct(struct appctx * ctx)7349 static void hlua_applet_htx_fct(struct appctx *ctx)
7350 {
7351 	struct stream_interface *si = ctx->owner;
7352 	struct stream *strm = si_strm(si);
7353 	struct channel *req = si_oc(si);
7354 	struct channel *res = si_ic(si);
7355 	struct act_rule *rule = ctx->rule;
7356 	struct proxy *px = strm->be;
7357 	struct hlua *hlua = ctx->ctx.hlua_apphttp.hlua;
7358 	struct htx *req_htx, *res_htx;
7359 
7360 	res_htx = htx_from_buf(&res->buf);
7361 
7362 	/* If the stream is disconnect or closed, ldo nothing. */
7363 	if (unlikely(si->state == SI_ST_DIS || si->state == SI_ST_CLO))
7364 		goto out;
7365 
7366 	/* Check if the input buffer is avalaible. */
7367 	if (!b_size(&res->buf)) {
7368 		si_rx_room_blk(si);
7369 		goto out;
7370 	}
7371 	/* check that the output is not closed */
7372 	if (res->flags & (CF_SHUTW|CF_SHUTW_NOW|CF_SHUTR))
7373 		ctx->ctx.hlua_apphttp.flags |= APPLET_DONE;
7374 
7375 	/* Set the currently running flag. */
7376 	if (!HLUA_IS_RUNNING(hlua) &&
7377 	    !(ctx->ctx.hlua_apphttp.flags & APPLET_DONE)) {
7378 		struct htx_blk *blk;
7379 		size_t count = co_data(req);
7380 
7381 		if (!count) {
7382 			si_cant_get(si);
7383 			goto out;
7384 		}
7385 
7386 		/* We need to flush the request header. This left the body for
7387 		 * the Lua.
7388 		 */
7389 		req_htx = htx_from_buf(&req->buf);
7390 		blk = htx_get_first_blk(req_htx);
7391 		while (count && blk) {
7392 			enum htx_blk_type type = htx_get_blk_type(blk);
7393 			uint32_t sz = htx_get_blksz(blk);
7394 
7395 			if (sz > count) {
7396 				si_cant_get(si);
7397 				htx_to_buf(req_htx, &req->buf);
7398 				goto out;
7399 			}
7400 
7401 			count -= sz;
7402 			co_set_data(req, co_data(req) - sz);
7403 			blk = htx_remove_blk(req_htx, blk);
7404 
7405 			if (type == HTX_BLK_EOH)
7406 				break;
7407 		}
7408 		htx_to_buf(req_htx, &req->buf);
7409 	}
7410 
7411 	/* Executes The applet if it is not done. */
7412 	if (!(ctx->ctx.hlua_apphttp.flags & APPLET_DONE)) {
7413 
7414 		/* Execute the function. */
7415 		switch (hlua_ctx_resume(hlua, 1)) {
7416 		/* finished. */
7417 		case HLUA_E_OK:
7418 			ctx->ctx.hlua_apphttp.flags |= APPLET_DONE;
7419 			break;
7420 
7421 		/* yield. */
7422 		case HLUA_E_AGAIN:
7423 			if (hlua->wake_time != TICK_ETERNITY)
7424 				task_schedule(ctx->ctx.hlua_apphttp.task, hlua->wake_time);
7425 			goto out;
7426 
7427 		/* finished with error. */
7428 		case HLUA_E_ERRMSG:
7429 			/* Display log. */
7430 			SEND_ERR(px, "Lua applet http '%s': %s.\n",
7431 			         rule->arg.hlua_rule->fcn.name, lua_tostring(hlua->T, -1));
7432 			lua_pop(hlua->T, 1);
7433 			goto error;
7434 
7435 		case HLUA_E_ETMOUT:
7436 			SEND_ERR(px, "Lua applet http '%s': execution timeout.\n",
7437 			         rule->arg.hlua_rule->fcn.name);
7438 			goto error;
7439 
7440 		case HLUA_E_NOMEM:
7441 			SEND_ERR(px, "Lua applet http '%s': out of memory error.\n",
7442 			         rule->arg.hlua_rule->fcn.name);
7443 			goto error;
7444 
7445 		case HLUA_E_YIELD: /* unexpected */
7446 			SEND_ERR(px, "Lua applet http '%s': yield not allowed.\n",
7447 			         rule->arg.hlua_rule->fcn.name);
7448 			goto error;
7449 
7450 		case HLUA_E_ERR:
7451 			/* Display log. */
7452 			SEND_ERR(px, "Lua applet http '%s' return an unknown error.\n",
7453 			         rule->arg.hlua_rule->fcn.name);
7454 			goto error;
7455 
7456 		default:
7457 			goto error;
7458 		}
7459 	}
7460 
7461 	if (ctx->ctx.hlua_apphttp.flags & APPLET_DONE) {
7462 		if (ctx->ctx.hlua_apphttp.flags & APPLET_RSP_SENT)
7463 			goto done;
7464 
7465 		if (!(ctx->ctx.hlua_apphttp.flags & APPLET_HDR_SENT))
7466 			goto error;
7467 
7468 		/* Don't add TLR because mux-h1 will take care of it */
7469 		if (!htx_add_endof(res_htx, HTX_BLK_EOM)) {
7470 			si_rx_room_blk(si);
7471 			goto out;
7472 		}
7473 		channel_add_input(res, 1);
7474 		strm->txn->status = ctx->ctx.hlua_apphttp.status;
7475 		ctx->ctx.hlua_apphttp.flags |= APPLET_RSP_SENT;
7476 	}
7477 
7478   done:
7479 	if (ctx->ctx.hlua_apphttp.flags & APPLET_DONE) {
7480 		if (!(res->flags & CF_SHUTR)) {
7481 			res->flags |= CF_READ_NULL;
7482 			si_shutr(si);
7483 		}
7484 
7485 		/* eat the whole request */
7486 		if (co_data(req)) {
7487 			req_htx = htx_from_buf(&req->buf);
7488 			co_htx_skip(req, req_htx, co_data(req));
7489 			htx_to_buf(req_htx, &req->buf);
7490 		}
7491 	}
7492 
7493   out:
7494 	htx_to_buf(res_htx, &res->buf);
7495 	return;
7496 
7497   error:
7498 
7499 	/* If we are in HTTP mode, and we are not send any
7500 	 * data, return a 500 server error in best effort:
7501 	 * if there is no room available in the buffer,
7502 	 * just close the connection.
7503 	 */
7504 	if (!(ctx->ctx.hlua_apphttp.flags & APPLET_HDR_SENT)) {
7505 		struct buffer *err = &htx_err_chunks[HTTP_ERR_500];
7506 
7507 		channel_erase(res);
7508 		res->buf.data = b_data(err);
7509                 memcpy(res->buf.area, b_head(err), b_data(err));
7510                 res_htx = htx_from_buf(&res->buf);
7511 		channel_add_input(res, res_htx->data);
7512 	}
7513 	if (!(strm->flags & SF_ERR_MASK))
7514 		strm->flags |= SF_ERR_RESOURCE;
7515 	ctx->ctx.hlua_apphttp.flags |= APPLET_DONE;
7516 	goto done;
7517 }
7518 
hlua_applet_http_fct(struct appctx * ctx)7519 void hlua_applet_http_fct(struct appctx *ctx)
7520 {
7521 	struct stream_interface *si = ctx->owner;
7522 	struct stream *strm = si_strm(si);
7523 	struct channel *req = si_oc(si);
7524 	struct channel *res = si_ic(si);
7525 	struct act_rule *rule = ctx->rule;
7526 	struct proxy *px = strm->be;
7527 	struct hlua *hlua = ctx->ctx.hlua_apphttp.hlua;
7528 	const char *blk1;
7529 	size_t len1;
7530 	const char *blk2;
7531 	size_t len2;
7532 	int ret;
7533 
7534 	if (IS_HTX_STRM(strm))
7535 		return hlua_applet_htx_fct(ctx);
7536 
7537 	/* If the stream is disconnect or closed, ldo nothing. */
7538 	if (unlikely(si->state == SI_ST_DIS || si->state == SI_ST_CLO))
7539 		goto out;
7540 
7541 	/* Check if the input buffer is avalaible. */
7542 	if (!b_size(&res->buf)) {
7543 		si_rx_room_blk(si);
7544 		goto out;
7545 	}
7546 	/* check that the output is not closed */
7547 	if (res->flags & (CF_SHUTW|CF_SHUTW_NOW|CF_SHUTR))
7548 		ctx->ctx.hlua_apphttp.flags |= APPLET_DONE;
7549 
7550 	/* Set the currently running flag. */
7551 	if (!HLUA_IS_RUNNING(hlua) &&
7552 	    !(ctx->ctx.hlua_apphttp.flags & APPLET_DONE)) {
7553 		/* Store the max amount of bytes that we can read. */
7554 		ctx->ctx.hlua_apphttp.left_bytes = strm->txn->req.body_len;
7555 
7556 		/* We need to flush the request header. This left the body
7557 		 * for the Lua.
7558 		 */
7559 
7560 		/* Read the maximum amount of data available. */
7561 		ret = co_getblk_nc(req, &blk1, &len1, &blk2, &len2);
7562 		if (ret == -1)
7563 			goto out;
7564 
7565 		/* No data available, ask for more data. */
7566 		if (ret == 1)
7567 			len2 = 0;
7568 		if (ret == 0)
7569 			len1 = 0;
7570 		if (len1 + len2 < strm->txn->req.eoh + strm->txn->req.eol) {
7571 			si_cant_get(si);
7572 			goto out;
7573 		}
7574 
7575 		/* skip the requests bytes. */
7576 		co_skip(req, strm->txn->req.eoh + strm->txn->req.eol);
7577 	}
7578 
7579 	/* Executes The applet if it is not done. */
7580 	if (!(ctx->ctx.hlua_apphttp.flags & APPLET_DONE)) {
7581 
7582 		/* Execute the function. */
7583 		switch (hlua_ctx_resume(hlua, 1)) {
7584 		/* finished. */
7585 		case HLUA_E_OK:
7586 			ctx->ctx.hlua_apphttp.flags |= APPLET_DONE;
7587 			break;
7588 
7589 		/* yield. */
7590 		case HLUA_E_AGAIN:
7591 			if (hlua->wake_time != TICK_ETERNITY)
7592 				task_schedule(ctx->ctx.hlua_apphttp.task, hlua->wake_time);
7593 			goto out;
7594 
7595 		/* finished with error. */
7596 		case HLUA_E_ERRMSG:
7597 			/* Display log. */
7598 			SEND_ERR(px, "Lua applet http '%s': %s.\n",
7599 			         rule->arg.hlua_rule->fcn.name, lua_tostring(hlua->T, -1));
7600 			lua_pop(hlua->T, 1);
7601 			goto error;
7602 
7603 		case HLUA_E_ETMOUT:
7604 			SEND_ERR(px, "Lua applet http '%s': execution timeout.\n",
7605 			         rule->arg.hlua_rule->fcn.name);
7606 			goto error;
7607 
7608 		case HLUA_E_NOMEM:
7609 			SEND_ERR(px, "Lua applet http '%s': out of memory error.\n",
7610 			         rule->arg.hlua_rule->fcn.name);
7611 			goto error;
7612 
7613 		case HLUA_E_YIELD: /* unexpected */
7614 			SEND_ERR(px, "Lua applet http '%s': yield not allowed.\n",
7615 			         rule->arg.hlua_rule->fcn.name);
7616 			goto error;
7617 
7618 		case HLUA_E_ERR:
7619 			/* Display log. */
7620 			SEND_ERR(px, "Lua applet http '%s' return an unknown error.\n",
7621 			         rule->arg.hlua_rule->fcn.name);
7622 			goto error;
7623 
7624 		default:
7625 			goto error;
7626 		}
7627 	}
7628 
7629 	if (ctx->ctx.hlua_apphttp.flags & APPLET_DONE) {
7630 		if (ctx->ctx.hlua_apphttp.flags & APPLET_RSP_SENT)
7631 			goto done;
7632 
7633 		if (!(ctx->ctx.hlua_apphttp.flags & APPLET_HDR_SENT))
7634 			goto error;
7635 
7636 		/* We must send the final chunk. */
7637 		if (ctx->ctx.hlua_apphttp.flags & APPLET_CHUNKED &&
7638 		    !(ctx->ctx.hlua_apphttp.flags & APPLET_LAST_CHK)) {
7639 
7640 			/* sent last chunk at once. */
7641 			ret = ci_putblk(res, "0\r\n\r\n", 5);
7642 
7643 			/* critical error. */
7644 			if (ret == -2 || ret == -3) {
7645 				SEND_ERR(px, "Lua applet http '%s'cannont send last chunk.\n",
7646 				         rule->arg.hlua_rule->fcn.name);
7647 				goto error;
7648 			}
7649 
7650 			/* no enough space error. */
7651 			if (ret == -1) {
7652 				si_rx_room_blk(si);
7653 				goto out;
7654 			}
7655 
7656 			strm->txn->status = ctx->ctx.hlua_apphttp.status;
7657 			ctx->ctx.hlua_apphttp.flags |= (APPLET_LAST_CHK|APPLET_RSP_SENT);
7658 		}
7659 	}
7660 
7661   done:
7662 	if (ctx->ctx.hlua_apphttp.flags & APPLET_DONE) {
7663 		if (!(res->flags & CF_SHUTR)) {
7664 			res->flags |= CF_READ_NULL;
7665 			si_shutr(si);
7666 		}
7667 
7668 		/* eat the whole request */
7669 		if (co_data(req))
7670 			co_skip(req, co_data(req));
7671 	}
7672 
7673   out:
7674 	return;
7675 
7676   error:
7677 
7678 	/* If we are in HTTP mode, and we are not send any
7679 	 * data, return a 500 server error in best effort:
7680 	 * if there is no room available in the buffer,
7681 	 * just close the connection.
7682 	 */
7683 	if (!(ctx->ctx.hlua_apphttp.flags & APPLET_HDR_SENT)) {
7684 		channel_erase(res);
7685 		ci_putblk(res, error_500, strlen(error_500));
7686 	}
7687 	if (!(strm->flags & SF_ERR_MASK))
7688 		strm->flags |= SF_ERR_RESOURCE;
7689 	ctx->ctx.hlua_apphttp.flags |= APPLET_DONE;
7690 	goto done;
7691 }
7692 
hlua_applet_http_release(struct appctx * ctx)7693 static void hlua_applet_http_release(struct appctx *ctx)
7694 {
7695 	task_destroy(ctx->ctx.hlua_apphttp.task);
7696 	ctx->ctx.hlua_apphttp.task = NULL;
7697 	hlua_ctx_destroy(ctx->ctx.hlua_apphttp.hlua);
7698 	ctx->ctx.hlua_apphttp.hlua = NULL;
7699 }
7700 
7701 /* global {tcp|http}-request parser. Return ACT_RET_PRS_OK in
7702  * succes case, else return ACT_RET_PRS_ERR.
7703  *
7704  * This function can fail with an abort() due to an Lua critical error.
7705  * We are in the configuration parsing process of HAProxy, this abort() is
7706  * tolerated.
7707  */
action_register_lua(const char ** args,int * cur_arg,struct proxy * px,struct act_rule * rule,char ** err)7708 static enum act_parse_ret action_register_lua(const char **args, int *cur_arg, struct proxy *px,
7709                                               struct act_rule *rule, char **err)
7710 {
7711 	struct hlua_function *fcn = rule->kw->private;
7712 	int i;
7713 
7714 	/* Memory for the rule. */
7715 	rule->arg.hlua_rule = calloc(1, sizeof(*rule->arg.hlua_rule));
7716 	if (!rule->arg.hlua_rule) {
7717 		memprintf(err, "out of memory error");
7718 		return ACT_RET_PRS_ERR;
7719 	}
7720 
7721 	/* Memory for arguments. */
7722 	rule->arg.hlua_rule->args = calloc(fcn->nargs + 1, sizeof(char *));
7723 	if (!rule->arg.hlua_rule->args) {
7724 		memprintf(err, "out of memory error");
7725 		return ACT_RET_PRS_ERR;
7726 	}
7727 
7728 	/* Reference the Lua function and store the reference. */
7729 	rule->arg.hlua_rule->fcn = *fcn;
7730 
7731 	/* Expect some arguments */
7732 	for (i = 0; i < fcn->nargs; i++) {
7733 		if (*args[*cur_arg] == '\0') {
7734 			memprintf(err, "expect %d arguments", fcn->nargs);
7735 			return ACT_RET_PRS_ERR;
7736 		}
7737 		rule->arg.hlua_rule->args[i] = strdup(args[*cur_arg]);
7738 		if (!rule->arg.hlua_rule->args[i]) {
7739 			memprintf(err, "out of memory error");
7740 			return ACT_RET_PRS_ERR;
7741 		}
7742 		(*cur_arg)++;
7743 	}
7744 	rule->arg.hlua_rule->args[i] = NULL;
7745 
7746 	rule->action = ACT_CUSTOM;
7747 	rule->action_ptr = hlua_action;
7748 	return ACT_RET_PRS_OK;
7749 }
7750 
action_register_service_http(const char ** args,int * cur_arg,struct proxy * px,struct act_rule * rule,char ** err)7751 static enum act_parse_ret action_register_service_http(const char **args, int *cur_arg, struct proxy *px,
7752                                                        struct act_rule *rule, char **err)
7753 {
7754 	struct hlua_function *fcn = rule->kw->private;
7755 
7756 	/* HTTP applets are forbidden in tcp-request rules.
7757 	 * HTTP applet request requires everything initilized by
7758 	 * "http_process_request" (analyzer flag AN_REQ_HTTP_INNER).
7759 	 * The applet will be immediately initilized, but its before
7760 	 * the call of this analyzer.
7761 	 */
7762 	if (rule->from != ACT_F_HTTP_REQ) {
7763 		memprintf(err, "HTTP applets are forbidden from 'tcp-request' rulesets");
7764 		return ACT_RET_PRS_ERR;
7765 	}
7766 
7767 	/* Memory for the rule. */
7768 	rule->arg.hlua_rule = calloc(1, sizeof(*rule->arg.hlua_rule));
7769 	if (!rule->arg.hlua_rule) {
7770 		memprintf(err, "out of memory error");
7771 		return ACT_RET_PRS_ERR;
7772 	}
7773 
7774 	/* Reference the Lua function and store the reference. */
7775 	rule->arg.hlua_rule->fcn = *fcn;
7776 
7777 	/* TODO: later accept arguments. */
7778 	rule->arg.hlua_rule->args = NULL;
7779 
7780 	/* Add applet pointer in the rule. */
7781 	rule->applet.obj_type = OBJ_TYPE_APPLET;
7782 	rule->applet.name = fcn->name;
7783 	rule->applet.init = hlua_applet_http_init;
7784 	rule->applet.fct = hlua_applet_http_fct;
7785 	rule->applet.release = hlua_applet_http_release;
7786 	rule->applet.timeout = hlua_timeout_applet;
7787 
7788 	return ACT_RET_PRS_OK;
7789 }
7790 
7791 /* This function is an LUA binding used for registering
7792  * "sample-conv" functions. It expects a converter name used
7793  * in the haproxy configuration file, and an LUA function.
7794  */
hlua_register_action(lua_State * L)7795 __LJMP static int hlua_register_action(lua_State *L)
7796 {
7797 	struct action_kw_list *akl;
7798 	const char *name;
7799 	int ref;
7800 	int len;
7801 	struct hlua_function *fcn;
7802 	int nargs;
7803 	struct buffer *trash;
7804 	struct action_kw *akw;
7805 
7806 	/* Initialise the number of expected arguments at 0. */
7807 	nargs = 0;
7808 
7809 	if (lua_gettop(L) < 3 || lua_gettop(L) > 4)
7810 		WILL_LJMP(luaL_error(L, "'register_action' needs between 3 and 4 arguments"));
7811 
7812 	/* First argument : converter name. */
7813 	name = MAY_LJMP(luaL_checkstring(L, 1));
7814 
7815 	/* Second argument : environment. */
7816 	if (lua_type(L, 2) != LUA_TTABLE)
7817 		WILL_LJMP(luaL_error(L, "register_action: second argument must be a table of strings"));
7818 
7819 	/* Third argument : lua function. */
7820 	ref = MAY_LJMP(hlua_checkfunction(L, 3));
7821 
7822 	/* Fourth argument : number of mandatory arguments expected on the configuration line. */
7823 	if (lua_gettop(L) >= 4)
7824 		nargs = MAY_LJMP(luaL_checkinteger(L, 4));
7825 
7826 	/* browse the second argument as an array. */
7827 	lua_pushnil(L);
7828 	while (lua_next(L, 2) != 0) {
7829 		if (lua_type(L, -1) != LUA_TSTRING)
7830 			WILL_LJMP(luaL_error(L, "register_action: second argument must be a table of strings"));
7831 
7832 		/* Check if action exists */
7833 		trash = get_trash_chunk();
7834 		chunk_printf(trash, "lua.%s", name);
7835 		if (strcmp(lua_tostring(L, -1), "tcp-req") == 0) {
7836 			akw = tcp_req_cont_action(trash->area);
7837 		} else if (strcmp(lua_tostring(L, -1), "tcp-res") == 0) {
7838 			akw = tcp_res_cont_action(trash->area);
7839 		} else if (strcmp(lua_tostring(L, -1), "http-req") == 0) {
7840 			akw = action_http_req_custom(trash->area);
7841 		} else if (strcmp(lua_tostring(L, -1), "http-res") == 0) {
7842 			akw = action_http_res_custom(trash->area);
7843 		} else {
7844 			akw = NULL;
7845 		}
7846 		if (akw != NULL) {
7847 			ha_warning("Trying to register action 'lua.%s' more than once. "
7848 			           "This will become a hard error in version 2.5.\n", name);
7849 		}
7850 
7851 		/* Check required environment. Only accepted "http" or "tcp". */
7852 		/* Allocate and fill the sample fetch keyword struct. */
7853 		akl = calloc(1, sizeof(*akl) + sizeof(struct action_kw) * 2);
7854 		if (!akl)
7855 			WILL_LJMP(luaL_error(L, "Lua out of memory error."));
7856 		fcn = calloc(1, sizeof(*fcn));
7857 		if (!fcn)
7858 			WILL_LJMP(luaL_error(L, "Lua out of memory error."));
7859 
7860 		/* Fill fcn. */
7861 		fcn->name = strdup(name);
7862 		if (!fcn->name)
7863 			WILL_LJMP(luaL_error(L, "Lua out of memory error."));
7864 		fcn->function_ref = ref;
7865 
7866 		/* Set the expected number od arguments. */
7867 		fcn->nargs = nargs;
7868 
7869 		/* List head */
7870 		akl->list.n = akl->list.p = NULL;
7871 
7872 		/* action keyword. */
7873 		len = strlen("lua.") + strlen(name) + 1;
7874 		akl->kw[0].kw = calloc(1, len);
7875 		if (!akl->kw[0].kw)
7876 			WILL_LJMP(luaL_error(L, "Lua out of memory error."));
7877 
7878 		snprintf((char *)akl->kw[0].kw, len, "lua.%s", name);
7879 
7880 		akl->kw[0].match_pfx = 0;
7881 		akl->kw[0].private = fcn;
7882 		akl->kw[0].parse = action_register_lua;
7883 
7884 		/* select the action registering point. */
7885 		if (strcmp(lua_tostring(L, -1), "tcp-req") == 0)
7886 			tcp_req_cont_keywords_register(akl);
7887 		else if (strcmp(lua_tostring(L, -1), "tcp-res") == 0)
7888 			tcp_res_cont_keywords_register(akl);
7889 		else if (strcmp(lua_tostring(L, -1), "http-req") == 0)
7890 			http_req_keywords_register(akl);
7891 		else if (strcmp(lua_tostring(L, -1), "http-res") == 0)
7892 			http_res_keywords_register(akl);
7893 		else
7894 			WILL_LJMP(luaL_error(L, "Lua action environment '%s' is unknown. "
7895 			                        "'tcp-req', 'tcp-res', 'http-req' or 'http-res' "
7896 			                        "are expected.", lua_tostring(L, -1)));
7897 
7898 		/* pop the environment string. */
7899 		lua_pop(L, 1);
7900 	}
7901 	return ACT_RET_PRS_OK;
7902 }
7903 
action_register_service_tcp(const char ** args,int * cur_arg,struct proxy * px,struct act_rule * rule,char ** err)7904 static enum act_parse_ret action_register_service_tcp(const char **args, int *cur_arg, struct proxy *px,
7905                                                       struct act_rule *rule, char **err)
7906 {
7907 	struct hlua_function *fcn = rule->kw->private;
7908 
7909 	if (px->mode == PR_MODE_HTTP && (px->options2 & PR_O2_USE_HTX)) {
7910 		memprintf(err, "Lua services cannot be used when the HTX internal representation is enabled");
7911 		return ACT_RET_PRS_ERR;
7912 	}
7913 
7914 	/* Memory for the rule. */
7915 	rule->arg.hlua_rule = calloc(1, sizeof(*rule->arg.hlua_rule));
7916 	if (!rule->arg.hlua_rule) {
7917 		memprintf(err, "out of memory error");
7918 		return ACT_RET_PRS_ERR;
7919 	}
7920 
7921 	/* Reference the Lua function and store the reference. */
7922 	rule->arg.hlua_rule->fcn = *fcn;
7923 
7924 	/* TODO: later accept arguments. */
7925 	rule->arg.hlua_rule->args = NULL;
7926 
7927 	/* Add applet pointer in the rule. */
7928 	rule->applet.obj_type = OBJ_TYPE_APPLET;
7929 	rule->applet.name = fcn->name;
7930 	rule->applet.init = hlua_applet_tcp_init;
7931 	rule->applet.fct = hlua_applet_tcp_fct;
7932 	rule->applet.release = hlua_applet_tcp_release;
7933 	rule->applet.timeout = hlua_timeout_applet;
7934 
7935 	return 0;
7936 }
7937 
7938 /* This function is an LUA binding used for registering
7939  * "sample-conv" functions. It expects a converter name used
7940  * in the haproxy configuration file, and an LUA function.
7941  */
hlua_register_service(lua_State * L)7942 __LJMP static int hlua_register_service(lua_State *L)
7943 {
7944 	struct action_kw_list *akl;
7945 	const char *name;
7946 	const char *env;
7947 	int ref;
7948 	int len;
7949 	struct hlua_function *fcn;
7950 	struct buffer *trash;
7951 	struct action_kw *akw;
7952 
7953 	MAY_LJMP(check_args(L, 3, "register_service"));
7954 
7955 	/* First argument : converter name. */
7956 	name = MAY_LJMP(luaL_checkstring(L, 1));
7957 
7958 	/* Second argument : environment. */
7959 	env = MAY_LJMP(luaL_checkstring(L, 2));
7960 
7961 	/* Third argument : lua function. */
7962 	ref = MAY_LJMP(hlua_checkfunction(L, 3));
7963 
7964 	/* Check for service already registered */
7965 	trash = get_trash_chunk();
7966 	chunk_printf(trash, "lua.%s", name);
7967 	akw = service_find(trash->area);
7968 	if (akw != NULL) {
7969 		ha_warning("Trying to register service 'lua.%s' more than once. "
7970 		           "This will become a hard error in version 2.5.\n", name);
7971 	}
7972 
7973 	/* Allocate and fill the sample fetch keyword struct. */
7974 	akl = calloc(1, sizeof(*akl) + sizeof(struct action_kw) * 2);
7975 	if (!akl)
7976 		WILL_LJMP(luaL_error(L, "Lua out of memory error."));
7977 	fcn = calloc(1, sizeof(*fcn));
7978 	if (!fcn)
7979 		WILL_LJMP(luaL_error(L, "Lua out of memory error."));
7980 
7981 	/* Fill fcn. */
7982 	len = strlen("<lua.>") + strlen(name) + 1;
7983 	fcn->name = calloc(1, len);
7984 	if (!fcn->name)
7985 		WILL_LJMP(luaL_error(L, "Lua out of memory error."));
7986 	snprintf((char *)fcn->name, len, "<lua.%s>", name);
7987 	fcn->function_ref = ref;
7988 
7989 	/* List head */
7990 	akl->list.n = akl->list.p = NULL;
7991 
7992 	/* converter keyword. */
7993 	len = strlen("lua.") + strlen(name) + 1;
7994 	akl->kw[0].kw = calloc(1, len);
7995 	if (!akl->kw[0].kw)
7996 		WILL_LJMP(luaL_error(L, "Lua out of memory error."));
7997 
7998 	snprintf((char *)akl->kw[0].kw, len, "lua.%s", name);
7999 
8000 	/* Check required environment. Only accepted "http" or "tcp". */
8001 	if (strcmp(env, "tcp") == 0)
8002 		akl->kw[0].parse = action_register_service_tcp;
8003 	else if (strcmp(env, "http") == 0)
8004 		akl->kw[0].parse = action_register_service_http;
8005 	else
8006 		WILL_LJMP(luaL_error(L, "Lua service environment '%s' is unknown. "
8007 		                        "'tcp' or 'http' are expected.", env));
8008 
8009 	akl->kw[0].match_pfx = 0;
8010 	akl->kw[0].private = fcn;
8011 
8012 	/* End of array. */
8013 	memset(&akl->kw[1], 0, sizeof(*akl->kw));
8014 
8015 	/* Register this new converter */
8016 	service_keywords_register(akl);
8017 
8018 	return 0;
8019 }
8020 
8021 /* This function initialises Lua cli handler. It copies the
8022  * arguments in the Lua stack and create channel IO objects.
8023  */
hlua_cli_parse_fct(char ** args,char * payload,struct appctx * appctx,void * private)8024 static int hlua_cli_parse_fct(char **args, char *payload, struct appctx *appctx, void *private)
8025 {
8026 	struct hlua *hlua;
8027 	struct hlua_function *fcn;
8028 	int i;
8029 	const char *error;
8030 
8031 	fcn = private;
8032 	appctx->ctx.hlua_cli.fcn = private;
8033 
8034 	hlua = pool_alloc(pool_head_hlua);
8035 	if (!hlua) {
8036 		SEND_ERR(NULL, "Lua cli '%s': out of memory.\n", fcn->name);
8037 		return 1;
8038 	}
8039 	HLUA_INIT(hlua);
8040 	appctx->ctx.hlua_cli.hlua = hlua;
8041 
8042 	/* Create task used by signal to wakeup applets.
8043 	 * We use the same wakeup fonction than the Lua applet_tcp and
8044 	 * applet_http. It is absolutely compatible.
8045 	 */
8046 	appctx->ctx.hlua_cli.task = task_new(tid_bit);
8047 	if (!appctx->ctx.hlua_cli.task) {
8048 		SEND_ERR(NULL, "Lua cli '%s': out of memory.\n", fcn->name);
8049 		goto error;
8050 	}
8051 	appctx->ctx.hlua_cli.task->nice = 0;
8052 	appctx->ctx.hlua_cli.task->context = appctx;
8053 	appctx->ctx.hlua_cli.task->process = hlua_applet_wakeup;
8054 
8055 	/* Initialises the Lua context */
8056 	if (!hlua_ctx_init(hlua, appctx->ctx.hlua_cli.task, 0)) {
8057 		SEND_ERR(NULL, "Lua cli '%s': can't initialize Lua context.\n", fcn->name);
8058 		goto error;
8059 	}
8060 
8061 	/* The following Lua calls can fail. */
8062 	if (!SET_SAFE_LJMP(hlua->T)) {
8063 		if (lua_type(hlua->T, -1) == LUA_TSTRING)
8064 			error = lua_tostring(hlua->T, -1);
8065 		else
8066 			error = "critical error";
8067 		SEND_ERR(NULL, "Lua cli '%s': %s.\n", fcn->name, error);
8068 		goto error;
8069 	}
8070 
8071 	/* Check stack available size. */
8072 	if (!lua_checkstack(hlua->T, 2)) {
8073 		SEND_ERR(NULL, "Lua cli '%s': full stack.\n", fcn->name);
8074 		goto error;
8075 	}
8076 
8077 	/* Restore the function in the stack. */
8078 	lua_rawgeti(hlua->T, LUA_REGISTRYINDEX, fcn->function_ref);
8079 
8080 	/* Once the arguments parsed, the CLI is like an AppletTCP,
8081 	 * so push AppletTCP in the stack.
8082 	 */
8083 	if (!hlua_applet_tcp_new(hlua->T, appctx)) {
8084 		SEND_ERR(NULL, "Lua cli '%s': full stack.\n", fcn->name);
8085 		goto error;
8086 	}
8087 	hlua->nargs = 1;
8088 
8089 	/* push keywords in the stack. */
8090 	for (i = 0; *args[i]; i++) {
8091 		/* Check stack available size. */
8092 		if (!lua_checkstack(hlua->T, 1)) {
8093 			SEND_ERR(NULL, "Lua cli '%s': full stack.\n", fcn->name);
8094 			goto error;
8095 		}
8096 		lua_pushstring(hlua->T, args[i]);
8097 		hlua->nargs++;
8098 	}
8099 
8100 	/* We must initialize the execution timeouts. */
8101 	hlua->max_time = hlua_timeout_session;
8102 
8103 	/* At this point the execution is safe. */
8104 	RESET_SAFE_LJMP(hlua->T);
8105 
8106 	/* It's ok */
8107 	return 0;
8108 
8109 	/* It's not ok. */
8110 error:
8111 	RESET_SAFE_LJMP(hlua->T);
8112 	hlua_ctx_destroy(hlua);
8113 	appctx->ctx.hlua_cli.hlua = NULL;
8114 	return 1;
8115 }
8116 
hlua_cli_io_handler_fct(struct appctx * appctx)8117 static int hlua_cli_io_handler_fct(struct appctx *appctx)
8118 {
8119 	struct hlua *hlua;
8120 	struct stream_interface *si;
8121 	struct hlua_function *fcn;
8122 
8123 	hlua = appctx->ctx.hlua_cli.hlua;
8124 	si = appctx->owner;
8125 	fcn = appctx->ctx.hlua_cli.fcn;
8126 
8127 	/* If the stream is disconnect or closed, ldo nothing. */
8128 	if (unlikely(si->state == SI_ST_DIS || si->state == SI_ST_CLO))
8129 		return 1;
8130 
8131 	/* Execute the function. */
8132 	switch (hlua_ctx_resume(hlua, 1)) {
8133 
8134 	/* finished. */
8135 	case HLUA_E_OK:
8136 		return 1;
8137 
8138 	/* yield. */
8139 	case HLUA_E_AGAIN:
8140 		/* We want write. */
8141 		if (HLUA_IS_WAKERESWR(hlua))
8142 			si_rx_room_blk(si);
8143 		/* Set the timeout. */
8144 		if (hlua->wake_time != TICK_ETERNITY)
8145 			task_schedule(hlua->task, hlua->wake_time);
8146 		return 0;
8147 
8148 	/* finished with error. */
8149 	case HLUA_E_ERRMSG:
8150 		/* Display log. */
8151 		SEND_ERR(NULL, "Lua cli '%s': %s.\n",
8152 		         fcn->name, lua_tostring(hlua->T, -1));
8153 		lua_pop(hlua->T, 1);
8154 		return 1;
8155 
8156 	case HLUA_E_ETMOUT:
8157 		SEND_ERR(NULL, "Lua converter '%s': execution timeout.\n",
8158 		         fcn->name);
8159 		return 1;
8160 
8161 	case HLUA_E_NOMEM:
8162 		SEND_ERR(NULL, "Lua converter '%s': out of memory error.\n",
8163 		         fcn->name);
8164 		return 1;
8165 
8166 	case HLUA_E_YIELD: /* unexpected */
8167 		SEND_ERR(NULL, "Lua converter '%s': yield not allowed.\n",
8168 		         fcn->name);
8169 		return 1;
8170 
8171 	case HLUA_E_ERR:
8172 		/* Display log. */
8173 		SEND_ERR(NULL, "Lua cli '%s' return an unknown error.\n",
8174 		         fcn->name);
8175 		return 1;
8176 
8177 	default:
8178 		return 1;
8179 	}
8180 
8181 	return 1;
8182 }
8183 
hlua_cli_io_release_fct(struct appctx * appctx)8184 static void hlua_cli_io_release_fct(struct appctx *appctx)
8185 {
8186 	hlua_ctx_destroy(appctx->ctx.hlua_cli.hlua);
8187 	appctx->ctx.hlua_cli.hlua = NULL;
8188 }
8189 
8190 /* This function is an LUA binding used for registering
8191  * new keywords in the cli. It expects a list of keywords
8192  * which are the "path". It is limited to 5 keywords. A
8193  * description of the command, a function to be executed
8194  * for the parsing and a function for io handlers.
8195  */
hlua_register_cli(lua_State * L)8196 __LJMP static int hlua_register_cli(lua_State *L)
8197 {
8198 	struct cli_kw_list *cli_kws;
8199 	const char *message;
8200 	int ref_io;
8201 	int len;
8202 	struct hlua_function *fcn;
8203 	int index;
8204 	int i;
8205 	struct buffer *trash;
8206 	const char *kw[5];
8207 	struct cli_kw *cli_kw;
8208 
8209 	MAY_LJMP(check_args(L, 3, "register_cli"));
8210 
8211 	/* First argument : an array of maximum 5 keywords. */
8212 	if (!lua_istable(L, 1))
8213 		WILL_LJMP(luaL_argerror(L, 1, "1st argument must be a table"));
8214 
8215 	/* Second argument : string with contextual message. */
8216 	message = MAY_LJMP(luaL_checkstring(L, 2));
8217 
8218 	/* Third and fourth argument : lua function. */
8219 	ref_io = MAY_LJMP(hlua_checkfunction(L, 3));
8220 
8221 	/* Check for CLI service already registered */
8222 	trash = get_trash_chunk();
8223 	index = 0;
8224 	lua_pushnil(L);
8225 	memset(kw, 0, sizeof(kw));
8226 	while (lua_next(L, 1) != 0) {
8227 		if (index >= CLI_PREFIX_KW_NB)
8228 			WILL_LJMP(luaL_argerror(L, 1, "1st argument must be a table with a maximum of 5 entries"));
8229 		if (lua_type(L, -1) != LUA_TSTRING)
8230 			WILL_LJMP(luaL_argerror(L, 1, "1st argument must be a table filled with strings"));
8231 		kw[index] = lua_tostring(L, -1);
8232 		if (index == 0)
8233 			chunk_printf(trash, "%s", kw[index]);
8234 		else
8235 			chunk_appendf(trash, " %s", kw[index]);
8236 		index++;
8237 		lua_pop(L, 1);
8238 	}
8239 	cli_kw = cli_find_kw_exact((char **)kw);
8240 	if (cli_kw != NULL) {
8241 		ha_warning("Trying to register CLI keyword 'lua.%s' more than once. "
8242 		           "This will become a hard error in version 2.5.\n", trash->area);
8243 	}
8244 
8245 	/* Allocate and fill the sample fetch keyword struct. */
8246 	cli_kws = calloc(1, sizeof(*cli_kws) + sizeof(struct cli_kw) * 2);
8247 	if (!cli_kws)
8248 		WILL_LJMP(luaL_error(L, "Lua out of memory error."));
8249 	fcn = calloc(1, sizeof(*fcn));
8250 	if (!fcn)
8251 		WILL_LJMP(luaL_error(L, "Lua out of memory error."));
8252 
8253 	/* Fill path. */
8254 	index = 0;
8255 	lua_pushnil(L);
8256 	while(lua_next(L, 1) != 0) {
8257 		if (index >= 5)
8258 			WILL_LJMP(luaL_argerror(L, 1, "1st argument must be a table with a maximum of 5 entries"));
8259 		if (lua_type(L, -1) != LUA_TSTRING)
8260 			WILL_LJMP(luaL_argerror(L, 1, "1st argument must be a table filled with strings"));
8261 		cli_kws->kw[0].str_kw[index] = strdup(lua_tostring(L, -1));
8262 		if (!cli_kws->kw[0].str_kw[index])
8263 			WILL_LJMP(luaL_error(L, "Lua out of memory error."));
8264 		index++;
8265 		lua_pop(L, 1);
8266 	}
8267 
8268 	/* Copy help message. */
8269 	cli_kws->kw[0].usage = strdup(message);
8270 	if (!cli_kws->kw[0].usage)
8271 		WILL_LJMP(luaL_error(L, "Lua out of memory error."));
8272 
8273 	/* Fill fcn io handler. */
8274 	len = strlen("<lua.cli>") + 1;
8275 	for (i = 0; i < index; i++)
8276 		len += strlen(cli_kws->kw[0].str_kw[i]) + 1;
8277 	fcn->name = calloc(1, len);
8278 	if (!fcn->name)
8279 		WILL_LJMP(luaL_error(L, "Lua out of memory error."));
8280 	strncat((char *)fcn->name, "<lua.cli", len);
8281 	for (i = 0; i < index; i++) {
8282 		strncat((char *)fcn->name, ".", len);
8283 		strncat((char *)fcn->name, cli_kws->kw[0].str_kw[i], len);
8284 	}
8285 	strncat((char *)fcn->name, ">", len);
8286 	fcn->function_ref = ref_io;
8287 
8288 	/* Fill last entries. */
8289 	cli_kws->kw[0].private = fcn;
8290 	cli_kws->kw[0].parse = hlua_cli_parse_fct;
8291 	cli_kws->kw[0].io_handler = hlua_cli_io_handler_fct;
8292 	cli_kws->kw[0].io_release = hlua_cli_io_release_fct;
8293 
8294 	/* Register this new converter */
8295 	cli_register_kw(cli_kws);
8296 
8297 	return 0;
8298 }
8299 
hlua_read_timeout(char ** args,int section_type,struct proxy * curpx,struct proxy * defpx,const char * file,int line,char ** err,unsigned int * timeout)8300 static int hlua_read_timeout(char **args, int section_type, struct proxy *curpx,
8301                              struct proxy *defpx, const char *file, int line,
8302                              char **err, unsigned int *timeout)
8303 {
8304 	const char *error;
8305 
8306 	error = parse_time_err(args[1], timeout, TIME_UNIT_MS);
8307 	if (error == PARSE_TIME_OVER) {
8308 		memprintf(err, "timer overflow in argument <%s> to <%s> (maximum value is 2147483647 ms or ~24.8 days)",
8309 			  args[1], args[0]);
8310 		return -1;
8311 	}
8312 	else if (error == PARSE_TIME_UNDER) {
8313 		memprintf(err, "timer underflow in argument <%s> to <%s> (minimum non-null value is 1 ms)",
8314 			  args[1], args[0]);
8315 		return -1;
8316 	}
8317 	else if (error) {
8318 		memprintf(err, "%s: invalid timeout", args[0]);
8319 		return -1;
8320 	}
8321 	return 0;
8322 }
8323 
hlua_session_timeout(char ** args,int section_type,struct proxy * curpx,struct proxy * defpx,const char * file,int line,char ** err)8324 static int hlua_session_timeout(char **args, int section_type, struct proxy *curpx,
8325                                 struct proxy *defpx, const char *file, int line,
8326                                 char **err)
8327 {
8328 	return hlua_read_timeout(args, section_type, curpx, defpx,
8329 	                         file, line, err, &hlua_timeout_session);
8330 }
8331 
hlua_task_timeout(char ** args,int section_type,struct proxy * curpx,struct proxy * defpx,const char * file,int line,char ** err)8332 static int hlua_task_timeout(char **args, int section_type, struct proxy *curpx,
8333                              struct proxy *defpx, const char *file, int line,
8334                              char **err)
8335 {
8336 	return hlua_read_timeout(args, section_type, curpx, defpx,
8337 	                         file, line, err, &hlua_timeout_task);
8338 }
8339 
hlua_applet_timeout(char ** args,int section_type,struct proxy * curpx,struct proxy * defpx,const char * file,int line,char ** err)8340 static int hlua_applet_timeout(char **args, int section_type, struct proxy *curpx,
8341                                struct proxy *defpx, const char *file, int line,
8342                                char **err)
8343 {
8344 	return hlua_read_timeout(args, section_type, curpx, defpx,
8345 	                         file, line, err, &hlua_timeout_applet);
8346 }
8347 
hlua_forced_yield(char ** args,int section_type,struct proxy * curpx,struct proxy * defpx,const char * file,int line,char ** err)8348 static int hlua_forced_yield(char **args, int section_type, struct proxy *curpx,
8349                              struct proxy *defpx, const char *file, int line,
8350                              char **err)
8351 {
8352 	char *error;
8353 
8354 	hlua_nb_instruction = strtoll(args[1], &error, 10);
8355 	if (*error != '\0') {
8356 		memprintf(err, "%s: invalid number", args[0]);
8357 		return -1;
8358 	}
8359 	return 0;
8360 }
8361 
hlua_parse_maxmem(char ** args,int section_type,struct proxy * curpx,struct proxy * defpx,const char * file,int line,char ** err)8362 static int hlua_parse_maxmem(char **args, int section_type, struct proxy *curpx,
8363                              struct proxy *defpx, const char *file, int line,
8364                              char **err)
8365 {
8366 	char *error;
8367 
8368 	if (*(args[1]) == 0) {
8369 		memprintf(err, "'%s' expects an integer argument (Lua memory size in MB).\n", args[0]);
8370 		return -1;
8371 	}
8372 	hlua_global_allocator.limit = strtoll(args[1], &error, 10) * 1024L * 1024L;
8373 	if (*error != '\0') {
8374 		memprintf(err, "%s: invalid number %s (error at '%c')", args[0], args[1], *error);
8375 		return -1;
8376 	}
8377 	return 0;
8378 }
8379 
8380 
8381 /* This function is called by the main configuration key "lua-load". It loads and
8382  * execute an lua file during the parsing of the HAProxy configuration file. It is
8383  * the main lua entry point.
8384  *
8385  * This function runs with the HAProxy keywords API. It returns -1 if an error
8386  * occurs, otherwise it returns 0.
8387  *
8388  * In some error case, LUA set an error message in top of the stack. This function
8389  * returns this error message in the HAProxy logs and pop it from the stack.
8390  *
8391  * This function can fail with an abort() due to an Lua critical error.
8392  * We are in the configuration parsing process of HAProxy, this abort() is
8393  * tolerated.
8394  */
hlua_load(char ** args,int section_type,struct proxy * curpx,struct proxy * defpx,const char * file,int line,char ** err)8395 static int hlua_load(char **args, int section_type, struct proxy *curpx,
8396                      struct proxy *defpx, const char *file, int line,
8397                      char **err)
8398 {
8399 	int error;
8400 
8401 	if (*(args[1]) == 0) {
8402 		memprintf(err, "'%s' expects a file name as parameter.\n", args[0]);
8403 		return -1;
8404 	}
8405 
8406 	/* Just load and compile the file. */
8407 	error = luaL_loadfile(gL.T, args[1]);
8408 	if (error) {
8409 		memprintf(err, "error in Lua file '%s': %s", args[1], lua_tostring(gL.T, -1));
8410 		lua_pop(gL.T, 1);
8411 		return -1;
8412 	}
8413 
8414 	/* If no syntax error where detected, execute the code. */
8415 	error = lua_pcall(gL.T, 0, LUA_MULTRET, 0);
8416 	switch (error) {
8417 	case LUA_OK:
8418 		break;
8419 	case LUA_ERRRUN:
8420 		memprintf(err, "Lua runtime error: %s\n", lua_tostring(gL.T, -1));
8421 		lua_pop(gL.T, 1);
8422 		return -1;
8423 	case LUA_ERRMEM:
8424 		memprintf(err, "Lua out of memory error.n");
8425 		return -1;
8426 	case LUA_ERRERR:
8427 		memprintf(err, "Lua message handler error: %s\n", lua_tostring(gL.T, -1));
8428 		lua_pop(gL.T, 1);
8429 		return -1;
8430 #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM <= 503
8431 	case LUA_ERRGCMM:
8432 		memprintf(err, "Lua garbage collector error: %s\n", lua_tostring(gL.T, -1));
8433 		lua_pop(gL.T, 1);
8434 		return -1;
8435 #endif
8436 	default:
8437 		memprintf(err, "Lua unknonwn error: %s\n", lua_tostring(gL.T, -1));
8438 		lua_pop(gL.T, 1);
8439 		return -1;
8440 	}
8441 
8442 	return 0;
8443 }
8444 
8445 /* configuration keywords declaration */
8446 static struct cfg_kw_list cfg_kws = {{ },{
8447 	{ CFG_GLOBAL, "lua-load",                 hlua_load },
8448 	{ CFG_GLOBAL, "tune.lua.session-timeout", hlua_session_timeout },
8449 	{ CFG_GLOBAL, "tune.lua.task-timeout",    hlua_task_timeout },
8450 	{ CFG_GLOBAL, "tune.lua.service-timeout", hlua_applet_timeout },
8451 	{ CFG_GLOBAL, "tune.lua.forced-yield",    hlua_forced_yield },
8452 	{ CFG_GLOBAL, "tune.lua.maxmem",          hlua_parse_maxmem },
8453 	{ 0, NULL, NULL },
8454 }};
8455 
8456 INITCALL1(STG_REGISTER, cfg_register_keywords, &cfg_kws);
8457 
8458 
8459 /* This function can fail with an abort() due to an Lua critical error.
8460  * We are in the initialisation process of HAProxy, this abort() is
8461  * tolerated.
8462  */
hlua_post_init()8463 int hlua_post_init()
8464 {
8465 	struct hlua_init_function *init;
8466 	const char *msg;
8467 	enum hlua_exec ret;
8468 	const char *error;
8469 
8470 	/* Call post initialisation function in safe environement. */
8471 	if (!SET_SAFE_LJMP(gL.T)) {
8472 		if (lua_type(gL.T, -1) == LUA_TSTRING)
8473 			error = lua_tostring(gL.T, -1);
8474 		else
8475 			error = "critical error";
8476 		fprintf(stderr, "Lua post-init: %s.\n", error);
8477 		exit(1);
8478 	}
8479 
8480 #if USE_OPENSSL
8481 	/* Initialize SSL server. */
8482 	if (socket_ssl.xprt->prepare_srv) {
8483 		int saved_used_backed = global.ssl_used_backend;
8484 		// don't affect maxconn automatic computation
8485 		socket_ssl.xprt->prepare_srv(&socket_ssl);
8486 		global.ssl_used_backend = saved_used_backed;
8487 	}
8488 #endif
8489 
8490 	hlua_fcn_post_init(gL.T);
8491 	RESET_SAFE_LJMP(gL.T);
8492 
8493 	list_for_each_entry(init, &hlua_init_functions, l) {
8494 		lua_rawgeti(gL.T, LUA_REGISTRYINDEX, init->function_ref);
8495 		ret = hlua_ctx_resume(&gL, 0);
8496 		switch (ret) {
8497 		case HLUA_E_OK:
8498 			lua_pop(gL.T, -1);
8499 			break;
8500 		case HLUA_E_AGAIN:
8501 			ha_alert("Lua init: yield not allowed.\n");
8502 			return 0;
8503 		case HLUA_E_ERRMSG:
8504 			msg = lua_tostring(gL.T, -1);
8505 			ha_alert("lua init: %s.\n", msg);
8506 			return 0;
8507 		case HLUA_E_ERR:
8508 		default:
8509 			ha_alert("Lua init: unknown runtime error.\n");
8510 			return 0;
8511 		}
8512 	}
8513 	return 1;
8514 }
8515 
8516 /* The memory allocator used by the Lua stack. <ud> is a pointer to the
8517  * allocator's context. <ptr> is the pointer to alloc/free/realloc. <osize>
8518  * is the previously allocated size or the kind of object in case of a new
8519  * allocation. <nsize> is the requested new size.
8520  */
hlua_alloc(void * ud,void * ptr,size_t osize,size_t nsize)8521 static void *hlua_alloc(void *ud, void *ptr, size_t osize, size_t nsize)
8522 {
8523 	struct hlua_mem_allocator *zone = ud;
8524 
8525 	if (nsize == 0) {
8526 		/* it's a free */
8527 		if (ptr)
8528 			zone->allocated -= osize;
8529 		free(ptr);
8530 		return NULL;
8531 	}
8532 
8533 	if (!ptr) {
8534 		/* it's a new allocation */
8535 		if (zone->limit && zone->allocated + nsize > zone->limit)
8536 			return NULL;
8537 
8538 		ptr = malloc(nsize);
8539 		if (ptr)
8540 			zone->allocated += nsize;
8541 		return ptr;
8542 	}
8543 
8544 	/* it's a realloc */
8545 	if (zone->limit && zone->allocated + nsize - osize > zone->limit)
8546 		return NULL;
8547 
8548 	ptr = realloc(ptr, nsize);
8549 	if (ptr)
8550 		zone->allocated += nsize - osize;
8551 	return ptr;
8552 }
8553 
8554 /* Ithis function can fail with an abort() due to an Lua critical error.
8555  * We are in the initialisation process of HAProxy, this abort() is
8556  * tolerated.
8557  */
hlua_init(void)8558 void hlua_init(void)
8559 {
8560 	int i;
8561 	int idx;
8562 	struct sample_fetch *sf;
8563 	struct sample_conv *sc;
8564 	char *p;
8565 	const char *error_msg;
8566 #ifdef USE_OPENSSL
8567 	struct srv_kw *kw;
8568 	int tmp_error;
8569 	char *error;
8570 	char *args[] = { /* SSL client configuration. */
8571 		"ssl",
8572 		"verify",
8573 		"none",
8574 		NULL
8575 	};
8576 #endif
8577 
8578 	/* Init main lua stack. */
8579 	gL.Mref = LUA_REFNIL;
8580 	gL.flags = 0;
8581 	LIST_INIT(&gL.com);
8582 	gL.T = lua_newstate(hlua_alloc, &hlua_global_allocator);
8583 	hlua_sethlua(&gL);
8584 	gL.Tref = LUA_REFNIL;
8585 	gL.task = NULL;
8586 
8587 	/* From this point, until the end of the initialisation function,
8588 	 * the Lua function can fail with an abort. We are in the initialisation
8589 	 * process of HAProxy, this abort() is tolerated.
8590 	 */
8591 
8592 	/* Set safe environment for the initialisation. */
8593 	if (!SET_SAFE_LJMP(gL.T)) {
8594 		if (lua_type(gL.T, -1) == LUA_TSTRING)
8595 			error_msg = lua_tostring(gL.T, -1);
8596 		else
8597 			error_msg = "critical error";
8598 		fprintf(stderr, "Lua init: %s.\n", error_msg);
8599 		exit(1);
8600 	}
8601 
8602 	/* Initialise lua. */
8603 	luaL_openlibs(gL.T);
8604 
8605 	/*
8606 	 *
8607 	 * Create "core" object.
8608 	 *
8609 	 */
8610 
8611 	/* This table entry is the object "core" base. */
8612 	lua_newtable(gL.T);
8613 
8614 	/* Push the loglevel constants. */
8615 	for (i = 0; i < NB_LOG_LEVELS; i++)
8616 		hlua_class_const_int(gL.T, log_levels[i], i);
8617 
8618 	/* Register special functions. */
8619 	hlua_class_function(gL.T, "register_init", hlua_register_init);
8620 	hlua_class_function(gL.T, "register_task", hlua_register_task);
8621 	hlua_class_function(gL.T, "register_fetches", hlua_register_fetches);
8622 	hlua_class_function(gL.T, "register_converters", hlua_register_converters);
8623 	hlua_class_function(gL.T, "register_action", hlua_register_action);
8624 	hlua_class_function(gL.T, "register_service", hlua_register_service);
8625 	hlua_class_function(gL.T, "register_cli", hlua_register_cli);
8626 	hlua_class_function(gL.T, "yield", hlua_yield);
8627 	hlua_class_function(gL.T, "set_nice", hlua_set_nice);
8628 	hlua_class_function(gL.T, "sleep", hlua_sleep);
8629 	hlua_class_function(gL.T, "msleep", hlua_msleep);
8630 	hlua_class_function(gL.T, "add_acl", hlua_add_acl);
8631 	hlua_class_function(gL.T, "del_acl", hlua_del_acl);
8632 	hlua_class_function(gL.T, "set_map", hlua_set_map);
8633 	hlua_class_function(gL.T, "del_map", hlua_del_map);
8634 	hlua_class_function(gL.T, "tcp", hlua_socket_new);
8635 	hlua_class_function(gL.T, "log", hlua_log);
8636 	hlua_class_function(gL.T, "Debug", hlua_log_debug);
8637 	hlua_class_function(gL.T, "Info", hlua_log_info);
8638 	hlua_class_function(gL.T, "Warning", hlua_log_warning);
8639 	hlua_class_function(gL.T, "Alert", hlua_log_alert);
8640 	hlua_class_function(gL.T, "done", hlua_done);
8641 	hlua_fcn_reg_core_fcn(gL.T);
8642 
8643 	lua_setglobal(gL.T, "core");
8644 
8645 	/*
8646 	 *
8647 	 * Register class Map
8648 	 *
8649 	 */
8650 
8651 	/* This table entry is the object "Map" base. */
8652 	lua_newtable(gL.T);
8653 
8654 	/* register pattern types. */
8655 	for (i=0; i<PAT_MATCH_NUM; i++)
8656 		hlua_class_const_int(gL.T, pat_match_names[i], i);
8657 	for (i=0; i<PAT_MATCH_NUM; i++) {
8658 		snprintf(trash.area, trash.size, "_%s", pat_match_names[i]);
8659 		hlua_class_const_int(gL.T, trash.area, i);
8660 	}
8661 
8662 	/* register constructor. */
8663 	hlua_class_function(gL.T, "new", hlua_map_new);
8664 
8665 	/* Create and fill the metatable. */
8666 	lua_newtable(gL.T);
8667 
8668 	/* Create and fille the __index entry. */
8669 	lua_pushstring(gL.T, "__index");
8670 	lua_newtable(gL.T);
8671 
8672 	/* Register . */
8673 	hlua_class_function(gL.T, "lookup", hlua_map_lookup);
8674 	hlua_class_function(gL.T, "slookup", hlua_map_slookup);
8675 
8676 	lua_rawset(gL.T, -3);
8677 
8678 	/* Register previous table in the registry with reference and named entry.
8679 	 * The function hlua_register_metatable() pops the stack, so we
8680 	 * previously create a copy of the table.
8681 	 */
8682 	lua_pushvalue(gL.T, -1); /* Copy the -1 entry and push it on the stack. */
8683 	class_map_ref = hlua_register_metatable(gL.T, CLASS_MAP);
8684 
8685 	/* Assign the metatable to the mai Map object. */
8686 	lua_setmetatable(gL.T, -2);
8687 
8688 	/* Set a name to the table. */
8689 	lua_setglobal(gL.T, "Map");
8690 
8691 	/*
8692 	 *
8693 	 * Register class Channel
8694 	 *
8695 	 */
8696 
8697 	/* Create and fill the metatable. */
8698 	lua_newtable(gL.T);
8699 
8700 	/* Create and fille the __index entry. */
8701 	lua_pushstring(gL.T, "__index");
8702 	lua_newtable(gL.T);
8703 
8704 	/* Register . */
8705 	hlua_class_function(gL.T, "get",         hlua_channel_get);
8706 	hlua_class_function(gL.T, "dup",         hlua_channel_dup);
8707 	hlua_class_function(gL.T, "getline",     hlua_channel_getline);
8708 	hlua_class_function(gL.T, "set",         hlua_channel_set);
8709 	hlua_class_function(gL.T, "append",      hlua_channel_append);
8710 	hlua_class_function(gL.T, "send",        hlua_channel_send);
8711 	hlua_class_function(gL.T, "forward",     hlua_channel_forward);
8712 	hlua_class_function(gL.T, "get_in_len",  hlua_channel_get_in_len);
8713 	hlua_class_function(gL.T, "get_out_len", hlua_channel_get_out_len);
8714 	hlua_class_function(gL.T, "is_full",     hlua_channel_is_full);
8715 
8716 	lua_rawset(gL.T, -3);
8717 
8718 	/* Register previous table in the registry with reference and named entry. */
8719 	class_channel_ref = hlua_register_metatable(gL.T, CLASS_CHANNEL);
8720 
8721 	/*
8722 	 *
8723 	 * Register class Fetches
8724 	 *
8725 	 */
8726 
8727 	/* Create and fill the metatable. */
8728 	lua_newtable(gL.T);
8729 
8730 	/* Create and fille the __index entry. */
8731 	lua_pushstring(gL.T, "__index");
8732 	lua_newtable(gL.T);
8733 
8734 	/* Browse existing fetches and create the associated
8735 	 * object method.
8736 	 */
8737 	sf = NULL;
8738 	while ((sf = sample_fetch_getnext(sf, &idx)) != NULL) {
8739 
8740 		/* Dont register the keywork if the arguments check function are
8741 		 * not safe during the runtime.
8742 		 */
8743 		if ((sf->val_args != NULL) &&
8744 		    (sf->val_args != val_payload_lv) &&
8745 			 (sf->val_args != val_hdr))
8746 			continue;
8747 
8748 		/* gL.Tua doesn't support '.' and '-' in the function names, replace it
8749 		 * by an underscore.
8750 		 */
8751 		strlcpy2(trash.area, sf->kw, trash.size);
8752 		for (p = trash.area; *p; p++)
8753 			if (*p == '.' || *p == '-' || *p == '+')
8754 				*p = '_';
8755 
8756 		/* Register the function. */
8757 		lua_pushstring(gL.T, trash.area);
8758 		lua_pushlightuserdata(gL.T, sf);
8759 		lua_pushcclosure(gL.T, hlua_run_sample_fetch, 1);
8760 		lua_rawset(gL.T, -3);
8761 	}
8762 
8763 	lua_rawset(gL.T, -3);
8764 
8765 	/* Register previous table in the registry with reference and named entry. */
8766 	class_fetches_ref = hlua_register_metatable(gL.T, CLASS_FETCHES);
8767 
8768 	/*
8769 	 *
8770 	 * Register class Converters
8771 	 *
8772 	 */
8773 
8774 	/* Create and fill the metatable. */
8775 	lua_newtable(gL.T);
8776 
8777 	/* Create and fill the __index entry. */
8778 	lua_pushstring(gL.T, "__index");
8779 	lua_newtable(gL.T);
8780 
8781 	/* Browse existing converters and create the associated
8782 	 * object method.
8783 	 */
8784 	sc = NULL;
8785 	while ((sc = sample_conv_getnext(sc, &idx)) != NULL) {
8786 		/* Dont register the keywork if the arguments check function are
8787 		 * not safe during the runtime.
8788 		 */
8789 		if (sc->val_args != NULL)
8790 			continue;
8791 
8792 		/* gL.Tua doesn't support '.' and '-' in the function names, replace it
8793 		 * by an underscore.
8794 		 */
8795 		strlcpy2(trash.area, sc->kw, trash.size);
8796 		for (p = trash.area; *p; p++)
8797 			if (*p == '.' || *p == '-' || *p == '+')
8798 				*p = '_';
8799 
8800 		/* Register the function. */
8801 		lua_pushstring(gL.T, trash.area);
8802 		lua_pushlightuserdata(gL.T, sc);
8803 		lua_pushcclosure(gL.T, hlua_run_sample_conv, 1);
8804 		lua_rawset(gL.T, -3);
8805 	}
8806 
8807 	lua_rawset(gL.T, -3);
8808 
8809 	/* Register previous table in the registry with reference and named entry. */
8810 	class_converters_ref = hlua_register_metatable(gL.T, CLASS_CONVERTERS);
8811 
8812 	/*
8813 	 *
8814 	 * Register class HTTP
8815 	 *
8816 	 */
8817 
8818 	/* Create and fill the metatable. */
8819 	lua_newtable(gL.T);
8820 
8821 	/* Create and fille the __index entry. */
8822 	lua_pushstring(gL.T, "__index");
8823 	lua_newtable(gL.T);
8824 
8825 	/* Register Lua functions. */
8826 	hlua_class_function(gL.T, "req_get_headers",hlua_http_req_get_headers);
8827 	hlua_class_function(gL.T, "req_del_header", hlua_http_req_del_hdr);
8828 	hlua_class_function(gL.T, "req_rep_header", hlua_http_req_rep_hdr);
8829 	hlua_class_function(gL.T, "req_rep_value",  hlua_http_req_rep_val);
8830 	hlua_class_function(gL.T, "req_add_header", hlua_http_req_add_hdr);
8831 	hlua_class_function(gL.T, "req_set_header", hlua_http_req_set_hdr);
8832 	hlua_class_function(gL.T, "req_set_method", hlua_http_req_set_meth);
8833 	hlua_class_function(gL.T, "req_set_path",   hlua_http_req_set_path);
8834 	hlua_class_function(gL.T, "req_set_query",  hlua_http_req_set_query);
8835 	hlua_class_function(gL.T, "req_set_uri",    hlua_http_req_set_uri);
8836 
8837 	hlua_class_function(gL.T, "res_get_headers",hlua_http_res_get_headers);
8838 	hlua_class_function(gL.T, "res_del_header", hlua_http_res_del_hdr);
8839 	hlua_class_function(gL.T, "res_rep_header", hlua_http_res_rep_hdr);
8840 	hlua_class_function(gL.T, "res_rep_value",  hlua_http_res_rep_val);
8841 	hlua_class_function(gL.T, "res_add_header", hlua_http_res_add_hdr);
8842 	hlua_class_function(gL.T, "res_set_header", hlua_http_res_set_hdr);
8843 	hlua_class_function(gL.T, "res_set_status", hlua_http_res_set_status);
8844 
8845 	lua_rawset(gL.T, -3);
8846 
8847 	/* Register previous table in the registry with reference and named entry. */
8848 	class_http_ref = hlua_register_metatable(gL.T, CLASS_HTTP);
8849 
8850 	/*
8851 	 *
8852 	 * Register class AppletTCP
8853 	 *
8854 	 */
8855 
8856 	/* Create and fill the metatable. */
8857 	lua_newtable(gL.T);
8858 
8859 	/* Create and fille the __index entry. */
8860 	lua_pushstring(gL.T, "__index");
8861 	lua_newtable(gL.T);
8862 
8863 	/* Register Lua functions. */
8864 	hlua_class_function(gL.T, "getline",   hlua_applet_tcp_getline);
8865 	hlua_class_function(gL.T, "receive",   hlua_applet_tcp_recv);
8866 	hlua_class_function(gL.T, "send",      hlua_applet_tcp_send);
8867 	hlua_class_function(gL.T, "set_priv",  hlua_applet_tcp_set_priv);
8868 	hlua_class_function(gL.T, "get_priv",  hlua_applet_tcp_get_priv);
8869 	hlua_class_function(gL.T, "set_var",   hlua_applet_tcp_set_var);
8870 	hlua_class_function(gL.T, "unset_var", hlua_applet_tcp_unset_var);
8871 	hlua_class_function(gL.T, "get_var",   hlua_applet_tcp_get_var);
8872 
8873 	lua_settable(gL.T, -3);
8874 
8875 	/* Register previous table in the registry with reference and named entry. */
8876 	class_applet_tcp_ref = hlua_register_metatable(gL.T, CLASS_APPLET_TCP);
8877 
8878 	/*
8879 	 *
8880 	 * Register class AppletHTTP
8881 	 *
8882 	 */
8883 
8884 	/* Create and fill the metatable. */
8885 	lua_newtable(gL.T);
8886 
8887 	/* Create and fille the __index entry. */
8888 	lua_pushstring(gL.T, "__index");
8889 	lua_newtable(gL.T);
8890 
8891 	/* Register Lua functions. */
8892 	hlua_class_function(gL.T, "set_priv",       hlua_applet_http_set_priv);
8893 	hlua_class_function(gL.T, "get_priv",       hlua_applet_http_get_priv);
8894 	hlua_class_function(gL.T, "set_var",        hlua_applet_http_set_var);
8895 	hlua_class_function(gL.T, "unset_var",      hlua_applet_http_unset_var);
8896 	hlua_class_function(gL.T, "get_var",        hlua_applet_http_get_var);
8897 	hlua_class_function(gL.T, "getline",        hlua_applet_http_getline);
8898 	hlua_class_function(gL.T, "receive",        hlua_applet_http_recv);
8899 	hlua_class_function(gL.T, "send",           hlua_applet_http_send);
8900 	hlua_class_function(gL.T, "add_header",     hlua_applet_http_addheader);
8901 	hlua_class_function(gL.T, "set_status",     hlua_applet_http_status);
8902 	hlua_class_function(gL.T, "start_response", hlua_applet_http_start_response);
8903 
8904 	lua_settable(gL.T, -3);
8905 
8906 	/* Register previous table in the registry with reference and named entry. */
8907 	class_applet_http_ref = hlua_register_metatable(gL.T, CLASS_APPLET_HTTP);
8908 
8909 	/*
8910 	 *
8911 	 * Register class TXN
8912 	 *
8913 	 */
8914 
8915 	/* Create and fill the metatable. */
8916 	lua_newtable(gL.T);
8917 
8918 	/* Create and fille the __index entry. */
8919 	lua_pushstring(gL.T, "__index");
8920 	lua_newtable(gL.T);
8921 
8922 	/* Register Lua functions. */
8923 	hlua_class_function(gL.T, "set_priv",            hlua_set_priv);
8924 	hlua_class_function(gL.T, "get_priv",            hlua_get_priv);
8925 	hlua_class_function(gL.T, "set_var",             hlua_set_var);
8926 	hlua_class_function(gL.T, "unset_var",           hlua_unset_var);
8927 	hlua_class_function(gL.T, "get_var",             hlua_get_var);
8928 	hlua_class_function(gL.T, "done",                hlua_txn_done);
8929 	hlua_class_function(gL.T, "set_loglevel",        hlua_txn_set_loglevel);
8930 	hlua_class_function(gL.T, "set_tos",             hlua_txn_set_tos);
8931 	hlua_class_function(gL.T, "set_mark",            hlua_txn_set_mark);
8932 	hlua_class_function(gL.T, "set_priority_class",  hlua_txn_set_priority_class);
8933 	hlua_class_function(gL.T, "set_priority_offset", hlua_txn_set_priority_offset);
8934 	hlua_class_function(gL.T, "deflog",              hlua_txn_deflog);
8935 	hlua_class_function(gL.T, "log",                 hlua_txn_log);
8936 	hlua_class_function(gL.T, "Debug",               hlua_txn_log_debug);
8937 	hlua_class_function(gL.T, "Info",                hlua_txn_log_info);
8938 	hlua_class_function(gL.T, "Warning",             hlua_txn_log_warning);
8939 	hlua_class_function(gL.T, "Alert",               hlua_txn_log_alert);
8940 
8941 	lua_rawset(gL.T, -3);
8942 
8943 	/* Register previous table in the registry with reference and named entry. */
8944 	class_txn_ref = hlua_register_metatable(gL.T, CLASS_TXN);
8945 
8946 	/*
8947 	 *
8948 	 * Register class Socket
8949 	 *
8950 	 */
8951 
8952 	/* Create and fill the metatable. */
8953 	lua_newtable(gL.T);
8954 
8955 	/* Create and fille the __index entry. */
8956 	lua_pushstring(gL.T, "__index");
8957 	lua_newtable(gL.T);
8958 
8959 #ifdef USE_OPENSSL
8960 	hlua_class_function(gL.T, "connect_ssl", hlua_socket_connect_ssl);
8961 #endif
8962 	hlua_class_function(gL.T, "connect",     hlua_socket_connect);
8963 	hlua_class_function(gL.T, "send",        hlua_socket_send);
8964 	hlua_class_function(gL.T, "receive",     hlua_socket_receive);
8965 	hlua_class_function(gL.T, "close",       hlua_socket_close);
8966 	hlua_class_function(gL.T, "getpeername", hlua_socket_getpeername);
8967 	hlua_class_function(gL.T, "getsockname", hlua_socket_getsockname);
8968 	hlua_class_function(gL.T, "setoption",   hlua_socket_setoption);
8969 	hlua_class_function(gL.T, "settimeout",  hlua_socket_settimeout);
8970 
8971 	lua_rawset(gL.T, -3); /* Push the last 2 entries in the table at index -3 */
8972 
8973 	/* Register the garbage collector entry. */
8974 	lua_pushstring(gL.T, "__gc");
8975 	lua_pushcclosure(gL.T, hlua_socket_gc, 0);
8976 	lua_rawset(gL.T, -3); /* Push the last 2 entries in the table at index -3 */
8977 
8978 	/* Register previous table in the registry with reference and named entry. */
8979 	class_socket_ref = hlua_register_metatable(gL.T, CLASS_SOCKET);
8980 
8981 	/* Proxy and server configuration initialisation. */
8982 	memset(&socket_proxy, 0, sizeof(socket_proxy));
8983 	init_new_proxy(&socket_proxy);
8984 	socket_proxy.parent = NULL;
8985 	socket_proxy.last_change = now.tv_sec;
8986 	socket_proxy.id = "LUA-SOCKET";
8987 	socket_proxy.cap = PR_CAP_FE | PR_CAP_BE;
8988 	socket_proxy.maxconn = 0;
8989 	socket_proxy.accept = NULL;
8990 	socket_proxy.options2 |= PR_O2_INDEPSTR;
8991 	socket_proxy.srv = NULL;
8992 	socket_proxy.conn_retries = 0;
8993 	socket_proxy.timeout.connect = 5000; /* By default the timeout connection is 5s. */
8994 
8995 	/* Init TCP server: unchanged parameters */
8996 	memset(&socket_tcp, 0, sizeof(socket_tcp));
8997 	socket_tcp.next = NULL;
8998 	socket_tcp.proxy = &socket_proxy;
8999 	socket_tcp.obj_type = OBJ_TYPE_SERVER;
9000 	LIST_INIT(&socket_tcp.actconns);
9001 	socket_tcp.pendconns = EB_ROOT;
9002 	socket_tcp.priv_conns = NULL;
9003 	socket_tcp.idle_conns = NULL;
9004 	socket_tcp.safe_conns = NULL;
9005 	socket_tcp.next_state = SRV_ST_RUNNING; /* early server setup */
9006 	socket_tcp.last_change = 0;
9007 	socket_tcp.id = "LUA-TCP-CONN";
9008 	socket_tcp.check.state &= ~CHK_ST_ENABLED; /* Disable health checks. */
9009 	socket_tcp.agent.state &= ~CHK_ST_ENABLED; /* Disable health checks. */
9010 	socket_tcp.pp_opts = 0; /* Remove proxy protocol. */
9011 
9012 	/* XXX: Copy default parameter from default server,
9013 	 * but the default server is not initialized.
9014 	 */
9015 	socket_tcp.maxqueue     = socket_proxy.defsrv.maxqueue;
9016 	socket_tcp.minconn      = socket_proxy.defsrv.minconn;
9017 	socket_tcp.maxconn      = socket_proxy.defsrv.maxconn;
9018 	socket_tcp.slowstart    = socket_proxy.defsrv.slowstart;
9019 	socket_tcp.onerror      = socket_proxy.defsrv.onerror;
9020 	socket_tcp.onmarkeddown = socket_proxy.defsrv.onmarkeddown;
9021 	socket_tcp.onmarkedup   = socket_proxy.defsrv.onmarkedup;
9022 	socket_tcp.consecutive_errors_limit = socket_proxy.defsrv.consecutive_errors_limit;
9023 	socket_tcp.uweight      = socket_proxy.defsrv.iweight;
9024 	socket_tcp.iweight      = socket_proxy.defsrv.iweight;
9025 
9026 	socket_tcp.check.status = HCHK_STATUS_INI;
9027 	socket_tcp.check.rise   = socket_proxy.defsrv.check.rise;
9028 	socket_tcp.check.fall   = socket_proxy.defsrv.check.fall;
9029 	socket_tcp.check.health = socket_tcp.check.rise;   /* socket, but will fall down at first failure */
9030 	socket_tcp.check.server = &socket_tcp;
9031 
9032 	socket_tcp.agent.status = HCHK_STATUS_INI;
9033 	socket_tcp.agent.rise   = socket_proxy.defsrv.agent.rise;
9034 	socket_tcp.agent.fall   = socket_proxy.defsrv.agent.fall;
9035 	socket_tcp.agent.health = socket_tcp.agent.rise;   /* socket, but will fall down at first failure */
9036 	socket_tcp.agent.server = &socket_tcp;
9037 
9038 	socket_tcp.xprt = xprt_get(XPRT_RAW);
9039 
9040 #ifdef USE_OPENSSL
9041 	/* Init TCP server: unchanged parameters */
9042 	memset(&socket_ssl, 0, sizeof(socket_ssl));
9043 	socket_ssl.next = NULL;
9044 	socket_ssl.proxy = &socket_proxy;
9045 	socket_ssl.obj_type = OBJ_TYPE_SERVER;
9046 	LIST_INIT(&socket_ssl.actconns);
9047 	socket_ssl.pendconns = EB_ROOT;
9048 	socket_ssl.priv_conns = NULL;
9049 	socket_ssl.idle_conns = NULL;
9050 	socket_ssl.safe_conns = NULL;
9051 	socket_ssl.next_state = SRV_ST_RUNNING; /* early server setup */
9052 	socket_ssl.last_change = 0;
9053 	socket_ssl.id = "LUA-SSL-CONN";
9054 	socket_ssl.check.state &= ~CHK_ST_ENABLED; /* Disable health checks. */
9055 	socket_ssl.agent.state &= ~CHK_ST_ENABLED; /* Disable health checks. */
9056 	socket_ssl.pp_opts = 0; /* Remove proxy protocol. */
9057 
9058 	/* XXX: Copy default parameter from default server,
9059 	 * but the default server is not initialized.
9060 	 */
9061 	socket_ssl.maxqueue     = socket_proxy.defsrv.maxqueue;
9062 	socket_ssl.minconn      = socket_proxy.defsrv.minconn;
9063 	socket_ssl.maxconn      = socket_proxy.defsrv.maxconn;
9064 	socket_ssl.slowstart    = socket_proxy.defsrv.slowstart;
9065 	socket_ssl.onerror      = socket_proxy.defsrv.onerror;
9066 	socket_ssl.onmarkeddown = socket_proxy.defsrv.onmarkeddown;
9067 	socket_ssl.onmarkedup   = socket_proxy.defsrv.onmarkedup;
9068 	socket_ssl.consecutive_errors_limit = socket_proxy.defsrv.consecutive_errors_limit;
9069 	socket_ssl.uweight      = socket_proxy.defsrv.iweight;
9070 	socket_ssl.iweight      = socket_proxy.defsrv.iweight;
9071 
9072 	socket_ssl.check.status = HCHK_STATUS_INI;
9073 	socket_ssl.check.rise   = socket_proxy.defsrv.check.rise;
9074 	socket_ssl.check.fall   = socket_proxy.defsrv.check.fall;
9075 	socket_ssl.check.health = socket_ssl.check.rise;   /* socket, but will fall down at first failure */
9076 	socket_ssl.check.server = &socket_ssl;
9077 
9078 	socket_ssl.agent.status = HCHK_STATUS_INI;
9079 	socket_ssl.agent.rise   = socket_proxy.defsrv.agent.rise;
9080 	socket_ssl.agent.fall   = socket_proxy.defsrv.agent.fall;
9081 	socket_ssl.agent.health = socket_ssl.agent.rise;   /* socket, but will fall down at first failure */
9082 	socket_ssl.agent.server = &socket_ssl;
9083 
9084 	socket_ssl.use_ssl = 1;
9085 	socket_ssl.xprt = xprt_get(XPRT_SSL);
9086 
9087 	for (idx = 0; args[idx] != NULL; idx++) {
9088 		if ((kw = srv_find_kw(args[idx])) != NULL) { /* Maybe it's registered server keyword */
9089 			/*
9090 			 *
9091 			 * If the keyword is not known, we can search in the registered
9092 			 * server keywords. This is useful to configure special SSL
9093 			 * features like client certificates and ssl_verify.
9094 			 *
9095 			 */
9096 			tmp_error = kw->parse(args, &idx, &socket_proxy, &socket_ssl, &error);
9097 			if (tmp_error != 0) {
9098 				fprintf(stderr, "INTERNAL ERROR: %s\n", error);
9099 				abort(); /* This must be never arrives because the command line
9100 				            not editable by the user. */
9101 			}
9102 			idx += kw->skip;
9103 		}
9104 	}
9105 #endif
9106 
9107 	RESET_SAFE_LJMP(gL.T);
9108 }
9109 
hlua_register_build_options(void)9110 static void hlua_register_build_options(void)
9111 {
9112 	char *ptr = NULL;
9113 
9114 	memprintf(&ptr, "Built with Lua version : %s", LUA_RELEASE);
9115 	hap_register_build_opts(ptr, 1);
9116 }
9117 
9118 INITCALL0(STG_REGISTER, hlua_register_build_options);
9119