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