Skip to content
Snippets Groups Projects
README.markdown 383 KiB
Newer Older
  • Learn to ignore specific revisions
  • [Back to TOC](#directives)
    
    
    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.
    
    
    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
         }
    
         echo "res = $b";
     }
    ```
    
    
    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
    
         rewrite_by_lua_block {
    
             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,
    
    
    ```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 / {
    
         rewrite_by_lua_block {
    
             local res = ngx.location.capture("/check-spam")
             if res.body == "spam" then
                 return ngx.redirect("/terms-of-use.html")
             end
    
    
         fastcgi_pass ...;
     }
    
    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 &lt;path-to-lua-script-file&gt;*
    
    **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.
    
    
    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 &lt;lua-script-str&gt;*
    
    **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.
    
    
    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;
    
    
         access_by_lua_block {
    
             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 / {
    
         access_by_lua_block {
    
             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 &lt;path-to-lua-script-file&gt;*
    
    **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.
    
    
    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 &lt;lua-script-str&gt;*
    
    **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).
    
    For instance,
    
     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 &lt;path-to-lua-script-file&gt;*
    
    **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 &lt;lua-script-str&gt;*
    
    **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.
    
    
    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;
    
    
         body_filter_by_lua_block {
    
             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"
         }
    
     }
    ```
    
    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 &lt;path-to-lua-script-file&gt;*
    
    **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 &lt;lua-script-str&gt;*
    
    **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.
    
    
    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;
    
    
             log_by_lua_block {
    
                 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
    
         }
    
         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 &lt;path-to-lua-script-file&gt;*
    
    **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.
    
    
    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 &lt;path-to-lua-script-file&gt;*
    
    **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)
    
    
    balancer_keepalive
    ------------------
    
    **syntax:** *balancer_keepalive &lt;total-connections&gt;*
    
    **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)
    
    
    lua_need_request_body
    ---------------------
    
    **syntax:** *lua_need_request_body &lt;on|off&gt;*
    
    **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
    
    work out of the box.
    
    
    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
    
    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 &lt;path-to-lua-script-file&gt;*
    
    **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
    
    [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 &lt;path-to-lua-script-file&gt;*
    
    **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*