The NGINX Lua module

NGINX has the nginx_lua module developed by Openresty.org that can be used to leverage Lua scripting. The module integrates Lua threads into the NGINX event model to enable asynchronous code execution. The module shares the loaded Lua libraries across all requests but segregates request contexts using Lua threads, thus resulting in a small memory footprint.

Note

Openresty.org provides a complete web server package with an NGINX core, nginx_lua, LuaJIT, and a host of NGINX modules that can be used to deploy applications.

Installation

This module is not enabled by default and needs to be built with NGINX. The module requires the Lua 5.1 version with the LuaJIT 2.0/ 2.1 interpreter. Download the latest version of the module from https://github.com/openresty/lua-nginx-module/releases. You can also use the following command:

$ wget https://github.com/openresty/lua-nginx-module/archive/v0.9.15.tar.gz
$ tar -xzvf v0.9.15.tar.gz

The module also requires ngx_develt_kit. The latest version of the kit can be downloaded from https://github.com/simpl/ngx_devel_kit/releases. You can also use the following command:

$ wget https://github.com/simpl/ngx_devel_kit/archive/v0.2.19.tar.gz
$ tar -xzvf v0.2.19.tar.gz

We need to build these modules with NGINX, but before we do that, we need to export Lua and the LuaJIT library as system variables. Lua and LuaJIT should be available in /usr/local/lib/lua/ and /usr/local/include/luajit-2.0 respectively:

$ export LUAJIT_LIB=/usr/local/lib 
$ export LUAJIT_INC=/usr/local/include/luajit-2.0

Next, configure NGINX to build the downloaded modules using the configure command. In addition to configuring the modules using the --add-module option, we also need to specify the luajit binary path to the linker:

 $ ./configure 
 --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro,-rpath,/usr/local/bin/luajit' 
 --prefix=/usr/share/nginx –conf-path=/etc/nginx/nginx.conf 
 --http-log-path=/var/log/nginx/access.log 
 --error-log-path=/var/log/nginx/error.log 
 --lock-path=/var/lock/nginx.lock 
 --pid-path=/run/nginx.pid 
 --http-client-body-temp-path=/var/lib/nginx/body 
 --http-fastcgi-temp-path=/var/lib/nginx/fastcgi 
 --http-proxy-temp-path=/var/lib/nginx/proxy 
 --http-scgi-temp-path=/var/lib/nginx/scgi 
 --http-uwsgi-temp-path=/var/lib/nginx/uwsgi 
 --with-pcre-jit 
 --with-http_realip_module 
 --with-http_addition_module 
 --with-http_sub_module 
 --with-pcre=/home/ubuntu/nginx/pcre-8.36 
 --add-module=/home/ubuntu/nginx/ngx_devel_kit-0.2.19 
 --add-module=/home/ubuntu/nginx/lua-nginx-module-0.9.15

After configuring the NGINX build, generate, and install the binary using make commands, as shown here:

$ make
$ sudo make install

Validate the NGINX installation using the -V option:

$ nginx -V 
nginx version: nginx/1.7.9 
built by gcc 4.8.2 (Ubuntu 4.8.2-19ubuntu1) 
configure arguments: -with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro,-rpath,/usr/local/bin/luajit' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-pcre-jit --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-pcre=/home/ubuntu/nginx/pcre-8.36 --add-module=/home/ubuntu/nginx/ngx_devel_kit-0.2.19 --add-module=/home/ubuntu/nginx/lua-nginx-module-0.9.15

Note

On some platforms, the nginx -v command may give the following error due to the loading of shared libraries:

error while loading shared libraries: libluajit-5.1.so.2: cannot open shared object file: No such file or directory

In order to fix the error, append the /usr/local/lib/ path to the shared library path by executing the following command:

$ LD_LIBRARY_PATH=/usr/local/lib/:$LD_LIBRARY_PATH

Directives

While working with Lua directives, it is important to understand that NGINX processes a request in different life cycle phases. Each of the NGINX modules is executed in one of these phases. The following is a list of important phases of the NGINX request life cycle:

  • Location selection phase: The server selects the location block to serve the request
  • Location rewrite phase: HttpRewriteModule is executed in this phase if the request requires a location rewrite
  • Access phase: HttpAccessModule is executed in this phase to determine whether the request should be allowed, denied, or authenticated
  • Try files phase: The request tries to get a response using the try_files block
  • Content phase: A response is generated in this phase using one of the various content handlers in NGINX, for example, Proxy, FastCGI, and so on
  • Log phase: An access log is generated in this phase for the served request

The ngx_lua module provides the following directives to enable execution of the Lua code in one of the phases of NGINX execution.

lua_package_path

This directive specifies the lookup path for Lua scripts used in set_by_lua, content_by_lua, and other directives.

lua_shared_dict

This directive creates a Lua dictionary that is shared across all NGINX workers.

init_by_lua/init_by_lua_file

This directive specifies the Lua code (as a string) executed by NGINX's master process at the global Lua VM level. The code can register Lua's global variables and import Lua modules that can be used later in other Lua directives. Here's an example:

init_by_lua 'cjson = require "cjson"';

