blob: 545ee375074aad87b43786a73a95e8b0442a0307 [file] [log] [blame]
Thierry FOURNIER17bd1522015-03-11 20:31:00 +01001.. toctree::
2 :maxdepth: 2
3
4
5How Lua runs in HAProxy
6=======================
7
8HAProxy Lua running contexts
9----------------------------
10
11The Lua code executed in HAProxy can be processed in 2 main modes. The first one
12is the **initialisation mode**, and the second is the **runtime mode**.
13
14* In the **initialisation mode**, we can perform DNS solves, but we cannot
15 perform socket I/O. In this initialisation mode, HAProxy still blocked during
16 the execution of the Lua program.
17
18* In the **runtime mode**, we cannot perform DNS solves, but we can use sockets.
19 The execution of the Lua code is multiplexed with the requests processing, so
20 the Lua code seems to be run in blocking, but it is not the case.
21
22The Lua code is loaded in one or more files. These files contains main code and
23functions. Lua have 6 execution context.
24
251. The Lua file **body context**. It is executed during the load of the Lua file
26 in the HAProxy `[global]` section with the directive `lua-load`. It is
27 executed in initialisation mode. This section is use for configuring Lua
28 bindings in HAProxy.
29
302. The Lua **init context**. It is an Lua function executed just after the
31 HAProxy configuration parsing. The execution is in initialisation mode. In
32 this context the HAProxy environment are already initialized. It is useful to
33 check configuration, or initializing socket connections or tasks. These
34 functions are declared in the body context with the Lua function
35 `core.register_init()`. The prototype of the function is a simple function
36 without return value and without parameters, like this: `function fcn()`.
37
383. The Lua **task context**. It is an Lua function executed after the start
39 of the HAProxy scheduler, and just after the declaration of the task with the
40 Lua function `core.register_task()`. This context can be concurrent with the
41 traffic processing. It is executed in runtime mode. The prototype of the
42 function is a simple function without return value and without parameters,
43 like this: `function fcn()`.
44
454. The **action context**. It is an Lua function conditionally executed. These
46 actions are declared by the HAProxy directives "`tcp-request content lua
47 <function>`", "`tcp-response content lua <function>`", "`http-request lua
48 <function>`" and "`http-response lua <function>`". The prototype of the
49 Lua called function is a function with doesn't returns anything and that take
50 an object of class TXN as entry. `function fcn(txn)`
51
525. The **sample-fetch context**. This function takes a TXN object as entry
53 argument and returns a string. These types of function cannot execute any
54 blocking function. They are useful to aggregate some of original HAProxy
55 sample-fetches and return the result. The prototype of the function is
56 `function string fcn(txn)`. These functions can be registered with the Lua
57 function `core.register_fetches()`. Each declared sample-fetch is prefixed by
58 the string "lua.".
59
60 **NOTE**: It is possible that this function cannot found the required data
61 in the original HAProxy sample-fetches, in this case, it cannot return the
62 result. This case is not yet supported
63
646. The **converter context**. It is an Lua function that takes a string as input
65 and returns another string as output. These types of function are stateless,
66 it cannot access to any context. They don't execute any blocking function.
67 The call prototype is `function string fcn(string)`. This function can be
68 registered with the Lua function `core.register_converters()`. Each declared
69 converter is prefixed by the string "lua.".
70
71HAProxy Lua Hello world
72-----------------------
73
74HAProxy configuration file (`hello_world.conf`):
75
76::
77
78 global
79 lua-load hello_world.lua
80
81 listen proxy
82 bind 127.0.0.1:10001
83 tcp-request content lua hello_world
84
85HAProxy Lua file (`hello_world.lua`):
86
87.. code-block:: lua
88
89 function hello_world(txn)
90 local res = txn:res_channel()
91 res:send("hello world\n")
92 end
93
94How to start HAProxy for testing this configuration:
95
96::
97
98 ./haproxy -f hello_world.conf
99
100On other terminal, you can test with telnet:
101
102::
103
104 #:~ telnet 127.0.0.1 10001
105 hello world
106
107Core class
108==========
109
110.. js:class:: core
111
112 The "core" class contains all the HAProxy core functions. These function are
113 useful for the controlling the execution flow, registering hooks, manipulating
114 global maps or ACL, ...
115
116 "core" class is basically provided with HAProxy. No `require` line is
117 required to uses these function.
118
119 The "core" class is static, t is not possible to create a new object of this
120 type.
121
122.. js:function:: core.add_acl(filename, key)
123
124 **context**: init, task, action, sample-fetch, converter
125
126 Add the ACL *key* in the ACLs list referenced by the file *filename*.
127
128 :param string filename: the filename that reference the ACL entries.
129 :param string key: the key which will be added.
130
131.. js:function:: core.del_acl(filename, key)
132
133 **context**: init, task, action, sample-fetch, converter
134
135 Delete the ACL entry referenced by the key *key* in the list of ACLs
136 referenced by *filename*.
137
138 :param string filename: the filename that reference the ACL entries.
139 :param string key: the key which will be deleted.
140
141.. js:function:: core.del_map(filename, key)
142
143 **context**: init, task, action, sample-fetch, converter
144
145 Delete the map entry indexed with the specified key in the list of maps
146 referenced by his filename.
147
148 :param string filename: the filename that reference the map entries.
149 :param string key: the key which will be deleted.
150
151.. js:function:: core.msleep(milliseconds)
152
153 **context**: body, init, task, action
154
155 The `core.msleep()` stops the Lua execution between specified milliseconds.
156
157 :param integer milliseconds: the required milliseconds.
158
159.. js:function:: core.register_converters(name, func)
160
161 **context**: body
162
163 Register an Lua function executed as converter. All the registered converters
164 can be used in HAProxy with the prefix "lua.". An converter get a string as
165 input and return a string as output. The registered function can take up to 9
166 values as parameter. All the value are strings.
167
168 :param string name: is the name of the converter.
169 :param function func: is the Lua function called to work as converter.
170
171 The prototype of the Lua function used as argument is:
172
173.. code-block:: lua
174
175 function(str, [p1 [, p2 [, ... [, p5]]]])
176..
177
178 * **str** (*string*): this is the input value automatically converted in
179 string.
180 * **p1** .. **p5** (*string*): this is a list of string arguments declared in
181 the haroxy configuration file. The number of arguments doesn't exceed 5.
182 The order and the nature of these is conventionally choose by the
183 developper.
184
185.. js:function:: core.register_fetches(name, func)
186
187 **context**: body
188
189 Register an Lua function executed as sample fetch. All the registered sample
190 fetchs can be used in HAProxy with the prefix "lua.". A Lua sample fetch
191 return a string as output. The registered function can take up to 9 values as
192 parameter. All the value are strings.
193
194 :param string name: is the name of the converter.
195 :param function func: is the Lua function called to work as sample fetch.
196
197 The prototype of the Lua function used as argument is:
198
199.. code-block:: lua
200
201 string function(txn, [p1 [, p2 [, ... [, p5]]]])
202..
203
204 * **txn** (*class txn*): this is the txn object associated with the current
205 request.
206 * **p1** .. **p5** (*string*): this is a list of string arguments declared in
207 the haroxy configuration file. The number of arguments doesn't exceed 5.
208 The order and the nature of these is conventionally choose by the
209 developper.
210 * **Returns**: A string containing some data, ot nil if the value cannot be
211 returned now.
212
213 lua example code:
214
215.. code-block:: lua
216
217 core.register_fetches("hello", function(txn)
218 return "hello"
219 end)
220..
221
222 HAProxy example configuration:
223
224::
225
226 frontend example
227 http-request redirect location /%[lua.hello]
228
229.. js:function:: core.register_init(func)
230
231 **context**: body
232
233 Register a function executed after the configuration parsing. This is useful
234 to check any parameters.
235
236 :param fuction func: is the Lua function called to work as initializer.
237
238 The prototype of the Lua function used as argument is:
239
240.. code-block:: lua
241
242 function()
243..
244
245 It takes no input, and no output is expected.
246
247.. js:function:: core.register_task(func)
248
249 **context**: body, init, task, action, sample-fetch, converter
250
251 Register and start independent task. The task is started when the HAProxy
252 main scheduler starts. For example this type of tasks can be executed to
253 perform complex health checks.
254
255 :param fuction func: is the Lua function called to work as initializer.
256
257 The prototype of the Lua function used as argument is:
258
259.. code-block:: lua
260
261 function()
262..
263
264 It takes no input, and no output is expected.
265
266.. js:function:: core.set_nice(nice)
267
268 **context**: task, action, sample-fetch, converter
269
270 Change the nice of the current task or current session.
271
272 :param integer nice: the nice value, it must be between -1024 and 1024.
273
274.. js:function:: core.set_map(filename, key, value)
275
276 **context**: init, task, action, sample-fetch, converter
277
278 set the value *value* associated to the key *key* in the map referenced by
279 *filename*.
280
281.. js:function:: core.sleep(int seconds)
282
283 **context**: body, init, task, action
284
285 The `core.sleep()` functions stop the Lua execution between specified seconds.
286
287 :param integer seconds: the required seconds.
288
289.. js:function:: core.tcp()
290
291 **context**: init, task, action
292
293 This function returns a new object of a *socket* class.
294
295 :returns: A socket class object.
296
297.. js:function:: socket core.yield()
298
299 **context**: task, action, sample-fetch, converter
300
301 Give back the hand at the HAProxy scheduler. It is used when the LUA
302 processing consumes a lot of processing time.
303
304Fetches class
305=============
306
307.. js:class:: Fetches
308
309 This class contains a lot of internal HAProxy sample fetches. See the
310 HAProxy documentation for more information about her usage.
311
312Converters class
313================
314
315.. js:class:: Converters
316
317 This class contains a lot of internal HAProxy sample converters. See the
318 HAProxy documentation for more information about her usage.
319
320Channel class
321=============
322
323.. js:class:: Channel
324
325 HAProxy uses two buffers for the processing of the requests. The first one is
326 used with the request data (from the client to the server) and the second is
327 used for the response data (from the server to the client).
328
329 Each buffer contains two types of data. The first type is the incoming data
330 waiting for a processing. The second part is the outgoing data already
331 processed. Usually, the incoming data is processed, after it is tagged as
332 outgoing data, and finally it is sent. The following functions provides tools
333 for manipulating these data in a buffer.
334
335 The following diagram shows where the channel class function are applied.
336
337 **Warning**: It is not possible to read from the response in request action,
338 and it is not possible to read for the request channel in response action.
339
340.. image:: _static/channel.png
341
342.. js:function:: channel.dup(channel)
343
344 This function returns a string that contain the entire buffer. The data is
345 not remove from the buffer and can be reprocessed later.
346
347 If the buffer cant receive more data, a 'nil' value is returned.
348
349 :param class_channel channel: The manipulated channel.
350 :returns: a string containig all the avalaible data or nil.
351
352.. js:function:: channel.get(channel)
353
354 This function returns a string that contain the entire buffer. The data is
355 consumed from the buffer.
356
357 If the buffer cant receive more data, a 'nil' value is returned.
358
359 :param class_channel channel: The manipulated channel.
360 :returns: a string containig all the avalaible data or nil.
361
362.. js:function:: channel.get_line(channel)
363
364 This function returns a string that contain the first line of the buffer. The
365 data is consumed. If the data returned doesn't contains a final '\n' its
366 assumed than its the last available data in the buffer.
367
368 If the buffer cant receive more data, a 'nil' value is returned.
369
370 :param class_channel channel: The manipulated channel.
371 :returns: a string containig the avalaiable line or nil.
372
373.. js:function:: channel.set(channel, string)
374
375 This function replace the content of the buffer by the string. The function
376 returns the copied length, otherwise, it returns -1.
377
378 The data set with this function are not send. They wait for the end of
379 HAProxy processing, so the buffer can be full.
380
381 :param class_channel channel: The manipulated channel.
382 :param string string: The data which will sent.
383 :returns: an integer containing the amount of butes copyed or -1.
384
385.. js:function:: channel.append(channel, string)
386
387 This function append the string argument to the content of the buffer. The
388 function returns the copied length, otherwise, it returns -1.
389
390 The data set with this function are not send. They wait for the end of
391 HAProxy processing, so the buffer can be full.
392
393 :param class_channel channel: The manipulated channel.
394 :param string string: The data which will sent.
395 :returns: an integer containing the amount of butes copyed or -1.
396
397.. js:function:: int channel.send(channel, string)
398
399 This function required immediate send of the data. Unless if the connection
400 is close, the buffer is regularly flushed and all the string can be sent.
401
402 :param class_channel channel: The manipulated channel.
403 :param string string: The data which will sent.
404 :returns: an integer containing the amount of butes copyed or -1.
405
406.. js:function:: int channel.get_in_length(channel)
407
408 This function returns the length of the input part of the buffer.
409
410 :param class_channel channel: The manipulated channel.
411 :returns: an integer containing the amount of avalaible bytes.
412
413.. js:function:: int channel.get_out_length(channel)
414
415 This function returns the length of the output part of the buffer.
416
417 :param class_channel channel: The manipulated channel.
418 :returns: an integer containing the amount of avalaible bytes.
419
420.. js:function:: channel.forward(channel, int)
421
422 This function transfer bytes from the input part of the buffer to the output
423 part.
424
425 :param class_channel channel: The manipulated channel.
426 :param integer int: The amount of data which will be forwarded.
427
428TXN class
429=========
430
431.. js:class:: TXN
432
433 The txn class contain all the functions relative to the http or tcp
434 transaction (Note than a tcp stream is the same than a tcp transaction, but
435 an HTTP transaction is not the same than a tcp stream).
436
437 The usage of this class permits to retrieve data from the requests, alter it
438 and forward it.
439
440 All the functions provided by this class are available in the context
441 **sample-fetches** and **actions**.
442
443.. js:attribute:: txn.c
444
445 This attribute contains a Converters class object.
446
447.. js:attribute:: txn.sc
448
449 This attribute contains a Converters class object. The functions of
450 this object returns always a string.
451
452.. js:attribute:: txn.f
453
454 This attribute contains a Fetches class object.
455
456.. js:attribute:: txn.sf
457
458 This attribute contains a Fetches class object. The functions of
459 this object returns always a string.
460
461.. js:attribute:: txn.req
462
463 This attribute contains a channel class object for the request buffer.
464
465.. js:attribute:: txn.res
466
467 This attribute contains a channel class object for the response buffer.
468
469.. js:function:: txn.get_priv(txn)
470
471 Return Lua data stored in the current transaction (with the `txn.set_priv()`)
472 function. If no data are stored, it returns a nil value.
473
474 :param class_txn txn: The class txn object containing the data.
475 :returns: the opaque data previsously stored, or nil if nothing is
476 avalaible.
477
478.. js:function:: txn.set_priv(txn, data)
479
480 Store any data in the current HAProxy transaction. This action replace the
481 old stored data.
482
483 :param class_txn txn: The class txn object containing the data.
484 :param opaque data: The data which is stored in the transaction.
485
486.. js:function:: txn.get_headers(txn)
487
488 This function returns an array of headers.
489
490 :param class_txn txn: The class txn object containing the data.
491 :returns: an array of headers.
492
493.. js:function:: txn.close(txn)
494
495 This function close the transaction and the associated session. It can be
496 used when a critical error is detected.
497
498 :param class_txn txn: The class txn object containing the data.
499
500.. js:function:: txn.http.redirect(txn, location)
501
502 Not yet avalaible.
503
504.. js:function:: txn.http.req.add_header(txn, name, value)
505
506 Not yet avalaible.
507
508.. js:function:: txn.http.req.set_method(txn, string)
509
510 Not yet avalaible.
511
512.. js:function:: txn.http.req.set_path(txn, string)
513
514 Not yet avalaible.
515
516.. js:function:: txn.http.req.set_query(txn, string)
517
518 Not yet avalaible.
519
520.. js:function:: txn.http.req.set_uri(txn, string)
521
522 Not yet avalaible.
523
524.. js:function:: txn.http.req.set_header(txn, name, value)
525
526 Not yet avalaible.
527
528.. js:function:: txn.http.req.del_header(txn, name)
529
530 Not yet avalaible.
531
532.. js:function:: txn.http.req.replace_header(txn, name, regex, string)
533
534 Not yet avalaible.
535
536.. js:function:: txn.http.req.replace_value(txn, name, regex, string)
537
538 Not yet avalaible.
539
540.. js:function:: txn.http.res.set_header(txn, name, value)
541
542 Not yet avalaible.
543
544.. js:function:: txn.http.res.del_header(txn, name)
545
546 Not yet avalaible.
547
548.. js:function:: txn.http.res.replace_header(txn, name, regex, string)
549
550 Not yet avalaible.
551
552.. js:function:: txn.http.res.replace_value(txn, name, regex, string)
553
554 Not yet avalaible.
555
Thierry FOURNIER2cce3532015-03-16 12:04:16 +0100556.. js:function:: txn.set_loglevel(txn, loglevel)
557
558 Is used to change the log level of the current request. The "loglevel" must
559 be an integer between 0 and 7.
560
561 :param class_txn txn: The class txn object containing the data.
562 :param integer loglevel: The required log level. This variable can be one of
563 :see: core.<loglevel>
564
565.. js:function:: txn.set_tos(txn, tos)
566
567 Is used to set the TOS or DSCP field value of packets sent to the client to
568 the value passed in "tos" on platforms which support this.
569
570 :param class_txn txn: The class txn object containing the data.
571 :param integer tos: The new TOS os DSCP.
572
573.. js:function:: txn.set_mark(txn, mark)
574
575 Is used to set the Netfilter MARK on all packets sent to the client to the
576 value passed in "mark" on platforms which support it.
577
578 :param class_txn txn: The class txn object containing the data.
579 :param integer mark: The mark value.
580
Thierry FOURNIER17bd1522015-03-11 20:31:00 +0100581Socket class
582============
583
584.. js:class:: Socket
585
586 This class must be compatible with the Lua Socket class. Only the 'client'
587 functions are available. See the Lua Socket documentation:
588
589 `http://w3.impa.br/~diego/software/luasocket/tcp.html
590 <http://w3.impa.br/~diego/software/luasocket/tcp.html>`_
591
592.. js:function:: socket.close(socket)
593
594 Closes a TCP object. The internal socket used by the object is closed and the
595 local address to which the object was bound is made available to other
596 applications. No further operations (except for further calls to the close
597 method) are allowed on a closed socket.
598
599 :param class_socket socket: Is the manipulated socket.
600
601 Note: It is important to close all used sockets once they are not needed,
602 since, in many systems, each socket uses a file descriptor, which are limited
603 system resources. Garbage-collected objects are automatically closed before
604 destruction, though.
605
606.. js:function:: socket.connect(socket, address, port)
607
608 Attempts to connect a socket object to a remote host.
609
610 Address can be an IP address or a host name. Port must be an integer number
611 in the range [1..64K).
612
613 In case of error, the method returns nil followed by a string describing the
614 error. In case of success, the method returns 1.
615
616 :param class_socket socket: Is the manipulated socket.
617 :returns: 1 or nil.
618
619 Note: The function socket.connect is available and is a shortcut for the
620 creation of client sockets.
621
622 Note: Starting with LuaSocket 2.0, the settimeout method affects the behavior
623 of connect, causing it to return with an error in case of a timeout. If that
624 happens, you can still call socket.select with the socket in the sendt table.
625 The socket will be writable when the connection is established.
626
627.. js:function:: socket.connect_ssl(socket, address, port)
628
629 Same behavior than the function socket:connect, but uses SSL.
630
631 :param class_socket socket: Is the manipulated socket.
632 :returns: 1 or nil.
633
634.. js:function:: socket.getpeername(socket)
635
636 Returns information about the remote side of a connected client object.
637
638 Returns a string with the IP address of the peer, followed by the port number
639 that peer is using for the connection. In case of error, the method returns
640 nil.
641
642 :param class_socket socket: Is the manipulated socket.
643 :returns: a string containing the server information.
644
645.. js:function:: socket.getsockname(socket)
646
647 Returns the local address information associated to the object.
648
649 The method returns a string with local IP address and a number with the port.
650 In case of error, the method returns nil.
651
652 :param class_socket socket: Is the manipulated socket.
653 :returns: a string containing the client information.
654
655.. js:function:: socket.receive(socket, [pattern [, prefix]])
656
657 Reads data from a client object, according to the specified read pattern.
658 Patterns follow the Lua file I/O format, and the difference in performance
659 between all patterns is negligible.
660
661 :param class_socket socket: Is the manipulated socket.
662 :param string|integer pattern: Describe what is required (see below).
663 :param string prefix: A string which will be prefix the returned data.
664 :returns: a string containing the required data or nil.
665
666 Pattern can be any of the following:
667
668 * **`*a`**: reads from the socket until the connection is closed. No
669 end-of-line translation is performed;
670
671 * **`*l`**: reads a line of text from the socket. The line is terminated by a
672 LF character (ASCII 10), optionally preceded by a CR character
673 (ASCII 13). The CR and LF characters are not included in the
674 returned line. In fact, all CR characters are ignored by the
675 pattern. This is the default pattern.
676
677 * **number**: causes the method to read a specified number of bytes from the
678 socket. Prefix is an optional string to be concatenated to the
679 beginning of any received data before return.
680
681 If successful, the method returns the received pattern. In case of error, the
682 method returns nil followed by an error message which can be the string
683 'closed' in case the connection was closed before the transmission was
684 completed or the string 'timeout' in case there was a timeout during the
685 operation. Also, after the error message, the function returns the partial
686 result of the transmission.
687
688 Important note: This function was changed severely. It used to support
689 multiple patterns (but I have never seen this feature used) and now it
690 doesn't anymore. Partial results used to be returned in the same way as
691 successful results. This last feature violated the idea that all functions
692 should return nil on error. Thus it was changed too.
693
694.. js:function:: socket.send(socket, data [, start [, end ]])
695
696 Sends data through client object.
697
698 :param class_socket socket: Is the manipulated socket.
699 :param string data: The data that will be sent.
700 :param integer start: The start position in the buffer of the data which will
701 be sent.
702 :param integer end: The end position in the buffer of the data which will
703 be sent.
704 :returns: see below.
705
706 Data is the string to be sent. The optional arguments i and j work exactly
707 like the standard string.sub Lua function to allow the selection of a
708 substring to be sent.
709
710 If successful, the method returns the index of the last byte within [start,
711 end] that has been sent. Notice that, if start is 1 or absent, this is
712 effectively the total number of bytes sent. In case of error, the method
713 returns nil, followed by an error message, followed by the index of the last
714 byte within [start, end] that has been sent. You might want to try again from
715 the byte following that. The error message can be 'closed' in case the
716 connection was closed before the transmission was completed or the string
717 'timeout' in case there was a timeout during the operation.
718
719 Note: Output is not buffered. For small strings, it is always better to
720 concatenate them in Lua (with the '..' operator) and send the result in one
721 call instead of calling the method several times.
722
723.. js:function:: socket.setoption(socket, option [, value])
724
725 Just implemented for compatibility, this cal does nothing.
726
727.. js:function:: socket.settimeout(socket, value [, mode])
728
729 Changes the timeout values for the object. All I/O operations are blocking.
730 That is, any call to the methods send, receive, and accept will block
731 indefinitely, until the operation completes. The settimeout method defines a
732 limit on the amount of time the I/O methods can block. When a timeout time
733 has elapsed, the affected methods give up and fail with an error code.
734
735 The amount of time to wait is specified as the value parameter, in seconds.
736
737 The timeout modes are bot implemented, the only settable timeout is the
738 inactivity time waiting for complete the internal buffer send or waiting for
739 receive data.
740
741 :param class_socket socket: Is the manipulated socket.
742 :param integer value: The timeout value.
743
744External Lua libraries
745======================
746
747A lot of useful lua libraries can be found here:
748
749* `https://lua-toolbox.com/ <https://lua-toolbox.com/>`_
750
751Redis acces:
752
753* `https://github.com/nrk/redis-lua <https://github.com/nrk/redis-lua>`_
754
755This is an example about the usage of the Redis library with HAProxy. Note that
756each call of any function of this library can throw an error if the socket
757connection fails.
758
759.. code-block:: lua
760
761 -- load the redis library
762 local redis = require("redis");
763
764 function do_something(txn)
765
766 -- create and connect new tcp socket
767 local tcp = core.tcp();
768 tcp:settimeout(1);
769 tcp:connect("127.0.0.1", 6379);
770
771 -- use the redis library with this new socket
772 local client = redis.connect({socket=tcp});
773 client:ping();
774
775 end
776
777OpenSSL:
778
779* `http://mkottman.github.io/luacrypto/index.html
780 <http://mkottman.github.io/luacrypto/index.html>`_
781
782* `https://github.com/brunoos/luasec/wiki
783 <https://github.com/brunoos/luasec/wiki>`_
784