### Additional spawn examples Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/pipe.md Examples of spawning processes with different command structures. ```lua local proc, err = ngx_pipe.spawn({"ls", "-l"}) local proc, err = ngx_pipe.spawn({"perl", "-e", "print 'hello, world'"}) ``` -------------------------------- ### Installing lua-resty-core with custom LUA_LIB_DIR Source: https://github.com/openresty/lua-resty-core/blob/master/README.markdown To resolve potential 'failed to load the 'resty.core' module' errors, install the module using 'make install' and specify the desired Lua library directory with LUA_LIB_DIR. ```bash cd lua-resty-core sudo make install LUA_LIB_DIR=/usr/local/share/lua/5.1 ``` ```bash cd lua-resty-core sudo make install LUA_LIB_DIR=/opt/nginx/lualib ``` -------------------------------- ### Log Messages Example Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/errlog.md This example demonstrates logging messages at different levels (INFO, WARN, ERR) and then retrieving them using `ngx.errlog.get_logs`. ```lua for i = 1, 20 do ngx.log(ngx.ERR, "test") end local errlog = require "ngx.errlog" local res = errlog.get_logs(10) -- the number of messages in the `res` table is 10 and the `res` table -- has 30 elements. ``` -------------------------------- ### Load and Set Upstream SSL Certificate and Key Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl/proxysslcert.md This example demonstrates loading a certificate and private key from files and setting them for an upstream SSL connection using `ngx.ssl.proxysslcert`. It requires the `ngx.ssl` and `ngx.ssl.proxysslcert` modules. ```lua local ssl = require "ngx.ssl" local proxy_ssl_cert = require "ngx.ssl.proxysslcert" -- NOTE: for illustration only, we don't handle error below local f = assert(io.open("/path/to/cert.crt")) local cert_data = f:read("*a") f:close() local cert, err = ssl.parse_pem_cert(cert_data) local ok, err = proxy_ssl_cert.set_cert(cert) local f = assert(io.open("/path/to/key.key")) local pkey_data = f:read("*a") f:close() local pkey, err = ssl.parse_pem_priv_key(pkey_data) local ok, err = proxy_ssl_cert.set_priv_key(pkey) ``` -------------------------------- ### Nginx Configuration with proxy_ssl_verify_by_lua Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl/proxysslverify.md Example nginx.conf demonstrating the usage of proxy_ssl_verify_by_lua for custom SSL certificate verification of upstream connections. ```nginx server { listen 443 ssl; server_name test.com; ssl_certificate /path/to/cert.crt; ssl_certificate_key /path/to/key.key; location /t { proxy_ssl_certificate /path/to/cert.crt; proxy_ssl_certificate_key /path/to/key.key; proxy_pass https://upstream; proxy_ssl_verify_by_lua_block { local proxy_ssl_vfy = require "ngx.ssl.proxysslverify" local cert, err = proxy_ssl_vfy.get_verify_cert() -- ocsp to verify cert -- check crl proxy_ssl_vfy.set_verify_result(0) } } ... } ``` -------------------------------- ### Configure NGINX for Dynamic SSL Certificates Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md Example NGINX configuration using ssl_certificate_by_lua_block to dynamically set certificates and private keys. ```nginx lua_package_path "/path/to/lua-resty-core/lib/?.lua;;"; server { listen 443 ssl; server_name test.com; # useless placeholders: just to shut up NGINX configuration # loader errors: ssl_certificate /path/to/fallback.crt; ssl_certificate_key /path/to/fallback.key; ssl_certificate_by_lua_block { local ssl = require "ngx.ssl" -- clear the fallback certificates and private keys -- set by the ssl_certificate and ssl_certificate_key -- directives above: local ok, err = ssl.clear_certs() if not ok then ngx.log(ngx.ERR, "failed to clear existing (fallback) certificates") return ngx.exit(ngx.ERROR) end -- assuming the user already defines the my_load_certificate_chain() -- herself. local pem_cert_chain = assert(my_load_certificate_chain()) local der_cert_chain, err = ssl.cert_pem_to_der(pem_cert_chain) if not der_cert_chain then ngx.log(ngx.ERR, "failed to convert certificate chain ", "from PEM to DER: ", err) return ngx.exit(ngx.ERROR) end local ok, err = ssl.set_der_cert(der_cert_chain) if not ok then ngx.log(ngx.ERR, "failed to set DER cert: ", err) return ngx.exit(ngx.ERROR) end -- assuming the user already defines the my_load_private_key() -- function herself. local pem_pkey = assert(my_load_private_key()) local passphrase = "password" -- or nil local der_pkey, err = ssl.priv_key_pem_to_der(pem_pkey, passphrase) if not der_pkey then ngx.log(ngx.ERR, "failed to convert private key ", "from PEM to DER: ", err) return ngx.exit(ngx.ERROR) end local ok, err = ssl.set_der_priv_key(der_pkey) if not ok then ngx.log(ngx.ERR, "failed to set DER private key: ", err) return ngx.exit(ngx.ERROR) end } location / { root html; } } ``` -------------------------------- ### Usage of resty.core.time in Nginx configuration Source: https://github.com/openresty/lua-resty-core/blob/master/lib/resty/core/time.md Example of how to require and use monotonic time functions within a content_by_lua_block. ```nginx location = /t { content_by_lua_block { local time = require "resty.core.time" ngx.say(time.monotonic_time()) ngx.say(time.monotonic_msec()) } } ``` -------------------------------- ### ngx.semaphore.new Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/semaphore.md Creates a new semaphore instance, optionally initialized with a starting count. ```APIDOC ## new ### Description Creates a new semaphore instance. The semaphore can be used to synchronize light threads within the same NGINX worker process. ### Parameters #### Arguments - **n** (number) - Optional - The initial count of the semaphore. Defaults to 0. ### Response - **sema** (object) - The semaphore instance. - **err** (string) - Error message if the creation fails. ``` -------------------------------- ### Fetch SSL Session by ID Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl/session.md Implement SSL session fetching logic within `ssl_session_fetch_by_lua_block`. This example shows how to retrieve a session ID and then look up the corresponding session data. It handles cache misses and errors. ```lua local ssl_sess = require "ngx.ssl.session" local sess_id, err = ssl_sess.get_session_id() if not sess_id then ngx.log(ngx.ERR, "failed to get session ID: ", err) -- considered a cache miss, and just return... return end -- the user is supposed to implement the my_lookup_ssl_session_by_id -- Lua function used below. She can look up an external memcached -- or redis cluster, for example. And she can also introduce a local -- cache layer at the same time... local sess, err = my_lookup_ssl_session_by_id(sess_id) if not sess then if err then ngx.log(ngx.ERR, "failed to look up the session by ID ", sess_id, ": ", err) return end -- cache miss...just return return end local ok, err = ssl_sess.set_serialized_session(sess) if not ok then ngx.log(ngx.ERR, "failed to set SSL session for ID ", sess_id, ": ", err) -- consider it as a cache miss... return end -- done here, SSL session successfully set and should resume accordingly... ``` -------------------------------- ### Splitting with Position Context Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/re.md The optional ctx table allows specifying a starting position for the split operation. ```lua local ngx_re = require "ngx.re" local res, err = ngx_re.split("a,b,c,d", ",", nil, {pos = 5}) -- res is now {"c", "d"} ``` -------------------------------- ### Nginx Configuration with Lua Keepalive (Not Recommended) Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/balancer.md This Nginx configuration demonstrates a non-recommended setup where both `balancer_by_lua` with `enable_keepalive` and Nginx's `keepalive` directives are used simultaneously. This can lead to conflicts and unexpected behavior. ```nginx http { upstream backend_ngx_keepalive { server 0.0.0.1; # placeholder balancer_by_lua_block { local balancer = require "ngx.balancer" local host = "example.org" balancer.set_current_peer("127.0.0.2", 8080, host) balancer.enable_keepalive(60, 100) } keepalive 60; keepalive_timeout 60s; keepalive_requests 100; } } ``` -------------------------------- ### Synchronize Threads in Different Contexts with ngx.semaphore Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/semaphore.md This example shows how to synchronize light threads across different request contexts, provided they run within the same NGINX worker process and lua_code_cache is enabled. It uses ngx.timer.at to schedule a handler that posts to the semaphore. ```nginx location = /t { content_by_lua_block { local semaphore = require "ngx.semaphore" local sema = semaphore.new() local outputs = {} local i = 1 local function out(s) outputs[i] = s i = i + 1 end local function handler() out("timer thread: sleeping for a little while...") ngx.sleep(0.1) -- wait a bit out("timer thread: posting on sema...") sema:post(1) end assert(ngx.timer.at(0, handler)) out("main thread: waiting on sema...") local ok, err = sema:wait(1) -- wait for a second at most if not ok then out("main thread: failed to wait on sema: ", err) else out("main thread: waited successfully.") end out("main thread: end.") ngx.say(table.concat(outputs, "\n")) } } ``` -------------------------------- ### Advanced Keepalive Pooling by IP, Port, and SNI Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/balancer.md An advanced Nginx configuration example demonstrating how to overcome NGINX's default upstream keepalive pooling limitations by pooling connections based on IP, port, and SNI using Lua. ```nginx http { upstream backend { server 0.0.0.1; # placeholder balancer_by_lua_block { local balancer = require "ngx.balancer" local host = "example.org" ``` -------------------------------- ### Store SSL Session Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl/session.md Implement SSL session storage logic within `ssl_session_store_by_lua_block`. This example retrieves the session ID and serialized session data, then schedules a save operation using a 0-delay timer. It includes error handling for session retrieval and timer creation. ```lua local ssl_sess = require "ngx.ssl.session" local sess_id, err = ssl_sess.get_session_id() if not sess_id then ngx.log(ngx.ERR, "failed to get session ID: ", err) -- just give up return end local sess, err = ssl_sess.get_serialized_session() if not sess then ngx.log(ngx.ERR, "failed to get SSL session from the ", "current connection: ", err) -- just give up return end -- for the best performance, we should avoid creating a closure -- dynamically here on the hot code path. Instead, we should -- put this function in one of our own Lua module files. this -- example is just for demonstration purposes... local function save_it(premature, sess_id, sess) -- the user is supposed to implement the -- my_save_ssl_session_by_id Lua function used below. -- She can save to an external memcached -- or redis cluster, for example. And she can also introduce -- a local cache layer at the same time... local sess, err = my_save_ssl_session_by_id(sess_id, sess) if not sess then if err then ngx.log(ngx.ERR, "failed to save the session by ID ", sess_id, ": ", err) return ngx.exit(ngx.ERROR) end -- cache miss...just return return end end -- create a 0-delay timer here... local ok, err = ngx.timer.at(0, save_it, sess_id, sess) if not ok then ngx.log(ngx.ERR, "failed to create a 0-delay timer: ", err) return end ``` -------------------------------- ### Bundle Certificates for Nginx Source: https://github.com/openresty/lua-resty-core/blob/master/t/cert/ocsp/cfssl/README.md Concatenate leaf, intermediate, and root CA certificates into a single bundle file. This format is often required for installation in web servers like Nginx. ```bash cat leaf.pem intermediate_ca.pem ca.pem > leaf-bundle.pem ``` -------------------------------- ### Handle Location Request and Get Master PID Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/process.md Handles requests at the /t location, displaying the current process type and the master process PID. Requires NGINX 1.13.8+. ```lua location = /t { content_by_lua_block { local process = require "ngx.process" ngx.say("process type: ", process.type()) ngx.say("master process pid: ", process.get_master_pid() or "-") } } ``` -------------------------------- ### Basic Usage of ngx.re Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/re.md Demonstrates basic string splitting and configuring the PCRE JIT stack size. ```lua local ngx_re = require "ngx.re" -- split local res, err = ngx_re.split("a,b,c,d", ",") --> res is now {"a", "b", "c", "d"} -- opt gx_re.opt("jit_stack_size", 128 * 1024) --> the PCRE jit stack can now handle more complex regular expressions ``` -------------------------------- ### Spawn a sub-process Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/pipe.md Shows how to spawn a process using an array of arguments. ```lua local ngx_pipe = require "ngx.pipe" local proc, err = ngx_pipe.spawn({"sh", "-c", "sleep 0.1 && exit 2"}) if not proc then ngx.say(err) return end ``` -------------------------------- ### Get the PID of a Sub-process Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/pipe.md Retrieve the process ID (PID) of the currently running sub-process. ```lua pid = proc:pid() ``` -------------------------------- ### Initialize and Log Process Type Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/process.md Initializes the privileged agent process and logs the process type during Nginx startup. Requires the ngx.process module. ```lua init_by_lua_block { local process = require "ngx.process" -- enables privileged agent process local ok, err = process.enable_privileged_agent() if not ok then ngx.log(ngx.ERR, "enables privileged agent failed error:", err) end -- output process type ngx.log(ngx.INFO, "process type: ", process.type()) } ``` ```lua init_worker_by_lua_block { local process = require "ngx.process" ngx.log(ngx.INFO, "process type: ", process.type()) } ``` -------------------------------- ### Get Upstream SSL Pointer Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md Retrieves the OpenSSL `SSL*` object for the current upstream connection. ```APIDOC ## GET ssl.get_upstream_ssl_pointer ### Description Retrieves the OpenSSL `SSL*` object for the current upstream connection. Returns an FFI pointer on success, or a `nil` value and a string describing the error otherwise. If you need to retain the pointer beyond the current phase then you will need to use OpenSSL's `SSL_up_ref` to increase the reference count. If you do, ensure that your reference is released with `SSL_free`. This function was first added in version `0.1.33`. ### Method GET ### Endpoint N/A (Function call within Lua code) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```lua local ssl_ptr, err = require('ngx.ssl').get_upstream_ssl_pointer() if ssl_ptr then -- Use ssl_ptr else ngx.log(ngx.ERR, err) end ``` ### Response #### Success Response (200) - **ssl_ptr** (pointer) - An FFI pointer to the OpenSSL `SSL*` object. - **err** (string) - Error message if retrieval fails (nil on success). #### Response Example ```json { "ssl_ptr": "", "err": null } ``` ``` -------------------------------- ### Get Request SSL Pointer Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md Retrieves the OpenSSL `SSL*` object for the current downstream connection. ```APIDOC ## GET ssl.get_req_ssl_pointer ### Description Retrieves the OpenSSL `SSL*` object for the current downstream connection. Returns an FFI pointer on success, or a `nil` value and a string describing the error otherwise. If you need to retain the pointer beyond the current phase then you will need to use OpenSSL's `SSL_up_ref` to increase the reference count. If you do, ensure that your reference is released with `SSL_free`. This function was first added in version `0.1.16`. ### Method GET ### Endpoint N/A (Function call within Lua code) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```lua local ssl_ptr, err = require('ngx.ssl').get_req_ssl_pointer() if ssl_ptr then -- Use ssl_ptr else ngx.log(ngx.ERR, err) end ``` ### Response #### Success Response (200) - **ssl_ptr** (pointer) - An FFI pointer to the OpenSSL `SSL*` object. - **err** (string) - Error message if retrieval fails (nil on success). #### Response Example ```json { "ssl_ptr": "", "err": null } ``` ``` -------------------------------- ### Spawn a process using shell mode Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/pipe.md Demonstrates spawning a process by passing a command string, which invokes the system shell. ```lua local ngx_pipe = require "ngx.pipe" local proc, err = ngx_pipe.spawn("sleep 0.1 && exit 2") if not proc then ngx.say(err) return end ``` -------------------------------- ### Get Semaphore Count Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/semaphore.md Returns the current number of available resources or waiting threads in the semaphore. ```APIDOC ## Get Semaphore Count ### Description Returns the number of resources readily available in the `sema` semaphore instance (if any). When the returned number is negative, it means the number of "light threads" waiting on this semaphore. ### Method `sema:count() ### Response #### Success Response (200) - **count** (number) - The number of available resources. A negative number indicates the count of waiting threads. ``` -------------------------------- ### Load the ngx.ssl.clienthello module Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl/clienthello.md Standard way to import the module within a Lua block. ```lua local ssl_clt = require "ngx.ssl.clienthello" ``` -------------------------------- ### Count characters using wc command Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/pipe.md Demonstrates feeding data to a spawned process and reading the output line by line. ```nginx location = /t { content_by_lua_block { local ngx_pipe = require "ngx.pipe" local select = select local function count_char(...) local proc = ngx_pipe.spawn({'wc', '-c'}) local n = select('#', ...) for i = 1, n do local arg = select(i, ...) local bytes, err = proc:write(arg) if not bytes then ngx.say(err) return end end local ok, err = proc:shutdown('stdin') if not ok then ngx.say(err) return end local data, err = proc:stdout_read_line() if not data then ngx.say(err) return end ngx.say(data) end count_char(("1234"):rep(2048)) } } ``` -------------------------------- ### Retrieve SSL Client Hello Ciphers Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl/clienthello.md Demonstrates how to fetch and iterate over client hello ciphers within an Nginx configuration block. ```nginx # nginx.conf server { listen 443 ssl; server_name test.com; ssl_client_hello_by_lua_block { local ssl_clt = require "ngx.ssl.clienthello" local ciphers, err = ssl_clt.get_client_hello_ciphers() if not ciphers then ngx.log(ngx.ERR, "failed to get_client_hello_ciphers()") ngx.exit(ngx.ERROR) end for i, cipher in ipairs(ciphers) do ngx.log(ngx.INFO, "ciphers ", cipher) end } ssl_certificate test.crt; ssl_certificate_key test.key; } ``` -------------------------------- ### spawn Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/pipe.md Creates and returns a new sub-process instance for communication. ```APIDOC ## spawn ### Description Creates and returns a new sub-process instance we can communicate with later. ### Syntax proc, err = pipe_module.spawn(args, opts?) ### Parameters - **args** (table or string) - Required - A single level array-like Lua table with string values, or a single string to be executed by the shell. - **opts** (table) - Optional - Configuration options for the spawned process. ### Response - **proc** (object) - The sub-process instance. - **err** (string) - Error message if the process could not be spawned. ``` -------------------------------- ### Get Current Nginx Process Type Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/process.md Returns the type of the current Nginx process. Can be 'master', 'worker', 'single', 'signaller', or 'privileged agent'. ```lua local process = require "ngx.process" ngx.say("process type:", process.type()) -- RESPONSE: worker ``` -------------------------------- ### Get SSL Verification Result Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl/proxysslverify.md Retrieves the current verification result code for the SSL server certificate. This function is applicable only within the proxy_ssl_verify_by_lua context. ```lua verify_result, err = proxy_ssl_vfy.get_verify_result() ``` -------------------------------- ### Spawn a Sub-process with Default Settings Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/pipe.md Use `ngx.pipe.spawn` to execute a command. Ensure the `env PATH` directive is configured in Nginx if sub-process searching relies on the environment. ```nginx env PATH; ... ``` ```lua local ngx_pipe = require "ngx.pipe" local proc = ngx_pipe.spawn({'ls'}) ``` -------------------------------- ### Get SSL Server Certificate Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl/proxysslverify.md Retrieves the server certificate that Nginx received from the upstream SSL connection. This function is intended for use within the proxy_ssl_verify_by_lua context. ```lua local cert, err = proxy_ssl_vfy.get_verify_cert() ``` -------------------------------- ### Configure SSL protocols dynamically in NGINX Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl/clienthello.md Demonstrates using ssl_client_hello_by_lua_block to set SSL protocols based on the SNI hostname. ```nginx # nginx.conf 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; ... } ``` -------------------------------- ### Get Shared SSL Ciphers Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md Returns an array of cipher IDs supported by both the server and client for the current SSL connection. Optionally filters GREASE cipher values. ```APIDOC ## GET ssl.get_req_shared_ssl_ciphers ### Description Returns an array of cipher IDs that are supported by both the server and client for the current SSL connection. The optional argument `filter_grease` defaults to `true`. Set it to `false` explicitly if you want to include GREASE cipher values in the results. GREASE (Generate Random Extensions And Sustain Extensibility) cipher values are automatically filtered out from the results by default. Returns `nil` and an error string on failure. This function can be called in any context where downstream https is used. This function was first added in version `0.1.29`. ### Method GET ### Endpoint N/A (Function call within Lua code) ### Parameters #### Path Parameters None #### Query Parameters - **filter_grease** (boolean) - Optional. Defaults to `true`. Set to `false` to include GREASE cipher values. #### Request Body None ### Request Example ```lua local ciphers, err = require('ngx.ssl').get_req_shared_ssl_ciphers() if ciphers then for i, cipher in ipairs(ciphers) do ngx.log(ngx.INFO, "Cipher: ", cipher) end else ngx.log(ngx.ERR, err) end ``` ### Response #### Success Response (200) - **ciphers** (array of strings) - An array of supported SSL cipher IDs. #### Response Example ```json { "ciphers": ["TLS_AES_128_GCM_SHA256", "TLS_AES_256_GCM_SHA384"] } ``` ``` -------------------------------- ### Get Server Port Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md Retrieves the server port for the current SSL connection. Returns nil if the server does not have a port. This function can be called in any context where downstream HTTPS is used. ```lua local port, err = ssl.server_port() if not port then ngx.log(ngx.ERR, "failed to get server port: ", err) return end print("Server port: ", port) ``` -------------------------------- ### Spawn a Sub-process with Custom Options Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/pipe.md Control spawned process behavior using the `opts` table, including merging stderr, setting buffer sizes, and defining environment variables or the working directory. ```lua local opts = { merge_stderr = true, buffer_size = 256, environ = {"PATH=/tmp/bin", "CWD=/tmp/work"} } local proc, err = ngx_pipe.spawn({"sh", "-c", ">&2 echo data"}, opts) if not proc then ngx.say(err) return end ``` -------------------------------- ### Add Headers and Set Status using ngx.resp Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/resp.md Demonstrates how to add multiple headers and set a custom status code with a reason phrase using the ngx.resp module. ```lua local ngx_resp = require "ngx.resp" -- add_header gx_resp.add_header("Foo", "bar") gx_resp.add_header("Foo", "baz") --> there will be two new headers in HTTP response: --> Foo: bar and Foo: baz gx_resp.set(531, "user defined error") --> the response line will be: 531 user defined error ``` -------------------------------- ### Get Master Process PID Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/process.md Returns the process ID (PID) of the Nginx master process. Requires NGINX 1.13.8+ and lua-resty-core v0.1.14 or later. Returns nil if not supported. ```lua pid = process_module.get_master_pid() ``` -------------------------------- ### HTTP Balancer Configuration with Lua Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/balancer.md Configures a dynamic upstream balancer for the HTTP subsystem using Lua. Requires `ngx.balancer.set_current_peer` to specify the backend host and port. ```nginx http { upstream backend { server 0.0.0.1; # just an invalid address as a place holder balancer_by_lua_block { local balancer = require "ngx.balancer" -- well, usually we calculate the peer's host and port -- according to some balancing policies instead of using -- hard-coded values like below local host = "127.0.0.2" local port = 8080 local ok, err = balancer.set_current_peer(host, port) if not ok then ngx.log(ngx.ERR, "failed to set the current peer: ", err) return ngx.exit(500) end } keepalive 10; # connection pool } server { # this is the real entry point listen 80; location / { # make use of the upstream named "backend" defined above: proxy_pass http://backend/fake; } } server { # this server is just for mocking up a backend peer here... listen 127.0.0.2:8080; location = /fake { echo "this is the fake backend peer..."; } } } ``` -------------------------------- ### Get System Error Log Filter Level Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/errlog.md Retrieve the current Nginx core's error log filter level as an integer. This value can be used with `errlog.set_filter_level` to adjust logging. ```lua local errlog = require "ngx.errlog" local log_level = errlog.get_sys_filter_level() -- Now the filter level is always one level higher than system default log level on priority local status, err = errlog.set_filter_level(log_level - 1) if not status then ngx.log(ngx.ERR, err) return end ``` -------------------------------- ### ngx_re.opt Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/re.md Configures regex settings, specifically the PCRE JIT stack size. ```APIDOC ## ngx_re.opt ### Description Allows changing of regex settings, currently limited to the 'jit_stack_size' of the PCRE engine. ### Parameters - **option** (string) - Required - The setting name (e.g., 'jit_stack_size'). - **value** (number) - Required - The value to set (cannot be lower than 32K). ### Request Example require "ngx.re".opt("jit_stack_size", 200 * 1024) ``` -------------------------------- ### Get Server Name Indication (SNI) Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md Retrieves the TLS SNI name set by the client. Returns nil if the client does not provide it. This is useful for identifying the website and loading the corresponding SSL certificate. ```lua local name, err = ssl.server_name() if not name then ngx.log(ngx.ERR, "failed to get server name: ", err) return end print("SNI name: ", name) ``` -------------------------------- ### ngx.ssl.clienthello.get_client_hello_ext Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl/clienthello.md Retrieves the raw data for a specific SSL client hello extension type. This function is intended for use within `ssl_client_hello_by_lua*` blocks. ```APIDOC ## GET /nginx.conf/ssl_client_hello_by_lua ### Description Retrieves the raw byte data of a specified SSL client hello extension. Returns `nil` if the extension type is not found. This function is intended for use within `ssl_client_hello_by_lua*` blocks. ### Method N/A (Lua API within Nginx configuration) ### Endpoint N/A (Contextual API within `ssl_client_hello_by_lua` block) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **ext_type** (number) - Required - The type of the extension to retrieve (e.g., `0` for Server Name Indication). ### Request Example ```nginx server { listen 443 ssl; server_name test.com; ssl_client_hello_by_lua_block { local ssl_clt = require "ngx.ssl.clienthello" -- Get Server Name Indication (SNI) extension data local ext_data = ssl_clt.get_client_hello_ext(0) -- 0 is TLSEXT_TYPE_server_name if ext_data then -- Example: Check if it's a hostname (TLSEXT_NAMETYPE_host_name is 0) if byte(ext_data, 3) == 0 then local hostname = ngx.decode_base64(string.sub(ext_data, 4)) ngx.log(ngx.INFO, "Client requested hostname: ", hostname) end end } ssl_certificate test.crt; ssl_certificate_key test.key; } ``` ### Response #### Success Response (200) - **ext_data** (string) - The raw byte data of the requested extension, or `nil` if the extension is not present. #### Response Example ```lua -- If SNI extension is present and contains a hostname: -- Client requested hostname: example.com ``` ``` -------------------------------- ### Get Last Failure Details Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/balancer.md Retrieve the state name and status code of the previous failed upstream attempt when the `next_upstream` mechanism is active. Returns `nil` if the current attempt is the first one. ```lua state_name, status_code = balancer.get_last_failure() ``` -------------------------------- ### Stream Balancer Configuration with Lua Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/balancer.md Configures a dynamic upstream balancer for the stream subsystem using Lua. Requires `ngx.balancer.set_current_peer` to specify the backend host and port. ```nginx stream { upstream backend { server 0.0.0.1:1234; # just an invalid address as a place holder balancer_by_lua_block { local balancer = require "ngx.balancer" -- well, usually we calculate the peer's host and port -- according to some balancing policies instead of using -- hard-coded values like below local host = "127.0.0.2" local port = 8080 local ok, err = balancer.set_current_peer(host, port) if not ok then ngx.log(ngx.ERR, "failed to set the current peer: ", err) return ngx.exit(ngx.ERROR) end } } server { # this is the real entry point listen 10000; # make use of the upstream named "backend" defined above: proxy_pass backend; } server { # this server is just for mocking up a backend peer here... listen 127.0.0.2:8080; echo "this is the fake backend peer..."; } } ``` -------------------------------- ### ngx.ssl.clienthello.get_client_hello_ext_present Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl/clienthello.md Retrieves a list of present extension types from the SSL client hello message. This function is intended for use within `ssl_client_hello_by_lua*` blocks. ```APIDOC ## GET /nginx.conf/ssl_client_hello_by_lua ### Description Retrieves a Lua table containing the types of extensions present in the client hello message. GREASE extensions are excluded. The order of extensions may be randomized by modern browsers, so sorting might be necessary. ### Method N/A (Lua API within Nginx configuration) ### Endpoint N/A (Contextual API within `ssl_client_hello_by_lua` block) ### Parameters None ### Request Example ```nginx server { listen 443 ssl; server_name test.com; ssl_client_hello_by_lua_block { local ssl_clt = require "ngx.ssl.clienthello" local exts = ssl_clt.get_client_hello_ext_present() if not exts then ngx.log(ngx.ERR, "failed to get_client_hello_ext_present()") ngx.exit(ngx.ERROR) end for i, ext in ipairs(exts) do ngx.log(ngx.INFO, "extension ", ext) end } ssl_certificate test.crt; ssl_certificate_key test.key; } ``` ### Response #### Success Response (200) - **exts** (table) - A Lua table containing the extension types present in the client hello message. #### Response Example ```lua -- Example output logged to Nginx error log: -- extension 0 -- extension 10 -- extension 11 ``` ``` -------------------------------- ### Get Upstream TLS Version Integer Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/proxyssl.md Call this function within an upstream SSL context to retrieve the TLS version as an integer of the current upstream SSL connection. It returns the version integer and an error message if any. ```lua ver, err = proxy_ssl.get_tls1_version() ``` -------------------------------- ### ngx.ssl.session API Methods Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl/session.md This section provides documentation for the methods available in the ngx.ssl.session Lua API. ```APIDOC ## ngx.ssl.session API ### Description The `ngx.ssl.session` module provides Lua functions to interact with SSL session data and session IDs for NGINX downstream SSL connections. ### Methods #### get_session_id ##### Description Retrieves the SSL session ID for the current connection. ##### Endpoint Not applicable (Lua API function) #### get_serialized_session ##### Description Retrieves the serialized SSL session data for the current connection. ##### Endpoint Not applicable (Lua API function) #### set_serialized_session ##### Description Sets the serialized SSL session data for the current connection. ##### Endpoint Not applicable (Lua API function) ``` -------------------------------- ### Get Upstream TLS Version String Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/proxyssl.md Call this function within an upstream SSL context to retrieve the TLS version string of the current upstream SSL connection. It returns the version string and an error message if any. ```lua ver, err = proxy_ssl.get_tls1_version_str() ``` -------------------------------- ### Get Upstream SSL Pointer Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md Retrieves the OpenSSL `SSL*` object for the current upstream connection. Returns an FFI pointer on success or `nil` and an error string. If retaining the pointer, use `SSL_up_ref` and ensure release with `SSL_free`. ```lua local ssl_ptr, err = ssl.get_upstream_ssl_pointer() ``` -------------------------------- ### Set SSL Protocols Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl/clienthello.md Configures supported SSL protocols for the downstream connection. Must be called within the ssl_client_hello_by_lua* context. ```lua ssl_clt.set_protocols({"TLSv1.1", "TLSv1.2", "TLSv1.3"}) ``` -------------------------------- ### Get Downstream SSL Pointer Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md Retrieves the OpenSSL `SSL*` object for the current downstream connection. Returns an FFI pointer on success or `nil` and an error string. If retaining the pointer, use `SSL_up_ref` and ensure release with `SSL_free`. ```lua local ssl_ptr, err = ssl.get_req_ssl_pointer() ``` -------------------------------- ### Require ngx.ssl.proxysslverify Module Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl/proxysslverify.md Demonstrates how to load the ngx.ssl.proxysslverify module in Lua. This is a prerequisite for using its functions. ```lua local proxy_ssl_vfy = require "ngx.ssl.proxysslverify" ``` -------------------------------- ### Create a new semaphore instance Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/semaphore.md Initializes a new semaphore object. The default resource count is 0. ```lua local semaphore = require "ngx.semaphore" local sema, err = semaphore.new() if not sema then ngx.say("create semaphore failed: ", err) end ``` -------------------------------- ### Get Server Random Value Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md Retrieves the random value sent from the server during the SSL/TLS handshake. Specify `outlen` for maximum length; if zero, returns total length. Defaults to 32 if omitted. Usable in any downstream HTTPS context. ```lua local server_random = ssl.get_server_random(32) ``` -------------------------------- ### Initiate CA Root Certificate Pair Source: https://github.com/openresty/lua-resty-core/blob/master/t/cert/ocsp/cfssl/README.md Create the root certificate authority (CA) by generating a certificate pair. This is the first step in establishing a trust hierarchy. ```bash cfssl gencert -initca ca_csr.json | cfssljson -bare ca ``` -------------------------------- ### Get Raw Server Address Information Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md Retrieves the raw server address (IP or Unix socket path) accessed by the client. It returns the address data, address type, and an error message if any. This is useful for logging or debugging connection details. ```lua local ssl = require "ngx.ssl" local byte = string.byte local addr, addrtyp, err = ssl.raw_server_addr() if not addr then ngx.log(ngx.ERR, "failed to fetch raw server addr: ", err) return end if addrtyp == "inet" then -- IPv4 ip = string.format("%d.%d.%d.%d", byte(addr, 1), byte(addr, 2), byte(addr, 3), byte(addr, 4)) print("Using IPv4 address: ", ip) elseif addrtyp == "unix" then -- UNIX print("Using unix socket file ", addr) else -- IPv6 -- leave as an exercise for the readers end ``` -------------------------------- ### Load the OCSP Module Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ocsp.md Import the module in Lua code. ```lua local ocsp = require "ngx.ocsp" ``` -------------------------------- ### raw_server_addr Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md Retrieves the raw server address that the client accessed in the current SSL connection. It returns the address data, address type (`unix`, `inet`, or `inet6`), and an error message if applicable. Examples show how to interpret IPv4 and UNIX domain socket addresses. ```APIDOC ## raw_server_addr ### Description Returns the raw server address actually accessed by the client in the current SSL connection. ### Method Not explicitly defined, likely a function call within Lua. ### Endpoint N/A (Lua function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```lua local ssl = require "ngx.ssl" local addr, addrtyp, err = ssl.raw_server_addr() if not addr then ngx.log(ngx.ERR, "failed to fetch raw server addr: ", err) return end if addrtyp == "inet" then -- IPv4 ip = string.format("%d.%d.%d.%d", string.byte(addr, 1), string.byte(addr, 2), string.byte(addr, 3), string.byte(addr, 4)) print("Using IPv4 address: ", ip) elseif addrtyp == "unix" then -- UNIX print("Using unix socket file ", addr) else -- IPv6 -- leave as an exercise for the readers end ``` ### Response #### Success Response (200) - **addr_data** (string) - The address data (e.g., IP address string, file path). - **addr_type** (string) - The type of address: `unix`, `inet` (IPv4), or `inet6` (IPv6). #### Response Example ```json { "addr_data": "192.168.1.100", "addr_type": "inet" } ``` #### Error Response - **nil, nil** - If an error occurs. - **err** (string) - Description of the error. ``` -------------------------------- ### Load ngx.ssl.session Module Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl/session.md To use the SSL session API, require the `ngx.ssl.session` module in your Lua code. ```lua local ssl_sess = require "ngx.ssl.session" ``` -------------------------------- ### ngx.ssl.session Module Usage Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl/session.md Demonstrates how to load and use the `ngx.ssl.session` module in Lua for NGINX configurations. ```APIDOC ## Loading the Module To use the `ngx.ssl.session` module in your Lua scripts, you need to require it: ```lua local ssl_sess = require "ngx.ssl.session" ``` ## ssl_session_fetch_by_lua* Context Example This example shows how to fetch an SSL session ID and then look up the corresponding session data. ### Description This block is executed when NGINX needs to fetch an SSL session from a cache. ### Method N/A (Lua block within NGINX configuration) ### Endpoint N/A (Configured within `nginx.conf`) ### Parameters None directly for the block, but `ngx.ssl.session.get_session_id()` is used internally. ### Request Body N/A ### Request Example ```lua ssl_session_fetch_by_lua_block { local ssl_sess = require "ngx.ssl.session" local sess_id, err = ssl_sess.get_session_id() if not sess_id then ngx.log(ngx.ERR, "failed to get session ID: ", err) return end -- Assume my_lookup_ssl_session_by_id is a user-defined Lua function local sess, err = my_lookup_ssl_session_by_id(sess_id) if not sess then if err then ngx.log(ngx.ERR, "failed to look up the session by ID ", sess_id, ": ", err) return end -- cache miss return end local ok, err = ssl_sess.set_serialized_session(sess) if not ok then ngx.log(ngx.ERR, "failed to set SSL session for ID ", sess_id, ": ", err) return end } ``` ### Response N/A (Operates within NGINX context) ## ssl_session_store_by_lua* Context Example This example demonstrates storing a serialized SSL session. ### Description This block is executed when NGINX needs to store an SSL session. ### Method N/A (Lua block within NGINX configuration) ### Endpoint N/A (Configured within `nginx.conf`) ### Parameters None directly for the block, but `ngx.ssl.session.get_session_id()` and `ngx.ssl.session.get_serialized_session()` are used internally. ### Request Body N/A ### Request Example ```lua ssl_session_store_by_lua_block { local ssl_sess = require "ngx.ssl.session" local sess_id, err = ssl_sess.get_session_id() if not sess_id then ngx.log(ngx.ERR, "failed to get session ID: ", err) return end local sess, err = ssl_sess.get_serialized_session() if not sess then ngx.log(ngx.ERR, "failed to get SSL session from the ", "current connection: ", err) return end -- Assume my_save_ssl_session_by_id is a user-defined Lua function local function save_it(premature, sess_id, sess) local _, err = my_save_ssl_session_by_id(sess_id, sess) if err then ngx.log(ngx.ERR, "failed to save the session by ID ", sess_id, ": ", err) return ngx.exit(ngx.ERROR) end end local ok, err = ngx.timer.at(0, save_it, sess_id, sess) if not ok then ngx.log(ngx.ERR, "failed to create a 0-delay timer: ", err) return end } ``` ### Response N/A (Operates within NGINX context) ``` -------------------------------- ### Get SSL Session Master Key Source: https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md Retrieves the master secret from the current SSL session, primarily useful for TLS 1.2. Specify `outlen` for maximum length; if zero, returns total length. Defaults to 48 if omitted. Usable in any downstream HTTPS context. ```lua local master_key = ssl.get_session_master_key(48) ```