The init_by_lua_file directive is similar to init_by_lua. It executes the code specified in a file to set the global context. Both directives are available under the http section of an NGINX configuration.

set_by_lua/set_by_lua_file

This directive specifies the Lua code (as a string), a return variable, and certain optional arguments. It executes the code using the passed arguments and provides the value in the specified variable. Here's an example:

set_by_lua $sum 'return (10 + 20)';
echo $sum; 

Arguments passed to the Lua code can be accessed using the ngx.arg[i] directive. The directive can only return a single value from the code. If multiple values are required, we need to use the ngx.var.VariableName directive to create multiple variables. Here's an example:

set_by_lua $sum 'return (ngx.arg[1] + ngx.arg[2])' 10 20;
echo $sum;

The set_by_lua_file directive is similar to set_by_lua. It executes the code specified in a file using optional parameters and returns the value in the specified variable. Both directives are available under the if (in location), location, and server sections of an NGINX configuration.

content_by_lua/content_by_lua_file

This directive acts as a content provider and executes the Lua code (as a string) to generate an NGINX response. It is important to note that the directive must not be used with other content handles, such as Proxy, in the same location block.

The content_by_lua_file directive is similar to content_by_lua. It executes the code specified in a file to generate an NGINX response. Both directives are available under the location and if (in location) sections of an NGINX configuration. Here's an example:

location /content {
   content_by_lua 'ngx.say("hello ! Content from lua")';
}

header_filter_by_lua/header_filter_by_lua_file

NGINX allows the manipulation of response headers using Lua. The code can add new header fields or manipulate/delete existing response headers. The header_filter_by_lua directive executes the Lua code as a response header filter. The code can access response headers using ngx.header.HeaderFieldName variable.

The header_filter_by_lua_file directive is similar to header_filter_by_lua. It executes the code specified in a file to manipulate response headers. Both directives are available under the http, server, location, and if (in location) sections of an NGINX configuration. Here's an example:

location /content {
   content_by_lua 'ngx.say("hello ! Content from lua")';
   header_filter_by_lua 'ngx.header.X-Source = "LuaScript"';
}

body_filter_by_lua/body_filter_by_lua_file

The directive executes during the output-body-filter phase of NGINX and can be used to manipulate the output body. The complete response body is passed in the ngx.arg[1] variable. The Lua code can alter the contents of the variable to return a new output body. The ngx.arg[2] variable contains the eof flag.

The body_filter_by_lua_file directive is similar to body_filter_by_lua. It executes the code specified in a file to filter the output body. Both directives are available under the http, server, location, and if (in location) sections of an NGINX configuration. Here's an example:

location /content {
   content_by_lua 'ngx.say("hello ! Content from lua")';
   header_filter_by_lua 'ngx.header.content_length = nil';
   body_filter_by_lua 'ngx.arg[1]=string.upper("from body filer"..ngx.arg[1]) ';
}

Tip

In the HTTP protocol, the Content-Length header field signifies the length of the message body. On the client side, the protocol determines the size of the message transferred, known as the transfer length. The two lengths should be the same. If the two lengths are going to be different, then the length of the message body should not be specified. Thus, it is always recommended that you clear the Content-Length header field when the Lua code modifies the body length.

access_by_lua/access_by_lua_file

The directive executes the Lua code during the access phase of NGINX after the execution of ngx_http_access_module.

The access_by_lua_file directive is similar to access_by_lua. It executes code specified in a file to determine access. Both directives are available under the http, server, location, and if (in location) sections of an NGINX configuration. Here's an example:

location /content {
   content_by_lua 'ngx.say("hello ! Content from lua")';
   access_by_lua ' if ngx.var.remote_addr == "192.168.2.111" then 
          ngx.exit(ngx.HTTP_FORBIDDEN) 
        end'; 
}

rewrite_by_lua/rewrite_by_lua_file

The rewrite_by_lua directive executes Lua code during the rewrite phase of NGINX after the execution of ngx_http_rewrite_module.

The rewrite_by_lua_file directive is similar to rewrite_by_lua. It executes the code specified in a file during the rewrite phase. Both directives are available under the http, server, location, and if (in location) sections of an NGINX configuration. Here's an example:

location /content {
   content_by_lua 'ngx.say("hello ! Content from lua")';
   rewrite_by_lua ' if ngx.var.remote_addr == "192.168.2.111" then 
          ngx.redirect("/forbidden.html") 
        end'; 
}

log_by_lua/log_by_lua_file

The log_by_lua directive executes the Lua code during the log request phase of NGINX. The code does not replace NGINX access logs, but can do sundry things, such as tracking request times, logging messages, and so on. The messages logged using ngx.log() will be sent to the NGINX error log. It is important to note that the request body is not accessible in this API.

The log_by_lua_file directive is similar to log_by_lua. It executes the code specified in a file during the log-request phase. Both directives are available under the http, server, location, and if (in location) sections of an NGINX configuration. Here's an example:

location /content {
   echo "hello world!"
   log_by_lua 'ngx.log(ngx.NOTICE,"logging request response")';
}
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.119.138.202