blob: 3c76e50bbe9c290d8e2a628f54b46279f7be1378 [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
556Socket class
557============
558
559.. js:class:: Socket
560
561 This class must be compatible with the Lua Socket class. Only the 'client'
562 functions are available. See the Lua Socket documentation:
563
564 `http://w3.impa.br/~diego/software/luasocket/tcp.html
565 <http://w3.impa.br/~diego/software/luasocket/tcp.html>`_
566
567.. js:function:: socket.close(socket)
568
569 Closes a TCP object. The internal socket used by the object is closed and the
570 local address to which the object was bound is made available to other
571 applications. No further operations (except for further calls to the close
572 method) are allowed on a closed socket.
573
574 :param class_socket socket: Is the manipulated socket.
575
576 Note: It is important to close all used sockets once they are not needed,
577 since, in many systems, each socket uses a file descriptor, which are limited
578 system resources. Garbage-collected objects are automatically closed before
579 destruction, though.
580
581.. js:function:: socket.connect(socket, address, port)
582
583 Attempts to connect a socket object to a remote host.
584
585 Address can be an IP address or a host name. Port must be an integer number
586 in the range [1..64K).
587
588 In case of error, the method returns nil followed by a string describing the
589 error. In case of success, the method returns 1.
590
591 :param class_socket socket: Is the manipulated socket.
592 :returns: 1 or nil.
593
594 Note: The function socket.connect is available and is a shortcut for the
595 creation of client sockets.
596
597 Note: Starting with LuaSocket 2.0, the settimeout method affects the behavior
598 of connect, causing it to return with an error in case of a timeout. If that
599 happens, you can still call socket.select with the socket in the sendt table.
600 The socket will be writable when the connection is established.
601
602.. js:function:: socket.connect_ssl(socket, address, port)
603
604 Same behavior than the function socket:connect, but uses SSL.
605
606 :param class_socket socket: Is the manipulated socket.
607 :returns: 1 or nil.
608
609.. js:function:: socket.getpeername(socket)
610
611 Returns information about the remote side of a connected client object.
612
613 Returns a string with the IP address of the peer, followed by the port number
614 that peer is using for the connection. In case of error, the method returns
615 nil.
616
617 :param class_socket socket: Is the manipulated socket.
618 :returns: a string containing the server information.
619
620.. js:function:: socket.getsockname(socket)
621
622 Returns the local address information associated to the object.
623
624 The method returns a string with local IP address and a number with the port.
625 In case of error, the method returns nil.
626
627 :param class_socket socket: Is the manipulated socket.
628 :returns: a string containing the client information.
629
630.. js:function:: socket.receive(socket, [pattern [, prefix]])
631
632 Reads data from a client object, according to the specified read pattern.
633 Patterns follow the Lua file I/O format, and the difference in performance
634 between all patterns is negligible.
635
636 :param class_socket socket: Is the manipulated socket.
637 :param string|integer pattern: Describe what is required (see below).
638 :param string prefix: A string which will be prefix the returned data.
639 :returns: a string containing the required data or nil.
640
641 Pattern can be any of the following:
642
643 * **`*a`**: reads from the socket until the connection is closed. No
644 end-of-line translation is performed;
645
646 * **`*l`**: reads a line of text from the socket. The line is terminated by a
647 LF character (ASCII 10), optionally preceded by a CR character
648 (ASCII 13). The CR and LF characters are not included in the
649 returned line. In fact, all CR characters are ignored by the
650 pattern. This is the default pattern.
651
652 * **number**: causes the method to read a specified number of bytes from the
653 socket. Prefix is an optional string to be concatenated to the
654 beginning of any received data before return.
655
656 If successful, the method returns the received pattern. In case of error, the
657 method returns nil followed by an error message which can be the string
658 'closed' in case the connection was closed before the transmission was
659 completed or the string 'timeout' in case there was a timeout during the
660 operation. Also, after the error message, the function returns the partial
661 result of the transmission.
662
663 Important note: This function was changed severely. It used to support
664 multiple patterns (but I have never seen this feature used) and now it
665 doesn't anymore. Partial results used to be returned in the same way as
666 successful results. This last feature violated the idea that all functions
667 should return nil on error. Thus it was changed too.
668
669.. js:function:: socket.send(socket, data [, start [, end ]])
670
671 Sends data through client object.
672
673 :param class_socket socket: Is the manipulated socket.
674 :param string data: The data that will be sent.
675 :param integer start: The start position in the buffer of the data which will
676 be sent.
677 :param integer end: The end position in the buffer of the data which will
678 be sent.
679 :returns: see below.
680
681 Data is the string to be sent. The optional arguments i and j work exactly
682 like the standard string.sub Lua function to allow the selection of a
683 substring to be sent.
684
685 If successful, the method returns the index of the last byte within [start,
686 end] that has been sent. Notice that, if start is 1 or absent, this is
687 effectively the total number of bytes sent. In case of error, the method
688 returns nil, followed by an error message, followed by the index of the last
689 byte within [start, end] that has been sent. You might want to try again from
690 the byte following that. The error message can be 'closed' in case the
691 connection was closed before the transmission was completed or the string
692 'timeout' in case there was a timeout during the operation.
693
694 Note: Output is not buffered. For small strings, it is always better to
695 concatenate them in Lua (with the '..' operator) and send the result in one
696 call instead of calling the method several times.
697
698.. js:function:: socket.setoption(socket, option [, value])
699
700 Just implemented for compatibility, this cal does nothing.
701
702.. js:function:: socket.settimeout(socket, value [, mode])
703
704 Changes the timeout values for the object. All I/O operations are blocking.
705 That is, any call to the methods send, receive, and accept will block
706 indefinitely, until the operation completes. The settimeout method defines a
707 limit on the amount of time the I/O methods can block. When a timeout time
708 has elapsed, the affected methods give up and fail with an error code.
709
710 The amount of time to wait is specified as the value parameter, in seconds.
711
712 The timeout modes are bot implemented, the only settable timeout is the
713 inactivity time waiting for complete the internal buffer send or waiting for
714 receive data.
715
716 :param class_socket socket: Is the manipulated socket.
717 :param integer value: The timeout value.
718
719External Lua libraries
720======================
721
722A lot of useful lua libraries can be found here:
723
724* `https://lua-toolbox.com/ <https://lua-toolbox.com/>`_
725
726Redis acces:
727
728* `https://github.com/nrk/redis-lua <https://github.com/nrk/redis-lua>`_
729
730This is an example about the usage of the Redis library with HAProxy. Note that
731each call of any function of this library can throw an error if the socket
732connection fails.
733
734.. code-block:: lua
735
736 -- load the redis library
737 local redis = require("redis");
738
739 function do_something(txn)
740
741 -- create and connect new tcp socket
742 local tcp = core.tcp();
743 tcp:settimeout(1);
744 tcp:connect("127.0.0.1", 6379);
745
746 -- use the redis library with this new socket
747 local client = redis.connect({socket=tcp});
748 client:ping();
749
750 end
751
752OpenSSL:
753
754* `http://mkottman.github.io/luacrypto/index.html
755 <http://mkottman.github.io/luacrypto/index.html>`_
756
757* `https://github.com/brunoos/luasec/wiki
758 <https://github.com/brunoos/luasec/wiki>`_
759