Newer
Older
rewrite_by_lua
--------------
**syntax:** *rewrite_by_lua <lua-script-str>*
**context:** *http, server, location, location if*
**phase:** *rewrite tail*
**NOTE** Use of this directive is *discouraged* following the `v0.9.17` release. Use the [rewrite_by_lua_block](#rewrite_by_lua_block) directive instead.
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
Similar to the [rewrite_by_lua_block](#rewrite_by_lua_block) directive, but accepts the Lua source directly in an Nginx string literal (which requires
special character escaping).
For instance,
```nginx
rewrite_by_lua '
do_something("hello, world!\nhiya\n")
';
```
[Back to TOC](#directives)
rewrite_by_lua_block
--------------------
**syntax:** *rewrite_by_lua_block { lua-script }*
**context:** *http, server, location, location if*
**phase:** *rewrite tail*
Acts as a rewrite phase handler and executes Lua code string specified in `{ lua-script }` for every request.
The Lua code may make [API calls](#nginx-api-for-lua) and is executed as a new spawned coroutine in an independent global environment (i.e. a sandbox).
Note that this handler always runs *after* the standard [ngx_http_rewrite_module](http://nginx.org/en/docs/http/ngx_http_rewrite_module.html). So the following will work as expected:
```nginx
location /foo {
set $a 12; # create and initialize $a
set $b ""; # create and initialize $b
rewrite_by_lua_block {
ngx.var.b = tonumber(ngx.var.a) + 1
}
because `set $a 12` and `set $b ""` run *before* [rewrite_by_lua_block](#rewrite_by_lua_block).
On the other hand, the following will not work as expected:
```nginx
? location /foo {
? set $a 12; # create and initialize $a
? set $b ''; # create and initialize $b
? rewrite_by_lua_block {
? ngx.var.b = tonumber(ngx.var.a) + 1
? }
? if ($b = '13') {
? rewrite ^ /bar redirect;
? break;
? }
?
? echo "res = $b";
? }
```
because `if` runs *before* [rewrite_by_lua_block](#rewrite_by_lua_block) even if it is placed after [rewrite_by_lua_block](#rewrite_by_lua_block) in the config.
The right way of doing this is as follows:
```nginx
location /foo {
set $a 12; # create and initialize $a
set $b ''; # create and initialize $b
ngx.var.b = tonumber(ngx.var.a) + 1
if tonumber(ngx.var.b) == 13 then
return ngx.redirect("/bar")
end
Note that the [ngx_eval](http://www.grid.net.ru/nginx/eval.en.html) module can be approximated by using [rewrite_by_lua_block](#rewrite_by_lua_block). For example,
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
```nginx
location / {
eval $res {
proxy_pass http://foo.com/check-spam;
}
if ($res = 'spam') {
rewrite ^ /terms-of-use.html redirect;
}
fastcgi_pass ...;
}
```
can be implemented in ngx_lua as:
```nginx
location = /check-spam {
internal;
proxy_pass http://foo.com/check-spam;
}
location / {
local res = ngx.location.capture("/check-spam")
if res.body == "spam" then
return ngx.redirect("/terms-of-use.html")
end
Just as any other rewrite phase handlers, [rewrite_by_lua_block](#rewrite_by_lua_block) also runs in subrequests.
Note that when calling `ngx.exit(ngx.OK)` within a [rewrite_by_lua_block](#rewrite_by_lua_block) handler, the Nginx request processing control flow will still continue to the content handler. To terminate the current request from within a [rewrite_by_lua_block](#rewrite_by_lua_block) handler, call [ngx.exit](#ngxexit) with status >= 200 (`ngx.HTTP_OK`) and status < 300 (`ngx.HTTP_SPECIAL_RESPONSE`) for successful quits and `ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)` (or its friends) for failures.
If the [ngx_http_rewrite_module](http://nginx.org/en/docs/http/ngx_http_rewrite_module.html)'s [rewrite](http://nginx.org/en/docs/http/ngx_http_rewrite_module.html#rewrite) directive is used to change the URI and initiate location re-lookups (internal redirections), then any [rewrite_by_lua_block](#rewrite_by_lua_block) or [rewrite_by_lua_file_block](#rewrite_by_lua_file_block) code sequences within the current location will not be executed. For example,
location /foo {
rewrite ^ /bar;
rewrite_by_lua_block {
ngx.exit(503)
}
}
location /bar {
...
Here the Lua code `ngx.exit(503)` will never run. This will be the case if `rewrite ^ /bar last` is used as this will similarly initiate an internal redirection. If the `break` modifier is used instead, there will be no internal redirection and the `rewrite_by_lua_block` code will be executed.
The `rewrite_by_lua_block` code will always run at the end of the `rewrite` request-processing phase unless [rewrite_by_lua_no_postpone](#rewrite_by_lua_no_postpone) is turned on.
This directive was first introduced in the `v0.9.17` release.
[Back to TOC](#directives)
rewrite_by_lua_file
-------------------
**syntax:** *rewrite_by_lua_file <path-to-lua-script-file>*
**context:** *http, server, location, location if*
**phase:** *rewrite tail*
Equivalent to [rewrite_by_lua_block](#rewrite_by_lua_block), except that the file specified by `<path-to-lua-script-file>` contains the Lua code, or, as from the `v0.5.0rc32` release, the [LuaJIT bytecode](#luajit-bytecode-support) to be executed.
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
Nginx variables can be used in the `<path-to-lua-script-file>` string to provide flexibility. This however carries some risks and is not ordinarily recommended.
When a relative path like `foo/bar.lua` is given, they will be turned into the absolute path relative to the `server prefix` path determined by the `-p PATH` command-line option while starting the Nginx server.
When the Lua code cache is turned on (by default), the user code is loaded once at the first request and cached and the Nginx config must be reloaded each time the Lua source file is modified. The Lua code cache can be temporarily disabled during development by switching [lua_code_cache](#lua_code_cache) `off` in `nginx.conf` to avoid reloading Nginx.
The `rewrite_by_lua_file` code will always run at the end of the `rewrite` request-processing phase unless [rewrite_by_lua_no_postpone](#rewrite_by_lua_no_postpone) is turned on.
Nginx variables are supported in the file path for dynamic dispatch just as in [content_by_lua_file](#content_by_lua_file).
[Back to TOC](#directives)
access_by_lua
-------------
**syntax:** *access_by_lua <lua-script-str>*
**context:** *http, server, location, location if*
**phase:** *access tail*
**NOTE** Use of this directive is *discouraged* following the `v0.9.17` release. Use the [access_by_lua_block](#access_by_lua_block) directive instead.
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
Similar to the [access_by_lua_block](#access_by_lua_block) directive, but accepts the Lua source directly in an Nginx string literal (which requires
special character escaping).
For instance,
```nginx
access_by_lua '
do_something("hello, world!\nhiya\n")
';
```
[Back to TOC](#directives)
access_by_lua_block
-------------------
**syntax:** *access_by_lua_block { lua-script }*
**context:** *http, server, location, location if*
**phase:** *access tail*
Acts as an access phase handler and executes Lua code string specified in `{ <lua-script }` for every request.
The Lua code may make [API calls](#nginx-api-for-lua) and is executed as a new spawned coroutine in an independent global environment (i.e. a sandbox).
Note that this handler always runs *after* the standard [ngx_http_access_module](http://nginx.org/en/docs/http/ngx_http_access_module.html). So the following will work as expected:
```nginx
location / {
deny 192.168.1.1;
allow 192.168.1.0/24;
allow 10.1.1.0/16;
deny all;
local res = ngx.location.capture("/mysql", { ... })
...
# proxy_pass/fastcgi_pass/...
}
```
That is, if a client IP address is in the blacklist, it will be denied before the MySQL query for more complex authentication is executed by [access_by_lua_block](#access_by_lua_block).
Note that the [ngx_auth_request](http://mdounin.ru/hg/ngx_http_auth_request_module/) module can be approximated by using [access_by_lua_block](#access_by_lua_block):
```nginx
location / {
auth_request /auth;
# proxy_pass/fastcgi_pass/postgres_pass/...
}
```
can be implemented in ngx_lua as:
```nginx
location / {
local res = ngx.location.capture("/auth")
if res.status == ngx.HTTP_OK then
return
end
if res.status == ngx.HTTP_FORBIDDEN then
ngx.exit(res.status)
end
ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
# proxy_pass/fastcgi_pass/postgres_pass/...
}
```
As with other access phase handlers, [access_by_lua_block](#access_by_lua_block) will *not* run in subrequests.
Note that when calling `ngx.exit(ngx.OK)` within a [access_by_lua_block](#access_by_lua_block) handler, the Nginx request processing control flow will still continue to the content handler. To terminate the current request from within a [access_by_lua_block](#access_by_lua_block) handler, call [ngx.exit](#ngxexit) with status >= 200 (`ngx.HTTP_OK`) and status < 300 (`ngx.HTTP_SPECIAL_RESPONSE`) for successful quits and `ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)` (or its friends) for failures.
Starting from the `v0.9.20` release, you can use the [access_by_lua_no_postpone](#access_by_lua_no_postpone)
directive to control when to run this handler inside the "access" request-processing phase
of Nginx.
This directive was first introduced in the `v0.9.17` release.
[Back to TOC](#directives)
access_by_lua_file
------------------
**syntax:** *access_by_lua_file <path-to-lua-script-file>*
**context:** *http, server, location, location if*
**phase:** *access tail*
Equivalent to [access_by_lua_block](#access_by_lua_block), except that the file specified by `<path-to-lua-script-file>` contains the Lua code, or, as from the `v0.5.0rc32` release, the [LuaJIT bytecode](#luajit-bytecode-support) to be executed.
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
Nginx variables can be used in the `<path-to-lua-script-file>` string to provide flexibility. This however carries some risks and is not ordinarily recommended.
When a relative path like `foo/bar.lua` is given, they will be turned into the absolute path relative to the `server prefix` path determined by the `-p PATH` command-line option while starting the Nginx server.
When the Lua code cache is turned on (by default), the user code is loaded once at the first request and cached
and the Nginx config must be reloaded each time the Lua source file is modified.
The Lua code cache can be temporarily disabled during development by switching [lua_code_cache](#lua_code_cache) `off` in `nginx.conf` to avoid repeatedly reloading Nginx.
Nginx variables are supported in the file path for dynamic dispatch just as in [content_by_lua_file](#content_by_lua_file).
[Back to TOC](#directives)
header_filter_by_lua
--------------------
**syntax:** *header_filter_by_lua <lua-script-str>*
**context:** *http, server, location, location if*
**phase:** *output-header-filter*
**NOTE** Use of this directive is *discouraged* following the `v0.9.17` release. Use the [header_filter_by_lua_block](#header_filter_by_lua_block) directive instead.
Similar to the [header_filter_by_lua_block](#header_filter_by_lua_block) directive, but accepts the Lua source directly in an Nginx string literal (which requires
special character escaping).
header_filter_by_lua '
ngx.header["content-length"] = nil
';
```
This directive was first introduced in the `v0.2.1rc20` release.
[Back to TOC](#directives)
header_filter_by_lua_block
--------------------------
**syntax:** *header_filter_by_lua_block { lua-script }*
**context:** *http, server, location, location if*
**phase:** *output-header-filter*
Uses Lua code specified in `{ lua-script }` to define an output header filter.
Note that the following API functions are currently disabled within this context:
* Output API functions (e.g., [ngx.say](#ngxsay) and [ngx.send_headers](#ngxsend_headers))
* Control API functions (e.g., [ngx.redirect](#ngxredirect) and [ngx.exec](#ngxexec))
* Subrequest API functions (e.g., [ngx.location.capture](#ngxlocationcapture) and [ngx.location.capture_multi](#ngxlocationcapture_multi))
* Cosocket API functions (e.g., [ngx.socket.tcp](#ngxsockettcp) and [ngx.req.socket](#ngxreqsocket)).
Here is an example of overriding a response header (or adding one if absent) in our Lua header filter:
location / {
proxy_pass http://mybackend;
header_filter_by_lua_block {
ngx.header.Foo = "blah"
}
}
```
This directive was first introduced in the `v0.9.17` release.
[Back to TOC](#directives)
header_filter_by_lua_file
-------------------------
**syntax:** *header_filter_by_lua_file <path-to-lua-script-file>*
**context:** *http, server, location, location if*
**phase:** *output-header-filter*
Equivalent to [header_filter_by_lua_block](#header_filter_by_lua_block), except that the file specified by `<path-to-lua-script-file>` contains the Lua code, or as from the `v0.5.0rc32` release, the [LuaJIT bytecode](#luajit-bytecode-support) to be executed.
When a relative path like `foo/bar.lua` is given, they will be turned into the absolute path relative to the `server prefix` path determined by the `-p PATH` command-line option while starting the Nginx server.
This directive was first introduced in the `v0.2.1rc20` release.
[Back to TOC](#directives)
body_filter_by_lua
------------------
**syntax:** *body_filter_by_lua <lua-script-str>*
**context:** *http, server, location, location if*
**phase:** *output-body-filter*
**NOTE** Use of this directive is *discouraged* following the `v0.9.17` release. Use the [body_filter_by_lua_block](#body_filter_by_lua_block) directive instead.
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
Similar to the [body_filter_by_lua_block](#body_filter_by_lua_block) directive, but accepts the Lua source directly in an Nginx string literal (which requires
special character escaping).
For instance,
```nginx
body_filter_by_lua '
local data, eof = ngx.arg[1], ngx.arg[2]
';
```
This directive was first introduced in the `v0.5.0rc32` release.
[Back to TOC](#directives)
body_filter_by_lua_block
------------------------
**syntax:** *body_filter_by_lua_block { lua-script-str }*
**context:** *http, server, location, location if*
**phase:** *output-body-filter*
Uses Lua code specified in `{ lua-script }` to define an output body filter.
The input data chunk is passed via [ngx.arg](#ngxarg)\[1\] (as a Lua string value) and the "eof" flag indicating the end of the response body data stream is passed via [ngx.arg](#ngxarg)\[2\] (as a Lua boolean value).
Behind the scene, the "eof" flag is just the `last_buf` (for main requests) or `last_in_chain` (for subrequests) flag of the Nginx chain link buffers. (Before the `v0.7.14` release, the "eof" flag does not work at all in subrequests.)
The output data stream can be aborted immediately by running the following Lua statement:
```lua
return ngx.ERROR
```
This will truncate the response body and usually result in incomplete and also invalid responses.
The Lua code can pass its own modified version of the input data chunk to the downstream Nginx output body filters by overriding [ngx.arg](#ngxarg)\[1\] with a Lua string or a Lua table of strings. For example, to transform all the lowercase letters in the response body, we can just write:
```nginx
location / {
proxy_pass http://mybackend;
body_filter_by_lua_block {
ngx.arg[1] = string.upper(ngx.arg[1])
}
}
```
When setting `nil` or an empty Lua string value to `ngx.arg[1]`, no data chunk will be passed to the downstream Nginx output filters at all.
Likewise, new "eof" flag can also be specified by setting a boolean value to [ngx.arg](#ngxarg)\[2\]. For example,
```nginx
location /t {
echo hello world;
echo hiya globe;
local chunk = ngx.arg[1]
if string.match(chunk, "hello") then
ngx.arg[2] = true -- new eof
return
end
-- just throw away any remaining chunk data
ngx.arg[1] = nil
}
```
Then `GET /t` will just return the output
hello world
That is, when the body filter sees a chunk containing the word "hello", then it will set the "eof" flag to true immediately, resulting in truncated but still valid responses.
When the Lua code may change the length of the response body, then it is required to always clear out the `Content-Length` response header (if any) in a header filter to enforce streaming output, as in
```nginx
location /foo {
# fastcgi_pass/proxy_pass/...
header_filter_by_lua_block {
ngx.header.content_length = nil
}
body_filter_by_lua_block {
ngx.arg[1] = string.len(ngx.arg[1]) .. "\n"
}
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
}
```
Note that the following API functions are currently disabled within this context due to the limitations in Nginx output filter's current implementation:
* Output API functions (e.g., [ngx.say](#ngxsay) and [ngx.send_headers](#ngxsend_headers))
* Control API functions (e.g., [ngx.exit](#ngxexit) and [ngx.exec](#ngxexec))
* Subrequest API functions (e.g., [ngx.location.capture](#ngxlocationcapture) and [ngx.location.capture_multi](#ngxlocationcapture_multi))
* Cosocket API functions (e.g., [ngx.socket.tcp](#ngxsockettcp) and [ngx.req.socket](#ngxreqsocket)).
Nginx output filters may be called multiple times for a single request because response body may be delivered in chunks. Thus, the Lua code specified by in this directive may also run multiple times in the lifetime of a single HTTP request.
This directive was first introduced in the `v0.9.17` release.
[Back to TOC](#directives)
body_filter_by_lua_file
-----------------------
**syntax:** *body_filter_by_lua_file <path-to-lua-script-file>*
**context:** *http, server, location, location if*
**phase:** *output-body-filter*
Equivalent to [body_filter_by_lua_block](#body_filter_by_lua_block), except that the file specified by `<path-to-lua-script-file>` contains the Lua code, or, as from the `v0.5.0rc32` release, the [LuaJIT bytecode](#luajit-bytecode-support) to be executed.
When a relative path like `foo/bar.lua` is given, they will be turned into the absolute path relative to the `server prefix` path determined by the `-p PATH` command-line option while starting the Nginx server.
This directive was first introduced in the `v0.5.0rc32` release.
[Back to TOC](#directives)
log_by_lua
----------
**syntax:** *log_by_lua <lua-script-str>*
**context:** *http, server, location, location if*
**phase:** *log*
**NOTE** Use of this directive is *discouraged* following the `v0.9.17` release. Use the [log_by_lua_block](#log_by_lua_block) directive instead.
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
Similar to the [log_by_lua_block](#log_by_lua_block) directive, but accepts the Lua source directly in an Nginx string literal (which requires
special character escaping).
For instance,
```nginx
log_by_lua '
print("I need no extra escaping here, for example: \r\nblah")
';
```
This directive was first introduced in the `v0.5.0rc31` release.
[Back to TOC](#directives)
log_by_lua_block
----------------
**syntax:** *log_by_lua_block { lua-script }*
**context:** *http, server, location, location if*
**phase:** *log*
Runs the Lua source code inlined as the `{ lua-script }` at the `log` request processing phase. This does not replace the current access logs, but runs before.
Note that the following API functions are currently disabled within this context:
* Output API functions (e.g., [ngx.say](#ngxsay) and [ngx.send_headers](#ngxsend_headers))
* Control API functions (e.g., [ngx.exit](#ngxexit))
* Subrequest API functions (e.g., [ngx.location.capture](#ngxlocationcapture) and [ngx.location.capture_multi](#ngxlocationcapture_multi))
* Cosocket API functions (e.g., [ngx.socket.tcp](#ngxsockettcp) and [ngx.req.socket](#ngxreqsocket)).
Here is an example of gathering average data for [$upstream_response_time](http://nginx.org/en/docs/http/ngx_http_upstream_module.html#var_upstream_response_time):
```nginx
lua_shared_dict log_dict 5M;
server {
location / {
proxy_pass http://mybackend;
local log_dict = ngx.shared.log_dict
local upstream_time = tonumber(ngx.var.upstream_response_time)
local sum = log_dict:get("upstream_time-sum") or 0
sum = sum + upstream_time
log_dict:set("upstream_time-sum", sum)
local newval, err = log_dict:incr("upstream_time-nb", 1)
if not newval and err == "not found" then
log_dict:add("upstream_time-nb", 0)
log_dict:incr("upstream_time-nb", 1)
end
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
}
location = /status {
content_by_lua_block {
local log_dict = ngx.shared.log_dict
local sum = log_dict:get("upstream_time-sum")
local nb = log_dict:get("upstream_time-nb")
if nb and sum then
ngx.say("average upstream response time: ", sum / nb,
" (", nb, " reqs)")
else
ngx.say("no data yet")
end
}
}
}
```
This directive was first introduced in the `v0.9.17` release.
[Back to TOC](#directives)
log_by_lua_file
---------------
**syntax:** *log_by_lua_file <path-to-lua-script-file>*
**context:** *http, server, location, location if*
**phase:** *log*
Equivalent to [log_by_lua_block](#log_by_lua_block), except that the file specified by `<path-to-lua-script-file>` contains the Lua code, or, as from the `v0.5.0rc32` release, the [LuaJIT bytecode](#luajit-bytecode-support) to be executed.
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
When a relative path like `foo/bar.lua` is given, they will be turned into the absolute path relative to the `server prefix` path determined by the `-p PATH` command-line option while starting the Nginx server.
This directive was first introduced in the `v0.5.0rc31` release.
[Back to TOC](#directives)
balancer_by_lua_block
---------------------
**syntax:** *balancer_by_lua_block { lua-script }*
**context:** *upstream*
**phase:** *content*
This directive runs Lua code as an upstream balancer for any upstream entities defined
by the `upstream {}` configuration block.
For instance,
```nginx
upstream foo {
server 127.0.0.1;
balancer_by_lua_block {
-- use Lua to do something interesting here
-- as a dynamic balancer
}
}
server {
location / {
proxy_pass http://foo;
}
}
```
The resulting Lua load balancer can work with any existing Nginx upstream modules
like [ngx_proxy](https://nginx.org/en/docs/http/ngx_http_proxy_module.html) and
[ngx_fastcgi](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html).
Also, the Lua load balancer can work with the standard upstream connection pool mechanism,
i.e., the standard [keepalive](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive) directive.
Just ensure that the [keepalive](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive) directive
is used *after* this `balancer_by_lua_block` directive in a single `upstream {}` configuration block.
The Lua load balancer can totally ignore the list of servers defined in the `upstream {}` block
and select peer from a completely dynamic server list (even changing per request) via the
[ngx.balancer](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/balancer.md) module
from the [lua-resty-core](https://github.com/openresty/lua-resty-core) library.
The Lua code handler registered by this directive might get called more than once in a single
downstream request when the Nginx upstream mechanism retries the request on conditions
specified by directives like the [proxy_next_upstream](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_next_upstream)
directive.
This Lua code execution context does not support yielding, so Lua APIs that may yield
(like cosockets and "light threads") are disabled in this context. One can usually work
around this limitation by doing such operations in an earlier phase handler (like
[access_by_lua*](#access_by_lua)) and passing along the result into this context
via the [ngx.ctx](#ngxctx) table.
This directive was first introduced in the `v0.10.0` release.
[Back to TOC](#directives)
balancer_by_lua_file
--------------------
**syntax:** *balancer_by_lua_file <path-to-lua-script-file>*
**context:** *upstream*
**phase:** *content*
Equivalent to [balancer_by_lua_block](#balancer_by_lua_block), except that the file specified by `<path-to-lua-script-file>` contains the Lua code, or, as from the `v0.5.0rc32` release, the [LuaJIT bytecode](#luajit-bytecode-support) to be executed.
When a relative path like `foo/bar.lua` is given, they will be turned into the absolute path relative to the `server prefix` path determined by the `-p PATH` command-line option while starting the Nginx server.
This directive was first introduced in the `v0.10.0` release.
[Back to TOC](#directives)
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
balancer_keepalive
------------------
**syntax:** *balancer_keepalive <total-connections>*
**context:** *upstream*
**phase:** *loading-config*
The `total-connections` parameter sets the maximum number of idle
keepalive connections to upstream servers that are preserved in the cache of
each worker process. When this number is exceeded, the least recently used
connections are closed.
It should be particularly noted that the keepalive directive does not limit the
total number of connections to upstream servers that an nginx worker process
can open. The connections parameter should be set to a number small enough to
let upstream servers process new incoming connections as well.
This directive was first introduced in the `v0.10.21` release.
[Back to TOC](#directives)
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
lua_need_request_body
---------------------
**syntax:** *lua_need_request_body <on|off>*
**default:** *off*
**context:** *http, server, location, location if*
**phase:** *depends on usage*
Determines whether to force the request body data to be read before running rewrite/access/content_by_lua* or not. The Nginx core does not read the client request body by default and if request body data is required, then this directive should be turned `on` or the [ngx.req.read_body](#ngxreqread_body) function should be called within the Lua code.
To read the request body data within the [$request_body](http://nginx.org/en/docs/http/ngx_http_core_module.html#var_request_body) variable,
[client_body_buffer_size](http://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_buffer_size) must have the same value as [client_max_body_size](http://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size). Because when the content length exceeds [client_body_buffer_size](http://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_buffer_size) but less than [client_max_body_size](http://nginx.org/en/docs/http/ngx_http_core_module.html#client_max_body_size), Nginx will buffer the data into a temporary file on the disk, which will lead to empty value in the [$request_body](http://nginx.org/en/docs/http/ngx_http_core_module.html#var_request_body) variable.
If the current location includes [rewrite_by_lua*](#rewrite_by_lua) directives,
then the request body will be read just before the [rewrite_by_lua*](#rewrite_by_lua) code is run (and also at the
`rewrite` phase). Similarly, if only [content_by_lua](#content_by_lua) is specified,
the request body will not be read until the content handler's Lua code is
about to run (i.e., the request body will be read during the content phase).
It is recommended however, to use the [ngx.req.read_body](#ngxreqread_body) and [ngx.req.discard_body](#ngxreqdiscard_body) functions for finer control over the request body reading process instead.
This also applies to [access_by_lua*](#access_by_lua).
[Back to TOC](#directives)
ssl_client_hello_by_lua_block
-----------------------------
**syntax:** *ssl_client_hello_by_lua_block { lua-script }*
**context:** *http, server*
**phase:** *right-after-client-hello-message-was-processed*
This directive runs user Lua code when Nginx is about to post-process the SSL client hello message for the downstream
SSL (https) connections.
It is particularly useful for dynamically setting the SSL protocols according to the SNI.
It is also useful to do some custom operations according to the per-connection information in the client hello message.
For example, one can parse custom client hello extension and do the corresponding handling in pure Lua.
This Lua handler will always run whether the SSL session is resumed (via SSL session IDs or TLS session tickets) or not.
While the `ssl_certificate_by_lua*` Lua handler will only runs when initiating a full SSL handshake.
The [ngx.ssl.clienthello](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl/clienthello.md) Lua modules
provided by the [lua-resty-core](https://github.com/openresty/lua-resty-core/#readme)
library are particularly useful in this context.
Note that this handler runs in extremely early stage of SSL handshake, before the SSL client hello extensions are parsed.
So you can not use some Lua API like `ssl.server_name()` which is dependent on the later stage's processing.
Also note that only the directive in default server is valid for several virtual servers with the same IP address and port.
Below is a trivial example using the
[ngx.ssl.clienthello](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl/clienthello.md) module
at the same time:
```nginx
server {
listen 443 ssl;
server_name test.com;
ssl_certificate /path/to/cert.crt;
ssl_certificate_key /path/to/key.key;
ssl_client_hello_by_lua_block {
local ssl_clt = require "ngx.ssl.clienthello"
local host, err = ssl_clt.get_client_hello_server_name()
if host == "test.com" then
ssl_clt.set_protocols({"TLSv1", "TLSv1.1"})
elseif host == "test2.com" then
ssl_clt.set_protocols({"TLSv1.2", "TLSv1.3"})
elseif not host then
ngx.log(ngx.ERR, "failed to get the SNI name: ", err)
ngx.exit(ngx.ERROR)
else
ngx.log(ngx.ERR, "unknown SNI name: ", host)
ngx.exit(ngx.ERROR)
end
}
...
}
server {
listen 443 ssl;
server_name test2.com;
ssl_certificate /path/to/cert.crt;
ssl_certificate_key /path/to/key.key;
...
}
```
See more information in the [ngx.ssl.clienthello](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl/clienthello.md)
Lua modules' official documentation.
Uncaught Lua exceptions in the user Lua code immediately abort the current SSL session, so does the
[ngx.exit](#ngxexit) call with an error code like `ngx.ERROR`.
This Lua code execution context *does* support yielding, so Lua APIs that may yield
(like cosockets, sleeping, and "light threads")
are enabled in this context
Note, you need to configure the [ssl_certificate](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_certificate)
and [ssl_certificate_key](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_certificate_key)
to avoid the following error while starting NGINX:
nginx: [emerg] no ssl configured for the server
This directive requires OpenSSL 1.1.1 or greater.
If you are using the [official pre-built
packages](https://openresty.org/en/linux-packages.html) for
[OpenResty](https://openresty.org/) 1.21.4.1 or later, then everything should
If you are not using the Nginx core shipped with
[OpenResty](https://openresty.org) 1.21.4.1 or later, you will need to apply
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
patches to the standard Nginx core:
<https://openresty.org/en/nginx-ssl-patches.html>
This directive was first introduced in the `v0.10.21` release.
[Back to TOC](#directives)
ssl_client_hello_by_lua_file
----------------------------
**syntax:** *ssl_client_hello_by_lua_file <path-to-lua-script-file>*
**context:** *http, server*
**phase:** *right-after-client-hello-message-was-processed*
Equivalent to [ssl_client_hello_by_lua_block](#ssl_client_hello_by_lua_block), except that the file specified by `<path-to-lua-script-file>` contains the Lua code, or, as from the `v0.5.0rc32` release, the [LuaJIT bytecode](#luajit-bytecode-support) to be executed.
When a relative path like `foo/bar.lua` is given, they will be turned into the absolute path relative to the `server prefix` path determined by the `-p PATH` command-line option while starting the Nginx server.
This directive was first introduced in the `v0.10.21` release.
[Back to TOC](#directives)
ssl_certificate_by_lua_block
----------------------------
**syntax:** *ssl_certificate_by_lua_block { lua-script }*
**context:** *server*
**phase:** *right-before-SSL-handshake*
This directive runs user Lua code when Nginx is about to start the SSL handshake for the downstream
SSL (https) connections.
It is particularly useful for setting the SSL certificate chain and the corresponding private key on a per-request
basis. It is also useful to load such handshake configurations nonblockingly from the remote (for example,
with the [cosocket](#ngxsockettcp) API). And one can also do per-request OCSP stapling handling in pure
Lua here as well.
Another typical use case is to do SSL handshake traffic control nonblockingly in this context,
with the help of the [lua-resty-limit-traffic#readme](https://github.com/openresty/lua-resty-limit-traffic)
library, for example.
One can also do interesting things with the SSL handshake requests from the client side, like
rejecting old SSL clients using the SSLv3 protocol or even below selectively.
The [ngx.ssl](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md)
and [ngx.ocsp](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ocsp.md) Lua modules
provided by the [lua-resty-core](https://github.com/openresty/lua-resty-core/#readme)
library are particularly useful in this context. You can use the Lua API offered by these two Lua modules
to manipulate the SSL certificate chain and private key for the current SSL connection
being initiated.
This Lua handler does not run at all, however, when Nginx/OpenSSL successfully resumes
the SSL session via SSL session IDs or TLS session tickets for the current SSL connection. In
other words, this Lua handler only runs when Nginx has to initiate a full SSL handshake.
Below is a trivial example using the
[ngx.ssl](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md) module
at the same time:
```nginx
server {
listen 443 ssl;
server_name test.com;
ssl_certificate_by_lua_block {
print("About to initiate a new SSL handshake!")
}
location / {
root html;
}
}
```
See more complicated examples in the [ngx.ssl](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md)
and [ngx.ocsp](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ocsp.md)
Lua modules' official documentation.
Uncaught Lua exceptions in the user Lua code immediately abort the current SSL session, so does the
[ngx.exit](#ngxexit) call with an error code like `ngx.ERROR`.
This Lua code execution context *does* support yielding, so Lua APIs that may yield
(like cosockets, sleeping, and "light threads")
are enabled in this context.
Note, however, you still need to configure the [ssl_certificate](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_certificate) and
[ssl_certificate_key](https://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_certificate_key)
directives even though you will not use this static certificate and private key at all. This is
because the NGINX core requires their appearance otherwise you are seeing the following error
while starting NGINX:
nginx: [emerg] no ssl configured for the server
This directive requires OpenSSL 1.0.2e or greater.
If you are using the [official pre-built
packages](https://openresty.org/en/linux-packages.html) for
[OpenResty](https://openresty.org/) 1.9.7.2 or later, then everything should
work out of the box.
If you are not using the Nginx core shipped with
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
[OpenResty](https://openresty.org) 1.9.7.2 or later, you will need to apply
patches to the standard Nginx core:
<https://openresty.org/en/nginx-ssl-patches.html>
This directive was first introduced in the `v0.10.0` release.
[Back to TOC](#directives)
ssl_certificate_by_lua_file
---------------------------
**syntax:** *ssl_certificate_by_lua_file <path-to-lua-script-file>*
**context:** *server*
**phase:** *right-before-SSL-handshake*
Equivalent to [ssl_certificate_by_lua_block](#ssl_certificate_by_lua_block), except that the file specified by `<path-to-lua-script-file>` contains the Lua code, or, as from the `v0.5.0rc32` release, the [LuaJIT bytecode](#luajit-bytecode-support) to be executed.
When a relative path like `foo/bar.lua` is given, they will be turned into the absolute path relative to the `server prefix` path determined by the `-p PATH` command-line option while starting the Nginx server.
This directive was first introduced in the `v0.10.0` release.
[Back to TOC](#directives)
ssl_session_fetch_by_lua_block
------------------------------
**syntax:** *ssl_session_fetch_by_lua_block { lua-script }*
**context:** *http*