Merge ~knyar/ubuntu/+source/nginx:lua-0.10.15-focal into ubuntu/+source/nginx:ubuntu/focal-proposed

Proposed by Anton Tolchanov
Status: Needs review
Proposed branch: ~knyar/ubuntu/+source/nginx:lua-0.10.15-focal
Merge into: ubuntu/+source/nginx:ubuntu/focal-proposed
Diff against target: 28926 lines (+12676/-3460)
180 files modified
debian/changelog (+6/-0)
debian/modules/control (+2/-1)
debian/modules/http-lua/README.markdown (+271/-95)
debian/modules/http-lua/config (+45/-0)
debian/modules/http-lua/doc/HttpLuaModule.wiki (+256/-87)
debian/modules/http-lua/src/api/ngx_http_lua_api.h (+8/-1)
debian/modules/http-lua/src/ngx_http_lua_accessby.c (+3/-1)
debian/modules/http-lua/src/ngx_http_lua_api.c (+1/-1)
debian/modules/http-lua/src/ngx_http_lua_args.c (+8/-3)
debian/modules/http-lua/src/ngx_http_lua_balancer.c (+6/-1)
debian/modules/http-lua/src/ngx_http_lua_bodyfilterby.c (+23/-27)
debian/modules/http-lua/src/ngx_http_lua_bodyfilterby.h (+1/-1)
debian/modules/http-lua/src/ngx_http_lua_cache.c (+19/-4)
debian/modules/http-lua/src/ngx_http_lua_clfactory.c (+63/-22)
debian/modules/http-lua/src/ngx_http_lua_common.h (+52/-9)
debian/modules/http-lua/src/ngx_http_lua_consts.c (+3/-0)
debian/modules/http-lua/src/ngx_http_lua_contentby.c (+2/-0)
debian/modules/http-lua/src/ngx_http_lua_control.c (+4/-1)
debian/modules/http-lua/src/ngx_http_lua_coroutine.c (+17/-1)
debian/modules/http-lua/src/ngx_http_lua_directive.c (+45/-17)
debian/modules/http-lua/src/ngx_http_lua_exception.h (+3/-3)
debian/modules/http-lua/src/ngx_http_lua_headerfilterby.c (+2/-1)
debian/modules/http-lua/src/ngx_http_lua_headers.c (+72/-90)
debian/modules/http-lua/src/ngx_http_lua_headers_in.c (+9/-1)
debian/modules/http-lua/src/ngx_http_lua_headers_out.c (+15/-5)
debian/modules/http-lua/src/ngx_http_lua_headers_out.h (+3/-3)
debian/modules/http-lua/src/ngx_http_lua_initworkerby.c (+45/-3)
debian/modules/http-lua/src/ngx_http_lua_input_filters.c (+137/-0)
debian/modules/http-lua/src/ngx_http_lua_input_filters.h (+29/-0)
debian/modules/http-lua/src/ngx_http_lua_log.c (+23/-0)
debian/modules/http-lua/src/ngx_http_lua_logby.c (+2/-1)
debian/modules/http-lua/src/ngx_http_lua_misc.c (+27/-0)
debian/modules/http-lua/src/ngx_http_lua_module.c (+59/-0)
debian/modules/http-lua/src/ngx_http_lua_ndk.c (+41/-0)
debian/modules/http-lua/src/ngx_http_lua_phase.c (+18/-0)
debian/modules/http-lua/src/ngx_http_lua_pipe.c (+2475/-0)
debian/modules/http-lua/src/ngx_http_lua_pipe.h (+95/-0)
debian/modules/http-lua/src/ngx_http_lua_probe.h (+2/-1)
debian/modules/http-lua/src/ngx_http_lua_regex.c (+8/-4)
debian/modules/http-lua/src/ngx_http_lua_req_method.c (+4/-3)
debian/modules/http-lua/src/ngx_http_lua_rewriteby.c (+13/-3)
debian/modules/http-lua/src/ngx_http_lua_script.c (+2/-2)
debian/modules/http-lua/src/ngx_http_lua_setby.c (+15/-19)
debian/modules/http-lua/src/ngx_http_lua_setby.h (+1/-1)
debian/modules/http-lua/src/ngx_http_lua_shdict.c (+37/-26)
debian/modules/http-lua/src/ngx_http_lua_socket_tcp.c (+1311/-578)
debian/modules/http-lua/src/ngx_http_lua_socket_tcp.h (+26/-3)
debian/modules/http-lua/src/ngx_http_lua_socket_udp.c (+50/-6)
debian/modules/http-lua/src/ngx_http_lua_ssl_certby.c (+78/-13)
debian/modules/http-lua/src/ngx_http_lua_ssl_ocsp.c (+4/-0)
debian/modules/http-lua/src/ngx_http_lua_ssl_session_fetchby.c (+19/-4)
debian/modules/http-lua/src/ngx_http_lua_ssl_session_fetchby.h (+5/-1)
debian/modules/http-lua/src/ngx_http_lua_ssl_session_storeby.c (+19/-3)
debian/modules/http-lua/src/ngx_http_lua_string.c (+14/-0)
debian/modules/http-lua/src/ngx_http_lua_subrequest.c (+14/-0)
debian/modules/http-lua/src/ngx_http_lua_time.c (+71/-0)
debian/modules/http-lua/src/ngx_http_lua_timer.c (+39/-5)
debian/modules/http-lua/src/ngx_http_lua_uthread.c (+2/-1)
debian/modules/http-lua/src/ngx_http_lua_util.c (+163/-19)
debian/modules/http-lua/src/ngx_http_lua_util.h (+62/-12)
debian/modules/http-lua/src/ngx_http_lua_variable.c (+22/-13)
debian/modules/http-lua/src/ngx_http_lua_worker.c (+26/-0)
debian/modules/http-lua/t/.gitignore (+2/-0)
debian/modules/http-lua/t/000--init.t (+0/-5)
debian/modules/http-lua/t/001-set.t (+15/-8)
debian/modules/http-lua/t/002-content.t (+19/-19)
debian/modules/http-lua/t/004-require.t (+6/-6)
debian/modules/http-lua/t/005-exit.t (+1/-1)
debian/modules/http-lua/t/009-log.t (+9/-3)
debian/modules/http-lua/t/011-md5_bin.t (+1/-1)
debian/modules/http-lua/t/013-base64.t (+1/-1)
debian/modules/http-lua/t/014-bugs.t (+25/-24)
debian/modules/http-lua/t/016-resp-header.t (+541/-87)
debian/modules/http-lua/t/017-exec.t (+2/-2)
debian/modules/http-lua/t/020-subrequest.t (+72/-68)
debian/modules/http-lua/t/022-redirect.t (+52/-1)
debian/modules/http-lua/t/023-rewrite/client-abort.t (+3/-3)
debian/modules/http-lua/t/023-rewrite/exec.t (+2/-2)
debian/modules/http-lua/t/023-rewrite/mixed.t (+2/-2)
debian/modules/http-lua/t/023-rewrite/multi-capture.t (+1/-1)
debian/modules/http-lua/t/023-rewrite/redirect.t (+40/-0)
debian/modules/http-lua/t/023-rewrite/req-socket.t (+3/-3)
debian/modules/http-lua/t/023-rewrite/sanity.t (+14/-14)
debian/modules/http-lua/t/023-rewrite/socket-keepalive.t (+6/-6)
debian/modules/http-lua/t/023-rewrite/subrequest.t (+21/-21)
debian/modules/http-lua/t/023-rewrite/tcp-socket-timeout.t (+6/-6)
debian/modules/http-lua/t/023-rewrite/tcp-socket.t (+16/-16)
debian/modules/http-lua/t/023-rewrite/uthread-exec.t (+6/-6)
debian/modules/http-lua/t/023-rewrite/uthread-exit.t (+20/-20)
debian/modules/http-lua/t/023-rewrite/uthread-redirect.t (+2/-2)
debian/modules/http-lua/t/023-rewrite/uthread-spawn.t (+33/-29)
debian/modules/http-lua/t/024-access/client-abort.t (+3/-3)
debian/modules/http-lua/t/024-access/exec.t (+1/-1)
debian/modules/http-lua/t/024-access/mixed.t (+5/-5)
debian/modules/http-lua/t/024-access/multi-capture.t (+1/-1)
debian/modules/http-lua/t/024-access/sanity.t (+15/-15)
debian/modules/http-lua/t/024-access/subrequest.t (+21/-21)
debian/modules/http-lua/t/024-access/uthread-exec.t (+6/-6)
debian/modules/http-lua/t/024-access/uthread-exit.t (+19/-19)
debian/modules/http-lua/t/024-access/uthread-redirect.t (+2/-2)
debian/modules/http-lua/t/024-access/uthread-spawn.t (+33/-29)
debian/modules/http-lua/t/025-codecache.t (+153/-23)
debian/modules/http-lua/t/027-multi-capture.t (+2/-2)
debian/modules/http-lua/t/028-req-header.t (+460/-74)
debian/modules/http-lua/t/030-uri-args.t (+185/-37)
debian/modules/http-lua/t/031-post-args.t (+66/-16)
debian/modules/http-lua/t/034-match.t (+33/-32)
debian/modules/http-lua/t/035-gmatch.t (+11/-11)
debian/modules/http-lua/t/036-sub.t (+2/-2)
debian/modules/http-lua/t/037-gsub.t (+1/-1)
debian/modules/http-lua/t/038-match-o.t (+22/-22)
debian/modules/http-lua/t/041-header-filter.t (+15/-6)
debian/modules/http-lua/t/043-shdict.t (+2/-2)
debian/modules/http-lua/t/044-req-body.t (+7/-1)
debian/modules/http-lua/t/047-match-jit.t (+6/-6)
debian/modules/http-lua/t/048-match-dfa.t (+6/-6)
debian/modules/http-lua/t/055-subreq-vars.t (+9/-9)
debian/modules/http-lua/t/056-flush.t (+1/-1)
debian/modules/http-lua/t/057-flush-timeout.t (+1/-1)
debian/modules/http-lua/t/058-tcp-socket.t (+419/-26)
debian/modules/http-lua/t/062-count.t (+102/-7)
debian/modules/http-lua/t/063-abort.t (+31/-31)
debian/modules/http-lua/t/064-pcall.t (+7/-7)
debian/modules/http-lua/t/065-tcp-socket-timeout.t (+12/-12)
debian/modules/http-lua/t/066-socket-receiveuntil.t (+15/-15)
debian/modules/http-lua/t/067-req-socket.t (+3/-3)
debian/modules/http-lua/t/068-socket-keepalive.t (+1436/-31)
debian/modules/http-lua/t/073-backtrace.t (+7/-7)
debian/modules/http-lua/t/075-logby.t (+7/-4)
debian/modules/http-lua/t/081-bytecode.t (+24/-21)
debian/modules/http-lua/t/082-body-filter.t (+2/-1)
debian/modules/http-lua/t/084-inclusive-receiveuntil.t (+10/-10)
debian/modules/http-lua/t/087-udp-socket.t (+77/-7)
debian/modules/http-lua/t/090-log-socket-errors.t (+5/-5)
debian/modules/http-lua/t/091-coroutine.t (+42/-39)
debian/modules/http-lua/t/093-uthread-spawn.t (+35/-31)
debian/modules/http-lua/t/094-uthread-exit.t (+23/-23)
debian/modules/http-lua/t/095-uthread-exec.t (+7/-7)
debian/modules/http-lua/t/096-uthread-redirect.t (+3/-3)
debian/modules/http-lua/t/097-uthread-rewrite.t (+6/-6)
debian/modules/http-lua/t/098-uthread-wait.t (+37/-37)
debian/modules/http-lua/t/099-c-api.t (+5/-5)
debian/modules/http-lua/t/100-client-abort.t (+3/-3)
debian/modules/http-lua/t/104-req-raw-header.t (+112/-0)
debian/modules/http-lua/t/106-timer.t (+9/-9)
debian/modules/http-lua/t/108-timer-safe.t (+8/-8)
debian/modules/http-lua/t/109-timer-hup.t (+9/-9)
debian/modules/http-lua/t/120-re-find.t (+2/-2)
debian/modules/http-lua/t/123-lua-path.t (+5/-5)
debian/modules/http-lua/t/124-init-worker.t (+205/-6)
debian/modules/http-lua/t/126-shdict-frag.t (+2/-2)
debian/modules/http-lua/t/127-uthread-kill.t (+13/-13)
debian/modules/http-lua/t/128-duplex-tcp-socket.t (+3/-3)
debian/modules/http-lua/t/129-ssl-socket.t (+179/-262)
debian/modules/http-lua/t/130-internal-api.t (+4/-13)
debian/modules/http-lua/t/132-lua-blocks.t (+124/-1)
debian/modules/http-lua/t/134-worker-count-5.t (+2/-2)
debian/modules/http-lua/t/135-worker-id.t (+1/-61)
debian/modules/http-lua/t/138-balancer.t (+3/-5)
debian/modules/http-lua/t/139-ssl-cert-by.t (+205/-2)
debian/modules/http-lua/t/140-ssl-c-api.t (+12/-11)
debian/modules/http-lua/t/142-ssl-session-store.t (+11/-13)
debian/modules/http-lua/t/143-ssl-session-fetch.t (+118/-13)
debian/modules/http-lua/t/147-tcp-socket-timeouts.t (+4/-4)
debian/modules/http-lua/t/152-timer-every.t (+2/-2)
debian/modules/http-lua/t/153-semaphore-hup.t (+1/-1)
debian/modules/http-lua/t/155-tls13.t (+106/-0)
debian/modules/http-lua/t/156-slow-network.t (+138/-0)
debian/modules/http-lua/t/157-socket-keepalive-hup.t (+91/-0)
debian/modules/http-lua/t/158-global-var.t (+508/-0)
debian/modules/http-lua/t/159-sa-restart.t (+180/-0)
debian/modules/http-lua/t/160-disable-init-by-lua.t (+194/-0)
debian/modules/http-lua/t/161-load-resty-core.t (+68/-0)
debian/modules/http-lua/t/cert/dst-ca.crt (+63/-0)
debian/modules/http-lua/t/data/fake-shm-module/ngx_http_lua_fake_shm_module.c (+13/-9)
debian/modules/http-lua/util/build.sh (+3/-1)
debian/modules/http-lua/valgrind.suppress (+33/-16)
debian/modules/patches/http-lua/disable-load_resty_core.patch (+20/-0)
debian/modules/patches/http-lua/series (+1/-1)
dev/null (+0/-838)
Reviewer Review Type Date Requested Status
Ubuntu Sponsors Team Pending
git-ubuntu developers Pending
Review via email: mp+393790@code.launchpad.net

Commit message

Upgrade http-lua to 0.10.15

Description of the change

0.10.15 is the latest version of lua-nginx-module that does not require `resty.core`, and it seems to be compatible with the version of nginx currently packaged.

Related LP: #1893753.

This proposal is for `focal`, but I have also proposed https://code.launchpad.net/~knyar/ubuntu/+source/nginx/+git/nginx/+merge/393789 to fix this in devel.

Apologies if this is not the right way to propose this, I am not very familiar with the way Ubuntu packaging configuration is usually changed and reviewed.

To post a comment you must log in.
Revision history for this message
Christian Ehrhardt  (paelzer) wrote :

You did everything right, but it was stalled in discussions between "how to solve in focal" vs "how to further go on".

I've worked on a similar case today and merged your change into mine to give it a second chance.
See
https://code.launchpad.net/~paelzer/ubuntu/+source/nginx/+git/nginx/+merge/409830

Unmerged commits

5fb2f64... by Anton Tolchanov

Update package to 1.18.0-0ubuntu2

e1bf86f... by Anton Tolchanov

http-lua: Upgrade to 0.10.15

Updated using `ngxmod uupdate --upstream-version 0.10.15 http-lua`

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/debian/changelog b/debian/changelog
2index afbc838..7c31225 100644
3--- a/debian/changelog
4+++ b/debian/changelog
5@@ -1,3 +1,9 @@
6+nginx (1.18.0-0ubuntu2) UNRELEASED; urgency=medium
7+
8+ * http-lua: Upgrade to 0.10.15 (LP: #1893753)
9+
10+ -- Anton Tolchanov <hesitater@baconmail.net> Sat, 14 Nov 2020 21:57:05 +0000
11+
12 nginx (1.18.0-0ubuntu1) focal; urgency=medium
13
14 * Stable Release Update for Version String (LP: #1875231)
15diff --git a/debian/modules/control b/debian/modules/control
16index 96f9434..e703726 100644
17--- a/debian/modules/control
18+++ b/debian/modules/control
19@@ -18,7 +18,7 @@ Files-Excluded: .gitignore .gitattributes .travis.yml
20
21 Module: http-lua
22 Homepage: https://github.com/openresty/lua-nginx-module
23-Version: 0.10.11
24+Version: 0.10.15
25 Patch:
26 openssl-1.1.0.patch
27 discover-luajit-2.1.patch
28@@ -71,3 +71,4 @@ Version: 1.2.1
29 Module: http-geoip2
30 Homepage: https://github.com/leev/ngx_http_geoip2_module
31 Version: 3.2
32+
33diff --git a/debian/modules/http-lua/README.markdown b/debian/modules/http-lua/README.markdown
34index c42bd3e..ed0c72d 100644
35--- a/debian/modules/http-lua/README.markdown
36+++ b/debian/modules/http-lua/README.markdown
37@@ -8,6 +8,8 @@ Name
38
39 ngx_http_lua_module - Embed the power of Lua into Nginx HTTP Servers.
40
41+This module is a core component of OpenResty. If you are using this module, then you are essentially using OpenResty :)
42+
43 *This module is not distributed with the Nginx source.* See [the installation instructions](#installation).
44
45 Table of Contents
46@@ -23,7 +25,6 @@ Table of Contents
47 * [Installation](#installation)
48 * [Building as a dynamic module](#building-as-a-dynamic-module)
49 * [C Macro Configurations](#c-macro-configurations)
50- * [Installation on Ubuntu 11.10](#installation-on-ubuntu-1110)
51 * [Community](#community)
52 * [English Mailing List](#english-mailing-list)
53 * [Chinese Mailing List](#chinese-mailing-list)
54@@ -62,7 +63,7 @@ Production ready.
55 Version
56 =======
57
58-This document describes ngx_lua [v0.10.11](https://github.com/openresty/lua-nginx-module/tags) released on 3 November 2017.
59+This document describes ngx_lua [v0.10.15](https://github.com/openresty/lua-nginx-module/tags) released on March 14th, 2019.
60
61 Synopsis
62 ========
63@@ -187,7 +188,9 @@ Synopsis
64 Description
65 ===========
66
67-This module embeds Lua, via the standard Lua 5.1 interpreter or [LuaJIT 2.0/2.1](http://luajit.org/luajit.html), into Nginx and by leveraging Nginx's subrequests, allows the integration of the powerful Lua threads (Lua coroutines) into the Nginx event model.
68+This module is a core component of OpenResty. If you are using this module, then you are essentially using OpenResty :)
69+
70+This module embeds Lua, via [LuaJIT 2.0/2.1](http://luajit.org/luajit.html), into Nginx and by leveraging Nginx's subrequests, allows the integration of the powerful Lua threads (Lua coroutines) into the Nginx event model.
71
72 Unlike [Apache's mod_lua](https://httpd.apache.org/docs/trunk/mod/mod_lua.html) and [Lighttpd's mod_magnet](http://redmine.lighttpd.net/wiki/1/Docs:ModMagnet), Lua code executed using this module can be *100% non-blocking* on network traffic as long as the [Nginx API for Lua](#nginx-api-for-lua) provided by this module is used to handle
73 requests to upstream services such as MySQL, PostgreSQL, Memcached, Redis, or upstream HTTP web services.
74@@ -250,6 +253,7 @@ Nginx Compatibility
75 The latest version of this module is compatible with the following versions of Nginx:
76
77 * 1.13.x (last tested: 1.13.6)
78+* 1.12.x
79 * 1.11.x (last tested: 1.11.2)
80 * 1.10.x
81 * 1.9.x (last tested: 1.9.15)
82@@ -264,12 +268,12 @@ Nginx cores older than 1.6.0 (exclusive) are *not* supported.
83 Installation
84 ============
85
86-It is *highly* recommended to use [OpenResty releases](http://openresty.org) which integrate Nginx, ngx_lua, LuaJIT 2.1, as well as other powerful companion Nginx modules and Lua libraries. It is discouraged to build this module with nginx yourself since it is tricky to set up exactly right. Also, the stock nginx cores have various limitations and long standing bugs that can make some of this modules' features become disabled, not work properly, or run slower.
87+It is *highly* recommended to use [OpenResty releases](http://openresty.org) which integrate Nginx, ngx_lua, OpenResty's LuaJIT 2.1 branch version, as well as other powerful companion Nginx modules and Lua libraries. It is discouraged to build this module with nginx yourself since it is tricky to set up exactly right. Also, the stock nginx cores have various limitations and long standing bugs that can make some of this modules' features become disabled, not work properly, or run slower. The same applies to LuaJIT as well. OpenResty includes its own version of LuaJIT which gets specifically optimized and enhanced for the OpenResty environment.
88
89 Alternatively, ngx_lua can be manually compiled into Nginx:
90
91-1. Install LuaJIT 2.0 or 2.1 (recommended) or Lua 5.1 (Lua 5.2 is *not* supported yet). LuaJIT can be downloaded from the [LuaJIT project website](http://luajit.org/download.html) and Lua 5.1, from the [Lua project website](http://www.lua.org/). Some distribution package managers also distribute LuaJIT and/or Lua.
92-1. Download the latest version of the ngx_devel_kit (NDK) module [HERE](https://github.com/simpl/ngx_devel_kit/tags).
93+1. LuaJIT can be downloaded from the [latest release of OpenResty's LuaJIT branch version](https://github.com/openresty/luajit2/releases). The official LuaJIT 2.0 and 2.1 releases are also supported, although the performance will be significantly lower in many cases.
94+1. Download the latest version of the ngx_devel_kit (NDK) module [HERE](https://github.com/simplresty/ngx_devel_kit/tags).
95 1. Download the latest version of ngx_lua [HERE](https://github.com/openresty/lua-nginx-module/tags).
96 1. Download the latest version of Nginx [HERE](http://nginx.org/) (See [Nginx Compatibility](#nginx-compatibility))
97
98@@ -346,29 +350,6 @@ To enable one or more of these macros, just pass extra C compiler options to the
99
100 [Back to TOC](#table-of-contents)
101
102-Installation on Ubuntu 11.10
103-----------------------------
104-
105-Note that it is recommended to use LuaJIT 2.0 or LuaJIT 2.1 instead of the standard Lua 5.1 interpreter wherever possible.
106-
107-If the standard Lua 5.1 interpreter is required however, run the following command to install it from the Ubuntu repository:
108-
109-```bash
110-
111- apt-get install -y lua5.1 liblua5.1-0 liblua5.1-0-dev
112-```
113-
114-Everything should be installed correctly, except for one small tweak.
115-
116-Library name `liblua.so` has been changed in liblua5.1 package, it only comes with `liblua5.1.so`, which needs to be symlinked to `/usr/lib` so it could be found during the configuration process.
117-
118-```bash
119-
120- ln -s /usr/lib/x86_64-linux-gnu/liblua5.1.so /usr/lib/liblua.so
121-```
122-
123-[Back to TOC](#table-of-contents)
124-
125 Community
126 =========
127
128@@ -410,7 +391,7 @@ Lua/LuaJIT bytecode support
129
130 As from the `v0.5.0rc32` release, all `*_by_lua_file` configure directives (such as [content_by_lua_file](#content_by_lua_file)) support loading Lua 5.1 and LuaJIT 2.0/2.1 raw bytecode files directly.
131
132-Please note that the bytecode format used by LuaJIT 2.0/2.1 is not compatible with that used by the standard Lua 5.1 interpreter. So if using LuaJIT 2.0/2.1 with ngx_lua, LuaJIT compatible bytecode files must be generated as shown:
133+Please note that the bytecode format used by LuaJIT 2.0/2.1 is not compatible with that used by the standard Lua 5.1 interpreter. So if you are using LuaJIT 2.0/2.1 with ngx_lua, LuaJIT compatible bytecode files must be generated as shown:
134
135 ```bash
136
137@@ -430,20 +411,6 @@ Please refer to the official LuaJIT documentation on the `-b` option for more de
138
139 Also, the bytecode files generated by LuaJIT 2.1 is *not* compatible with LuaJIT 2.0, and vice versa. The support for LuaJIT 2.1 bytecode was first added in ngx_lua v0.9.3.
140
141-Similarly, if using the standard Lua 5.1 interpreter with ngx_lua, Lua compatible bytecode files must be generated using the `luac` commandline utility as shown:
142-
143-```bash
144-
145- luac -o /path/to/output_file.luac /path/to/input_file.lua
146-```
147-
148-Unlike as with LuaJIT, debug information is included in standard Lua 5.1 bytecode files by default. This can be striped out by specifying the `-s` option as shown:
149-
150-```bash
151-
152- luac -s -o /path/to/output_file.luac /path/to/input_file.lua
153-```
154-
155 Attempts to load standard Lua 5.1 bytecode files into ngx_lua instances linked to LuaJIT 2.0/2.1 or vice versa, will result in an error message, such as that below, being logged into the Nginx `error.log` file:
156
157
158@@ -641,8 +608,7 @@ This issue is due to limitations in the Nginx event model and only appears to af
159
160 Lua Coroutine Yielding/Resuming
161 -------------------------------
162-* Because Lua's `dofile` and `require` builtins are currently implemented as C functions in both Lua 5.1 and LuaJIT 2.0/2.1, if the Lua file being loaded by `dofile` or `require` invokes [ngx.location.capture*](#ngxlocationcapture), [ngx.exec](#ngxexec), [ngx.exit](#ngxexit), or other API functions requiring yielding in the *top-level* scope of the Lua file, then the Lua error "attempt to yield across C-call boundary" will be raised. To avoid this, put these calls requiring yielding into your own Lua functions in the Lua file instead of the top-level scope of the file.
163-* As the standard Lua 5.1 interpreter's VM is not fully resumable, the methods [ngx.location.capture](#ngxlocationcapture), [ngx.location.capture_multi](#ngxlocationcapture_multi), [ngx.redirect](#ngxredirect), [ngx.exec](#ngxexec), and [ngx.exit](#ngxexit) cannot be used within the context of a Lua [pcall()](http://www.lua.org/manual/5.1/manual.html#pdf-pcall) or [xpcall()](http://www.lua.org/manual/5.1/manual.html#pdf-xpcall) or even the first line of the `for ... in ...` statement when the standard Lua 5.1 interpreter is used and the `attempt to yield across metamethod/C-call boundary` error will be produced. Please use LuaJIT 2.x, which supports a fully resumable VM, to avoid this.
164+* Because Lua's `dofile` and `require` builtins are currently implemented as C functions in LuaJIT 2.0/2.1, if the Lua file being loaded by `dofile` or `require` invokes [ngx.location.capture*](#ngxlocationcapture), [ngx.exec](#ngxexec), [ngx.exit](#ngxexit), or other API functions requiring yielding in the *top-level* scope of the Lua file, then the Lua error "attempt to yield across C-call boundary" will be raised. To avoid this, put these calls requiring yielding into your own Lua functions in the Lua file instead of the top-level scope of the file.
165
166 [Back to TOC](#table-of-contents)
167
168@@ -839,7 +805,7 @@ As noted earlier, PCRE sequences presented within `*_by_lua_block {}` directives
169 # nginx.conf
170 location /test {
171 content_by_lua_block {
172- local regex = "\d+"
173+ local regex = [[\d+]]
174 local m = ngx.re.match("hello, 1234", regex)
175 if m then ngx.say(m[0]) else ngx.say("not matched!") end
176 }
177@@ -940,7 +906,7 @@ The following dependencies are required to run the test suite:
178 * Test::Nginx: <https://github.com/openresty/test-nginx>
179
180 * Nginx modules:
181- * [ngx_devel_kit](https://github.com/simpl/ngx_devel_kit)
182+ * [ngx_devel_kit](https://github.com/simplresty/ngx_devel_kit)
183 * [ngx_set_misc](https://github.com/openresty/set-misc-nginx-module)
184 * [ngx_auth_request](http://mdounin.ru/files/ngx_http_auth_request_module-0.2.tar.gz) (this is not needed if you're using Nginx 1.5.4+.
185 * [ngx_echo](https://github.com/openresty/echo-nginx-module)
186@@ -994,7 +960,7 @@ This module is licensed under the BSD license.
187
188 Copyright (C) 2009-2017, by Xiaozhe Wang (chaoslawful) <chaoslawful@gmail.com>.
189
190-Copyright (C) 2009-2017, by Yichun "agentzh" Zhang (章亦春) <agentzh@gmail.com>, OpenResty Inc.
191+Copyright (C) 2009-2019, by Yichun "agentzh" Zhang (章亦春) <agentzh@gmail.com>, OpenResty Inc.
192
193 All rights reserved.
194
195@@ -1025,7 +991,7 @@ See Also
196 * [Dynamic Routing Based on Redis and Lua](http://openresty.org/#DynamicRoutingBasedOnRedis)
197 * [Using LuaRocks with ngx_lua](http://openresty.org/#UsingLuaRocks)
198 * [Introduction to ngx_lua](https://github.com/openresty/lua-nginx-module/wiki/Introduction)
199-* [ngx_devel_kit](https://github.com/simpl/ngx_devel_kit)
200+* [ngx_devel_kit](https://github.com/simplresty/ngx_devel_kit)
201 * [echo-nginx-module](http://github.com/openresty/echo-nginx-module)
202 * [drizzle-nginx-module](http://github.com/openresty/drizzle-nginx-module)
203 * [postgres-nginx-module](https://github.com/FRiCKLE/ngx_postgres)
204@@ -1038,6 +1004,7 @@ See Also
205 Directives
206 ==========
207
208+* [lua_load_resty_core](#lua_load_resty_core)
209 * [lua_capture_error_log](#lua_capture_error_log)
210 * [lua_use_default_type](#lua_use_default_type)
211 * [lua_malloc_trim](#lua_malloc_trim)
212@@ -1103,6 +1070,7 @@ Directives
213 * [lua_check_client_abort](#lua_check_client_abort)
214 * [lua_max_pending_timers](#lua_max_pending_timers)
215 * [lua_max_running_timers](#lua_max_running_timers)
216+* [lua_sa_restart](#lua_sa_restart)
217
218
219 The basic building blocks of scripting Nginx with Lua are directives. Directives are used to specify when the user Lua code is run and
220@@ -1112,6 +1080,38 @@ how the result will be used. Below is a diagram showing the order in which direc
221
222 [Back to TOC](#table-of-contents)
223
224+lua_load_resty_core
225+-------------------
226+
227+**syntax:** *lua_load_resty_core on|off*
228+
229+**default:** *lua_load_resty_core on*
230+
231+**context:** *http*
232+
233+Controls whether the `resty.core` module (from
234+[lua-resty-core](https://github.com/openresty/lua-resty-core)) should be loaded
235+or not. When enabled, this directive is equivalent to executing the following
236+when the Lua VM is created:
237+
238+```lua
239+
240+ require "resty.core"
241+```
242+
243+Note that usage of the `resty.core` module is recommended, as its
244+FFI implementation is both faster, safer, and more complete than the Lua C API
245+of the ngx_lua module.
246+
247+It must also be noted that the Lua C API of the ngx_lua module will eventually
248+be removed, and usage of the FFI-based API (i.e. the `resty.core`
249+module) will become mandatory. This directive only aims at providing a
250+temporary backwards-compatibility mode in case of edge-cases.
251+
252+This directive was first introduced in the `v0.10.15` release.
253+
254+[Back to TOC](#directives)
255+
256 lua_capture_error_log
257 ---------------------
258 **syntax:** *lua_capture_error_log size*
259@@ -1486,6 +1486,8 @@ This hook is often used to create per-worker reoccurring timers (via the [ngx.ti
260
261 This directive was first introduced in the `v0.9.5` release.
262
263+This hook no longer runs in the cache manager and cache loader processes since the `v0.10.12` release.
264+
265 [Back to TOC](#directives)
266
267 init_worker_by_lua_block
268@@ -1513,6 +1515,8 @@ For instance,
269
270 This directive was first introduced in the `v0.9.17` release.
271
272+This hook no longer runs in the cache manager and cache loader processes since the `v0.10.12` release.
273+
274 [Back to TOC](#directives)
275
276 init_worker_by_lua_file
277@@ -1528,6 +1532,8 @@ Similar to [init_worker_by_lua](#init_worker_by_lua), but accepts the file path
278
279 This directive was first introduced in the `v0.9.5` release.
280
281+This hook no longer runs in the cache manager and cache loader processes since the `v0.10.12` release.
282+
283 [Back to TOC](#directives)
284
285 set_by_lua
286@@ -1587,7 +1593,7 @@ This directive can be freely mixed with all directives of the [ngx_http_rewrite_
287
288 As from the `v0.5.0rc29` release, Nginx variable interpolation is disabled in the `<lua-script-str>` argument of this directive and therefore, the dollar sign character (`$`) can be used directly.
289
290-This directive requires the [ngx_devel_kit](https://github.com/simpl/ngx_devel_kit) module.
291+This directive requires the [ngx_devel_kit](https://github.com/simplresty/ngx_devel_kit) module.
292
293 [Back to TOC](#directives)
294
295@@ -1640,7 +1646,7 @@ and the Nginx config must be reloaded each time the Lua source file is modified.
296 The Lua code cache can be temporarily disabled during development by
297 switching [lua_code_cache](#lua_code_cache) `off` in `nginx.conf` to avoid reloading Nginx.
298
299-This directive requires the [ngx_devel_kit](https://github.com/simpl/ngx_devel_kit) module.
300+This directive requires the [ngx_devel_kit](https://github.com/simplresty/ngx_devel_kit) module.
301
302 [Back to TOC](#directives)
303
304@@ -2595,14 +2601,14 @@ SSL session resumption can then get immediately initiated and bypass the full SS
305 Please note that TLS session tickets are very different and it is the clients' responsibility
306 to cache the SSL session state when session tickets are used. SSL session resumptions based on
307 TLS session tickets would happen automatically without going through this hook (nor the
308-[ssl_session_store_by_lua_block](#ssl_session_store_by_lua) hook). This hook is mainly
309+[ssl_session_store_by_lua*](#ssl_session_store_by_lua_block) hook). This hook is mainly
310 for older or less capable SSL clients that can only do SSL sessions by session IDs.
311
312 When [ssl_certificate_by_lua*](#ssl_certificate_by_lua_block) is specified at the same time,
313 this hook usually runs before [ssl_certificate_by_lua*](#ssl_certificate_by_lua_block).
314 When the SSL session is found and successfully loaded for the current SSL connection,
315 SSL session resumption will happen and thus bypass the [ssl_certificate_by_lua*](#ssl_certificate_by_lua_block)
316-hook completely. In this case, NGINX also bypasses the [ssl_session_store_by_lua_block](#ssl_session_store_by_lua)
317+hook completely. In this case, NGINX also bypasses the [ssl_session_store_by_lua*](#ssl_session_store_by_lua_block)
318 hook, for obvious reasons.
319
320 To easily test this hook locally with a modern web browser, you can temporarily put the following line
321@@ -2914,7 +2920,7 @@ This directive was first introduced in the `v0.9.11` release.
322 lua_ssl_protocols
323 -----------------
324
325-**syntax:** *lua_ssl_protocols \[SSLv2\] \[SSLv3\] \[TLSv1\] [TLSv1.1] [TLSv1.2]*
326+**syntax:** *lua_ssl_protocols \[SSLv2\] \[SSLv3\] \[TLSv1\] [TLSv1.1] [TLSv1.2] [TLSv1.3]*
327
328 **default:** *lua_ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2*
329
330@@ -2922,6 +2928,8 @@ lua_ssl_protocols
331
332 Enables the specified protocols for requests to a SSL/TLS server in the [tcpsock:sslhandshake](#tcpsocksslhandshake) method.
333
334+The support for the `TLSv1.3` parameter requires version `v0.10.12` *and* OpenSSL 1.1.1.
335+
336 This directive was first introduced in the `v0.9.11` release.
337
338 [Back to TOC](#directives)
339@@ -3099,6 +3107,23 @@ This directive was first introduced in the `v0.8.0` release.
340
341 [Back to TOC](#directives)
342
343+lua_sa_restart
344+--------------
345+
346+**syntax:** *lua_sa_restart on|off*
347+
348+**default:** *lua_sa_restart on*
349+
350+**context:** *http*
351+
352+When enabled, this module will set the `SA_RESTART` flag on nginx workers signal dispositions.
353+
354+This allows Lua I/O primitives to not be interrupted by nginx's handling of various signals.
355+
356+This directive was first introduced in the `v0.10.14` release.
357+
358+[Back to TOC](#directives)
359+
360 Nginx API for Lua
361 =================
362
363@@ -3212,6 +3237,7 @@ Nginx API for Lua
364 * [tcpsock:sslhandshake](#tcpsocksslhandshake)
365 * [tcpsock:send](#tcpsocksend)
366 * [tcpsock:receive](#tcpsockreceive)
367+* [tcpsock:receiveany](#tcpsockreceiveany)
368 * [tcpsock:receiveuntil](#tcpsockreceiveuntil)
369 * [tcpsock:close](#tcpsockclose)
370 * [tcpsock:settimeout](#tcpsocksettimeout)
371@@ -3400,7 +3426,7 @@ Core constants
372 ngx.DECLINED (-5)
373 ```
374
375-Note that only three of these constants are utilized by the [Nginx API for Lua](#nginx-api-for-lua) (i.e., [ngx.exit](#ngxexit) accepts `NGX_OK`, `NGX_ERROR`, and `NGX_DECLINED` as input).
376+Note that only three of these constants are utilized by the [Nginx API for Lua](#nginx-api-for-lua) (i.e., [ngx.exit](#ngxexit) accepts `ngx.OK`, `ngx.ERROR`, and `ngx.DECLINED` as input).
377
378 ```lua
379
380@@ -3458,6 +3484,7 @@ HTTP status constants
381 value = ngx.HTTP_SEE_OTHER (303)
382 value = ngx.HTTP_NOT_MODIFIED (304)
383 value = ngx.HTTP_TEMPORARY_REDIRECT (307) (first added in the v0.9.20 release)
384+ value = ngx.HTTP_PERMANENT_REDIRECT (308)
385 value = ngx.HTTP_BAD_REQUEST (400)
386 value = ngx.HTTP_UNAUTHORIZED (401)
387 value = ngx.HTTP_PAYMENT_REQUIRED (402) (first added in the v0.9.20 release)
388@@ -4114,7 +4141,7 @@ The same applies to assigning an empty table:
389 ngx.header["X-My-Header"] = {};
390 ```
391
392-Setting `ngx.header.HEADER` after sending out response headers (either explicitly with [ngx.send_headers](#ngxsend_headers) or implicitly with [ngx.print](#ngxprint) and similar) will throw out a Lua exception.
393+Setting `ngx.header.HEADER` after sending out response headers (either explicitly with [ngx.send_headers](#ngxsend_headers) or implicitly with [ngx.print](#ngxprint) and similar) will log an error message.
394
395 Reading `ngx.header.HEADER` will return the value of the response header named `HEADER`.
396
397@@ -4163,7 +4190,7 @@ For reading *request* headers, use the [ngx.req.get_headers](#ngxreqget_headers)
398
399 ngx.resp.get_headers
400 --------------------
401-**syntax:** *headers = ngx.resp.get_headers(max_headers?, raw?)*
402+**syntax:** *headers, err = ngx.resp.get_headers(max_headers?, raw?)*
403
404 **context:** *set_by_lua&#42;, rewrite_by_lua&#42;, access_by_lua&#42;, content_by_lua&#42;, header_filter_by_lua&#42;, body_filter_by_lua&#42;, log_by_lua&#42;, balancer_by_lua&#42;*
405
406@@ -4171,7 +4198,12 @@ Returns a Lua table holding all the current response headers for the current req
407
408 ```lua
409
410- local h = ngx.resp.get_headers()
411+ local h, err = ngx.resp.get_headers()
412+
413+ if err == "truncated" then
414+ -- one can choose to ignore or reject the current response here
415+ end
416+
417 for k, v in pairs(h) do
418 ...
419 end
420@@ -4179,6 +4211,8 @@ Returns a Lua table holding all the current response headers for the current req
421
422 This function has the same signature as [ngx.req.get_headers](#ngxreqget_headers) except getting response headers instead of request headers.
423
424+Note that a maximum of 100 response headers are parsed by default (including those with the same name) and that additional response headers are silently discarded to guard against potential denial of service attacks. Since `v0.10.13`, when the limit is exceeded, it will return a second value which is the string `"truncated"`.
425+
426 This API was first introduced in the `v0.9.5` release.
427
428 [Back to TOC](#nginx-api-for-lua)
429@@ -4285,7 +4319,7 @@ ngx.req.get_method
430 ------------------
431 **syntax:** *method_name = ngx.req.get_method()*
432
433-**context:** *set_by_lua&#42;, rewrite_by_lua&#42;, access_by_lua&#42;, content_by_lua&#42;, header_filter_by_lua&#42;, balancer_by_lua&#42;*
434+**context:** *set_by_lua&#42;, rewrite_by_lua&#42;, access_by_lua&#42;, content_by_lua&#42;, header_filter_by_lua&#42;, body_filter_by_lua&#42;, balancer_by_lua&#42;, log_by_lua&#42;*
435
436 Retrieves the current request's request method name. Strings like `"GET"` and `"POST"` are returned instead of numerical [method constants](#http-method-constants).
437
438@@ -4451,7 +4485,7 @@ See also [ngx.req.set_uri](#ngxreqset_uri).
439
440 ngx.req.get_uri_args
441 --------------------
442-**syntax:** *args = ngx.req.get_uri_args(max_args?)*
443+**syntax:** *args, err = ngx.req.get_uri_args(max_args?)*
444
445 **context:** *set_by_lua&#42;, rewrite_by_lua&#42;, access_by_lua&#42;, content_by_lua&#42;, header_filter_by_lua&#42;, body_filter_by_lua&#42;, log_by_lua&#42;, balancer_by_lua&#42;*
446
447@@ -4461,7 +4495,12 @@ Returns a Lua table holding all the current request URL query arguments.
448
449 location = /test {
450 content_by_lua_block {
451- local args = ngx.req.get_uri_args()
452+ local args, err = ngx.req.get_uri_args()
453+
454+ if err == "truncated" then
455+ -- one can choose to ignore or reject the current request here
456+ end
457+
458 for key, val in pairs(args) do
459 if type(val) == "table" then
460 ngx.say(key, ": ", table.concat(val, ", "))
461@@ -4513,7 +4552,7 @@ Updating query arguments via the nginx variable `$args` (or `ngx.var.args` in Lu
462 ```lua
463
464 ngx.var.args = "a=3&b=42"
465- local args = ngx.req.get_uri_args()
466+ local args, err = ngx.req.get_uri_args()
467 ```
468
469 Here the `args` table will always look like
470@@ -4525,20 +4564,23 @@ Here the `args` table will always look like
471
472 regardless of the actual request query string.
473
474-Note that a maximum of 100 request arguments are parsed by default (including those with the same name) and that additional request arguments are silently discarded to guard against potential denial of service attacks.
475+Note that a maximum of 100 request arguments are parsed by default (including those with the same name) and that additional request arguments are silently discarded to guard against potential denial of service attacks. Since `v0.10.13`, when the limit is exceeded, it will return a second value which is the string `"truncated"`.
476
477 However, the optional `max_args` function argument can be used to override this limit:
478
479 ```lua
480
481- local args = ngx.req.get_uri_args(10)
482+ local args, err = ngx.req.get_uri_args(10)
483+ if err == "truncated" then
484+ -- one can choose to ignore or reject the current request here
485+ end
486 ```
487
488 This argument can be set to zero to remove the limit and to process all request arguments received:
489
490 ```lua
491
492- local args = ngx.req.get_uri_args(0)
493+ local args, err = ngx.req.get_uri_args(0)
494 ```
495
496 Removing the `max_args` cap is strongly discouraged.
497@@ -4559,6 +4601,11 @@ Returns a Lua table holding all the current request POST query arguments (of the
498 content_by_lua_block {
499 ngx.req.read_body()
500 local args, err = ngx.req.get_post_args()
501+
502+ if err == "truncated" then
503+ -- one can choose to ignore or reject the current request here
504+ end
505+
506 if not args then
507 ngx.say("failed to get post args: ", err)
508 return
509@@ -4627,20 +4674,23 @@ That is, they will take Lua boolean values `true`. However, they are different f
510
511 Empty key arguments are discarded. `POST /test` with body `=hello&=world` will yield empty outputs for instance.
512
513-Note that a maximum of 100 request arguments are parsed by default (including those with the same name) and that additional request arguments are silently discarded to guard against potential denial of service attacks.
514+Note that a maximum of 100 request arguments are parsed by default (including those with the same name) and that additional request arguments are silently discarded to guard against potential denial of service attacks. Since `v0.10.13`, when the limit is exceeded, it will return a second value which is the string `"truncated"`.
515
516 However, the optional `max_args` function argument can be used to override this limit:
517
518 ```lua
519
520- local args = ngx.req.get_post_args(10)
521+ local args, err = ngx.req.get_post_args(10)
522+ if err == "truncated" then
523+ -- one can choose to ignore or reject the current request here
524+ end
525 ```
526
527 This argument can be set to zero to remove the limit and to process all request arguments received:
528
529 ```lua
530
531- local args = ngx.req.get_post_args(0)
532+ local args, err = ngx.req.get_post_args(0)
533 ```
534
535 Removing the `max_args` cap is strongly discouraged.
536@@ -4649,7 +4699,7 @@ Removing the `max_args` cap is strongly discouraged.
537
538 ngx.req.get_headers
539 -------------------
540-**syntax:** *headers = ngx.req.get_headers(max_headers?, raw?)*
541+**syntax:** *headers, err = ngx.req.get_headers(max_headers?, raw?)*
542
543 **context:** *set_by_lua&#42;, rewrite_by_lua&#42;, access_by_lua&#42;, content_by_lua&#42;, header_filter_by_lua&#42;, body_filter_by_lua&#42;, log_by_lua&#42;*
544
545@@ -4657,7 +4707,12 @@ Returns a Lua table holding all the current request headers.
546
547 ```lua
548
549- local h = ngx.req.get_headers()
550+ local h, err = ngx.req.get_headers()
551+
552+ if err == "truncated" then
553+ -- one can choose to ignore or reject the current request here
554+ end
555+
556 for k, v in pairs(h) do
557 ...
558 end
559@@ -4688,20 +4743,24 @@ the value of `ngx.req.get_headers()["Foo"]` will be a Lua (array) table such as:
560 {"foo", "bar", "baz"}
561 ```
562
563-Note that a maximum of 100 request headers are parsed by default (including those with the same name) and that additional request headers are silently discarded to guard against potential denial of service attacks.
564+Note that a maximum of 100 request headers are parsed by default (including those with the same name) and that additional request headers are silently discarded to guard against potential denial of service attacks. Since `v0.10.13`, when the limit is exceeded, it will return a second value which is the string `"truncated"`.
565
566 However, the optional `max_headers` function argument can be used to override this limit:
567
568 ```lua
569
570- local headers = ngx.req.get_headers(10)
571+ local headers, err = ngx.req.get_headers(10)
572+
573+ if err == "truncated" then
574+ -- one can choose to ignore or reject the current request here
575+ end
576 ```
577
578 This argument can be set to zero to remove the limit and to process all request headers received:
579
580 ```lua
581
582- local headers = ngx.req.get_headers(0)
583+ local headers, err = ngx.req.get_headers(0)
584 ```
585
586 Removing the `max_headers` cap is strongly discouraged.
587@@ -4845,7 +4904,7 @@ This function returns `nil` if
588 1. the request body has been read into disk temporary files,
589 1. or the request body has zero size.
590
591-If the request body has not been read yet, call [ngx.req.read_body](#ngxreqread_body) first (or turned on [lua_need_request_body](#lua_need_request_body) to force this module to read the request body. This is not recommended however).
592+If the request body has not been read yet, call [ngx.req.read_body](#ngxreqread_body) first (or turn on [lua_need_request_body](#lua_need_request_body) to force this module to read the request body. This is not recommended however).
593
594 If the request body has been read into disk files, try calling the [ngx.req.get_body_file](#ngxreqget_body_file) function instead.
595
596@@ -4869,7 +4928,7 @@ Retrieves the file name for the in-file request body data. Returns `nil` if the
597
598 The returned file is read only and is usually cleaned up by Nginx's memory pool. It should not be manually modified, renamed, or removed in Lua code.
599
600-If the request body has not been read yet, call [ngx.req.read_body](#ngxreqread_body) first (or turned on [lua_need_request_body](#lua_need_request_body) to force this module to read the request body. This is not recommended however).
601+If the request body has not been read yet, call [ngx.req.read_body](#ngxreqread_body) first (or turn on [lua_need_request_body](#lua_need_request_body) to force this module to read the request body. This is not recommended however).
602
603 If the request body has been read into memory, try calling the [ngx.req.get_body_data](#ngxreqget_body_data) function instead.
604
605@@ -4889,7 +4948,9 @@ ngx.req.set_body_data
606
607 Set the current request's request body using the in-memory data specified by the `data` argument.
608
609-If the current request's request body has not been read, then it will be properly discarded. When the current request's request body has been read into memory or buffered into a disk file, then the old request body's memory will be freed or the disk file will be cleaned up immediately, respectively.
610+If the request body has not been read yet, call [ngx.req.read_body](#ngxreqread_body) first (or turn on [lua_need_request_body](#lua_need_request_body) to force this module to read the request body. This is not recommended however). Additionally, the request body must not have been previously discarded by [ngx.req.discard_body](#ngxreqdiscard_body).
611+
612+Whether the previous request body has been read into memory or buffered into a disk file, it will be freed or the disk file will be cleaned up immediately, respectively.
613
614 This function was first introduced in the `v0.3.1rc18` release.
615
616@@ -4905,11 +4966,13 @@ ngx.req.set_body_file
617
618 Set the current request's request body using the in-file data specified by the `file_name` argument.
619
620+If the request body has not been read yet, call [ngx.req.read_body](#ngxreqread_body) first (or turn on [lua_need_request_body](#lua_need_request_body) to force this module to read the request body. This is not recommended however). Additionally, the request body must not have been previously discarded by [ngx.req.discard_body](#ngxreqdiscard_body).
621+
622 If the optional `auto_clean` argument is given a `true` value, then this file will be removed at request completion or the next time this function or [ngx.req.set_body_data](#ngxreqset_body_data) are called in the same request. The `auto_clean` is default to `false`.
623
624 Please ensure that the file specified by the `file_name` argument exists and is readable by an Nginx worker process by setting its permission properly to avoid Lua exception errors.
625
626-If the current request's request body has not been read, then it will be properly discarded. When the current request's request body has been read into memory or buffered into a disk file, then the old request body's memory will be freed or the disk file will be cleaned up immediately, respectively.
627+Whether the previous request body has been read into memory or buffered into a disk file, it will be freed or the disk file will be cleaned up immediately, respectively.
628
629 This function was first introduced in the `v0.3.1rc18` release.
630
631@@ -5092,6 +5155,7 @@ The optional `status` parameter specifies the HTTP status code to be used. The f
632 * `302` (default)
633 * `303`
634 * `307`
635+* `308`
636
637 It is `302` (`ngx.HTTP_MOVED_TEMPORARILY`) by default.
638
639@@ -5325,7 +5389,7 @@ Number literals can be used directly as the argument, for instance,
640 ngx.exit(501)
641 ```
642
643-Note that while this method accepts all [HTTP status constants](#http-status-constants) as input, it only accepts `NGX_OK` and `NGX_ERROR` of the [core constants](#core-constants).
644+Note that while this method accepts all [HTTP status constants](#http-status-constants) as input, it only accepts `ngx.OK` and `ngx.ERROR` of the [core constants](#core-constants).
645
646 Also note that this method call terminates the processing of the current request and that it is recommended that a coding style that combines this method call with the `return` statement, i.e., `return ngx.exit(...)` be used to reinforce the fact that the request processing is being terminated.
647
648@@ -5478,13 +5542,13 @@ This method was first introduced in the `v0.3.1rc27` release.
649
650 ngx.decode_args
651 ---------------
652-**syntax:** *table = ngx.decode_args(str, max_args?)*
653+**syntax:** *table, err = ngx.decode_args(str, max_args?)*
654
655 **context:** *set_by_lua&#42;, rewrite_by_lua&#42;, access_by_lua&#42;, content_by_lua&#42;, header_filter_by_lua&#42;, body_filter_by_lua&#42;, log_by_lua&#42;, ngx.timer.&#42;, balancer_by_lua&#42;, ssl_certificate_by_lua&#42;, ssl_session_fetch_by_lua&#42;, ssl_session_store_by_lua&#42;*
656
657 Decodes a URI encoded query-string into a Lua table. This is the inverse function of [ngx.encode_args](#ngxencode_args).
658
659-The optional `max_args` argument can be used to specify the maximum number of arguments parsed from the `str` argument. By default, a maximum of 100 request arguments are parsed (including those with the same name) and that additional URI arguments are silently discarded to guard against potential denial of service attacks.
660+The optional `max_args` argument can be used to specify the maximum number of arguments parsed from the `str` argument. By default, a maximum of 100 request arguments are parsed (including those with the same name) and that additional URI arguments are silently discarded to guard against potential denial of service attacks. Since `v0.10.13`, when the limit is exceeded, it will return a second value which is the string `"truncated"`.
661
662 This argument can be set to zero to remove the limit and to process all request arguments received:
663
664@@ -6444,10 +6508,12 @@ See also [ngx.shared.DICT](#ngxshareddict).
665
666 ngx.shared.DICT.incr
667 --------------------
668-**syntax:** *newval, err, forcible? = ngx.shared.DICT:incr(key, value, init?)*
669+**syntax:** *newval, err, forcible? = ngx.shared.DICT:incr(key, value, init?, init_ttl?)*
670
671 **context:** *init_by_lua&#42;, set_by_lua&#42;, rewrite_by_lua&#42;, access_by_lua&#42;, content_by_lua&#42;, header_filter_by_lua&#42;, body_filter_by_lua&#42;, log_by_lua&#42;, ngx.timer.&#42;, balancer_by_lua&#42;, ssl_certificate_by_lua&#42;, ssl_session_fetch_by_lua&#42;, ssl_session_store_by_lua&#42;*
672
673+**optional requirement:** `resty.core.shdict` or `resty.core`
674+
675 Increments the (numerical) value for `key` in the shm-based dictionary [ngx.shared.DICT](#ngxshareddict) by the step value `value`. Returns the new resulting number if the operation is successfully completed or `nil` and an error message otherwise.
676
677 When the key does not exist or has already expired in the shared dictionary,
678@@ -6457,6 +6523,25 @@ When the key does not exist or has already expired in the shared dictionary,
679
680 Like the [add](#ngxshareddictadd) method, it also overrides the (least recently used) unexpired items in the store when running out of storage in the shared memory zone.
681
682+The optional `init_ttl` argument specifies expiration time (in seconds) of the value when it is initialized via the `init` argument. The time resolution is `0.001` seconds. If `init_ttl` takes the value `0` (which is the default), then the item will never expire. This argument cannot be provided without providing the `init` argument as well, and has no effect if the value already exists (e.g., if it was previously inserted via [set](#ngxshareddictset) or the likes).
683+
684+**Note:** Usage of the `init_ttl` argument requires the `resty.core.shdict` or `resty.core` modules from the [lua-resty-core](https://github.com/openresty/lua-resty-core) library. Example:
685+
686+```lua
687+
688+ require "resty.core"
689+
690+ local cats = ngx.shared.cats
691+ local newval, err = cats:incr("black_cats", 1, 0, 0.1)
692+
693+ print(newval) -- 1
694+
695+ ngx.sleep(0.2)
696+
697+ local val, err = cats:get("black_cats")
698+ print(val) -- nil
699+```
700+
701 The `forcible` return value will always be `nil` when the `init` argument is not specified.
702
703 If this method succeeds in storing the current item by forcibly removing other not-yet-expired items in the dictionary via LRU, the `forcible` return value will be `true`. If it stores the item without forcibly removing other valid items, then the return value `forcible` will be `false`.
704@@ -6469,6 +6554,8 @@ This method was first introduced in the `v0.3.1rc22` release.
705
706 The optional `init` parameter was first added in the `v0.10.6` release.
707
708+The optional `init_ttl` parameter was introduced in the `v0.10.12rc2` release.
709+
710 See also [ngx.shared.DICT](#ngxshareddict).
711
712 [Back to TOC](#nginx-api-for-lua)
713@@ -6651,7 +6738,7 @@ ngx.shared.DICT.flush_expired
714
715 Flushes out the expired items in the dictionary, up to the maximal number specified by the optional `max_count` argument. When the `max_count` argument is given `0` or not given at all, then it means unlimited. Returns the number of items that have actually been flushed.
716
717-Unlike the [flush_all](#ngxshareddictflush_all) method, this method actually free up the memory used by the expired items.
718+Unlike the [flush_all](#ngxshareddictflush_all) method, this method actually frees up the memory used by the expired items.
719
720 This feature was first introduced in the `v0.6.3` release.
721
722@@ -6936,6 +7023,7 @@ Creates and returns a TCP or stream-oriented unix domain socket object (also kno
723 * [settimeout](#tcpsocksettimeout)
724 * [settimeouts](#tcpsocksettimeouts)
725 * [setoption](#tcpsocksetoption)
726+* [receiveany](#tcpsockreceiveany)
727 * [receiveuntil](#tcpsockreceiveuntil)
728 * [setkeepalive](#tcpsocksetkeepalive)
729 * [getreusedtimes](#tcpsockgetreusedtimes)
730@@ -7040,6 +7128,43 @@ An optional Lua table can be specified as the last argument to this method to sp
731 * `pool`
732 specify a custom name for the connection pool being used. If omitted, then the connection pool name will be generated from the string template `"<host>:<port>"` or `"<unix-socket-path>"`.
733
734+* `pool_size`
735+ specify the size of the connection pool. If omitted and no
736+ `backlog` option was provided, no pool will be created. If omitted
737+ but `backlog` was provided, the pool will be created with a default
738+ size equal to the value of the [lua_socket_pool_size](#lua_socket_pool_size)
739+ directive.
740+ The connection pool holds up to `pool_size` alive connections
741+ ready to be reused by subsequent calls to [connect](#tcpsockconnect), but
742+ note that there is no upper limit to the total number of opened connections
743+ outside of the pool. If you need to restrict the total number of opened
744+ connections, specify the `backlog` option.
745+ When the connection pool would exceed its size limit, the least recently used
746+ (kept-alive) connection already in the pool will be closed to make room for
747+ the current connection.
748+ Note that the cosocket connection pool is per Nginx worker process rather
749+ than per Nginx server instance, so the size limit specified here also applies
750+ to every single Nginx worker process. Also note that the size of the connection
751+ pool cannot be changed once it has been created.
752+ This option was first introduced in the `v0.10.14` release.
753+
754+* `backlog`
755+ if specified, this module will limit the total number of opened connections
756+ for this pool. No more connections than `pool_size` can be opened
757+ for this pool at any time. If the connection pool is full, subsequent
758+ connect operations will be queued into a queue equal to this option's
759+ value (the "backlog" queue).
760+ If the number of queued connect operations is equal to `backlog`,
761+ subsequent connect operations will fail and return `nil` plus the
762+ error string `"too many waiting connect operations"`.
763+ The queued connect operations will be resumed once the number of connections
764+ in the pool is less than `pool_size`.
765+ The queued connect operation will abort once they have been queued for more
766+ than `connect_timeout`, controlled by
767+ [settimeouts](#tcpsocksettimeouts), and will return `nil` plus
768+ the error string `"timeout"`.
769+ This option was first introduced in the `v0.10.14` release.
770+
771 The support for the options table argument was first introduced in the `v0.5.7` release.
772
773 This method was first introduced in the `v0.5.0rc1` release.
774@@ -7165,6 +7290,40 @@ This feature was first introduced in the `v0.5.0rc1` release.
775
776 [Back to TOC](#nginx-api-for-lua)
777
778+tcpsock:receiveany
779+------------------
780+**syntax:** *data, err = tcpsock:receiveany(max)*
781+
782+**context:** *rewrite_by_lua&#42;, access_by_lua&#42;, content_by_lua&#42;, ngx.timer.&#42;, ssl_certificate_by_lua&#42;, ssl_session_fetch_by_lua&#42;*
783+
784+Returns any data received by the connected socket, at most `max` bytes.
785+
786+This method is a synchronous operation just like the [send](#tcpsocksend) method and is 100% nonblocking.
787+
788+In case of success, it returns the data received; in case of error, it returns `nil` with a string describing the error.
789+
790+If the received data is more than this size, this method will return with exactly this size of data.
791+The remaining data in the underlying receive buffer could be returned in the next reading operation.
792+
793+Timeout for the reading operation is controlled by the [lua_socket_read_timeout](#lua_socket_read_timeout) config directive and the [settimeouts](#tcpsocksettimeouts) method. And the latter takes priority. For example:
794+
795+```lua
796+
797+ sock:settimeouts(1000, 1000, 1000) -- one second timeout for connect/read/write
798+ local data, err = sock:receiveany(10 * 1024 * 1024) -- read any data, at most 10K
799+ if not data then
800+ ngx.say("failed to read any data: ", err)
801+ return
802+ end
803+ ngx.say("successfully read: ", data)
804+```
805+
806+This method doesn't automatically close the current connection when the read timeout error occurs. For other connection errors, this method always automatically closes the connection.
807+
808+This feature was first introduced in the `v0.10.14` release.
809+
810+[Back to TOC](#nginx-api-for-lua)
811+
812 tcpsock:receiveuntil
813 --------------------
814 **syntax:** *iterator = tcpsock:receiveuntil(pattern, options?)*
815@@ -7337,13 +7496,31 @@ Puts the current socket's connection immediately into the cosocket built-in conn
816
817 The first optional argument, `timeout`, can be used to specify the maximal idle timeout (in milliseconds) for the current connection. If omitted, the default setting in the [lua_socket_keepalive_timeout](#lua_socket_keepalive_timeout) config directive will be used. If the `0` value is given, then the timeout interval is unlimited.
818
819-The second optional argument, `size`, can be used to specify the maximal number of connections allowed in the connection pool for the current server (i.e., the current host-port pair or the unix domain socket file path). Note that the size of the connection pool cannot be changed once the pool is created. When this argument is omitted, the default setting in the [lua_socket_pool_size](#lua_socket_pool_size) config directive will be used.
820-
821-When the connection pool exceeds the available size limit, the least recently used (idle) connection already in the pool will be closed to make room for the current connection.
822-
823-Note that the cosocket connection pool is per Nginx worker process rather than per Nginx server instance, so the size limit specified here also applies to every single Nginx worker process.
824-
825-Idle connections in the pool will be monitored for any exceptional events like connection abortion or unexpected incoming data on the line, in which cases the connection in question will be closed and removed from the pool.
826+The second optional argument `size` is considered deprecated since
827+the `v0.10.14` release of this module, in favor of the
828+`pool_size` option of the [connect](#tcpsockconnect) method.
829+Since the `v0.10.14` release, this option will only take effect if
830+the call to [connect](#tcpsockconnect) did not already create a connection
831+pool.
832+When this option takes effect (no connection pool was previously created by
833+[connect](#tcpsockconnect)), it will specify the size of the connection pool,
834+and create it.
835+If omitted (and no pool was previously created), the default size is the value
836+of the [lua_socket_pool_size](#lua_socket_pool_size) directive.
837+The connection pool holds up to `size` alive connections ready to be
838+reused by subsequent calls to [connect](#tcpsockconnect), but note that there
839+is no upper limit to the total number of opened connections outside of the
840+pool.
841+When the connection pool would exceed its size limit, the least recently used
842+(kept-alive) connection already in the pool will be closed to make room for
843+the current connection.
844+Note that the cosocket connection pool is per Nginx worker process rather
845+than per Nginx server instance, so the size limit specified here also applies
846+to every single Nginx worker process. Also note that the size of the connection
847+pool cannot be changed once it has been created.
848+If you need to restrict the total number of opened connections, specify both
849+the `pool_size` and `backlog` option in the call to
850+[connect](#tcpsockconnect).
851
852 In case of success, this method returns `1`; otherwise, it returns `nil` and a string describing the error.
853
854@@ -7832,7 +8009,7 @@ timers" here mean timers that have not yet been expired and "running
855 timers" are those whose user callbacks are currently running.
856
857 The maximal number of pending timers allowed in an Nginx
858-worker is constrolled by the [lua_max_pending_timers](#lua_max_pending_timers)
859+worker is controlled by the [lua_max_pending_timers](#lua_max_pending_timers)
860 directive. The maximal number of running timers is controlled by the
861 [lua_max_running_timers](#lua_max_running_timers) directive.
862
863@@ -8115,7 +8292,7 @@ This Lua module does not ship with this ngx_lua module itself rather it is shipp
864 the
865 [lua-resty-core](https://github.com/openresty/lua-resty-core) library.
866
867-Please refer to the [documentation](https://github.com/openresty/lua-resty-core/blob/ocsp-cert-by-lua-2/lib/ngx/ocsp.md)
868+Please refer to the [documentation](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ocsp.md)
869 for this `ngx.ocsp` Lua module for more details.
870
871 This feature requires at least ngx_lua `v0.10.0`.
872@@ -8128,7 +8305,7 @@ ndk.set_var.DIRECTIVE
873
874 **context:** *init_worker_by_lua&#42;, set_by_lua&#42;, rewrite_by_lua&#42;, access_by_lua&#42;, content_by_lua&#42;, header_filter_by_lua&#42;, body_filter_by_lua&#42;, log_by_lua&#42;, ngx.timer.&#42;, balancer_by_lua&#42;, ssl_certificate_by_lua&#42;, ssl_session_fetch_by_lua&#42;, ssl_session_store_by_lua&#42;*
875
876-This mechanism allows calling other nginx C modules' directives that are implemented by [Nginx Devel Kit](https://github.com/simpl/ngx_devel_kit) (NDK)'s set_var submodule's `ndk_set_var_value`.
877+This mechanism allows calling other nginx C modules' directives that are implemented by [Nginx Devel Kit](https://github.com/simplresty/ngx_devel_kit) (NDK)'s set_var submodule's `ndk_set_var_value`.
878
879 For example, the following [set-misc-nginx-module](http://github.com/openresty/set-misc-nginx-module) directives can be invoked this way:
880
881@@ -8159,7 +8336,7 @@ Similarly, the following directives provided by [encrypted-session-nginx-module]
882 * [set_encrypt_session](http://github.com/openresty/encrypted-session-nginx-module#set_encrypt_session)
883 * [set_decrypt_session](http://github.com/openresty/encrypted-session-nginx-module#set_decrypt_session)
884
885-This feature requires the [ngx_devel_kit](https://github.com/simpl/ngx_devel_kit) module.
886+This feature requires the [ngx_devel_kit](https://github.com/simplresty/ngx_devel_kit) module.
887
888 [Back to TOC](#nginx-api-for-lua)
889
890@@ -8264,4 +8441,3 @@ Special PCRE Sequences
891 ----------------------
892
893 This section has been renamed to [Special Escaping Sequences](#special-escaping-sequences).
894-
895diff --git a/debian/modules/http-lua/config b/debian/modules/http-lua/config
896index 044deb9..e1d5e35 100644
897--- a/debian/modules/http-lua/config
898+++ b/debian/modules/http-lua/config
899@@ -361,6 +361,8 @@ HTTP_LUA_SRCS=" \
900 $ngx_addon_dir/src/ngx_http_lua_ssl_session_fetchby.c \
901 $ngx_addon_dir/src/ngx_http_lua_ssl.c \
902 $ngx_addon_dir/src/ngx_http_lua_log_ringbuf.c \
903+ $ngx_addon_dir/src/ngx_http_lua_input_filters.c \
904+ $ngx_addon_dir/src/ngx_http_lua_pipe.c \
905 "
906
907 HTTP_LUA_DEPS=" \
908@@ -422,6 +424,8 @@ HTTP_LUA_DEPS=" \
909 $ngx_addon_dir/src/ngx_http_lua_ssl_session_fetchby.h \
910 $ngx_addon_dir/src/ngx_http_lua_ssl.h \
911 $ngx_addon_dir/src/ngx_http_lua_log_ringbuf.h \
912+ $ngx_addon_dir/src/ngx_http_lua_input_filters.h \
913+ $ngx_addon_dir/src/ngx_http_lua_pipe.h \
914 "
915
916 CFLAGS="$CFLAGS -DNDK_SET_VAR"
917@@ -474,6 +478,17 @@ ngx_feature_test='setsockopt(1, SOL_SOCKET, SO_PASSCRED, NULL, 0);'
918
919 . auto/feature
920
921+ngx_feature="SA_RESTART"
922+ngx_feature_libs=
923+ngx_feature_name="NGX_HTTP_LUA_HAVE_SA_RESTART"
924+ngx_feature_run=no
925+ngx_feature_incs="#include <signal.h>"
926+ngx_feature_path=
927+ngx_feature_test='struct sigaction act;
928+ act.sa_flags |= SA_RESTART;'
929+
930+. auto/feature
931+
932 ngx_feature="__attribute__(constructor)"
933 ngx_feature_libs=
934 ngx_feature_name="NGX_HTTP_LUA_HAVE_CONSTRUCTOR"
935@@ -512,6 +527,36 @@ CC_TEST_FLAGS="$SAVED_CC_TEST_FLAGS"
936
937 # ----------------------------------------
938
939+ngx_feature="pipe2"
940+ngx_feature_libs=
941+ngx_feature_name="NGX_HTTP_LUA_HAVE_PIPE2"
942+ngx_feature_run=no
943+ngx_feature_incs="#include <fcntl.h>"
944+ngx_feature_test="int fd[2]; pipe2(fd, O_CLOEXEC|O_NONBLOCK);"
945+SAVED_CC_TEST_FLAGS="$CC_TEST_FLAGS"
946+CC_TEST_FLAGS="-Werror -Wall $CC_TEST_FLAGS"
947+
948+. auto/feature
949+
950+CC_TEST_FLAGS="$SAVED_CC_TEST_FLAGS"
951+
952+# ----------------------------------------
953+
954+ngx_feature="signalfd"
955+ngx_feature_libs=
956+ngx_feature_name="NGX_HTTP_LUA_HAVE_SIGNALFD"
957+ngx_feature_run=no
958+ngx_feature_incs="#include <sys/signalfd.h>"
959+ngx_feature_test="sigset_t set; signalfd(-1, &set, SFD_NONBLOCK|SFD_CLOEXEC);"
960+SAVED_CC_TEST_FLAGS="$CC_TEST_FLAGS"
961+CC_TEST_FLAGS="-Werror -Wall $CC_TEST_FLAGS"
962+
963+. auto/feature
964+
965+CC_TEST_FLAGS="$SAVED_CC_TEST_FLAGS"
966+
967+# ----------------------------------------
968+
969 if test -n "$ngx_module_link"; then
970 ngx_module_type=HTTP_AUX_FILTER
971 ngx_module_name=$ngx_addon_name
972diff --git a/debian/modules/http-lua/doc/HttpLuaModule.wiki b/debian/modules/http-lua/doc/HttpLuaModule.wiki
973index 2424d39..ff9b269 100644
974--- a/debian/modules/http-lua/doc/HttpLuaModule.wiki
975+++ b/debian/modules/http-lua/doc/HttpLuaModule.wiki
976@@ -2,6 +2,8 @@
977
978 ngx_http_lua_module - Embed the power of Lua into Nginx HTTP Servers.
979
980+This module is a core component of OpenResty. If you are using this module, then you are essentially using OpenResty :)
981+
982 ''This module is not distributed with the Nginx source.'' See [[#Installation|the installation instructions]].
983
984 = Status =
985@@ -10,7 +12,7 @@ Production ready.
986
987 = Version =
988
989-This document describes ngx_lua [https://github.com/openresty/lua-nginx-module/tags v0.10.11] released on 3 November 2017.
990+This document describes ngx_lua [https://github.com/openresty/lua-nginx-module/tags v0.10.15] released on March 14th, 2019.
991
992 = Synopsis =
993 <geshi lang="nginx">
994@@ -130,7 +132,9 @@ This document describes ngx_lua [https://github.com/openresty/lua-nginx-module/t
995
996 = Description =
997
998-This module embeds Lua, via the standard Lua 5.1 interpreter or [http://luajit.org/luajit.html LuaJIT 2.0/2.1], into Nginx and by leveraging Nginx's subrequests, allows the integration of the powerful Lua threads (Lua coroutines) into the Nginx event model.
999+This module is a core component of OpenResty. If you are using this module, then you are essentially using OpenResty :)
1000+
1001+This module embeds Lua, via [http://luajit.org/luajit.html LuaJIT 2.0/2.1], into Nginx and by leveraging Nginx's subrequests, allows the integration of the powerful Lua threads (Lua coroutines) into the Nginx event model.
1002
1003 Unlike [https://httpd.apache.org/docs/trunk/mod/mod_lua.html Apache's mod_lua] and [http://redmine.lighttpd.net/wiki/1/Docs:ModMagnet Lighttpd's mod_magnet], Lua code executed using this module can be ''100% non-blocking'' on network traffic as long as the [[#Nginx API for Lua|Nginx API for Lua]] provided by this module is used to handle
1004 requests to upstream services such as MySQL, PostgreSQL, Memcached, Redis, or upstream HTTP web services.
1005@@ -187,6 +191,7 @@ The Lua state (Lua VM instance) is shared across all the requests handled by a s
1006 The latest version of this module is compatible with the following versions of Nginx:
1007
1008 * 1.13.x (last tested: 1.13.6)
1009+* 1.12.x
1010 * 1.11.x (last tested: 1.11.2)
1011 * 1.10.x
1012 * 1.9.x (last tested: 1.9.15)
1013@@ -198,12 +203,12 @@ Nginx cores older than 1.6.0 (exclusive) are *not* supported.
1014
1015 = Installation =
1016
1017-It is *highly* recommended to use [http://openresty.org OpenResty releases] which integrate Nginx, ngx_lua, LuaJIT 2.1, as well as other powerful companion Nginx modules and Lua libraries. It is discouraged to build this module with nginx yourself since it is tricky to set up exactly right. Also, the stock nginx cores have various limitations and long standing bugs that can make some of this modules' features become disabled, not work properly, or run slower.
1018+It is *highly* recommended to use [http://openresty.org OpenResty releases] which integrate Nginx, ngx_lua, OpenResty's LuaJIT 2.1 branch version, as well as other powerful companion Nginx modules and Lua libraries. It is discouraged to build this module with nginx yourself since it is tricky to set up exactly right. Also, the stock nginx cores have various limitations and long standing bugs that can make some of this modules' features become disabled, not work properly, or run slower. The same applies to LuaJIT as well. OpenResty includes its own version of LuaJIT which gets specifically optimized and enhanced for the OpenResty environment.
1019
1020 Alternatively, ngx_lua can be manually compiled into Nginx:
1021
1022-# Install LuaJIT 2.0 or 2.1 (recommended) or Lua 5.1 (Lua 5.2 is ''not'' supported yet). LuaJIT can be downloaded from the [http://luajit.org/download.html LuaJIT project website] and Lua 5.1, from the [http://www.lua.org/ Lua project website]. Some distribution package managers also distribute LuaJIT and/or Lua.
1023-# Download the latest version of the ngx_devel_kit (NDK) module [https://github.com/simpl/ngx_devel_kit/tags HERE].
1024+# LuaJIT can be downloaded from the [https://github.com/openresty/luajit2/releases latest release of OpenResty's LuaJIT branch version]. The official LuaJIT 2.0 and 2.1 releases are also supported, although the performance will be significantly lower in many cases.
1025+# Download the latest version of the ngx_devel_kit (NDK) module [https://github.com/simplresty/ngx_devel_kit/tags HERE].
1026 # Download the latest version of ngx_lua [https://github.com/openresty/lua-nginx-module/tags HERE].
1027 # Download the latest version of Nginx [http://nginx.org/ HERE] (See [[#Nginx Compatibility|Nginx Compatibility]])
1028
1029@@ -270,24 +275,6 @@ To enable one or more of these macros, just pass extra C compiler options to the
1030 ./configure --with-cc-opt="-DNGX_LUA_USE_ASSERT -DNGX_LUA_ABORT_AT_PANIC"
1031 </geshi>
1032
1033-== Installation on Ubuntu 11.10 ==
1034-
1035-Note that it is recommended to use LuaJIT 2.0 or LuaJIT 2.1 instead of the standard Lua 5.1 interpreter wherever possible.
1036-
1037-If the standard Lua 5.1 interpreter is required however, run the following command to install it from the Ubuntu repository:
1038-
1039-<geshi lang="bash">
1040-apt-get install -y lua5.1 liblua5.1-0 liblua5.1-0-dev
1041-</geshi>
1042-
1043-Everything should be installed correctly, except for one small tweak.
1044-
1045-Library name <code>liblua.so</code> has been changed in liblua5.1 package, it only comes with <code>liblua5.1.so</code>, which needs to be symlinked to <code>/usr/lib</code> so it could be found during the configuration process.
1046-
1047-<geshi lang="bash">
1048-ln -s /usr/lib/x86_64-linux-gnu/liblua5.1.so /usr/lib/liblua.so
1049-</geshi>
1050-
1051 = Community =
1052
1053 == English Mailing List ==
1054@@ -313,7 +300,7 @@ Please submit bug reports, wishlists, or patches by
1055
1056 As from the <code>v0.5.0rc32</code> release, all <code>*_by_lua_file</code> configure directives (such as [[#content_by_lua_file|content_by_lua_file]]) support loading Lua 5.1 and LuaJIT 2.0/2.1 raw bytecode files directly.
1057
1058-Please note that the bytecode format used by LuaJIT 2.0/2.1 is not compatible with that used by the standard Lua 5.1 interpreter. So if using LuaJIT 2.0/2.1 with ngx_lua, LuaJIT compatible bytecode files must be generated as shown:
1059+Please note that the bytecode format used by LuaJIT 2.0/2.1 is not compatible with that used by the standard Lua 5.1 interpreter. So if you are using LuaJIT 2.0/2.1 with ngx_lua, LuaJIT compatible bytecode files must be generated as shown:
1060
1061 <geshi lang="bash">
1062 /path/to/luajit/bin/luajit -b /path/to/input_file.lua /path/to/output_file.ljbc
1063@@ -331,18 +318,6 @@ http://luajit.org/running.html#opt_b
1064
1065 Also, the bytecode files generated by LuaJIT 2.1 is ''not'' compatible with LuaJIT 2.0, and vice versa. The support for LuaJIT 2.1 bytecode was first added in ngx_lua v0.9.3.
1066
1067-Similarly, if using the standard Lua 5.1 interpreter with ngx_lua, Lua compatible bytecode files must be generated using the <code>luac</code> commandline utility as shown:
1068-
1069-<geshi lang="bash">
1070- luac -o /path/to/output_file.luac /path/to/input_file.lua
1071-</geshi>
1072-
1073-Unlike as with LuaJIT, debug information is included in standard Lua 5.1 bytecode files by default. This can be striped out by specifying the <code>-s</code> option as shown:
1074-
1075-<geshi lang="bash">
1076- luac -s -o /path/to/output_file.luac /path/to/input_file.lua
1077-</geshi>
1078-
1079 Attempts to load standard Lua 5.1 bytecode files into ngx_lua instances linked to LuaJIT 2.0/2.1 or vice versa, will result in an error message, such as that below, being logged into the Nginx <code>error.log</code> file:
1080
1081 <geshi lang="text">
1082@@ -509,8 +484,7 @@ However, later attempts to manipulate the cosocket object will fail and return t
1083 This issue is due to limitations in the Nginx event model and only appears to affect Mac OS X.
1084
1085 == Lua Coroutine Yielding/Resuming ==
1086-* Because Lua's <code>dofile</code> and <code>require</code> builtins are currently implemented as C functions in both Lua 5.1 and LuaJIT 2.0/2.1, if the Lua file being loaded by <code>dofile</code> or <code>require</code> invokes [[#ngx.location.capture|ngx.location.capture*]], [[#ngx.exec|ngx.exec]], [[#ngx.exit|ngx.exit]], or other API functions requiring yielding in the *top-level* scope of the Lua file, then the Lua error "attempt to yield across C-call boundary" will be raised. To avoid this, put these calls requiring yielding into your own Lua functions in the Lua file instead of the top-level scope of the file.
1087-* As the standard Lua 5.1 interpreter's VM is not fully resumable, the methods [[#ngx.location.capture|ngx.location.capture]], [[#ngx.location.capture_multi|ngx.location.capture_multi]], [[#ngx.redirect|ngx.redirect]], [[#ngx.exec|ngx.exec]], and [[#ngx.exit|ngx.exit]] cannot be used within the context of a Lua [http://www.lua.org/manual/5.1/manual.html#pdf-pcall pcall()] or [http://www.lua.org/manual/5.1/manual.html#pdf-xpcall xpcall()] or even the first line of the <code>for ... in ...</code> statement when the standard Lua 5.1 interpreter is used and the <code>attempt to yield across metamethod/C-call boundary</code> error will be produced. Please use LuaJIT 2.x, which supports a fully resumable VM, to avoid this.
1088+* Because Lua's <code>dofile</code> and <code>require</code> builtins are currently implemented as C functions in LuaJIT 2.0/2.1, if the Lua file being loaded by <code>dofile</code> or <code>require</code> invokes [[#ngx.location.capture|ngx.location.capture*]], [[#ngx.exec|ngx.exec]], [[#ngx.exit|ngx.exit]], or other API functions requiring yielding in the *top-level* scope of the Lua file, then the Lua error "attempt to yield across C-call boundary" will be raised. To avoid this, put these calls requiring yielding into your own Lua functions in the Lua file instead of the top-level scope of the file.
1089
1090 == Lua Variable Scope ==
1091 Care must be taken when importing modules and this form should be used:
1092@@ -683,7 +657,7 @@ As noted earlier, PCRE sequences presented within <code>*_by_lua_block {}</code>
1093 # nginx.conf
1094 location /test {
1095 content_by_lua_block {
1096- local regex = "\d+"
1097+ local regex = [[\d+]]
1098 local m = ngx.re.match("hello, 1234", regex)
1099 if m then ngx.say(m[0]) else ngx.say("not matched!") end
1100 }
1101@@ -765,7 +739,7 @@ The following dependencies are required to run the test suite:
1102 ** Test::Nginx: https://github.com/openresty/test-nginx
1103
1104 * Nginx modules:
1105-** [https://github.com/simpl/ngx_devel_kit ngx_devel_kit]
1106+** [https://github.com/simplresty/ngx_devel_kit ngx_devel_kit]
1107 ** [https://github.com/openresty/set-misc-nginx-module ngx_set_misc]
1108 ** [http://mdounin.ru/files/ngx_http_auth_request_module-0.2.tar.gz ngx_auth_request] (this is not needed if you're using Nginx 1.5.4+.
1109 ** [https://github.com/openresty/echo-nginx-module ngx_echo]
1110@@ -816,7 +790,7 @@ This module is licensed under the BSD license.
1111
1112 Copyright (C) 2009-2017, by Xiaozhe Wang (chaoslawful) <chaoslawful@gmail.com>.
1113
1114-Copyright (C) 2009-2017, by Yichun "agentzh" Zhang (章亦春) <agentzh@gmail.com>, OpenResty Inc.
1115+Copyright (C) 2009-2019, by Yichun "agentzh" Zhang (章亦春) <agentzh@gmail.com>, OpenResty Inc.
1116
1117 All rights reserved.
1118
1119@@ -844,7 +818,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
1120 * [http://openresty.org/#DynamicRoutingBasedOnRedis Dynamic Routing Based on Redis and Lua]
1121 * [http://openresty.org/#UsingLuaRocks Using LuaRocks with ngx_lua]
1122 * [https://github.com/openresty/lua-nginx-module/wiki/Introduction Introduction to ngx_lua]
1123-* [https://github.com/simpl/ngx_devel_kit ngx_devel_kit]
1124+* [https://github.com/simplresty/ngx_devel_kit ngx_devel_kit]
1125 * [[HttpEchoModule]]
1126 * [[HttpDrizzleModule]]
1127 * [https://github.com/FRiCKLE/ngx_postgres postgres-nginx-module]
1128@@ -861,6 +835,34 @@ how the result will be used. Below is a diagram showing the order in which direc
1129
1130 ![Lua Nginx Modules Directives](https://cloud.githubusercontent.com/assets/2137369/15272097/77d1c09e-1a37-11e6-97ef-d9767035fc3e.png)
1131
1132+== lua_load_resty_core ==
1133+
1134+'''syntax:''' ''lua_load_resty_core on|off''
1135+
1136+'''default:''' ''lua_load_resty_core on''
1137+
1138+'''context:''' ''http''
1139+
1140+Controls whether the <code>resty.core</code> module (from
1141+[https://github.com/openresty/lua-resty-core lua-resty-core]) should be loaded
1142+or not. When enabled, this directive is equivalent to executing the following
1143+when the Lua VM is created:
1144+
1145+<geshi lang="lua">
1146+ require "resty.core"
1147+</geshi>
1148+
1149+Note that usage of the <code>resty.core</code> module is recommended, as its
1150+FFI implementation is both faster, safer, and more complete than the Lua C API
1151+of the ngx_lua module.
1152+
1153+It must also be noted that the Lua C API of the ngx_lua module will eventually
1154+be removed, and usage of the FFI-based API (i.e. the <code>resty.core</code>
1155+module) will become mandatory. This directive only aims at providing a
1156+temporary backwards-compatibility mode in case of edge-cases.
1157+
1158+This directive was first introduced in the <code>v0.10.15</code> release.
1159+
1160 == lua_capture_error_log ==
1161 '''syntax:''' ''lua_capture_error_log size''
1162
1163@@ -1195,6 +1197,8 @@ This hook is often used to create per-worker reoccurring timers (via the [[#ngx.
1164
1165 This directive was first introduced in the <code>v0.9.5</code> release.
1166
1167+This hook no longer runs in the cache manager and cache loader processes since the <code>v0.10.12</code> release.
1168+
1169 == init_worker_by_lua_block ==
1170
1171 '''syntax:''' ''init_worker_by_lua_block { lua-script }''
1172@@ -1218,6 +1222,8 @@ For instance,
1173
1174 This directive was first introduced in the <code>v0.9.17</code> release.
1175
1176+This hook no longer runs in the cache manager and cache loader processes since the <code>v0.10.12</code> release.
1177+
1178 == init_worker_by_lua_file ==
1179
1180 '''syntax:''' ''init_worker_by_lua_file <lua-file-path>''
1181@@ -1230,6 +1236,8 @@ Similar to [[#init_worker_by_lua|init_worker_by_lua]], but accepts the file path
1182
1183 This directive was first introduced in the <code>v0.9.5</code> release.
1184
1185+This hook no longer runs in the cache manager and cache loader processes since the <code>v0.10.12</code> release.
1186+
1187 == set_by_lua ==
1188
1189 '''syntax:''' ''set_by_lua $res <lua-script-str> [$arg1 $arg2 ...]''
1190@@ -1284,7 +1292,7 @@ This directive can be freely mixed with all directives of the [[HttpRewriteModul
1191
1192 As from the <code>v0.5.0rc29</code> release, Nginx variable interpolation is disabled in the <code><lua-script-str></code> argument of this directive and therefore, the dollar sign character (<code>$</code>) can be used directly.
1193
1194-This directive requires the [https://github.com/simpl/ngx_devel_kit ngx_devel_kit] module.
1195+This directive requires the [https://github.com/simplresty/ngx_devel_kit ngx_devel_kit] module.
1196
1197 == set_by_lua_block ==
1198
1199@@ -1330,7 +1338,7 @@ and the Nginx config must be reloaded each time the Lua source file is modified.
1200 The Lua code cache can be temporarily disabled during development by
1201 switching [[#lua_code_cache|lua_code_cache]] <code>off</code> in <code>nginx.conf</code> to avoid reloading Nginx.
1202
1203-This directive requires the [https://github.com/simpl/ngx_devel_kit ngx_devel_kit] module.
1204+This directive requires the [https://github.com/simplresty/ngx_devel_kit ngx_devel_kit] module.
1205
1206 == content_by_lua ==
1207
1208@@ -2189,14 +2197,14 @@ SSL session resumption can then get immediately initiated and bypass the full SS
1209 Please note that TLS session tickets are very different and it is the clients' responsibility
1210 to cache the SSL session state when session tickets are used. SSL session resumptions based on
1211 TLS session tickets would happen automatically without going through this hook (nor the
1212-[[#ssl_session_store_by_lua*|ssl_session_store_by_lua_block]] hook). This hook is mainly
1213+[[#ssl_session_store_by_lua_block|ssl_session_store_by_lua*]] hook). This hook is mainly
1214 for older or less capable SSL clients that can only do SSL sessions by session IDs.
1215
1216 When [[#ssl_certificate_by_lua_block|ssl_certificate_by_lua*]] is specified at the same time,
1217 this hook usually runs before [[#ssl_certificate_by_lua_block|ssl_certificate_by_lua*]].
1218 When the SSL session is found and successfully loaded for the current SSL connection,
1219 SSL session resumption will happen and thus bypass the [[#ssl_certificate_by_lua_block|ssl_certificate_by_lua*]]
1220-hook completely. In this case, NGINX also bypasses the [[#ssl_session_store_by_lua*|ssl_session_store_by_lua_block]]
1221+hook completely. In this case, NGINX also bypasses the [[#ssl_session_store_by_lua_block|ssl_session_store_by_lua*]]
1222 hook, for obvious reasons.
1223
1224 To easily test this hook locally with a modern web browser, you can temporarily put the following line
1225@@ -2462,7 +2470,7 @@ This directive was first introduced in the <code>v0.9.11</code> release.
1226
1227 == lua_ssl_protocols ==
1228
1229-'''syntax:''' ''lua_ssl_protocols [SSLv2] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2]''
1230+'''syntax:''' ''lua_ssl_protocols [SSLv2] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2] [TLSv1.3]''
1231
1232 '''default:''' ''lua_ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2''
1233
1234@@ -2470,6 +2478,8 @@ This directive was first introduced in the <code>v0.9.11</code> release.
1235
1236 Enables the specified protocols for requests to a SSL/TLS server in the [[#tcpsock:sslhandshake|tcpsock:sslhandshake]] method.
1237
1238+The support for the <code>TLSv1.3</code> parameter requires version <code>v0.10.12</code> *and* OpenSSL 1.1.1.
1239+
1240 This directive was first introduced in the <code>v0.9.11</code> release.
1241
1242 == lua_ssl_trusted_certificate ==
1243@@ -2617,6 +2627,20 @@ When exceeding this limit, Nginx will stop running the callbacks of newly expire
1244
1245 This directive was first introduced in the <code>v0.8.0</code> release.
1246
1247+== lua_sa_restart ==
1248+
1249+'''syntax:''' ''lua_sa_restart on|off''
1250+
1251+'''default:''' ''lua_sa_restart on''
1252+
1253+'''context:''' ''http''
1254+
1255+When enabled, this module will set the `SA_RESTART` flag on nginx workers signal dispositions.
1256+
1257+This allows Lua I/O primitives to not be interrupted by nginx's handling of various signals.
1258+
1259+This directive was first introduced in the <code>v0.10.14</code> release.
1260+
1261 = Nginx API for Lua =
1262
1263 <!-- inline-toc -->
1264@@ -2748,7 +2772,7 @@ This API requires a relatively expensive metamethod call and it is recommended t
1265 ngx.DECLINED (-5)
1266 </geshi>
1267
1268-Note that only three of these constants are utilized by the [[#Nginx API for Lua|Nginx API for Lua]] (i.e., [[#ngx.exit|ngx.exit]] accepts <code>NGX_OK</code>, <code>NGX_ERROR</code>, and <code>NGX_DECLINED</code> as input).
1269+Note that only three of these constants are utilized by the [[#Nginx API for Lua|Nginx API for Lua]] (i.e., [[#ngx.exit|ngx.exit]] accepts <code>ngx.OK</code>, <code>ngx.ERROR</code>, and <code>ngx.DECLINED</code> as input).
1270
1271 <geshi lang="lua">
1272 ngx.null
1273@@ -2798,6 +2822,7 @@ These constants are usually used in [[#ngx.location.capture|ngx.location.capture
1274 value = ngx.HTTP_SEE_OTHER (303)
1275 value = ngx.HTTP_NOT_MODIFIED (304)
1276 value = ngx.HTTP_TEMPORARY_REDIRECT (307) (first added in the v0.9.20 release)
1277+ value = ngx.HTTP_PERMANENT_REDIRECT (308)
1278 value = ngx.HTTP_BAD_REQUEST (400)
1279 value = ngx.HTTP_UNAUTHORIZED (401)
1280 value = ngx.HTTP_PAYMENT_REQUIRED (402) (first added in the v0.9.20 release)
1281@@ -3399,7 +3424,7 @@ The same applies to assigning an empty table:
1282 ngx.header["X-My-Header"] = {};
1283 </geshi>
1284
1285-Setting <code>ngx.header.HEADER</code> after sending out response headers (either explicitly with [[#ngx.send_headers|ngx.send_headers]] or implicitly with [[#ngx.print|ngx.print]] and similar) will throw out a Lua exception.
1286+Setting <code>ngx.header.HEADER</code> after sending out response headers (either explicitly with [[#ngx.send_headers|ngx.send_headers]] or implicitly with [[#ngx.print|ngx.print]] and similar) will log an error message.
1287
1288 Reading <code>ngx.header.HEADER</code> will return the value of the response header named <code>HEADER</code>.
1289
1290@@ -3443,14 +3468,19 @@ Note that <code>ngx.header</code> is not a normal Lua table and as such, it is n
1291 For reading ''request'' headers, use the [[#ngx.req.get_headers|ngx.req.get_headers]] function instead.
1292
1293 == ngx.resp.get_headers ==
1294-'''syntax:''' ''headers = ngx.resp.get_headers(max_headers?, raw?)''
1295+'''syntax:''' ''headers, err = ngx.resp.get_headers(max_headers?, raw?)''
1296
1297 '''context:''' ''set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*, body_filter_by_lua*, log_by_lua*, balancer_by_lua*''
1298
1299 Returns a Lua table holding all the current response headers for the current request.
1300
1301 <geshi lang="lua">
1302-local h = ngx.resp.get_headers()
1303+local h, err = ngx.resp.get_headers()
1304+
1305+if err == "truncated" then
1306+ -- one can choose to ignore or reject the current response here
1307+end
1308+
1309 for k, v in pairs(h) do
1310 ...
1311 end
1312@@ -3458,6 +3488,8 @@ end
1313
1314 This function has the same signature as [[#ngx.req.get_headers|ngx.req.get_headers]] except getting response headers instead of request headers.
1315
1316+Note that a maximum of 100 response headers are parsed by default (including those with the same name) and that additional response headers are silently discarded to guard against potential denial of service attacks. Since <code>v0.10.13</code>, when the limit is exceeded, it will return a second value which is the string `"truncated"`.
1317+
1318 This API was first introduced in the <code>v0.9.5</code> release.
1319
1320 == ngx.req.is_internal ==
1321@@ -3546,7 +3578,7 @@ This method does not work in HTTP/2 requests yet.
1322 == ngx.req.get_method ==
1323 '''syntax:''' ''method_name = ngx.req.get_method()''
1324
1325-'''context:''' ''set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*, balancer_by_lua*''
1326+'''context:''' ''set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*, body_filter_by_lua*, balancer_by_lua*, log_by_lua*''
1327
1328 Retrieves the current request's request method name. Strings like <code>"GET"</code> and <code>"POST"</code> are returned instead of numerical [[#HTTP method constants|method constants]].
1329
1330@@ -3687,7 +3719,7 @@ This interface was first introduced in the <code>v0.3.1rc13</code> release.
1331 See also [[#ngx.req.set_uri|ngx.req.set_uri]].
1332
1333 == ngx.req.get_uri_args ==
1334-'''syntax:''' ''args = ngx.req.get_uri_args(max_args?)''
1335+'''syntax:''' ''args, err = ngx.req.get_uri_args(max_args?)''
1336
1337 '''context:''' ''set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*, body_filter_by_lua*, log_by_lua*, balancer_by_lua*''
1338
1339@@ -3696,7 +3728,12 @@ Returns a Lua table holding all the current request URL query arguments.
1340 <geshi lang="nginx">
1341 location = /test {
1342 content_by_lua_block {
1343- local args = ngx.req.get_uri_args()
1344+ local args, err = ngx.req.get_uri_args()
1345+
1346+ if err == "truncated" then
1347+ -- one can choose to ignore or reject the current request here
1348+ end
1349+
1350 for key, val in pairs(args) do
1351 if type(val) == "table" then
1352 ngx.say(key, ": ", table.concat(val, ", "))
1353@@ -3743,7 +3780,7 @@ Updating query arguments via the nginx variable <code>$args</code> (or <code>ngx
1354
1355 <geshi lang="lua">
1356 ngx.var.args = "a=3&b=42"
1357- local args = ngx.req.get_uri_args()
1358+ local args, err = ngx.req.get_uri_args()
1359 </geshi>
1360
1361 Here the <code>args</code> table will always look like
1362@@ -3754,18 +3791,21 @@ Here the <code>args</code> table will always look like
1363
1364 regardless of the actual request query string.
1365
1366-Note that a maximum of 100 request arguments are parsed by default (including those with the same name) and that additional request arguments are silently discarded to guard against potential denial of service attacks.
1367+Note that a maximum of 100 request arguments are parsed by default (including those with the same name) and that additional request arguments are silently discarded to guard against potential denial of service attacks. Since <code>v0.10.13</code>, when the limit is exceeded, it will return a second value which is the string `"truncated"`.
1368
1369 However, the optional <code>max_args</code> function argument can be used to override this limit:
1370
1371 <geshi lang="lua">
1372- local args = ngx.req.get_uri_args(10)
1373+ local args, err = ngx.req.get_uri_args(10)
1374+ if err == "truncated" then
1375+ -- one can choose to ignore or reject the current request here
1376+ end
1377 </geshi>
1378
1379 This argument can be set to zero to remove the limit and to process all request arguments received:
1380
1381 <geshi lang="lua">
1382- local args = ngx.req.get_uri_args(0)
1383+ local args, err = ngx.req.get_uri_args(0)
1384 </geshi>
1385
1386 Removing the <code>max_args</code> cap is strongly discouraged.
1387@@ -3782,6 +3822,11 @@ Returns a Lua table holding all the current request POST query arguments (of the
1388 content_by_lua_block {
1389 ngx.req.read_body()
1390 local args, err = ngx.req.get_post_args()
1391+
1392+ if err == "truncated" then
1393+ -- one can choose to ignore or reject the current request here
1394+ end
1395+
1396 if not args then
1397 ngx.say("failed to get post args: ", err)
1398 return
1399@@ -3844,31 +3889,39 @@ That is, they will take Lua boolean values <code>true</code>. However, they are
1400
1401 Empty key arguments are discarded. <code>POST /test</code> with body <code>=hello&=world</code> will yield empty outputs for instance.
1402
1403-Note that a maximum of 100 request arguments are parsed by default (including those with the same name) and that additional request arguments are silently discarded to guard against potential denial of service attacks.
1404+Note that a maximum of 100 request arguments are parsed by default (including those with the same name) and that additional request arguments are silently discarded to guard against potential denial of service attacks. Since <code>v0.10.13</code>, when the limit is exceeded, it will return a second value which is the string `"truncated"`.
1405
1406 However, the optional <code>max_args</code> function argument can be used to override this limit:
1407
1408 <geshi lang="lua">
1409- local args = ngx.req.get_post_args(10)
1410+ local args, err = ngx.req.get_post_args(10)
1411+ if err == "truncated" then
1412+ -- one can choose to ignore or reject the current request here
1413+ end
1414 </geshi>
1415
1416 This argument can be set to zero to remove the limit and to process all request arguments received:
1417
1418 <geshi lang="lua">
1419- local args = ngx.req.get_post_args(0)
1420+ local args, err = ngx.req.get_post_args(0)
1421 </geshi>
1422
1423 Removing the <code>max_args</code> cap is strongly discouraged.
1424
1425 == ngx.req.get_headers ==
1426-'''syntax:''' ''headers = ngx.req.get_headers(max_headers?, raw?)''
1427+'''syntax:''' ''headers, err = ngx.req.get_headers(max_headers?, raw?)''
1428
1429 '''context:''' ''set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*, body_filter_by_lua*, log_by_lua*''
1430
1431 Returns a Lua table holding all the current request headers.
1432
1433 <geshi lang="lua">
1434- local h = ngx.req.get_headers()
1435+ local h, err = ngx.req.get_headers()
1436+
1437+ if err == "truncated" then
1438+ -- one can choose to ignore or reject the current request here
1439+ end
1440+
1441 for k, v in pairs(h) do
1442 ...
1443 end
1444@@ -3896,18 +3949,22 @@ the value of <code>ngx.req.get_headers()["Foo"]</code> will be a Lua (array) tab
1445 {"foo", "bar", "baz"}
1446 </geshi>
1447
1448-Note that a maximum of 100 request headers are parsed by default (including those with the same name) and that additional request headers are silently discarded to guard against potential denial of service attacks.
1449+Note that a maximum of 100 request headers are parsed by default (including those with the same name) and that additional request headers are silently discarded to guard against potential denial of service attacks. Since <code>v0.10.13</code>, when the limit is exceeded, it will return a second value which is the string `"truncated"`.
1450
1451 However, the optional <code>max_headers</code> function argument can be used to override this limit:
1452
1453 <geshi lang="lua">
1454- local headers = ngx.req.get_headers(10)
1455+ local headers, err = ngx.req.get_headers(10)
1456+
1457+ if err == "truncated" then
1458+ -- one can choose to ignore or reject the current request here
1459+ end
1460 </geshi>
1461
1462 This argument can be set to zero to remove the limit and to process all request headers received:
1463
1464 <geshi lang="lua">
1465- local headers = ngx.req.get_headers(0)
1466+ local headers, err = ngx.req.get_headers(0)
1467 </geshi>
1468
1469 Removing the <code>max_headers</code> cap is strongly discouraged.
1470@@ -4029,7 +4086,7 @@ This function returns <code>nil</code> if
1471 # the request body has been read into disk temporary files,
1472 # or the request body has zero size.
1473
1474-If the request body has not been read yet, call [[#ngx.req.read_body|ngx.req.read_body]] first (or turned on [[#lua_need_request_body|lua_need_request_body]] to force this module to read the request body. This is not recommended however).
1475+If the request body has not been read yet, call [[#ngx.req.read_body|ngx.req.read_body]] first (or turn on [[#lua_need_request_body|lua_need_request_body]] to force this module to read the request body. This is not recommended however).
1476
1477 If the request body has been read into disk files, try calling the [[#ngx.req.get_body_file|ngx.req.get_body_file]] function instead.
1478
1479@@ -4050,7 +4107,7 @@ Retrieves the file name for the in-file request body data. Returns <code>nil</co
1480
1481 The returned file is read only and is usually cleaned up by Nginx's memory pool. It should not be manually modified, renamed, or removed in Lua code.
1482
1483-If the request body has not been read yet, call [[#ngx.req.read_body|ngx.req.read_body]] first (or turned on [[#lua_need_request_body|lua_need_request_body]] to force this module to read the request body. This is not recommended however).
1484+If the request body has not been read yet, call [[#ngx.req.read_body|ngx.req.read_body]] first (or turn on [[#lua_need_request_body|lua_need_request_body]] to force this module to read the request body. This is not recommended however).
1485
1486 If the request body has been read into memory, try calling the [[#ngx.req.get_body_data|ngx.req.get_body_data]] function instead.
1487
1488@@ -4067,7 +4124,9 @@ See also [[#ngx.req.get_body_data|ngx.req.get_body_data]].
1489
1490 Set the current request's request body using the in-memory data specified by the <code>data</code> argument.
1491
1492-If the current request's request body has not been read, then it will be properly discarded. When the current request's request body has been read into memory or buffered into a disk file, then the old request body's memory will be freed or the disk file will be cleaned up immediately, respectively.
1493+If the request body has not been read yet, call [[#ngx.req.read_body|ngx.req.read_body]] first (or turn on [[#lua_need_request_body|lua_need_request_body]] to force this module to read the request body. This is not recommended however). Additionally, the request body must not have been previously discarded by [[#ngx.req.discard_body|ngx.req.discard_body]].
1494+
1495+Whether the previous request body has been read into memory or buffered into a disk file, it will be freed or the disk file will be cleaned up immediately, respectively.
1496
1497 This function was first introduced in the <code>v0.3.1rc18</code> release.
1498
1499@@ -4080,11 +4139,13 @@ See also [[#ngx.req.set_body_file|ngx.req.set_body_file]].
1500
1501 Set the current request's request body using the in-file data specified by the <code>file_name</code> argument.
1502
1503+If the request body has not been read yet, call [[#ngx.req.read_body|ngx.req.read_body]] first (or turn on [[#lua_need_request_body|lua_need_request_body]] to force this module to read the request body. This is not recommended however). Additionally, the request body must not have been previously discarded by [[#ngx.req.discard_body|ngx.req.discard_body]].
1504+
1505 If the optional <code>auto_clean</code> argument is given a <code>true</code> value, then this file will be removed at request completion or the next time this function or [[#ngx.req.set_body_data|ngx.req.set_body_data]] are called in the same request. The <code>auto_clean</code> is default to <code>false</code>.
1506
1507 Please ensure that the file specified by the <code>file_name</code> argument exists and is readable by an Nginx worker process by setting its permission properly to avoid Lua exception errors.
1508
1509-If the current request's request body has not been read, then it will be properly discarded. When the current request's request body has been read into memory or buffered into a disk file, then the old request body's memory will be freed or the disk file will be cleaned up immediately, respectively.
1510+Whether the previous request body has been read into memory or buffered into a disk file, it will be freed or the disk file will be cleaned up immediately, respectively.
1511
1512 This function was first introduced in the <code>v0.3.1rc18</code> release.
1513
1514@@ -4244,6 +4305,7 @@ The optional <code>status</code> parameter specifies the HTTP status code to be
1515 * <code>302</code> (default)
1516 * <code>303</code>
1517 * <code>307</code>
1518+* <code>308</code>
1519
1520 It is <code>302</code> (<code>ngx.HTTP_MOVED_TEMPORARILY</code>) by default.
1521
1522@@ -4442,7 +4504,7 @@ Number literals can be used directly as the argument, for instance,
1523 ngx.exit(501)
1524 </geshi>
1525
1526-Note that while this method accepts all [[#HTTP status constants|HTTP status constants]] as input, it only accepts <code>NGX_OK</code> and <code>NGX_ERROR</code> of the [[#core constants|core constants]].
1527+Note that while this method accepts all [[#HTTP status constants|HTTP status constants]] as input, it only accepts <code>ngx.OK</code> and <code>ngx.ERROR</code> of the [[#core constants|core constants]].
1528
1529 Also note that this method call terminates the processing of the current request and that it is recommended that a coding style that combines this method call with the <code>return</code> statement, i.e., <code>return ngx.exit(...)</code> be used to reinforce the fact that the request processing is being terminated.
1530
1531@@ -4571,13 +4633,13 @@ If the argument value is <code>false</code>, then the effect is equivalent to th
1532 This method was first introduced in the <code>v0.3.1rc27</code> release.
1533
1534 == ngx.decode_args ==
1535-'''syntax:''' ''table = ngx.decode_args(str, max_args?)''
1536+'''syntax:''' ''table, err = ngx.decode_args(str, max_args?)''
1537
1538 '''context:''' ''set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*, body_filter_by_lua*, log_by_lua*, ngx.timer.*, balancer_by_lua*, ssl_certificate_by_lua*, ssl_session_fetch_by_lua*, ssl_session_store_by_lua*''
1539
1540 Decodes a URI encoded query-string into a Lua table. This is the inverse function of [[#ngx.encode_args|ngx.encode_args]].
1541
1542-The optional <code>max_args</code> argument can be used to specify the maximum number of arguments parsed from the <code>str</code> argument. By default, a maximum of 100 request arguments are parsed (including those with the same name) and that additional URI arguments are silently discarded to guard against potential denial of service attacks.
1543+The optional <code>max_args</code> argument can be used to specify the maximum number of arguments parsed from the <code>str</code> argument. By default, a maximum of 100 request arguments are parsed (including those with the same name) and that additional URI arguments are silently discarded to guard against potential denial of service attacks. Since <code>v0.10.13</code>, when the limit is exceeded, it will return a second value which is the string `"truncated"`.
1544
1545 This argument can be set to zero to remove the limit and to process all request arguments received:
1546
1547@@ -5405,10 +5467,12 @@ This feature was first introduced in the <code>v0.3.1rc22</code> release.
1548 See also [[#ngx.shared.DICT|ngx.shared.DICT]].
1549
1550 == ngx.shared.DICT.incr ==
1551-'''syntax:''' ''newval, err, forcible? = ngx.shared.DICT:incr(key, value, init?)''
1552+'''syntax:''' ''newval, err, forcible? = ngx.shared.DICT:incr(key, value, init?, init_ttl?)''
1553
1554 '''context:''' ''init_by_lua*, set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*, body_filter_by_lua*, log_by_lua*, ngx.timer.*, balancer_by_lua*, ssl_certificate_by_lua*, ssl_session_fetch_by_lua*, ssl_session_store_by_lua*''
1555
1556+'''optional requirement:''' <code>resty.core.shdict</code> or <code>resty.core</code>
1557+
1558 Increments the (numerical) value for <code>key</code> in the shm-based dictionary [[#ngx.shared.DICT|ngx.shared.DICT]] by the step value <code>value</code>. Returns the new resulting number if the operation is successfully completed or <code>nil</code> and an error message otherwise.
1559
1560 When the key does not exist or has already expired in the shared dictionary,
1561@@ -5418,6 +5482,24 @@ When the key does not exist or has already expired in the shared dictionary,
1562
1563 Like the [[#ngx.shared.DICT.add|add]] method, it also overrides the (least recently used) unexpired items in the store when running out of storage in the shared memory zone.
1564
1565+The optional <code>init_ttl</code> argument specifies expiration time (in seconds) of the value when it is initialized via the <code>init</code> argument. The time resolution is <code>0.001</code> seconds. If <code>init_ttl</code> takes the value <code>0</code> (which is the default), then the item will never expire. This argument cannot be provided without providing the <code>init</code> argument as well, and has no effect if the value already exists (e.g., if it was previously inserted via [[#ngx.shared.DICT.set|set]] or the likes).
1566+
1567+'''Note:''' Usage of the <code>init_ttl</code> argument requires the <code>resty.core.shdict</code> or <code>resty.core</code> modules from the [https://github.com/openresty/lua-resty-core lua-resty-core] library. Example:
1568+
1569+<geshi lang="lua">
1570+ require "resty.core"
1571+
1572+ local cats = ngx.shared.cats
1573+ local newval, err = cats:incr("black_cats", 1, 0, 0.1)
1574+
1575+ print(newval) -- 1
1576+
1577+ ngx.sleep(0.2)
1578+
1579+ local val, err = cats:get("black_cats")
1580+ print(val) -- nil
1581+</geshi>
1582+
1583 The <code>forcible</code> return value will always be <code>nil</code> when the <code>init</code> argument is not specified.
1584
1585 If this method succeeds in storing the current item by forcibly removing other not-yet-expired items in the dictionary via LRU, the <code>forcible</code> return value will be <code>true</code>. If it stores the item without forcibly removing other valid items, then the return value <code>forcible</code> will be <code>false</code>.
1586@@ -5430,6 +5512,8 @@ This method was first introduced in the <code>v0.3.1rc22</code> release.
1587
1588 The optional <code>init</code> parameter was first added in the <code>v0.10.6</code> release.
1589
1590+The optional <code>init_ttl</code> parameter was introduced in the <code>v0.10.12rc2</code> release.
1591+
1592 See also [[#ngx.shared.DICT|ngx.shared.DICT]].
1593
1594 == ngx.shared.DICT.lpush ==
1595@@ -5583,7 +5667,7 @@ See also [[#ngx.shared.DICT.flush_expired|ngx.shared.DICT.flush_expired]] and [[
1596
1597 Flushes out the expired items in the dictionary, up to the maximal number specified by the optional <code>max_count</code> argument. When the <code>max_count</code> argument is given <code>0</code> or not given at all, then it means unlimited. Returns the number of items that have actually been flushed.
1598
1599-Unlike the [[#ngx.shared.DICT.flush_all|flush_all]] method, this method actually free up the memory used by the expired items.
1600+Unlike the [[#ngx.shared.DICT.flush_all|flush_all]] method, this method actually frees up the memory used by the expired items.
1601
1602 This feature was first introduced in the <code>v0.6.3</code> release.
1603
1604@@ -5829,6 +5913,7 @@ Creates and returns a TCP or stream-oriented unix domain socket object (also kno
1605 * [[#tcpsock:settimeout|settimeout]]
1606 * [[#tcpsock:settimeouts|settimeouts]]
1607 * [[#tcpsock:setoption|setoption]]
1608+* [[#tcpsock:receiveany|receiveany]]
1609 * [[#tcpsock:receiveuntil|receiveuntil]]
1610 * [[#tcpsock:setkeepalive|setkeepalive]]
1611 * [[#tcpsock:getreusedtimes|getreusedtimes]]
1612@@ -5926,6 +6011,43 @@ An optional Lua table can be specified as the last argument to this method to sp
1613 * <code>pool</code>
1614 : specify a custom name for the connection pool being used. If omitted, then the connection pool name will be generated from the string template <code>"<host>:<port>"</code> or <code>"<unix-socket-path>"</code>.
1615
1616+* <code>pool_size</code>
1617+: specify the size of the connection pool. If omitted and no
1618+: <code>backlog</code> option was provided, no pool will be created. If omitted
1619+: but <code>backlog</code> was provided, the pool will be created with a default
1620+: size equal to the value of the [[#lua_socket_pool_size|lua_socket_pool_size]]
1621+: directive.
1622+: The connection pool holds up to <code>pool_size</code> alive connections
1623+: ready to be reused by subsequent calls to [[#tcpsock:connect|connect]], but
1624+: note that there is no upper limit to the total number of opened connections
1625+: outside of the pool. If you need to restrict the total number of opened
1626+: connections, specify the <code>backlog</code> option.
1627+: When the connection pool would exceed its size limit, the least recently used
1628+: (kept-alive) connection already in the pool will be closed to make room for
1629+: the current connection.
1630+: Note that the cosocket connection pool is per Nginx worker process rather
1631+: than per Nginx server instance, so the size limit specified here also applies
1632+: to every single Nginx worker process. Also note that the size of the connection
1633+: pool cannot be changed once it has been created.
1634+: This option was first introduced in the <code>v0.10.14</code> release.
1635+
1636+* <code>backlog</code>
1637+: if specified, this module will limit the total number of opened connections
1638+: for this pool. No more connections than <code>pool_size</code> can be opened
1639+: for this pool at any time. If the connection pool is full, subsequent
1640+: connect operations will be queued into a queue equal to this option's
1641+: value (the "backlog" queue).
1642+: If the number of queued connect operations is equal to <code>backlog</code>,
1643+: subsequent connect operations will fail and return <code>nil</code> plus the
1644+: error string <code>"too many waiting connect operations"</code>.
1645+: The queued connect operations will be resumed once the number of connections
1646+: in the pool is less than <code>pool_size</code>.
1647+: The queued connect operation will abort once they have been queued for more
1648+: than <code>connect_timeout</code>, controlled by
1649+: [[#tcpsock:settimeouts|settimeouts]], and will return <code>nil</code> plus
1650+: the error string <code>"timeout"</code>.
1651+: This option was first introduced in the <code>v0.10.14</code> release.
1652+
1653 The support for the options table argument was first introduced in the <code>v0.5.7</code> release.
1654
1655 This method was first introduced in the <code>v0.5.0rc1</code> release.
1656@@ -6038,6 +6160,36 @@ Since the <code>v0.8.8</code> release, this method no longer automatically close
1657
1658 This feature was first introduced in the <code>v0.5.0rc1</code> release.
1659
1660+== tcpsock:receiveany ==
1661+'''syntax:''' ''data, err = tcpsock:receiveany(max)''
1662+
1663+'''context:''' ''rewrite_by_lua*, access_by_lua*, content_by_lua*, ngx.timer.*, ssl_certificate_by_lua*, ssl_session_fetch_by_lua*''
1664+
1665+Returns any data received by the connected socket, at most <code>max</code> bytes.
1666+
1667+This method is a synchronous operation just like the [[#tcpsock:send|send]] method and is 100% nonblocking.
1668+
1669+In case of success, it returns the data received; in case of error, it returns <code>nil</code> with a string describing the error.
1670+
1671+If the received data is more than this size, this method will return with exactly this size of data.
1672+The remaining data in the underlying receive buffer could be returned in the next reading operation.
1673+
1674+Timeout for the reading operation is controlled by the [[#lua_socket_read_timeout|lua_socket_read_timeout]] config directive and the [[#tcpsock:settimeouts|settimeouts]] method. And the latter takes priority. For example:
1675+
1676+<geshi lang="lua">
1677+ sock:settimeouts(1000, 1000, 1000) -- one second timeout for connect/read/write
1678+ local data, err = sock:receiveany(10 * 1024 * 1024) -- read any data, at most 10K
1679+ if not data then
1680+ ngx.say("failed to read any data: ", err)
1681+ return
1682+ end
1683+ ngx.say("successfully read: ", data)
1684+</geshi>
1685+
1686+This method doesn't automatically close the current connection when the read timeout error occurs. For other connection errors, this method always automatically closes the connection.
1687+
1688+This feature was first introduced in the <code>v0.10.14</code> release.
1689+
1690 == tcpsock:receiveuntil ==
1691 '''syntax:''' ''iterator = tcpsock:receiveuntil(pattern, options?)''
1692
1693@@ -6190,13 +6342,31 @@ Puts the current socket's connection immediately into the cosocket built-in conn
1694
1695 The first optional argument, <code>timeout</code>, can be used to specify the maximal idle timeout (in milliseconds) for the current connection. If omitted, the default setting in the [[#lua_socket_keepalive_timeout|lua_socket_keepalive_timeout]] config directive will be used. If the <code>0</code> value is given, then the timeout interval is unlimited.
1696
1697-The second optional argument, <code>size</code>, can be used to specify the maximal number of connections allowed in the connection pool for the current server (i.e., the current host-port pair or the unix domain socket file path). Note that the size of the connection pool cannot be changed once the pool is created. When this argument is omitted, the default setting in the [[#lua_socket_pool_size|lua_socket_pool_size]] config directive will be used.
1698-
1699-When the connection pool exceeds the available size limit, the least recently used (idle) connection already in the pool will be closed to make room for the current connection.
1700-
1701-Note that the cosocket connection pool is per Nginx worker process rather than per Nginx server instance, so the size limit specified here also applies to every single Nginx worker process.
1702-
1703-Idle connections in the pool will be monitored for any exceptional events like connection abortion or unexpected incoming data on the line, in which cases the connection in question will be closed and removed from the pool.
1704+The second optional argument <code>size</code> is considered deprecated since
1705+the <code>v0.10.14</code> release of this module, in favor of the
1706+<code>pool_size</code> option of the [[#tcpsock:connect|connect]] method.
1707+Since the <code>v0.10.14</code> release, this option will only take effect if
1708+the call to [[#tcpsock:connect|connect]] did not already create a connection
1709+pool.
1710+When this option takes effect (no connection pool was previously created by
1711+[[#tcpsock:connect|connect]]), it will specify the size of the connection pool,
1712+and create it.
1713+If omitted (and no pool was previously created), the default size is the value
1714+of the [[#lua_socket_pool_size|lua_socket_pool_size]] directive.
1715+The connection pool holds up to <code>size</code> alive connections ready to be
1716+reused by subsequent calls to [[#tcpsock:connect|connect]], but note that there
1717+is no upper limit to the total number of opened connections outside of the
1718+pool.
1719+When the connection pool would exceed its size limit, the least recently used
1720+(kept-alive) connection already in the pool will be closed to make room for
1721+the current connection.
1722+Note that the cosocket connection pool is per Nginx worker process rather
1723+than per Nginx server instance, so the size limit specified here also applies
1724+to every single Nginx worker process. Also note that the size of the connection
1725+pool cannot be changed once it has been created.
1726+If you need to restrict the total number of opened connections, specify both
1727+the <code>pool_size</code> and <code>backlog</code> option in the call to
1728+[[#tcpsock:connect|connect]].
1729
1730 In case of success, this method returns <code>1</code>; otherwise, it returns <code>nil</code> and a string describing the error.
1731
1732@@ -6653,7 +6823,7 @@ timers" here mean timers that have not yet been expired and "running
1733 timers" are those whose user callbacks are currently running.
1734
1735 The maximal number of pending timers allowed in an Nginx
1736-worker is constrolled by the [[#lua_max_pending_timers|lua_max_pending_timers]]
1737+worker is controlled by the [[#lua_max_pending_timers|lua_max_pending_timers]]
1738 directive. The maximal number of running timers is controlled by the
1739 [[#lua_max_running_timers|lua_max_running_timers]] directive.
1740
1741@@ -6885,7 +7055,7 @@ This Lua module does not ship with this ngx_lua module itself rather it is shipp
1742 the
1743 [https://github.com/openresty/lua-resty-core lua-resty-core] library.
1744
1745-Please refer to the [https://github.com/openresty/lua-resty-core/blob/ocsp-cert-by-lua-2/lib/ngx/ocsp.md documentation]
1746+Please refer to the [https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ocsp.md documentation]
1747 for this <code>ngx.ocsp</code> Lua module for more details.
1748
1749 This feature requires at least ngx_lua <code>v0.10.0</code>.
1750@@ -6895,7 +7065,7 @@ This feature requires at least ngx_lua <code>v0.10.0</code>.
1751
1752 '''context:''' ''init_worker_by_lua*, set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*, body_filter_by_lua*, log_by_lua*, ngx.timer.*, balancer_by_lua*, ssl_certificate_by_lua*, ssl_session_fetch_by_lua*, ssl_session_store_by_lua*''
1753
1754-This mechanism allows calling other nginx C modules' directives that are implemented by [https://github.com/simpl/ngx_devel_kit Nginx Devel Kit] (NDK)'s set_var submodule's <code>ndk_set_var_value</code>.
1755+This mechanism allows calling other nginx C modules' directives that are implemented by [https://github.com/simplresty/ngx_devel_kit Nginx Devel Kit] (NDK)'s set_var submodule's <code>ndk_set_var_value</code>.
1756
1757 For example, the following [[HttpSetMiscModule]] directives can be invoked this way:
1758
1759@@ -6925,7 +7095,7 @@ Similarly, the following directives provided by [[HttpEncryptedSessionModule]] c
1760 * [[HttpEncryptedSessionModule#set_encrypt_session|set_encrypt_session]]
1761 * [[HttpEncryptedSessionModule#set_decrypt_session|set_decrypt_session]]
1762
1763-This feature requires the [https://github.com/simpl/ngx_devel_kit ngx_devel_kit] module.
1764+This feature requires the [https://github.com/simplresty/ngx_devel_kit ngx_devel_kit] module.
1765
1766 == coroutine.create ==
1767 '''syntax:''' ''co = coroutine.create(f)''
1768@@ -7006,4 +7176,3 @@ This section is just holding obsolete documentation sections that have been eith
1769 == Special PCRE Sequences ==
1770
1771 This section has been renamed to [[#Special Escaping Sequences|Special Escaping Sequences]].
1772-
1773diff --git a/debian/modules/http-lua/src/api/ngx_http_lua_api.h b/debian/modules/http-lua/src/api/ngx_http_lua_api.h
1774index 1e07b71..129eb99 100644
1775--- a/debian/modules/http-lua/src/api/ngx_http_lua_api.h
1776+++ b/debian/modules/http-lua/src/api/ngx_http_lua_api.h
1777@@ -19,7 +19,7 @@
1778 /* Public API for other Nginx modules */
1779
1780
1781-#define ngx_http_lua_version 10011
1782+#define ngx_http_lua_version 10015
1783
1784
1785 typedef struct {
1786@@ -34,6 +34,13 @@ typedef struct {
1787 } ngx_http_lua_value_t;
1788
1789
1790+typedef struct {
1791+ int len;
1792+ /* this padding hole on 64-bit systems is expected */
1793+ u_char *data;
1794+} ngx_http_lua_ffi_str_t;
1795+
1796+
1797 lua_State *ngx_http_lua_get_global_state(ngx_conf_t *cf);
1798
1799 ngx_http_request_t *ngx_http_lua_get_request(lua_State *L);
1800diff --git a/debian/modules/http-lua/src/ngx_http_lua_accessby.c b/debian/modules/http-lua/src/ngx_http_lua_accessby.c
1801index 56bf0fa..d3fe294 100644
1802--- a/debian/modules/http-lua/src/ngx_http_lua_accessby.c
1803+++ b/debian/modules/http-lua/src/ngx_http_lua_accessby.c
1804@@ -60,7 +60,7 @@ ngx_http_lua_access_handler(ngx_http_request_t *r)
1805 #endif
1806
1807 if (cur_ph < last_ph) {
1808- dd("swaping the contents of cur_ph and last_ph...");
1809+ dd("swapping the contents of cur_ph and last_ph...");
1810
1811 tmp = *cur_ph;
1812
1813@@ -261,9 +261,11 @@ ngx_http_lua_access_by_chunk(lua_State *L, ngx_http_request_t *r)
1814 /* move code closure to new coroutine */
1815 lua_xmove(L, co, 1);
1816
1817+#ifndef OPENRESTY_LUAJIT
1818 /* set closure's env table to new coroutine's globals table */
1819 ngx_http_lua_get_globals_table(co);
1820 lua_setfenv(co, -2);
1821+#endif
1822
1823 /* save nginx request in coroutine globals table */
1824 ngx_http_lua_set_req(co, r);
1825diff --git a/debian/modules/http-lua/src/ngx_http_lua_api.c b/debian/modules/http-lua/src/ngx_http_lua_api.c
1826index 7b590e7..ac014f2 100644
1827--- a/debian/modules/http-lua/src/ngx_http_lua_api.c
1828+++ b/debian/modules/http-lua/src/ngx_http_lua_api.c
1829@@ -195,7 +195,7 @@ ngx_http_lua_shared_memory_init(ngx_shm_zone_t *shm_zone, void *data)
1830 lmcf->shm_zones_inited++;
1831
1832 if (lmcf->shm_zones_inited == lmcf->shm_zones->nelts
1833- && lmcf->init_handler)
1834+ && lmcf->init_handler && !ngx_test_config)
1835 {
1836 saved_cycle = ngx_cycle;
1837 ngx_cycle = ctx->cycle;
1838diff --git a/debian/modules/http-lua/src/ngx_http_lua_args.c b/debian/modules/http-lua/src/ngx_http_lua_args.c
1839index b43697c..2712bcd 100644
1840--- a/debian/modules/http-lua/src/ngx_http_lua_args.c
1841+++ b/debian/modules/http-lua/src/ngx_http_lua_args.c
1842@@ -311,10 +311,11 @@ ngx_http_lua_parse_args(lua_State *L, u_char *buf, u_char *last, int max)
1843 }
1844
1845 if (max > 0 && ++count == max) {
1846+ lua_pushliteral(L, "truncated");
1847+
1848 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
1849 "lua hit query args limit %d", max);
1850-
1851- return 1;
1852+ return 2;
1853 }
1854
1855 } else {
1856@@ -387,7 +388,8 @@ ngx_http_lua_ffi_req_get_querystring_len(ngx_http_request_t *r)
1857
1858
1859 int
1860-ngx_http_lua_ffi_req_get_uri_args_count(ngx_http_request_t *r, int max)
1861+ngx_http_lua_ffi_req_get_uri_args_count(ngx_http_request_t *r, int max,
1862+ int *truncated)
1863 {
1864 int count;
1865 u_char *p, *last;
1866@@ -396,6 +398,8 @@ ngx_http_lua_ffi_req_get_uri_args_count(ngx_http_request_t *r, int max)
1867 return NGX_HTTP_LUA_FFI_BAD_CONTEXT;
1868 }
1869
1870+ *truncated = 0;
1871+
1872 if (max < 0) {
1873 max = NGX_HTTP_LUA_MAX_ARGS;
1874 }
1875@@ -417,6 +421,7 @@ ngx_http_lua_ffi_req_get_uri_args_count(ngx_http_request_t *r, int max)
1876 if (count) {
1877 if (max > 0 && count > max) {
1878 count = max;
1879+ *truncated = 1;
1880 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1881 "lua hit query args limit %d", max);
1882 }
1883diff --git a/debian/modules/http-lua/src/ngx_http_lua_balancer.c b/debian/modules/http-lua/src/ngx_http_lua_balancer.c
1884index 2fa634e..3ecd592 100644
1885--- a/debian/modules/http-lua/src/ngx_http_lua_balancer.c
1886+++ b/debian/modules/http-lua/src/ngx_http_lua_balancer.c
1887@@ -173,13 +173,15 @@ ngx_http_lua_balancer_by_lua(ngx_conf_t *cf, ngx_command_t *cmd,
1888
1889 lscf->balancer.src = value[1];
1890
1891- p = ngx_palloc(cf->pool, NGX_HTTP_LUA_INLINE_KEY_LEN + 1);
1892+ p = ngx_palloc(cf->pool,
1893+ sizeof("balancer_by_lua") + NGX_HTTP_LUA_INLINE_KEY_LEN);
1894 if (p == NULL) {
1895 return NGX_CONF_ERROR;
1896 }
1897
1898 lscf->balancer.src_key = p;
1899
1900+ p = ngx_copy(p, "balancer_by_lua", sizeof("balancer_by_lua") - 1);
1901 p = ngx_copy(p, NGX_HTTP_LUA_INLINE_TAG, NGX_HTTP_LUA_INLINE_TAG_LEN);
1902 p = ngx_http_lua_digest_hex(p, value[1].data, value[1].len);
1903 *p = '\0';
1904@@ -360,6 +362,8 @@ ngx_http_lua_balancer_by_chunk(lua_State *L, ngx_http_request_t *r)
1905
1906 /* init nginx context in Lua VM */
1907 ngx_http_lua_set_req(L, r);
1908+
1909+#ifndef OPENRESTY_LUAJIT
1910 ngx_http_lua_create_new_globals_table(L, 0 /* narr */, 1 /* nrec */);
1911
1912 /* {{{ make new env inheriting main thread's globals table */
1913@@ -370,6 +374,7 @@ ngx_http_lua_balancer_by_chunk(lua_State *L, ngx_http_request_t *r)
1914 /* }}} */
1915
1916 lua_setfenv(L, -2); /* set new running env for the code closure */
1917+#endif /* OPENRESTY_LUAJIT */
1918
1919 lua_pushcfunction(L, ngx_http_lua_traceback);
1920 lua_insert(L, 1); /* put it under chunk and args */
1921diff --git a/debian/modules/http-lua/src/ngx_http_lua_bodyfilterby.c b/debian/modules/http-lua/src/ngx_http_lua_bodyfilterby.c
1922index 2b3c38f..f3af14c 100644
1923--- a/debian/modules/http-lua/src/ngx_http_lua_bodyfilterby.c
1924+++ b/debian/modules/http-lua/src/ngx_http_lua_bodyfilterby.c
1925@@ -32,10 +32,6 @@ static void ngx_http_lua_body_filter_by_lua_env(lua_State *L,
1926 static ngx_http_output_body_filter_pt ngx_http_next_body_filter;
1927
1928
1929-/* key for the ngx_chain_t *in pointer in the Lua thread */
1930-#define ngx_http_lua_chain_key "__ngx_cl"
1931-
1932-
1933 /**
1934 * Set environment table for the given code closure.
1935 *
1936@@ -51,12 +47,14 @@ static void
1937 ngx_http_lua_body_filter_by_lua_env(lua_State *L, ngx_http_request_t *r,
1938 ngx_chain_t *in)
1939 {
1940- /* set nginx request pointer to current lua thread's globals table */
1941+ ngx_http_lua_main_conf_t *lmcf;
1942+
1943 ngx_http_lua_set_req(L, r);
1944
1945- lua_pushlightuserdata(L, in);
1946- lua_setglobal(L, ngx_http_lua_chain_key);
1947+ lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module);
1948+ lmcf->body_filter_chain = in;
1949
1950+#ifndef OPENRESTY_LUAJIT
1951 /**
1952 * we want to create empty environment for current script
1953 *
1954@@ -79,6 +77,7 @@ ngx_http_lua_body_filter_by_lua_env(lua_State *L, ngx_http_request_t *r,
1955 /* }}} */
1956
1957 lua_setfenv(L, -2); /* set new running env for the code closure */
1958+#endif /* OPENRESTY_LUAJIT */
1959 }
1960
1961
1962@@ -236,8 +235,8 @@ ngx_http_lua_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
1963 ngx_int_t rc;
1964 uint16_t old_context;
1965 ngx_http_cleanup_t *cln;
1966- lua_State *L;
1967 ngx_chain_t *out;
1968+ ngx_http_lua_main_conf_t *lmcf;
1969
1970 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1971 "lua body filter for user lua code, uri \"%V\"", &r->uri);
1972@@ -299,11 +298,8 @@ ngx_http_lua_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
1973 return NGX_ERROR;
1974 }
1975
1976- L = ngx_http_lua_get_lua_vm(r, ctx);
1977-
1978- lua_getglobal(L, ngx_http_lua_chain_key);
1979- out = lua_touserdata(L, -1);
1980- lua_pop(L, 1);
1981+ lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module);
1982+ out = lmcf->body_filter_chain;
1983
1984 if (in == out) {
1985 return ngx_http_next_body_filter(r, in);
1986@@ -345,7 +341,7 @@ ngx_http_lua_body_filter_init(void)
1987
1988
1989 int
1990-ngx_http_lua_body_filter_param_get(lua_State *L)
1991+ngx_http_lua_body_filter_param_get(lua_State *L, ngx_http_request_t *r)
1992 {
1993 u_char *data, *p;
1994 size_t size;
1995@@ -354,6 +350,8 @@ ngx_http_lua_body_filter_param_get(lua_State *L)
1996 int idx;
1997 ngx_chain_t *in;
1998
1999+ ngx_http_lua_main_conf_t *lmcf;
2000+
2001 idx = luaL_checkint(L, 2);
2002
2003 dd("index: %d", idx);
2004@@ -363,8 +361,8 @@ ngx_http_lua_body_filter_param_get(lua_State *L)
2005 return 1;
2006 }
2007
2008- lua_getglobal(L, ngx_http_lua_chain_key);
2009- in = lua_touserdata(L, -1);
2010+ lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module);
2011+ in = lmcf->body_filter_chain;
2012
2013 if (idx == 2) {
2014 /* asking for the eof argument */
2015@@ -442,6 +440,8 @@ ngx_http_lua_body_filter_param_set(lua_State *L, ngx_http_request_t *r,
2016 ngx_chain_t *cl;
2017 ngx_chain_t *in;
2018
2019+ ngx_http_lua_main_conf_t *lmcf;
2020+
2021 idx = luaL_checkint(L, 2);
2022
2023 dd("index: %d", idx);
2024@@ -450,13 +450,13 @@ ngx_http_lua_body_filter_param_set(lua_State *L, ngx_http_request_t *r,
2025 return luaL_error(L, "bad index: %d", idx);
2026 }
2027
2028+ lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module);
2029+
2030 if (idx == 2) {
2031 /* overwriting the eof flag */
2032 last = lua_toboolean(L, 3);
2033
2034- lua_getglobal(L, ngx_http_lua_chain_key);
2035- in = lua_touserdata(L, -1);
2036- lua_pop(L, 1);
2037+ in = lmcf->body_filter_chain;
2038
2039 if (last) {
2040 ctx->seen_last_in_filter = 1;
2041@@ -521,9 +521,7 @@ ngx_http_lua_body_filter_param_set(lua_State *L, ngx_http_request_t *r,
2042 case LUA_TNIL:
2043 /* discard the buffers */
2044
2045- lua_getglobal(L, ngx_http_lua_chain_key); /* key val */
2046- in = lua_touserdata(L, -1);
2047- lua_pop(L, 1);
2048+ in = lmcf->body_filter_chain;
2049
2050 last = 0;
2051
2052@@ -557,9 +555,7 @@ ngx_http_lua_body_filter_param_set(lua_State *L, ngx_http_request_t *r,
2053 lua_typename(L, type));
2054 }
2055
2056- lua_getglobal(L, ngx_http_lua_chain_key);
2057- in = lua_touserdata(L, -1);
2058- lua_pop(L, 1);
2059+ in = lmcf->body_filter_chain;
2060
2061 last = 0;
2062
2063@@ -625,8 +621,8 @@ done:
2064 }
2065 }
2066
2067- lua_pushlightuserdata(L, cl);
2068- lua_setglobal(L, ngx_http_lua_chain_key);
2069+ lmcf->body_filter_chain = cl;
2070+
2071 return 0;
2072 }
2073
2074diff --git a/debian/modules/http-lua/src/ngx_http_lua_bodyfilterby.h b/debian/modules/http-lua/src/ngx_http_lua_bodyfilterby.h
2075index 6a4b306..b108202 100644
2076--- a/debian/modules/http-lua/src/ngx_http_lua_bodyfilterby.h
2077+++ b/debian/modules/http-lua/src/ngx_http_lua_bodyfilterby.h
2078@@ -21,7 +21,7 @@ ngx_int_t ngx_http_lua_body_filter_inline(ngx_http_request_t *r,
2079 ngx_chain_t *in);
2080 ngx_int_t ngx_http_lua_body_filter_file(ngx_http_request_t *r,
2081 ngx_chain_t *in);
2082-int ngx_http_lua_body_filter_param_get(lua_State *L);
2083+int ngx_http_lua_body_filter_param_get(lua_State *L, ngx_http_request_t *r);
2084 int ngx_http_lua_body_filter_param_set(lua_State *L, ngx_http_request_t *r,
2085 ngx_http_lua_ctx_t *ctx);
2086
2087diff --git a/debian/modules/http-lua/src/ngx_http_lua_cache.c b/debian/modules/http-lua/src/ngx_http_lua_cache.c
2088index 5ea3069..5b29527 100644
2089--- a/debian/modules/http-lua/src/ngx_http_lua_cache.c
2090+++ b/debian/modules/http-lua/src/ngx_http_lua_cache.c
2091@@ -35,11 +35,14 @@ static ngx_int_t
2092 ngx_http_lua_cache_load_code(ngx_log_t *log, lua_State *L,
2093 const char *key)
2094 {
2095+#ifndef OPENRESTY_LUAJIT
2096 int rc;
2097 u_char *err;
2098+#endif
2099
2100 /* get code cache table */
2101- lua_pushlightuserdata(L, &ngx_http_lua_code_cache_key);
2102+ lua_pushlightuserdata(L, ngx_http_lua_lightudata_mask(
2103+ code_cache_key));
2104 lua_rawget(L, LUA_REGISTRYINDEX); /* sp++ */
2105
2106 dd("Code cache table to load: %p", lua_topointer(L, -1));
2107@@ -52,6 +55,10 @@ ngx_http_lua_cache_load_code(ngx_log_t *log, lua_State *L,
2108 lua_getfield(L, -1, key); /* sp++ */
2109
2110 if (lua_isfunction(L, -1)) {
2111+#ifdef OPENRESTY_LUAJIT
2112+ lua_remove(L, -2); /* sp-- */
2113+ return NGX_OK;
2114+#else
2115 /* call closure factory to gen new closure */
2116 rc = lua_pcall(L, 0, 1, 0);
2117 if (rc == 0) {
2118@@ -73,6 +80,7 @@ ngx_http_lua_cache_load_code(ngx_log_t *log, lua_State *L,
2119 key, err);
2120 lua_pop(L, 2);
2121 return NGX_ERROR;
2122+#endif /* OPENRESTY_LUAJIT */
2123 }
2124
2125 dd("Value associated with given key in code cache table is not code "
2126@@ -102,10 +110,13 @@ ngx_http_lua_cache_load_code(ngx_log_t *log, lua_State *L,
2127 static ngx_int_t
2128 ngx_http_lua_cache_store_code(lua_State *L, const char *key)
2129 {
2130+#ifndef OPENRESTY_LUAJIT
2131 int rc;
2132+#endif
2133
2134 /* get code cache table */
2135- lua_pushlightuserdata(L, &ngx_http_lua_code_cache_key);
2136+ lua_pushlightuserdata(L, ngx_http_lua_lightudata_mask(
2137+ code_cache_key));
2138 lua_rawget(L, LUA_REGISTRYINDEX);
2139
2140 dd("Code cache table to store: %p", lua_topointer(L, -1));
2141@@ -121,12 +132,14 @@ ngx_http_lua_cache_store_code(lua_State *L, const char *key)
2142 /* remove cache table, leave closure factory at top of stack */
2143 lua_pop(L, 1); /* closure */
2144
2145+#ifndef OPENRESTY_LUAJIT
2146 /* call closure factory to generate new closure */
2147 rc = lua_pcall(L, 0, 1, 0);
2148 if (rc != 0) {
2149 dd("Error: failed to call closure factory!!");
2150 return NGX_ERROR;
2151 }
2152+#endif
2153
2154 return NGX_OK;
2155 }
2156@@ -143,7 +156,8 @@ ngx_http_lua_cache_loadbuffer(ngx_log_t *log, lua_State *L,
2157
2158 n = lua_gettop(L);
2159
2160- dd("XXX cache key: [%s]", cache_key);
2161+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
2162+ "looking up Lua code cache with key '%s'", cache_key);
2163
2164 rc = ngx_http_lua_cache_load_code(log, L, (char *) cache_key);
2165 if (rc == NGX_OK) {
2166@@ -227,7 +241,8 @@ ngx_http_lua_cache_loadfile(ngx_log_t *log, lua_State *L,
2167 dd("CACHE file key already pre-calculated");
2168 }
2169
2170- dd("XXX cache key for file: [%s]", cache_key);
2171+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
2172+ "looking up Lua code cache with key '%s'", cache_key);
2173
2174 rc = ngx_http_lua_cache_load_code(log, L, (char *) cache_key);
2175 if (rc == NGX_OK) {
2176diff --git a/debian/modules/http-lua/src/ngx_http_lua_clfactory.c b/debian/modules/http-lua/src/ngx_http_lua_clfactory.c
2177index 89698c7..754ed8d 100644
2178--- a/debian/modules/http-lua/src/ngx_http_lua_clfactory.c
2179+++ b/debian/modules/http-lua/src/ngx_http_lua_clfactory.c
2180@@ -15,11 +15,13 @@
2181 #include "ngx_http_lua_clfactory.h"
2182
2183
2184+#ifndef OPENRESTY_LUAJIT
2185 #define CLFACTORY_BEGIN_CODE "return function() "
2186 #define CLFACTORY_BEGIN_SIZE (sizeof(CLFACTORY_BEGIN_CODE) - 1)
2187
2188 #define CLFACTORY_END_CODE "\nend"
2189 #define CLFACTORY_END_SIZE (sizeof(CLFACTORY_END_CODE) - 1)
2190+#endif
2191
2192
2193 /*
2194@@ -59,15 +61,16 @@
2195 * length(Instruction) = 4 or 8
2196 * little endian or big endian
2197 */
2198-#define LUA_LITTLE_ENDIAN_4BYTES_CODE \
2199+#ifndef OPENRESTY_LUAJIT
2200+#define LUA_LITTLE_ENDIAN_4BYTES_CODE \
2201 "\x24\x00\x00\x00\x1e\x00\x00\x01\x1e\x00\x80\x00"
2202-#define LUA_LITTLE_ENDIAN_8BYTES_CODE \
2203- "\x24\x00\x00\x00\x00\x00\x00\x00\x1e\x00\x00\x01" \
2204+#define LUA_LITTLE_ENDIAN_8BYTES_CODE \
2205+ "\x24\x00\x00\x00\x00\x00\x00\x00\x1e\x00\x00\x01" \
2206 "\x00\x00\x00\x00\x1e\x00\x80\x00\x00\x00\x00\x00"
2207-#define LUA_BIG_ENDIAN_4BYTES_CODE \
2208+#define LUA_BIG_ENDIAN_4BYTES_CODE \
2209 "\x00\x00\x00\x24\x01\x00\x00\x1e\x00\x08\x00\x1e"
2210-#define LUA_BIG_ENDIAN_8BYTES_CODE \
2211- "\x00\x00\x00\x00\x00\x00\x00\x24\x00\x00\x00\x00" \
2212+#define LUA_BIG_ENDIAN_8BYTES_CODE \
2213+ "\x00\x00\x00\x00\x00\x00\x00\x24\x00\x00\x00\x00" \
2214 "\x01\x00\x00\x1e\x00\x00\x00\x00\x00\x08\x00\x1e"
2215 #define LUA_LITTLE_ENDIAN_4BYTES_CODE_LEN (4 + 4 + 4)
2216 #define LUA_LITTLE_ENDIAN_8BYTES_CODE_LEN (8 + 8 + 8)
2217@@ -75,6 +78,7 @@
2218 #define LUA_BIG_ENDIAN_8BYTES_CODE_LEN (8 + 8 + 8)
2219 #define LUAC_HEADERSIZE 12
2220 #define LUAC_VERSION 0x51
2221+#endif /* OPENRESTY_LUAJIT */
2222
2223
2224 /*
2225@@ -147,6 +151,7 @@
2226 * ---------------------
2227 */
2228
2229+#ifndef OPENRESTY_LUAJIT
2230 #define POS_SOURCE_STR_LEN LUAC_HEADERSIZE
2231 #define POS_START_LINE (POS_SOURCE_STR_LEN + sizeof(size_t))
2232 #define POS_LAST_LINE (POS_START_LINE + sizeof(int))
2233@@ -156,10 +161,11 @@
2234 #define POS_MAX_STACK_SIZE (POS_IS_VAR_ARG + sizeof(char))
2235 #define POS_NUM_OF_INST (POS_MAX_STACK_SIZE +sizeof(char))
2236 #define POS_BYTECODE (POS_NUM_OF_INST + sizeof(int))
2237-#define MAX_BEGIN_CODE_SIZE \
2238- (POS_BYTECODE + LUA_LITTLE_ENDIAN_8BYTES_CODE_LEN \
2239+#define MAX_BEGIN_CODE_SIZE \
2240+ (POS_BYTECODE + LUA_LITTLE_ENDIAN_8BYTES_CODE_LEN \
2241 + sizeof(int) + sizeof(int))
2242 #define MAX_END_CODE_SIZE (sizeof(int) + sizeof(int) + sizeof(int))
2243+#endif /* OPENRESTY_LUAJIT */
2244
2245 /*
2246 * taken from chaoslawful:
2247@@ -225,24 +231,25 @@
2248
2249 /* bytecode for luajit 2.0 */
2250
2251-#define LJ20_LITTLE_ENDIAN_CODE_STRIPPED \
2252- "\x14\x03\x00\x01\x00\x01\x00\x03" \
2253- "\x31\x00\x00\x00\x30\x00\x00\x80\x48\x00\x02\x00" \
2254+#ifndef OPENRESTY_LUAJIT
2255+#define LJ20_LITTLE_ENDIAN_CODE_STRIPPED \
2256+ "\x14\x03\x00\x01\x00\x01\x00\x03" \
2257+ "\x31\x00\x00\x00\x30\x00\x00\x80\x48\x00\x02\x00" \
2258 "\x00\x00"
2259
2260-#define LJ20_BIG_ENDIAN_CODE_STRIPPED \
2261- "\x14\x03\x00\x01\x00\x01\x00\x03" \
2262- "\x00\x00\x00\x31\x80\x00\x00\x30\x00\x02\x00\x48" \
2263+#define LJ20_BIG_ENDIAN_CODE_STRIPPED \
2264+ "\x14\x03\x00\x01\x00\x01\x00\x03" \
2265+ "\x00\x00\x00\x31\x80\x00\x00\x30\x00\x02\x00\x48" \
2266 "\x00\x00"
2267
2268-#define LJ20_LITTLE_ENDIAN_CODE \
2269- "\x15\x03\x00\x01\x00\x01\x00\x03\x00" \
2270- "\x31\x00\x00\x00\x30\x00\x00\x80\x48\x00\x02\x00" \
2271+#define LJ20_LITTLE_ENDIAN_CODE \
2272+ "\x15\x03\x00\x01\x00\x01\x00\x03\x00" \
2273+ "\x31\x00\x00\x00\x30\x00\x00\x80\x48\x00\x02\x00" \
2274 "\x00\x00"
2275
2276-#define LJ20_BIG_ENDIAN_CODE \
2277- "\x15\x03\x00\x01\x00\x01\x00\x03\x00" \
2278- "\x00\x00\x00\x31\x80\x00\x00\x30\x00\x02\x00\x48" \
2279+#define LJ20_BIG_ENDIAN_CODE \
2280+ "\x15\x03\x00\x01\x00\x01\x00\x03\x00" \
2281+ "\x00\x00\x00\x31\x80\x00\x00\x30\x00\x02\x00\x48" \
2282 "\x00\x00"
2283
2284 /* bytecode for luajit 2.1 */
2285@@ -275,6 +282,7 @@
2286 #define LJ21_BCDUMP_VERSION 2
2287 #define LJ20_BCDUMP_VERSION 1
2288 #define LJ_SIGNATURE "\x1b\x4c\x4a"
2289+#endif /* OPENRESTY_LUAJIT */
2290
2291
2292 typedef enum {
2293@@ -292,10 +300,11 @@ enum {
2294 typedef struct {
2295 ngx_http_lua_clfactory_file_type_e file_type;
2296
2297- int sent_begin;
2298- int sent_end;
2299 int extraline;
2300 FILE *f;
2301+#ifndef OPENRESTY_LUAJIT
2302+ int sent_begin;
2303+ int sent_end;
2304 size_t begin_code_len;
2305 size_t end_code_len;
2306 size_t rest_len;
2307@@ -307,13 +316,16 @@ typedef struct {
2308 char *ptr;
2309 char str[MAX_END_CODE_SIZE];
2310 } end_code;
2311+#endif /* OPENRESTY_LUAJIT */
2312 char buff[NGX_LUA_READER_BUFSIZE];
2313 } ngx_http_lua_clfactory_file_ctx_t;
2314
2315
2316 typedef struct {
2317+#ifndef OPENRESTY_LUAJIT
2318 int sent_begin;
2319 int sent_end;
2320+#endif
2321 const char *s;
2322 size_t size;
2323 } ngx_http_lua_clfactory_buffer_ctx_t;
2324@@ -325,9 +337,12 @@ static int ngx_http_lua_clfactory_errfile(lua_State *L, const char *what,
2325 int fname_index);
2326 static const char *ngx_http_lua_clfactory_getS(lua_State *L, void *ud,
2327 size_t *size);
2328+#ifndef OPENRESTY_LUAJIT
2329 static long ngx_http_lua_clfactory_file_size(FILE *f);
2330+#endif
2331
2332
2333+#ifndef OPENRESTY_LUAJIT
2334 int
2335 ngx_http_lua_clfactory_bytecode_prepare(lua_State *L,
2336 ngx_http_lua_clfactory_file_ctx_t *lf, int fname_index)
2337@@ -593,6 +608,7 @@ error:
2338
2339 return LUA_ERRFILE;
2340 }
2341+#endif /* OPENRESTY_LUAJIT */
2342
2343
2344 ngx_int_t
2345@@ -612,10 +628,12 @@ ngx_http_lua_clfactory_loadfile(lua_State *L, const char *filename)
2346 lf.extraline = 0;
2347 lf.file_type = NGX_LUA_TEXT_FILE;
2348
2349+#ifndef OPENRESTY_LUAJIT
2350 lf.begin_code.ptr = CLFACTORY_BEGIN_CODE;
2351 lf.begin_code_len = CLFACTORY_BEGIN_SIZE;
2352 lf.end_code.ptr = CLFACTORY_END_CODE;
2353 lf.end_code_len = CLFACTORY_END_SIZE;
2354+#endif
2355
2356 lua_pushfstring(L, "@%s", filename);
2357
2358@@ -683,20 +701,27 @@ ngx_http_lua_clfactory_loadfile(lua_State *L, const char *filename)
2359 /* skip eventual `#!...' */
2360 }
2361
2362+#ifndef OPENRESTY_LUAJIT
2363 status = ngx_http_lua_clfactory_bytecode_prepare(L, &lf, fname_index);
2364
2365 if (status != 0) {
2366 return status;
2367 }
2368+#endif
2369
2370 lf.extraline = 0;
2371 }
2372
2373+#ifndef OPENRESTY_LUAJIT
2374 if (lf.file_type == NGX_LUA_TEXT_FILE) {
2375 ungetc(c, lf.f);
2376 }
2377
2378 lf.sent_begin = lf.sent_end = 0;
2379+
2380+#else
2381+ ungetc(c, lf.f);
2382+#endif
2383 status = lua_load(L, ngx_http_lua_clfactory_getF, &lf,
2384 lua_tostring(L, -1));
2385
2386@@ -725,8 +750,10 @@ ngx_http_lua_clfactory_loadbuffer(lua_State *L, const char *buff,
2387
2388 ls.s = buff;
2389 ls.size = size;
2390+#ifndef OPENRESTY_LUAJIT
2391 ls.sent_begin = 0;
2392 ls.sent_end = 0;
2393+#endif
2394
2395 return lua_load(L, ngx_http_lua_clfactory_getS, &ls, name);
2396 }
2397@@ -735,7 +762,9 @@ ngx_http_lua_clfactory_loadbuffer(lua_State *L, const char *buff,
2398 static const char *
2399 ngx_http_lua_clfactory_getF(lua_State *L, void *ud, size_t *size)
2400 {
2401+#ifndef OPENRESTY_LUAJIT
2402 char *buf;
2403+#endif
2404 size_t num;
2405
2406 ngx_http_lua_clfactory_file_ctx_t *lf;
2407@@ -748,6 +777,7 @@ ngx_http_lua_clfactory_getF(lua_State *L, void *ud, size_t *size)
2408 return "\n";
2409 }
2410
2411+#ifndef OPENRESTY_LUAJIT
2412 if (lf->sent_begin == 0) {
2413 lf->sent_begin = 1;
2414 *size = lf->begin_code_len;
2415@@ -761,12 +791,14 @@ ngx_http_lua_clfactory_getF(lua_State *L, void *ud, size_t *size)
2416
2417 return buf;
2418 }
2419+#endif /* OPENRESTY_LUAJIT */
2420
2421 num = fread(lf->buff, 1, sizeof(lf->buff), lf->f);
2422
2423 dd("fread returned %d", (int) num);
2424
2425 if (num == 0) {
2426+#ifndef OPENRESTY_LUAJIT
2427 if (lf->sent_end == 0) {
2428 lf->sent_end = 1;
2429 *size = lf->end_code_len;
2430@@ -780,11 +812,13 @@ ngx_http_lua_clfactory_getF(lua_State *L, void *ud, size_t *size)
2431
2432 return buf;
2433 }
2434+#endif /* OPENRESTY_LUAJIT */
2435
2436 *size = 0;
2437 return NULL;
2438 }
2439
2440+#ifndef OPENRESTY_LUAJIT
2441 if (lf->file_type == NGX_LUA_BT_LJ) {
2442 /* skip the footer(\x00) in luajit */
2443
2444@@ -800,6 +834,7 @@ ngx_http_lua_clfactory_getF(lua_State *L, void *ud, size_t *size)
2445 }
2446 }
2447 }
2448+#endif /* OPENRESTY_LUAJIT */
2449
2450 *size = num;
2451 return lf->buff;
2452@@ -833,19 +868,23 @@ ngx_http_lua_clfactory_getS(lua_State *L, void *ud, size_t *size)
2453 {
2454 ngx_http_lua_clfactory_buffer_ctx_t *ls = ud;
2455
2456+#ifndef OPENRESTY_LUAJIT
2457 if (ls->sent_begin == 0) {
2458 ls->sent_begin = 1;
2459 *size = CLFACTORY_BEGIN_SIZE;
2460
2461 return CLFACTORY_BEGIN_CODE;
2462 }
2463+#endif
2464
2465 if (ls->size == 0) {
2466+#ifndef OPENRESTY_LUAJIT
2467 if (ls->sent_end == 0) {
2468 ls->sent_end = 1;
2469 *size = CLFACTORY_END_SIZE;
2470 return CLFACTORY_END_CODE;
2471 }
2472+#endif
2473
2474 return NULL;
2475 }
2476@@ -857,6 +896,7 @@ ngx_http_lua_clfactory_getS(lua_State *L, void *ud, size_t *size)
2477 }
2478
2479
2480+#ifndef OPENRESTY_LUAJIT
2481 static long
2482 ngx_http_lua_clfactory_file_size(FILE *f)
2483 {
2484@@ -882,6 +922,7 @@ ngx_http_lua_clfactory_file_size(FILE *f)
2485
2486 return len;
2487 }
2488+#endif /* OPENRESTY_LUAJIT */
2489
2490
2491 /* vi:set ft=c ts=4 sw=4 et fdm=marker: */
2492diff --git a/debian/modules/http-lua/src/ngx_http_lua_common.h b/debian/modules/http-lua/src/ngx_http_lua_common.h
2493index e389783..dae5245 100644
2494--- a/debian/modules/http-lua/src/ngx_http_lua_common.h
2495+++ b/debian/modules/http-lua/src/ngx_http_lua_common.h
2496@@ -17,7 +17,7 @@
2497 #include <setjmp.h>
2498 #include <stdint.h>
2499
2500-#include <lua.h>
2501+#include <luajit.h>
2502 #include <lualib.h>
2503 #include <lauxlib.h>
2504
2505@@ -54,6 +54,9 @@
2506 # define NGX_HTTP_LUA_USE_OCSP 1
2507 #endif
2508
2509+#ifndef NGX_HTTP_PERMANENT_REDIRECT
2510+# define NGX_HTTP_PERMANENT_REDIRECT 308
2511+#endif
2512
2513 #ifndef NGX_HAVE_SHA1
2514 # if (nginx_version >= 1011002)
2515@@ -79,20 +82,20 @@
2516
2517 #define NGX_HTTP_LUA_INLINE_TAG "nhli_"
2518
2519-#define NGX_HTTP_LUA_INLINE_TAG_LEN \
2520+#define NGX_HTTP_LUA_INLINE_TAG_LEN \
2521 (sizeof(NGX_HTTP_LUA_INLINE_TAG) - 1)
2522
2523-#define NGX_HTTP_LUA_INLINE_KEY_LEN \
2524+#define NGX_HTTP_LUA_INLINE_KEY_LEN \
2525 (NGX_HTTP_LUA_INLINE_TAG_LEN + 2 * MD5_DIGEST_LENGTH)
2526
2527 /* Nginx HTTP Lua File tag prefix */
2528
2529 #define NGX_HTTP_LUA_FILE_TAG "nhlf_"
2530
2531-#define NGX_HTTP_LUA_FILE_TAG_LEN \
2532+#define NGX_HTTP_LUA_FILE_TAG_LEN \
2533 (sizeof(NGX_HTTP_LUA_FILE_TAG) - 1)
2534
2535-#define NGX_HTTP_LUA_FILE_KEY_LEN \
2536+#define NGX_HTTP_LUA_FILE_KEY_LEN \
2537 (NGX_HTTP_LUA_FILE_TAG_LEN + 2 * MD5_DIGEST_LENGTH)
2538
2539
2540@@ -137,6 +140,15 @@ typedef struct {
2541 #endif
2542
2543
2544+#if (NGX_PTR_SIZE >= 8 && !defined(_WIN64))
2545+#define ngx_http_lua_lightudata_mask(ludata) \
2546+ ((void *) ((uintptr_t) (&ngx_http_lua_##ludata) & ((1UL << 47) - 1)))
2547+
2548+#else
2549+#define ngx_http_lua_lightudata_mask(ludata) (&ngx_http_lua_##ludata)
2550+#endif
2551+
2552+
2553 typedef struct ngx_http_lua_main_conf_s ngx_http_lua_main_conf_t;
2554 typedef union ngx_http_lua_srv_conf_u ngx_http_lua_srv_conf_t;
2555
2556@@ -162,6 +174,7 @@ typedef struct {
2557
2558 struct ngx_http_lua_main_conf_s {
2559 lua_State *lua;
2560+ ngx_pool_cleanup_t *vm_cleanup;
2561
2562 ngx_str_t lua_path;
2563 ngx_str_t lua_cpath;
2564@@ -169,6 +182,8 @@ struct ngx_http_lua_main_conf_s {
2565 ngx_cycle_t *cycle;
2566 ngx_pool_t *pool;
2567
2568+ ngx_flag_t load_resty_core;
2569+
2570 ngx_int_t max_pending_timers;
2571 ngx_int_t pending_timers;
2572
2573@@ -204,9 +219,31 @@ struct ngx_http_lua_main_conf_s {
2574 ngx_str_t init_worker_src;
2575
2576 ngx_http_lua_balancer_peer_data_t *balancer_peer_data;
2577- /* balancer_by_lua does not support yielding and
2578- * there cannot be any conflicts among concurrent requests,
2579- * thus it is safe to store the peer data in the main conf.
2580+ /* neither yielding nor recursion is possible in
2581+ * balancer_by_lua*, so there cannot be any races among
2582+ * concurrent requests and it is safe to store the peer
2583+ * data pointer in the main conf.
2584+ */
2585+
2586+ ngx_chain_t *body_filter_chain;
2587+ /* neither yielding nor recursion is possible in
2588+ * body_filter_by_lua*, so there cannot be any races among
2589+ * concurrent requests when storing the chain
2590+ * data pointer in the main conf.
2591+ */
2592+
2593+ ngx_http_variable_value_t *setby_args;
2594+ /* neither yielding nor recursion is possible in
2595+ * set_by_lua*, so there cannot be any races among
2596+ * concurrent requests when storing the args pointer
2597+ * in the main conf.
2598+ */
2599+
2600+ size_t setby_nargs;
2601+ /* neither yielding nor recursion is possible in
2602+ * set_by_lua*, so there cannot be any races among
2603+ * concurrent requests when storing the nargs in the
2604+ * main conf.
2605 */
2606
2607 ngx_uint_t shm_zones_inited;
2608@@ -223,6 +260,10 @@ struct ngx_http_lua_main_conf_s {
2609 ngx_int_t busy_buf_ptr_count;
2610 #endif
2611
2612+ ngx_int_t host_var_index;
2613+
2614+ ngx_flag_t set_sa_restart;
2615+
2616 unsigned requires_header_filter:1;
2617 unsigned requires_body_filter:1;
2618 unsigned requires_capture_filter:1;
2619@@ -440,7 +481,7 @@ typedef struct {
2620
2621
2622 typedef struct ngx_http_lua_ctx_s {
2623- /* for lua_coce_cache off: */
2624+ /* for lua_code_cache off: */
2625 ngx_http_lua_vm_state_t *vm_state;
2626
2627 ngx_http_request_t *request;
2628@@ -527,6 +568,8 @@ typedef struct ngx_http_lua_ctx_s {
2629
2630 unsigned headers_set:1; /* whether the user has set custom
2631 response headers */
2632+ unsigned mime_set:1; /* whether the user has set Content-Type
2633+ response header */
2634
2635 unsigned entered_rewrite_phase:1;
2636 unsigned entered_access_phase:1;
2637diff --git a/debian/modules/http-lua/src/ngx_http_lua_consts.c b/debian/modules/http-lua/src/ngx_http_lua_consts.c
2638index 30a86f1..809e712 100644
2639--- a/debian/modules/http-lua/src/ngx_http_lua_consts.c
2640+++ b/debian/modules/http-lua/src/ngx_http_lua_consts.c
2641@@ -124,6 +124,9 @@ ngx_http_lua_inject_http_consts(lua_State *L)
2642 lua_setfield(L, -2, "HTTP_SEE_OTHER");
2643 #endif
2644
2645+ lua_pushinteger(L, NGX_HTTP_PERMANENT_REDIRECT);
2646+ lua_setfield(L, -2, "HTTP_PERMANENT_REDIRECT");
2647+
2648 lua_pushinteger(L, NGX_HTTP_NOT_MODIFIED);
2649 lua_setfield(L, -2, "HTTP_NOT_MODIFIED");
2650
2651diff --git a/debian/modules/http-lua/src/ngx_http_lua_contentby.c b/debian/modules/http-lua/src/ngx_http_lua_contentby.c
2652index ecd6c0e..274c9ad 100644
2653--- a/debian/modules/http-lua/src/ngx_http_lua_contentby.c
2654+++ b/debian/modules/http-lua/src/ngx_http_lua_contentby.c
2655@@ -63,9 +63,11 @@ ngx_http_lua_content_by_chunk(lua_State *L, ngx_http_request_t *r)
2656 /* move code closure to new coroutine */
2657 lua_xmove(L, co, 1);
2658
2659+#ifndef OPENRESTY_LUAJIT
2660 /* set closure's env table to new coroutine's globals table */
2661 ngx_http_lua_get_globals_table(co);
2662 lua_setfenv(co, -2);
2663+#endif
2664
2665 /* save nginx request in coroutine globals table */
2666 ngx_http_lua_set_req(co, r);
2667diff --git a/debian/modules/http-lua/src/ngx_http_lua_control.c b/debian/modules/http-lua/src/ngx_http_lua_control.c
2668index ae36505..5cd1d64 100644
2669--- a/debian/modules/http-lua/src/ngx_http_lua_control.c
2670+++ b/debian/modules/http-lua/src/ngx_http_lua_control.c
2671@@ -213,10 +213,12 @@ ngx_http_lua_ngx_redirect(lua_State *L)
2672 if (rc != NGX_HTTP_MOVED_TEMPORARILY
2673 && rc != NGX_HTTP_MOVED_PERMANENTLY
2674 && rc != NGX_HTTP_SEE_OTHER
2675+ && rc != NGX_HTTP_PERMANENT_REDIRECT
2676 && rc != NGX_HTTP_TEMPORARY_REDIRECT)
2677 {
2678 return luaL_error(L, "only ngx.HTTP_MOVED_TEMPORARILY, "
2679 "ngx.HTTP_MOVED_PERMANENTLY, "
2680+ "ngx.HTTP_PERMANENT_REDIRECT, "
2681 "ngx.HTTP_SEE_OTHER, and "
2682 "ngx.HTTP_TEMPORARY_REDIRECT are allowed");
2683 }
2684@@ -430,7 +432,8 @@ ngx_http_lua_on_abort(lua_State *L)
2685
2686 ngx_http_lua_coroutine_create_helper(L, r, ctx, &coctx);
2687
2688- lua_pushlightuserdata(L, &ngx_http_lua_coroutines_key);
2689+ lua_pushlightuserdata(L, ngx_http_lua_lightudata_mask(
2690+ coroutines_key));
2691 lua_rawget(L, LUA_REGISTRYINDEX);
2692 lua_pushvalue(L, -2);
2693
2694diff --git a/debian/modules/http-lua/src/ngx_http_lua_coroutine.c b/debian/modules/http-lua/src/ngx_http_lua_coroutine.c
2695index b790814..99a2423 100644
2696--- a/debian/modules/http-lua/src/ngx_http_lua_coroutine.c
2697+++ b/debian/modules/http-lua/src/ngx_http_lua_coroutine.c
2698@@ -104,11 +104,15 @@ ngx_http_lua_coroutine_create_helper(lua_State *L, ngx_http_request_t *r,
2699 coctx->co = co;
2700 coctx->co_status = NGX_HTTP_LUA_CO_SUSPENDED;
2701
2702+#ifdef OPENRESTY_LUAJIT
2703+ ngx_http_lua_set_req(co, r);
2704+#else
2705 /* make new coroutine share globals of the parent coroutine.
2706 * NOTE: globals don't have to be separated! */
2707 ngx_http_lua_get_globals_table(L);
2708 lua_xmove(L, co, 1);
2709 ngx_http_lua_set_globals_table(co);
2710+#endif
2711
2712 lua_xmove(vm, L, 1); /* move coroutine from main thread to L */
2713
2714@@ -288,15 +292,27 @@ ngx_http_lua_inject_coroutine_api(ngx_log_t *log, lua_State *L)
2715 {
2716 const char buf[] =
2717 "local keys = {'create', 'yield', 'resume', 'status'}\n"
2718+#ifdef OPENRESTY_LUAJIT
2719+ "local get_req = require 'thread.exdata'\n"
2720+#else
2721 "local getfenv = getfenv\n"
2722+#endif
2723 "for _, key in ipairs(keys) do\n"
2724 "local std = coroutine['_' .. key]\n"
2725 "local ours = coroutine['__' .. key]\n"
2726 "local raw_ctx = ngx._phase_ctx\n"
2727 "coroutine[key] = function (...)\n"
2728+#ifdef OPENRESTY_LUAJIT
2729+ "local r = get_req()\n"
2730+#else
2731 "local r = getfenv(0).__ngx_req\n"
2732- "if r then\n"
2733+#endif
2734+ "if r ~= nil then\n"
2735+#ifdef OPENRESTY_LUAJIT
2736+ "local ctx = raw_ctx()\n"
2737+#else
2738 "local ctx = raw_ctx(r)\n"
2739+#endif
2740 /* ignore header and body filters */
2741 "if ctx ~= 0x020 and ctx ~= 0x040 then\n"
2742 "return ours(...)\n"
2743diff --git a/debian/modules/http-lua/src/ngx_http_lua_directive.c b/debian/modules/http-lua/src/ngx_http_lua_directive.c
2744index 014a472..a989c26 100644
2745--- a/debian/modules/http-lua/src/ngx_http_lua_directive.c
2746+++ b/debian/modules/http-lua/src/ngx_http_lua_directive.c
2747@@ -43,7 +43,7 @@ static ngx_int_t ngx_http_lua_set_by_lua_init(ngx_http_request_t *r);
2748 #endif
2749
2750 static u_char *ngx_http_lua_gen_chunk_name(ngx_conf_t *cf, const char *tag,
2751- size_t tag_len);
2752+ size_t tag_len, size_t *chunkname_len);
2753 static ngx_int_t ngx_http_lua_conf_read_lua_token(ngx_conf_t *cf,
2754 ngx_http_lua_block_parser_ctx_t *ctx);
2755 static u_char *ngx_http_lua_strlstrn(u_char *s1, u_char *last, u_char *s2,
2756@@ -271,13 +271,15 @@ ngx_http_lua_set_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
2757
2758 filter_data->size = filter.size;
2759
2760- p = ngx_palloc(cf->pool, NGX_HTTP_LUA_INLINE_KEY_LEN + 1);
2761+ p = ngx_palloc(cf->pool,
2762+ sizeof("set_by_lua") + NGX_HTTP_LUA_INLINE_KEY_LEN);
2763 if (p == NULL) {
2764 return NGX_CONF_ERROR;
2765 }
2766
2767 filter_data->key = p;
2768
2769+ p = ngx_copy(p, "set_by_lua", sizeof("set_by_lua") - 1);
2770 p = ngx_copy(p, NGX_HTTP_LUA_INLINE_TAG, NGX_HTTP_LUA_INLINE_TAG_LEN);
2771 p = ngx_http_lua_digest_hex(p, value[2].data, value[2].len);
2772 *p = '\0';
2773@@ -448,6 +450,7 @@ ngx_http_lua_rewrite_by_lua_block(ngx_conf_t *cf, ngx_command_t *cmd,
2774 char *
2775 ngx_http_lua_rewrite_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
2776 {
2777+ size_t chunkname_len;
2778 u_char *p, *chunkname;
2779 ngx_str_t *value;
2780 ngx_http_lua_main_conf_t *lmcf;
2781@@ -482,7 +485,8 @@ ngx_http_lua_rewrite_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
2782
2783 if (cmd->post == ngx_http_lua_rewrite_handler_inline) {
2784 chunkname = ngx_http_lua_gen_chunk_name(cf, "rewrite_by_lua",
2785- sizeof("rewrite_by_lua") - 1);
2786+ sizeof("rewrite_by_lua") - 1,
2787+ &chunkname_len);
2788 if (chunkname == NULL) {
2789 return NGX_CONF_ERROR;
2790 }
2791@@ -493,13 +497,15 @@ ngx_http_lua_rewrite_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
2792
2793 llcf->rewrite_src.value = value[1];
2794
2795- p = ngx_palloc(cf->pool, NGX_HTTP_LUA_INLINE_KEY_LEN + 1);
2796+ p = ngx_palloc(cf->pool,
2797+ chunkname_len + NGX_HTTP_LUA_INLINE_KEY_LEN + 1);
2798 if (p == NULL) {
2799 return NGX_CONF_ERROR;
2800 }
2801
2802 llcf->rewrite_src_key = p;
2803
2804+ p = ngx_copy(p, chunkname, chunkname_len);
2805 p = ngx_copy(p, NGX_HTTP_LUA_INLINE_TAG, NGX_HTTP_LUA_INLINE_TAG_LEN);
2806 p = ngx_http_lua_digest_hex(p, value[1].data, value[1].len);
2807 *p = '\0';
2808@@ -562,6 +568,7 @@ ngx_http_lua_access_by_lua_block(ngx_conf_t *cf, ngx_command_t *cmd,
2809 char *
2810 ngx_http_lua_access_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
2811 {
2812+ size_t chunkname_len;
2813 u_char *p, *chunkname;
2814 ngx_str_t *value;
2815 ngx_http_lua_main_conf_t *lmcf;
2816@@ -592,7 +599,8 @@ ngx_http_lua_access_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
2817
2818 if (cmd->post == ngx_http_lua_access_handler_inline) {
2819 chunkname = ngx_http_lua_gen_chunk_name(cf, "access_by_lua",
2820- sizeof("access_by_lua") - 1);
2821+ sizeof("access_by_lua") - 1,
2822+ &chunkname_len);
2823 if (chunkname == NULL) {
2824 return NGX_CONF_ERROR;
2825 }
2826@@ -603,13 +611,15 @@ ngx_http_lua_access_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
2827
2828 llcf->access_src.value = value[1];
2829
2830- p = ngx_palloc(cf->pool, NGX_HTTP_LUA_INLINE_KEY_LEN + 1);
2831+ p = ngx_palloc(cf->pool,
2832+ chunkname_len + NGX_HTTP_LUA_INLINE_KEY_LEN + 1);
2833 if (p == NULL) {
2834 return NGX_CONF_ERROR;
2835 }
2836
2837 llcf->access_src_key = p;
2838
2839+ p = ngx_copy(p, chunkname, chunkname_len);
2840 p = ngx_copy(p, NGX_HTTP_LUA_INLINE_TAG, NGX_HTTP_LUA_INLINE_TAG_LEN);
2841 p = ngx_http_lua_digest_hex(p, value[1].data, value[1].len);
2842 *p = '\0';
2843@@ -672,6 +682,7 @@ ngx_http_lua_content_by_lua_block(ngx_conf_t *cf, ngx_command_t *cmd,
2844 char *
2845 ngx_http_lua_content_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
2846 {
2847+ size_t chunkname_len;
2848 u_char *p;
2849 u_char *chunkname;
2850 ngx_str_t *value;
2851@@ -706,7 +717,8 @@ ngx_http_lua_content_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
2852
2853 if (cmd->post == ngx_http_lua_content_handler_inline) {
2854 chunkname = ngx_http_lua_gen_chunk_name(cf, "content_by_lua",
2855- sizeof("content_by_lua") - 1);
2856+ sizeof("content_by_lua") - 1,
2857+ &chunkname_len);
2858 if (chunkname == NULL) {
2859 return NGX_CONF_ERROR;
2860 }
2861@@ -719,13 +731,15 @@ ngx_http_lua_content_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
2862
2863 llcf->content_src.value = value[1];
2864
2865- p = ngx_palloc(cf->pool, NGX_HTTP_LUA_INLINE_KEY_LEN + 1);
2866+ p = ngx_palloc(cf->pool,
2867+ chunkname_len + NGX_HTTP_LUA_INLINE_KEY_LEN + 1);
2868 if (p == NULL) {
2869 return NGX_CONF_ERROR;
2870 }
2871
2872 llcf->content_src_key = p;
2873
2874+ p = ngx_copy(p, chunkname, chunkname_len);
2875 p = ngx_copy(p, NGX_HTTP_LUA_INLINE_TAG, NGX_HTTP_LUA_INLINE_TAG_LEN);
2876 p = ngx_http_lua_digest_hex(p, value[1].data, value[1].len);
2877 *p = '\0';
2878@@ -795,6 +809,7 @@ ngx_http_lua_log_by_lua_block(ngx_conf_t *cf, ngx_command_t *cmd,
2879 char *
2880 ngx_http_lua_log_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
2881 {
2882+ size_t chunkname_len;
2883 u_char *p, *chunkname;
2884 ngx_str_t *value;
2885 ngx_http_lua_main_conf_t *lmcf;
2886@@ -825,7 +840,8 @@ ngx_http_lua_log_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
2887
2888 if (cmd->post == ngx_http_lua_log_handler_inline) {
2889 chunkname = ngx_http_lua_gen_chunk_name(cf, "log_by_lua",
2890- sizeof("log_by_lua") - 1);
2891+ sizeof("log_by_lua") - 1,
2892+ &chunkname_len);
2893 if (chunkname == NULL) {
2894 return NGX_CONF_ERROR;
2895 }
2896@@ -836,13 +852,15 @@ ngx_http_lua_log_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
2897
2898 llcf->log_src.value = value[1];
2899
2900- p = ngx_palloc(cf->pool, NGX_HTTP_LUA_INLINE_KEY_LEN + 1);
2901+ p = ngx_palloc(cf->pool,
2902+ chunkname_len + NGX_HTTP_LUA_INLINE_KEY_LEN + 1);
2903 if (p == NULL) {
2904 return NGX_CONF_ERROR;
2905 }
2906
2907 llcf->log_src_key = p;
2908
2909+ p = ngx_copy(p, chunkname, chunkname_len);
2910 p = ngx_copy(p, NGX_HTTP_LUA_INLINE_TAG, NGX_HTTP_LUA_INLINE_TAG_LEN);
2911 p = ngx_http_lua_digest_hex(p, value[1].data, value[1].len);
2912 *p = '\0';
2913@@ -936,13 +954,17 @@ ngx_http_lua_header_filter_by_lua(ngx_conf_t *cf, ngx_command_t *cmd,
2914 /* Don't eval nginx variables for inline lua code */
2915 llcf->header_filter_src.value = value[1];
2916
2917- p = ngx_palloc(cf->pool, NGX_HTTP_LUA_INLINE_KEY_LEN + 1);
2918+ p = ngx_palloc(cf->pool,
2919+ sizeof("header_filter_by_lua") +
2920+ NGX_HTTP_LUA_INLINE_KEY_LEN + 1);
2921 if (p == NULL) {
2922 return NGX_CONF_ERROR;
2923 }
2924
2925 llcf->header_filter_src_key = p;
2926
2927+ p = ngx_copy(p, "header_filter_by_lua",
2928+ sizeof("header_filter_by_lua") - 1);
2929 p = ngx_copy(p, NGX_HTTP_LUA_INLINE_TAG, NGX_HTTP_LUA_INLINE_TAG_LEN);
2930 p = ngx_http_lua_digest_hex(p, value[1].data, value[1].len);
2931 *p = '\0';
2932@@ -1036,13 +1058,16 @@ ngx_http_lua_body_filter_by_lua(ngx_conf_t *cf, ngx_command_t *cmd,
2933 /* Don't eval nginx variables for inline lua code */
2934 llcf->body_filter_src.value = value[1];
2935
2936- p = ngx_palloc(cf->pool, NGX_HTTP_LUA_INLINE_KEY_LEN + 1);
2937+ p = ngx_palloc(cf->pool,
2938+ sizeof("body_filter_by_lua") +
2939+ NGX_HTTP_LUA_INLINE_KEY_LEN + 1);
2940 if (p == NULL) {
2941 return NGX_CONF_ERROR;
2942 }
2943
2944 llcf->body_filter_src_key = p;
2945
2946+ p = ngx_copy(p, "body_filter_by_lua", sizeof("body_filter_by_lua") - 1);
2947 p = ngx_copy(p, NGX_HTTP_LUA_INLINE_TAG, NGX_HTTP_LUA_INLINE_TAG_LEN);
2948 p = ngx_http_lua_digest_hex(p, value[1].data, value[1].len);
2949 *p = '\0';
2950@@ -1248,7 +1273,8 @@ ngx_http_lua_set_by_lua_init(ngx_http_request_t *r)
2951
2952
2953 static u_char *
2954-ngx_http_lua_gen_chunk_name(ngx_conf_t *cf, const char *tag, size_t tag_len)
2955+ngx_http_lua_gen_chunk_name(ngx_conf_t *cf, const char *tag, size_t tag_len,
2956+ size_t *chunkname_len)
2957 {
2958 u_char *p, *out;
2959 size_t len;
2960@@ -1278,10 +1304,12 @@ ngx_http_lua_gen_chunk_name(ngx_conf_t *cf, const char *tag, size_t tag_len)
2961
2962 found:
2963
2964- ngx_snprintf(out, len, "=%*s(%*s:%d)%Z",
2965- tag_len, tag, cf->conf_file->file.name.data
2966- + cf->conf_file->file.name.len - p,
2967- p, cf->conf_file->line);
2968+ p = ngx_snprintf(out, len, "=%*s(%*s:%d)%Z",
2969+ tag_len, tag, cf->conf_file->file.name.data
2970+ + cf->conf_file->file.name.len - p,
2971+ p, cf->conf_file->line);
2972+
2973+ *chunkname_len = p - out - 1; /* exclude the trailing '\0' byte */
2974
2975 return out;
2976 }
2977diff --git a/debian/modules/http-lua/src/ngx_http_lua_exception.h b/debian/modules/http-lua/src/ngx_http_lua_exception.h
2978index a70708a..93dfb8f 100644
2979--- a/debian/modules/http-lua/src/ngx_http_lua_exception.h
2980+++ b/debian/modules/http-lua/src/ngx_http_lua_exception.h
2981@@ -12,13 +12,13 @@
2982 #include "ngx_http_lua_common.h"
2983
2984
2985-#define NGX_LUA_EXCEPTION_TRY \
2986+#define NGX_LUA_EXCEPTION_TRY \
2987 if (setjmp(ngx_http_lua_exception) == 0)
2988
2989-#define NGX_LUA_EXCEPTION_CATCH \
2990+#define NGX_LUA_EXCEPTION_CATCH \
2991 else
2992
2993-#define NGX_LUA_EXCEPTION_THROW(x) \
2994+#define NGX_LUA_EXCEPTION_THROW(x) \
2995 longjmp(ngx_http_lua_exception, (x))
2996
2997
2998diff --git a/debian/modules/http-lua/src/ngx_http_lua_headerfilterby.c b/debian/modules/http-lua/src/ngx_http_lua_headerfilterby.c
2999index b504530..a0acd4a 100644
3000--- a/debian/modules/http-lua/src/ngx_http_lua_headerfilterby.c
3001+++ b/debian/modules/http-lua/src/ngx_http_lua_headerfilterby.c
3002@@ -42,9 +42,9 @@ static ngx_http_output_header_filter_pt ngx_http_next_header_filter;
3003 static void
3004 ngx_http_lua_header_filter_by_lua_env(lua_State *L, ngx_http_request_t *r)
3005 {
3006- /* set nginx request pointer to current lua thread's globals table */
3007 ngx_http_lua_set_req(L, r);
3008
3009+#ifndef OPENRESTY_LUAJIT
3010 /**
3011 * we want to create empty environment for current script
3012 *
3013@@ -68,6 +68,7 @@ ngx_http_lua_header_filter_by_lua_env(lua_State *L, ngx_http_request_t *r)
3014 /* }}} */
3015
3016 lua_setfenv(L, -2); /* set new running env for the code closure */
3017+#endif /* OPENRESTY_LUAJIT */
3018 }
3019
3020
3021diff --git a/debian/modules/http-lua/src/ngx_http_lua_headers.c b/debian/modules/http-lua/src/ngx_http_lua_headers.c
3022index 6700ce8..e3f48bc 100644
3023--- a/debian/modules/http-lua/src/ngx_http_lua_headers.c
3024+++ b/debian/modules/http-lua/src/ngx_http_lua_headers.c
3025@@ -113,7 +113,7 @@ ngx_http_lua_ngx_req_raw_header(lua_State *L)
3026
3027 #if (NGX_HTTP_V2)
3028 if (mr->stream) {
3029- return luaL_error(L, "http v2 not supported yet");
3030+ return luaL_error(L, "http2 requests not supported yet");
3031 }
3032 #endif
3033
3034@@ -245,7 +245,7 @@ ngx_http_lua_ngx_req_raw_header(lua_State *L)
3035
3036 if (b != mr->header_in) {
3037 /* skip truncated header entries (if any) */
3038- while (last > data && last[-1] != LF) {
3039+ while (last > data && last[-1] != LF && last[-1] != '\0') {
3040 last--;
3041 }
3042 }
3043@@ -315,7 +315,7 @@ ngx_http_lua_ngx_req_raw_header(lua_State *L)
3044
3045 #if 1
3046 /* skip truncated header entries (if any) */
3047- while (last > p && last[-1] != LF) {
3048+ while (last > p && last[-1] != LF && last[-1] != '\0') {
3049 last--;
3050 }
3051 #endif
3052@@ -325,8 +325,7 @@ ngx_http_lua_ngx_req_raw_header(lua_State *L)
3053 if (*p == '\0') {
3054 j++;
3055 if (p + 1 == last) {
3056- /* XXX this should not happen */
3057- dd("found string end!!");
3058+ *p = LF;
3059
3060 } else if (*(p + 1) == LF) {
3061 *p = CR;
3062@@ -398,6 +397,7 @@ ngx_http_lua_ngx_req_get_headers(lua_State *L)
3063 int max;
3064 int raw = 0;
3065 int count = 0;
3066+ int truncated = 0;
3067
3068 n = lua_gettop(L);
3069
3070@@ -426,21 +426,24 @@ ngx_http_lua_ngx_req_get_headers(lua_State *L)
3071
3072 part = &r->headers_in.headers.part;
3073 count = part->nelts;
3074- while (part->next) {
3075+ while (part->next != NULL) {
3076 part = part->next;
3077 count += part->nelts;
3078 }
3079
3080 if (max > 0 && count > max) {
3081+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
3082+ "lua exceeding request header limit %d > %d", count,
3083+ max);
3084 count = max;
3085- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
3086- "lua exceeding request header limit %d", max);
3087+ truncated = 1;
3088 }
3089
3090 lua_createtable(L, 0, count);
3091
3092 if (!raw) {
3093- lua_pushlightuserdata(L, &ngx_http_lua_headers_metatable_key);
3094+ lua_pushlightuserdata(L, ngx_http_lua_lightudata_mask(
3095+ headers_metatable_key));
3096 lua_rawget(L, LUA_REGISTRYINDEX);
3097 lua_setmetatable(L, -2);
3098 }
3099@@ -481,9 +484,14 @@ ngx_http_lua_ngx_req_get_headers(lua_State *L)
3100 "lua request header: \"%V: %V\"",
3101 &header[i].key, &header[i].value);
3102
3103- if (--count == 0) {
3104- return 1;
3105+ if (--count <= 0) {
3106+ break;
3107 }
3108+ } /* for */
3109+
3110+ if (truncated) {
3111+ lua_pushliteral(L, "truncated");
3112+ return 2;
3113 }
3114
3115 return 1;
3116@@ -497,7 +505,6 @@ ngx_http_lua_ngx_resp_get_headers(lua_State *L)
3117 ngx_table_elt_t *header;
3118 ngx_http_request_t *r;
3119 ngx_http_lua_ctx_t *ctx;
3120- ngx_int_t rc;
3121 u_char *lowcase_key = NULL;
3122 size_t lowcase_key_sz = 0;
3123 ngx_uint_t i;
3124@@ -505,6 +512,8 @@ ngx_http_lua_ngx_resp_get_headers(lua_State *L)
3125 int max;
3126 int raw = 0;
3127 int count = 0;
3128+ int truncated = 0;
3129+ int extra = 0;
3130
3131 n = lua_gettop(L);
3132
3133@@ -534,42 +543,27 @@ ngx_http_lua_ngx_resp_get_headers(lua_State *L)
3134 return luaL_error(L, "no ctx found");
3135 }
3136
3137- if (!ctx->headers_set) {
3138- rc = ngx_http_lua_set_content_type(r);
3139- if (rc != NGX_OK) {
3140- return luaL_error(L,
3141- "failed to set default content type: %d",
3142- (int) rc);
3143- }
3144-
3145- ctx->headers_set = 1;
3146- }
3147-
3148 ngx_http_lua_check_fake_request(L, r);
3149
3150 part = &r->headers_out.headers.part;
3151 count = part->nelts;
3152- while (part->next) {
3153+ while (part->next != NULL) {
3154 part = part->next;
3155 count += part->nelts;
3156 }
3157
3158- if (max > 0 && count > max) {
3159- count = max;
3160- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
3161- "lua exceeding request header limit %d", max);
3162- }
3163-
3164- lua_createtable(L, 0, count);
3165+ lua_createtable(L, 0, count + 2);
3166
3167 if (!raw) {
3168- lua_pushlightuserdata(L, &ngx_http_lua_headers_metatable_key);
3169+ lua_pushlightuserdata(L, ngx_http_lua_lightudata_mask(
3170+ headers_metatable_key));
3171 lua_rawget(L, LUA_REGISTRYINDEX);
3172 lua_setmetatable(L, -2);
3173 }
3174
3175 #if 1
3176 if (r->headers_out.content_type.len) {
3177+ extra++;
3178 lua_pushliteral(L, "content-type");
3179 lua_pushlstring(L, (char *) r->headers_out.content_type.data,
3180 r->headers_out.content_type.len);
3181@@ -579,11 +573,13 @@ ngx_http_lua_ngx_resp_get_headers(lua_State *L)
3182 if (r->headers_out.content_length == NULL
3183 && r->headers_out.content_length_n >= 0)
3184 {
3185+ extra++;
3186 lua_pushliteral(L, "content-length");
3187 lua_pushfstring(L, "%d", (int) r->headers_out.content_length_n);
3188 lua_rawset(L, -3);
3189 }
3190
3191+ extra++;
3192 lua_pushliteral(L, "connection");
3193 if (r->headers_out.status == NGX_HTTP_SWITCHING_PROTOCOLS) {
3194 lua_pushliteral(L, "upgrade");
3195@@ -597,12 +593,21 @@ ngx_http_lua_ngx_resp_get_headers(lua_State *L)
3196 lua_rawset(L, -3);
3197
3198 if (r->chunked) {
3199+ extra++;
3200 lua_pushliteral(L, "transfer-encoding");
3201 lua_pushliteral(L, "chunked");
3202 lua_rawset(L, -3);
3203 }
3204 #endif
3205
3206+ if (max > 0 && count + extra > max) {
3207+ truncated = 1;
3208+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
3209+ "lua exceeding response header limit %d > %d",
3210+ count + extra, max);
3211+ count = max - extra;
3212+ }
3213+
3214 part = &r->headers_out.headers.part;
3215 header = part->elts;
3216
3217@@ -655,9 +660,14 @@ ngx_http_lua_ngx_resp_get_headers(lua_State *L)
3218 "lua response header: \"%V: %V\"",
3219 &header[i].key, &header[i].value);
3220
3221- if (--count == 0) {
3222- return 1;
3223+ if (--count <= 0) {
3224+ break;
3225 }
3226+ } /* for */
3227+
3228+ if (truncated) {
3229+ lua_pushliteral(L, "truncated");
3230+ return 2;
3231 }
3232
3233 return 1;
3234@@ -674,7 +684,6 @@ ngx_http_lua_ngx_header_get(lua_State *L)
3235 size_t len;
3236 ngx_http_lua_loc_conf_t *llcf;
3237 ngx_http_lua_ctx_t *ctx;
3238- ngx_int_t rc;
3239
3240 r = ngx_http_lua_get_req(L);
3241 if (r == NULL) {
3242@@ -717,18 +726,7 @@ ngx_http_lua_ngx_header_get(lua_State *L)
3243
3244 key.len = len;
3245
3246- if (!ctx->headers_set) {
3247- rc = ngx_http_lua_set_content_type(r);
3248- if (rc != NGX_OK) {
3249- return luaL_error(L,
3250- "failed to set default content type: %d",
3251- (int) rc);
3252- }
3253-
3254- ctx->headers_set = 1;
3255- }
3256-
3257- return ngx_http_lua_get_output_header(L, r, &key);
3258+ return ngx_http_lua_get_output_header(L, r, ctx, &key);
3259 }
3260
3261
3262@@ -791,16 +789,7 @@ ngx_http_lua_ngx_header_set(lua_State *L)
3263 }
3264 }
3265
3266- if (!ctx->headers_set) {
3267- rc = ngx_http_lua_set_content_type(r);
3268- if (rc != NGX_OK) {
3269- return luaL_error(L,
3270- "failed to set default content type: %d",
3271- (int) rc);
3272- }
3273-
3274- ctx->headers_set = 1;
3275- }
3276+ ctx->headers_set = 1;
3277
3278 if (lua_type(L, 3) == LUA_TNIL) {
3279 ngx_str_null(&value);
3280@@ -825,7 +814,7 @@ ngx_http_lua_ngx_header_set(lua_State *L)
3281 ngx_memcpy(value.data, p, len);
3282 value.len = len;
3283
3284- rc = ngx_http_lua_set_output_header(r, key, value,
3285+ rc = ngx_http_lua_set_output_header(r, ctx, key, value,
3286 i == 1 /* override */);
3287
3288 if (rc == NGX_ERROR) {
3289@@ -852,7 +841,7 @@ ngx_http_lua_ngx_header_set(lua_State *L)
3290 dd("key: %.*s, value: %.*s",
3291 (int) key.len, key.data, (int) value.len, value.data);
3292
3293- rc = ngx_http_lua_set_output_header(r, key, value, 1 /* override */);
3294+ rc = ngx_http_lua_set_output_header(r, ctx, key, value, 1 /* override */);
3295
3296 if (rc == NGX_ERROR) {
3297 return luaL_error(L, "failed to set header %s (error: %d)",
3298@@ -1061,7 +1050,8 @@ ngx_http_lua_create_headers_metatable(ngx_log_t *log, lua_State *L)
3299 "local new_key = string.gsub(string.lower(key), '_', '-')\n"
3300 "if new_key ~= key then return tb[new_key] else return nil end";
3301
3302- lua_pushlightuserdata(L, &ngx_http_lua_headers_metatable_key);
3303+ lua_pushlightuserdata(L, ngx_http_lua_lightudata_mask(
3304+ headers_metatable_key));
3305
3306 /* metatable for ngx.req.get_headers(_, true) and
3307 * ngx.resp.get_headers(_, true) */
3308@@ -1084,7 +1074,8 @@ ngx_http_lua_create_headers_metatable(ngx_log_t *log, lua_State *L)
3309
3310 #ifndef NGX_LUA_NO_FFI_API
3311 int
3312-ngx_http_lua_ffi_req_get_headers_count(ngx_http_request_t *r, int max)
3313+ngx_http_lua_ffi_req_get_headers_count(ngx_http_request_t *r, int max,
3314+ int *truncated)
3315 {
3316 int count;
3317 ngx_list_part_t *part;
3318@@ -1093,21 +1084,26 @@ ngx_http_lua_ffi_req_get_headers_count(ngx_http_request_t *r, int max)
3319 return NGX_HTTP_LUA_FFI_BAD_CONTEXT;
3320 }
3321
3322+ *truncated = 0;
3323+
3324 if (max < 0) {
3325 max = NGX_HTTP_LUA_MAX_HEADERS;
3326 }
3327
3328 part = &r->headers_in.headers.part;
3329 count = part->nelts;
3330- while (part->next) {
3331+ while (part->next != NULL) {
3332 part = part->next;
3333 count += part->nelts;
3334 }
3335
3336 if (max > 0 && count > max) {
3337+ *truncated = 1;
3338+
3339+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
3340+ "lua exceeding request header limit %d > %d", count,
3341+ max);
3342 count = max;
3343- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
3344- "lua exceeding request header limit %d", max);
3345 }
3346
3347 return count;
3348@@ -1167,7 +1163,8 @@ ngx_http_lua_ffi_req_get_headers(ngx_http_request_t *r,
3349 int
3350 ngx_http_lua_ffi_set_resp_header(ngx_http_request_t *r, const u_char *key_data,
3351 size_t key_len, int is_nil, const u_char *sval, size_t sval_len,
3352- ngx_http_lua_ffi_str_t *mvals, size_t mvals_len, char **errmsg)
3353+ ngx_http_lua_ffi_str_t *mvals, size_t mvals_len, int override,
3354+ char **errmsg)
3355 {
3356 u_char *p;
3357 ngx_str_t value, key;
3358@@ -1214,15 +1211,7 @@ ngx_http_lua_ffi_set_resp_header(ngx_http_request_t *r, const u_char *key_data,
3359 }
3360 }
3361
3362- if (!ctx->headers_set) {
3363- rc = ngx_http_lua_set_content_type(r);
3364- if (rc != NGX_OK) {
3365- *errmsg = "failed to set default content type";
3366- return NGX_ERROR;
3367- }
3368-
3369- ctx->headers_set = 1;
3370- }
3371+ ctx->headers_set = 1;
3372
3373 if (is_nil) {
3374 value.data = NULL;
3375@@ -1249,8 +1238,8 @@ ngx_http_lua_ffi_set_resp_header(ngx_http_request_t *r, const u_char *key_data,
3376 ngx_memcpy(value.data, p, len);
3377 value.len = len;
3378
3379- rc = ngx_http_lua_set_output_header(r, key, value,
3380- i == 0 /* override */);
3381+ rc = ngx_http_lua_set_output_header(r, ctx, key, value,
3382+ override && i == 0);
3383
3384 if (rc == NGX_ERROR) {
3385 *errmsg = "failed to set header";
3386@@ -1275,7 +1264,7 @@ ngx_http_lua_ffi_set_resp_header(ngx_http_request_t *r, const u_char *key_data,
3387 dd("key: %.*s, value: %.*s",
3388 (int) key.len, key.data, (int) value.len, value.data);
3389
3390- rc = ngx_http_lua_set_output_header(r, key, value, 1 /* override */);
3391+ rc = ngx_http_lua_set_output_header(r, ctx, key, value, override);
3392
3393 if (rc == NGX_ERROR) {
3394 *errmsg = "failed to set header";
3395@@ -1343,7 +1332,8 @@ ngx_http_lua_ffi_req_header_set_single_value(ngx_http_request_t *r,
3396 int
3397 ngx_http_lua_ffi_get_resp_header(ngx_http_request_t *r,
3398 const u_char *key, size_t key_len,
3399- u_char *key_buf, ngx_http_lua_ffi_str_t *values, int max_nvalues)
3400+ u_char *key_buf, ngx_http_lua_ffi_str_t *values, int max_nvalues,
3401+ char **errmsg)
3402 {
3403 int found;
3404 u_char c, *p;
3405@@ -1360,19 +1350,10 @@ ngx_http_lua_ffi_get_resp_header(ngx_http_request_t *r,
3406
3407 ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
3408 if (ctx == NULL) {
3409- /* *errmsg = "no ctx found"; */
3410+ *errmsg = "no ctx found";
3411 return NGX_ERROR;
3412 }
3413
3414- if (!ctx->headers_set) {
3415- if (ngx_http_lua_set_content_type(r) != NGX_OK) {
3416- /* *errmsg = "failed to set default content type"; */
3417- return NGX_ERROR;
3418- }
3419-
3420- ctx->headers_set = 1;
3421- }
3422-
3423 llcf = ngx_http_get_module_loc_conf(r, ngx_http_lua_module);
3424 if (llcf->transform_underscores_in_resp_headers
3425 && memchr(key, '_', key_len) != NULL)
3426@@ -1398,6 +1379,7 @@ ngx_http_lua_ffi_get_resp_header(ngx_http_request_t *r,
3427 {
3428 p = ngx_palloc(r->pool, NGX_OFF_T_LEN);
3429 if (p == NULL) {
3430+ *errmsg = "no memory";
3431 return NGX_ERROR;
3432 }
3433
3434@@ -1411,8 +1393,8 @@ ngx_http_lua_ffi_get_resp_header(ngx_http_request_t *r,
3435 break;
3436
3437 case 12:
3438- if (r->headers_out.content_type.len
3439- && ngx_strncasecmp(key_buf, (u_char *) "Content-Type", 12) == 0)
3440+ if (ngx_strncasecmp(key_buf, (u_char *) "Content-Type", 12) == 0
3441+ && r->headers_out.content_type.len)
3442 {
3443 values[0].data = r->headers_out.content_type.data;
3444 values[0].len = r->headers_out.content_type.len;
3445diff --git a/debian/modules/http-lua/src/ngx_http_lua_headers_in.c b/debian/modules/http-lua/src/ngx_http_lua_headers_in.c
3446index 4852b2f..c52cd13 100644
3447--- a/debian/modules/http-lua/src/ngx_http_lua_headers_in.c
3448+++ b/debian/modules/http-lua/src/ngx_http_lua_headers_in.c
3449@@ -432,10 +432,14 @@ static ngx_int_t
3450 ngx_http_set_host_header(ngx_http_request_t *r, ngx_http_lua_header_val_t *hv,
3451 ngx_str_t *value)
3452 {
3453- ngx_str_t host;
3454+ ngx_str_t host;
3455+ ngx_http_lua_main_conf_t *lmcf;
3456+ ngx_http_variable_value_t *var;
3457
3458 dd("server new value len: %d", (int) value->len);
3459
3460+ lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module);
3461+
3462 if (value->len) {
3463 host= *value;
3464
3465@@ -449,6 +453,10 @@ ngx_http_set_host_header(ngx_http_request_t *r, ngx_http_lua_header_val_t *hv,
3466 r->headers_in.server = *value;
3467 }
3468
3469+ var = &r->variables[lmcf->host_var_index];
3470+ var->valid = 0;
3471+ var->not_found = 0;
3472+
3473 return ngx_http_set_builtin_header(r, hv, value);
3474 }
3475
3476diff --git a/debian/modules/http-lua/src/ngx_http_lua_headers_out.c b/debian/modules/http-lua/src/ngx_http_lua_headers_out.c
3477index b908eae..cf94bd0 100644
3478--- a/debian/modules/http-lua/src/ngx_http_lua_headers_out.c
3479+++ b/debian/modules/http-lua/src/ngx_http_lua_headers_out.c
3480@@ -106,6 +106,12 @@ static ngx_http_lua_set_header_t ngx_http_lua_set_handlers[] = {
3481 offsetof(ngx_http_headers_out_t, cache_control),
3482 ngx_http_set_builtin_multi_header },
3483
3484+#if defined(nginx_version) && nginx_version >= 1013009
3485+ { ngx_string("Link"),
3486+ offsetof(ngx_http_headers_out_t, link),
3487+ ngx_http_set_builtin_multi_header },
3488+#endif
3489+
3490 { ngx_null_string, 0, ngx_http_set_header }
3491 };
3492
3493@@ -476,8 +482,8 @@ ngx_http_clear_builtin_header(ngx_http_request_t *r,
3494
3495
3496 ngx_int_t
3497-ngx_http_lua_set_output_header(ngx_http_request_t *r, ngx_str_t key,
3498- ngx_str_t value, unsigned override)
3499+ngx_http_lua_set_output_header(ngx_http_request_t *r, ngx_http_lua_ctx_t *ctx,
3500+ ngx_str_t key, ngx_str_t value, unsigned override)
3501 {
3502 ngx_http_lua_header_val_t hv;
3503 ngx_http_lua_set_header_t *handlers = ngx_http_lua_set_handlers;
3504@@ -508,6 +514,10 @@ ngx_http_lua_set_output_header(ngx_http_request_t *r, ngx_str_t key,
3505 hv.offset = handlers[i].offset;
3506 hv.handler = handlers[i].handler;
3507
3508+ if (hv.handler == ngx_http_set_content_type_header) {
3509+ ctx->mime_set = 1;
3510+ }
3511+
3512 break;
3513 }
3514
3515@@ -528,7 +538,7 @@ ngx_http_lua_set_output_header(ngx_http_request_t *r, ngx_str_t key,
3516
3517 int
3518 ngx_http_lua_get_output_header(lua_State *L, ngx_http_request_t *r,
3519- ngx_str_t *key)
3520+ ngx_http_lua_ctx_t *ctx, ngx_str_t *key)
3521 {
3522 ngx_table_elt_t *h;
3523 ngx_list_part_t *part;
3524@@ -550,8 +560,8 @@ ngx_http_lua_get_output_header(lua_State *L, ngx_http_request_t *r,
3525 break;
3526
3527 case 12:
3528- if (r->headers_out.content_type.len
3529- && ngx_strncasecmp(key->data, (u_char *) "Content-Type", 12) == 0)
3530+ if (ngx_strncasecmp(key->data, (u_char *) "Content-Type", 12) == 0
3531+ && r->headers_out.content_type.len)
3532 {
3533 lua_pushlstring(L, (char *) r->headers_out.content_type.data,
3534 r->headers_out.content_type.len);
3535diff --git a/debian/modules/http-lua/src/ngx_http_lua_headers_out.h b/debian/modules/http-lua/src/ngx_http_lua_headers_out.h
3536index ef5e6d4..6ec1fe3 100644
3537--- a/debian/modules/http-lua/src/ngx_http_lua_headers_out.h
3538+++ b/debian/modules/http-lua/src/ngx_http_lua_headers_out.h
3539@@ -12,10 +12,10 @@
3540 #include "ngx_http_lua_common.h"
3541
3542
3543-ngx_int_t ngx_http_lua_set_output_header(ngx_http_request_t *r, ngx_str_t key,
3544- ngx_str_t value, unsigned override);
3545+ngx_int_t ngx_http_lua_set_output_header(ngx_http_request_t *r,
3546+ ngx_http_lua_ctx_t *ctx, ngx_str_t key, ngx_str_t value, unsigned override);
3547 int ngx_http_lua_get_output_header(lua_State *L, ngx_http_request_t *r,
3548- ngx_str_t *key);
3549+ ngx_http_lua_ctx_t *ctx, ngx_str_t *key);
3550
3551
3552 #endif /* _NGX_HTTP_LUA_HEADERS_OUT_H_INCLUDED_ */
3553diff --git a/debian/modules/http-lua/src/ngx_http_lua_initworkerby.c b/debian/modules/http-lua/src/ngx_http_lua_initworkerby.c
3554index 6754b4b..76acdc3 100644
3555--- a/debian/modules/http-lua/src/ngx_http_lua_initworkerby.c
3556+++ b/debian/modules/http-lua/src/ngx_http_lua_initworkerby.c
3557@@ -12,6 +12,7 @@
3558
3559 #include "ngx_http_lua_initworkerby.h"
3560 #include "ngx_http_lua_util.h"
3561+#include "ngx_http_lua_pipe.h"
3562
3563
3564 static u_char *ngx_http_lua_log_init_worker_error(ngx_log_t *log,
3565@@ -25,6 +26,7 @@ ngx_http_lua_init_worker(ngx_cycle_t *cycle)
3566 void *cur, *prev;
3567 ngx_uint_t i;
3568 ngx_conf_t conf;
3569+ ngx_conf_file_t cf_file;
3570 ngx_cycle_t *fake_cycle;
3571 ngx_module_t **modules;
3572 ngx_open_file_t *file, *ofile;
3573@@ -40,10 +42,46 @@ ngx_http_lua_init_worker(ngx_cycle_t *cycle)
3574
3575 lmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_lua_module);
3576
3577- if (lmcf == NULL
3578- || lmcf->init_worker_handler == NULL
3579- || lmcf->lua == NULL)
3580+ if (lmcf == NULL || lmcf->lua == NULL) {
3581+ return NGX_OK;
3582+ }
3583+
3584+ /* lmcf != NULL && lmcf->lua != NULL */
3585+
3586+#if !(NGX_WIN32)
3587+ if (ngx_process == NGX_PROCESS_HELPER
3588+# ifdef HAVE_PRIVILEGED_PROCESS_PATCH
3589+ && !ngx_is_privileged_agent
3590+# endif
3591+ )
3592 {
3593+ /* disable init_worker_by_lua* and destroy lua VM in cache processes */
3594+
3595+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
3596+ "lua close the global Lua VM %p in the "
3597+ "cache helper process %P", lmcf->lua, ngx_pid);
3598+
3599+ lmcf->vm_cleanup->handler(lmcf->vm_cleanup->data);
3600+ lmcf->vm_cleanup->handler = NULL;
3601+
3602+ return NGX_OK;
3603+ }
3604+
3605+#ifdef HAVE_NGX_LUA_PIPE
3606+ if (ngx_http_lua_pipe_add_signal_handler(cycle) != NGX_OK) {
3607+ return NGX_ERROR;
3608+ }
3609+#endif
3610+
3611+#endif /* NGX_WIN32 */
3612+
3613+#if (NGX_HTTP_LUA_HAVE_SA_RESTART)
3614+ if (lmcf->set_sa_restart) {
3615+ ngx_http_lua_set_sa_restart(ngx_cycle->log);
3616+ }
3617+#endif
3618+
3619+ if (lmcf->init_worker_handler == NULL) {
3620 return NGX_OK;
3621 }
3622
3623@@ -143,6 +181,10 @@ ngx_http_lua_init_worker(ngx_cycle_t *cycle)
3624 conf.pool = fake_cycle->pool;
3625 conf.log = cycle->log;
3626
3627+ ngx_memzero(&cf_file, sizeof(cf_file));
3628+ cf_file.file.name = cycle->conf_file;
3629+ conf.conf_file = &cf_file;
3630+
3631 http_ctx.loc_conf = ngx_pcalloc(conf.pool,
3632 sizeof(void *) * ngx_http_max_module);
3633 if (http_ctx.loc_conf == NULL) {
3634diff --git a/debian/modules/http-lua/src/ngx_http_lua_input_filters.c b/debian/modules/http-lua/src/ngx_http_lua_input_filters.c
3635new file mode 100644
3636index 0000000..87a9d8c
3637--- /dev/null
3638+++ b/debian/modules/http-lua/src/ngx_http_lua_input_filters.c
3639@@ -0,0 +1,137 @@
3640+
3641+/*
3642+ * Copyright (C) by OpenResty Inc.
3643+ */
3644+
3645+
3646+#ifndef DDEBUG
3647+#define DDEBUG 0
3648+#endif
3649+#include "ddebug.h"
3650+
3651+
3652+#include "ngx_http_lua_common.h"
3653+
3654+
3655+ngx_int_t
3656+ngx_http_lua_read_bytes(ngx_buf_t *src, ngx_chain_t *buf_in, size_t *rest,
3657+ ssize_t bytes, ngx_log_t *log)
3658+{
3659+ if (bytes == 0) {
3660+ return NGX_ERROR;
3661+ }
3662+
3663+ if ((size_t) bytes >= *rest) {
3664+
3665+ buf_in->buf->last += *rest;
3666+ src->pos += *rest;
3667+ *rest = 0;
3668+
3669+ return NGX_OK;
3670+ }
3671+
3672+ /* bytes < *rest */
3673+
3674+ buf_in->buf->last += bytes;
3675+ src->pos += bytes;
3676+ *rest -= bytes;
3677+
3678+ return NGX_AGAIN;
3679+}
3680+
3681+
3682+ngx_int_t
3683+ngx_http_lua_read_all(ngx_buf_t *src, ngx_chain_t *buf_in, ssize_t bytes,
3684+ ngx_log_t *log)
3685+{
3686+ if (bytes == 0) {
3687+ return NGX_OK;
3688+ }
3689+
3690+ buf_in->buf->last += bytes;
3691+ src->pos += bytes;
3692+
3693+ return NGX_AGAIN;
3694+}
3695+
3696+
3697+ngx_int_t
3698+ngx_http_lua_read_any(ngx_buf_t *src, ngx_chain_t *buf_in, size_t *max,
3699+ ssize_t bytes, ngx_log_t *log)
3700+{
3701+ if (bytes == 0) {
3702+ return NGX_ERROR;
3703+ }
3704+
3705+ if (bytes >= (ssize_t) *max) {
3706+ bytes = (ssize_t) *max;
3707+ }
3708+
3709+ buf_in->buf->last += bytes;
3710+ src->pos += bytes;
3711+
3712+ return NGX_OK;
3713+}
3714+
3715+
3716+ngx_int_t
3717+ngx_http_lua_read_line(ngx_buf_t *src, ngx_chain_t *buf_in, ssize_t bytes,
3718+ ngx_log_t *log)
3719+{
3720+ u_char *dst;
3721+ u_char c;
3722+#if (NGX_DEBUG)
3723+ u_char *begin;
3724+#endif
3725+
3726+#if (NGX_DEBUG)
3727+ begin = src->pos;
3728+#endif
3729+
3730+ if (bytes == 0) {
3731+ return NGX_ERROR;
3732+ }
3733+
3734+ dd("already read: %p: %.*s", buf_in,
3735+ (int) (buf_in->buf->last - buf_in->buf->pos), buf_in->buf->pos);
3736+
3737+ dd("data read: %.*s", (int) bytes, src->pos);
3738+
3739+ dst = buf_in->buf->last;
3740+
3741+ while (bytes--) {
3742+
3743+ c = *src->pos++;
3744+
3745+ switch (c) {
3746+ case '\n':
3747+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, log, 0,
3748+ "lua read the final line part: \"%*s\"",
3749+ src->pos - 1 - begin, begin);
3750+
3751+ buf_in->buf->last = dst;
3752+
3753+ dd("read a line: %p: %.*s", buf_in,
3754+ (int) (buf_in->buf->last - buf_in->buf->pos), buf_in->buf->pos);
3755+
3756+ return NGX_OK;
3757+
3758+ case '\r':
3759+ /* ignore it */
3760+ break;
3761+
3762+ default:
3763+ *dst++ = c;
3764+ break;
3765+ }
3766+ }
3767+
3768+#if (NGX_DEBUG)
3769+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, log, 0,
3770+ "lua read partial line data: %*s", dst - begin, begin);
3771+#endif
3772+
3773+ buf_in->buf->last = dst;
3774+
3775+ return NGX_AGAIN;
3776+}
3777diff --git a/debian/modules/http-lua/src/ngx_http_lua_input_filters.h b/debian/modules/http-lua/src/ngx_http_lua_input_filters.h
3778new file mode 100644
3779index 0000000..046d40f
3780--- /dev/null
3781+++ b/debian/modules/http-lua/src/ngx_http_lua_input_filters.h
3782@@ -0,0 +1,29 @@
3783+
3784+/*
3785+ * Copyright (C) by OpenResty Inc.
3786+ */
3787+
3788+
3789+#ifndef _NGX_HTTP_LUA_INPUT_FILTERS_H_INCLUDED_
3790+#define _NGX_HTTP_LUA_INPUT_FILTERS_H_INCLUDED_
3791+
3792+
3793+#include "ngx_http_lua_common.h"
3794+
3795+
3796+ngx_int_t ngx_http_lua_read_bytes(ngx_buf_t *src, ngx_chain_t *buf_in,
3797+ size_t *rest, ssize_t bytes, ngx_log_t *log);
3798+
3799+ngx_int_t ngx_http_lua_read_all(ngx_buf_t *src, ngx_chain_t *buf_in,
3800+ ssize_t bytes, ngx_log_t *log);
3801+
3802+ngx_int_t ngx_http_lua_read_any(ngx_buf_t *src, ngx_chain_t *buf_in,
3803+ size_t *max, ssize_t bytes, ngx_log_t *log);
3804+
3805+ngx_int_t ngx_http_lua_read_line(ngx_buf_t *src, ngx_chain_t *buf_in,
3806+ ssize_t bytes, ngx_log_t *log);
3807+
3808+
3809+#endif /* _NGX_HTTP_LUA_INPUT_FILTERS_H_INCLUDED_ */
3810+
3811+/* vi:set ft=c ts=4 sw=4 et fdm=marker: */
3812diff --git a/debian/modules/http-lua/src/ngx_http_lua_log.c b/debian/modules/http-lua/src/ngx_http_lua_log.c
3813index c18e6b0..0042a5e 100644
3814--- a/debian/modules/http-lua/src/ngx_http_lua_log.c
3815+++ b/debian/modules/http-lua/src/ngx_http_lua_log.c
3816@@ -428,6 +428,29 @@ ngx_http_lua_ffi_errlog_get_sys_filter_level(ngx_http_request_t *r)
3817 return log_level;
3818 }
3819
3820+
3821+int
3822+ngx_http_lua_ffi_raw_log(ngx_http_request_t *r, int level, u_char *s,
3823+ size_t s_len)
3824+{
3825+ ngx_log_t *log;
3826+
3827+ if (level > NGX_LOG_DEBUG || level < NGX_LOG_STDERR) {
3828+ return NGX_ERROR;
3829+ }
3830+
3831+ if (r && r->connection && r->connection->log) {
3832+ log = r->connection->log;
3833+
3834+ } else {
3835+ log = ngx_cycle->log;
3836+ }
3837+
3838+ ngx_log_error((unsigned) level, log, 0, "%*s", s_len, s);
3839+
3840+ return NGX_OK;
3841+}
3842+
3843 #endif
3844
3845 /* vi:set ft=c ts=4 sw=4 et fdm=marker: */
3846diff --git a/debian/modules/http-lua/src/ngx_http_lua_logby.c b/debian/modules/http-lua/src/ngx_http_lua_logby.c
3847index 0f1d2f3..32d1cba 100644
3848--- a/debian/modules/http-lua/src/ngx_http_lua_logby.c
3849+++ b/debian/modules/http-lua/src/ngx_http_lua_logby.c
3850@@ -38,9 +38,9 @@ static ngx_int_t ngx_http_lua_log_by_chunk(lua_State *L, ngx_http_request_t *r);
3851 static void
3852 ngx_http_lua_log_by_lua_env(lua_State *L, ngx_http_request_t *r)
3853 {
3854- /* set nginx request pointer to current lua thread's globals table */
3855 ngx_http_lua_set_req(L, r);
3856
3857+#ifndef OPENRESTY_LUAJIT
3858 /**
3859 * we want to create empty environment for current script
3860 *
3861@@ -64,6 +64,7 @@ ngx_http_lua_log_by_lua_env(lua_State *L, ngx_http_request_t *r)
3862 /* }}} */
3863
3864 lua_setfenv(L, -2); /* set new running env for the code closure */
3865+#endif /* OPENRESTY_LUAJIT */
3866 }
3867
3868
3869diff --git a/debian/modules/http-lua/src/ngx_http_lua_misc.c b/debian/modules/http-lua/src/ngx_http_lua_misc.c
3870index f96e2f2..145ca9b 100644
3871--- a/debian/modules/http-lua/src/ngx_http_lua_misc.c
3872+++ b/debian/modules/http-lua/src/ngx_http_lua_misc.c
3873@@ -286,6 +286,33 @@ ngx_http_lua_ffi_headers_sent(ngx_http_request_t *r)
3874
3875 return r->header_sent ? 1 : 0;
3876 }
3877+
3878+
3879+int
3880+ngx_http_lua_ffi_get_conf_env(u_char *name, u_char **env_buf, size_t *name_len)
3881+{
3882+ ngx_uint_t i;
3883+ ngx_str_t *var;
3884+ ngx_core_conf_t *ccf;
3885+
3886+ ccf = (ngx_core_conf_t *) ngx_get_conf(ngx_cycle->conf_ctx,
3887+ ngx_core_module);
3888+
3889+ var = ccf->env.elts;
3890+
3891+ for (i = 0; i < ccf->env.nelts; i++) {
3892+ if (var[i].data[var[i].len] == '='
3893+ && ngx_strncmp(name, var[i].data, var[i].len) == 0)
3894+ {
3895+ *env_buf = var[i].data;
3896+ *name_len = var[i].len;
3897+
3898+ return NGX_OK;
3899+ }
3900+ }
3901+
3902+ return NGX_DECLINED;
3903+}
3904 #endif /* NGX_LUA_NO_FFI_API */
3905
3906
3907diff --git a/debian/modules/http-lua/src/ngx_http_lua_module.c b/debian/modules/http-lua/src/ngx_http_lua_module.c
3908index 9d914e8..2a3f5d5 100644
3909--- a/debian/modules/http-lua/src/ngx_http_lua_module.c
3910+++ b/debian/modules/http-lua/src/ngx_http_lua_module.c
3911@@ -29,6 +29,7 @@
3912 #include "ngx_http_lua_ssl_session_storeby.h"
3913 #include "ngx_http_lua_ssl_session_fetchby.h"
3914 #include "ngx_http_lua_headers.h"
3915+#include "ngx_http_lua_pipe.h"
3916
3917
3918 static void *ngx_http_lua_create_main_conf(ngx_conf_t *cf);
3919@@ -65,6 +66,9 @@ static ngx_conf_bitmask_t ngx_http_lua_ssl_protocols[] = {
3920 { ngx_string("TLSv1"), NGX_SSL_TLSv1 },
3921 { ngx_string("TLSv1.1"), NGX_SSL_TLSv1_1 },
3922 { ngx_string("TLSv1.2"), NGX_SSL_TLSv1_2 },
3923+#ifdef NGX_SSL_TLSv1_3
3924+ { ngx_string("TLSv1.3"), NGX_SSL_TLSv1_3 },
3925+#endif
3926 { ngx_null_string, 0 }
3927 };
3928
3929@@ -73,6 +77,13 @@ static ngx_conf_bitmask_t ngx_http_lua_ssl_protocols[] = {
3930
3931 static ngx_command_t ngx_http_lua_cmds[] = {
3932
3933+ { ngx_string("lua_load_resty_core"),
3934+ NGX_HTTP_MAIN_CONF|NGX_CONF_FLAG,
3935+ ngx_conf_set_flag_slot,
3936+ NGX_HTTP_MAIN_CONF_OFFSET,
3937+ offsetof(ngx_http_lua_main_conf_t, load_resty_core),
3938+ NULL },
3939+
3940 { ngx_string("lua_max_running_timers"),
3941 NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
3942 ngx_conf_set_num_slot,
3943@@ -101,6 +112,13 @@ static ngx_command_t ngx_http_lua_cmds[] = {
3944 0,
3945 NULL },
3946
3947+ { ngx_string("lua_sa_restart"),
3948+ NGX_HTTP_MAIN_CONF|NGX_CONF_FLAG,
3949+ ngx_conf_set_flag_slot,
3950+ NGX_HTTP_MAIN_CONF_OFFSET,
3951+ offsetof(ngx_http_lua_main_conf_t, set_sa_restart),
3952+ NULL },
3953+
3954 #if (NGX_PCRE)
3955 { ngx_string("lua_regex_cache_max_entries"),
3956 NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
3957@@ -635,9 +653,19 @@ ngx_http_lua_init(ngx_conf_t *cf)
3958 #if !defined(NGX_LUA_NO_FFI_API) || nginx_version >= 1011011
3959 ngx_pool_cleanup_t *cln;
3960 #endif
3961+ ngx_str_t name = ngx_string("host");
3962+
3963+ if (ngx_process == NGX_PROCESS_SIGNALLER || ngx_test_config) {
3964+ return NGX_OK;
3965+ }
3966
3967 lmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_lua_module);
3968
3969+ lmcf->host_var_index = ngx_http_get_variable_index(cf, &name);
3970+ if (lmcf->host_var_index == NGX_ERROR) {
3971+ return NGX_ERROR;
3972+ }
3973+
3974 if (ngx_http_lua_prev_cycle != ngx_cycle) {
3975 ngx_http_lua_prev_cycle = ngx_cycle;
3976 multi_http_blocks = 0;
3977@@ -722,6 +750,11 @@ ngx_http_lua_init(ngx_conf_t *cf)
3978
3979 cln->data = lmcf;
3980 cln->handler = ngx_http_lua_sema_mm_cleanup;
3981+
3982+#ifdef HAVE_NGX_LUA_PIPE
3983+ ngx_http_lua_pipe_init();
3984+#endif
3985+
3986 #endif
3987
3988 #if nginx_version >= 1011011
3989@@ -737,6 +770,19 @@ ngx_http_lua_init(ngx_conf_t *cf)
3990 if (lmcf->lua == NULL) {
3991 dd("initializing lua vm");
3992
3993+#ifndef OPENRESTY_LUAJIT
3994+ if (ngx_process != NGX_PROCESS_SIGNALLER && !ngx_test_config) {
3995+ ngx_log_error(NGX_LOG_ALERT, cf->log, 0,
3996+ "detected a LuaJIT version which is not OpenResty's"
3997+ "; many optimizations will be disabled and "
3998+ "performance will be compromised (see "
3999+ "https://github.com/openresty/luajit2 for "
4000+ "OpenResty's LuaJIT or, even better, consider using "
4001+ "the OpenResty releases from https://openresty.org/"
4002+ "en/download.html)");
4003+ }
4004+#endif
4005+
4006 ngx_http_lua_content_length_hash =
4007 ngx_http_lua_hash_literal("content-length");
4008 ngx_http_lua_location_hash = ngx_http_lua_hash_literal("location");
4009@@ -838,6 +884,7 @@ ngx_http_lua_create_main_conf(ngx_conf_t *cf)
4010 */
4011
4012 lmcf->pool = cf->pool;
4013+ lmcf->load_resty_core = NGX_CONF_UNSET;
4014 lmcf->max_pending_timers = NGX_CONF_UNSET;
4015 lmcf->max_running_timers = NGX_CONF_UNSET;
4016 #if (NGX_PCRE)
4017@@ -847,6 +894,8 @@ ngx_http_lua_create_main_conf(ngx_conf_t *cf)
4018 lmcf->postponed_to_rewrite_phase_end = NGX_CONF_UNSET;
4019 lmcf->postponed_to_access_phase_end = NGX_CONF_UNSET;
4020
4021+ lmcf->set_sa_restart = NGX_CONF_UNSET;
4022+
4023 #if (NGX_HTTP_LUA_HAVE_MALLOC_TRIM)
4024 lmcf->malloc_trim_cycle = NGX_CONF_UNSET_UINT;
4025 #endif
4026@@ -869,6 +918,10 @@ ngx_http_lua_init_main_conf(ngx_conf_t *cf, void *conf)
4027 {
4028 ngx_http_lua_main_conf_t *lmcf = conf;
4029
4030+ if (lmcf->load_resty_core == NGX_CONF_UNSET) {
4031+ lmcf->load_resty_core = 1;
4032+ }
4033+
4034 #if (NGX_PCRE)
4035 if (lmcf->regex_cache_max_entries == NGX_CONF_UNSET) {
4036 lmcf->regex_cache_max_entries = 1024;
4037@@ -887,6 +940,12 @@ ngx_http_lua_init_main_conf(ngx_conf_t *cf, void *conf)
4038 lmcf->max_running_timers = 256;
4039 }
4040
4041+#if (NGX_HTTP_LUA_HAVE_SA_RESTART)
4042+ if (lmcf->set_sa_restart == NGX_CONF_UNSET) {
4043+ lmcf->set_sa_restart = 1;
4044+ }
4045+#endif
4046+
4047 #if (NGX_HTTP_LUA_HAVE_MALLOC_TRIM)
4048 if (lmcf->malloc_trim_cycle == NGX_CONF_UNSET_UINT) {
4049 lmcf->malloc_trim_cycle = 1000; /* number of reqs */
4050diff --git a/debian/modules/http-lua/src/ngx_http_lua_ndk.c b/debian/modules/http-lua/src/ngx_http_lua_ndk.c
4051index 24b80b4..6344183 100644
4052--- a/debian/modules/http-lua/src/ngx_http_lua_ndk.c
4053+++ b/debian/modules/http-lua/src/ngx_http_lua_ndk.c
4054@@ -186,6 +186,47 @@ ngx_http_lua_inject_ndk_api(lua_State *L)
4055 }
4056
4057
4058+int
4059+ngx_http_lua_ffi_ndk_lookup_directive(const u_char *var_data,
4060+ size_t var_len, ndk_set_var_value_pt *func)
4061+{
4062+ *func = ngx_http_lookup_ndk_set_var_directive((u_char *) var_data, var_len);
4063+
4064+ if (*func == NULL) {
4065+ return NGX_ERROR;
4066+ }
4067+
4068+ return NGX_OK;
4069+}
4070+
4071+
4072+int
4073+ngx_http_lua_ffi_ndk_set_var_get(ngx_http_request_t *r,
4074+ ndk_set_var_value_pt func, const u_char *arg_data, size_t arg_len,
4075+ ngx_http_lua_ffi_str_t *value)
4076+{
4077+ ngx_int_t rc;
4078+ ngx_str_t res;
4079+ ngx_http_variable_value_t arg;
4080+
4081+ ngx_memzero(&arg, sizeof(ngx_http_variable_value_t));
4082+ arg.valid = 1;
4083+
4084+ arg.data = (u_char *) arg_data;
4085+ arg.len = arg_len;
4086+
4087+ rc = func(r, &res, &arg);
4088+
4089+ if (rc != NGX_OK) {
4090+ return rc;
4091+ }
4092+
4093+ value->data = res.data;
4094+ value->len = res.len;
4095+ return NGX_OK;
4096+}
4097+
4098+
4099 #endif /* defined(NDK) && NDK */
4100
4101 /* vi:set ft=c ts=4 sw=4 et fdm=marker: */
4102diff --git a/debian/modules/http-lua/src/ngx_http_lua_phase.c b/debian/modules/http-lua/src/ngx_http_lua_phase.c
4103index 50c5311..304c88a 100644
4104--- a/debian/modules/http-lua/src/ngx_http_lua_phase.c
4105+++ b/debian/modules/http-lua/src/ngx_http_lua_phase.c
4106@@ -107,4 +107,22 @@ ngx_http_lua_inject_phase_api(lua_State *L)
4107 lua_setfield(L, -2, "get_phase");
4108 }
4109
4110+
4111+#ifndef NGX_LUA_NO_FFI_API
4112+int
4113+ngx_http_lua_ffi_get_phase(ngx_http_request_t *r, char **err)
4114+{
4115+ ngx_http_lua_ctx_t *ctx;
4116+
4117+ ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
4118+ if (ctx == NULL) {
4119+ *err = "no request context";
4120+ return NGX_ERROR;
4121+ }
4122+
4123+ return ctx->context;
4124+}
4125+#endif
4126+
4127+
4128 /* vi:set ft=c ts=4 sw=4 et fdm=marker: */
4129diff --git a/debian/modules/http-lua/src/ngx_http_lua_pipe.c b/debian/modules/http-lua/src/ngx_http_lua_pipe.c
4130new file mode 100644
4131index 0000000..8c8221f
4132--- /dev/null
4133+++ b/debian/modules/http-lua/src/ngx_http_lua_pipe.c
4134@@ -0,0 +1,2475 @@
4135+
4136+/*
4137+ * Copyright (C) by OpenResty Inc.
4138+ */
4139+
4140+
4141+#ifndef DDEBUG
4142+#define DDEBUG 0
4143+#endif
4144+#include "ddebug.h"
4145+
4146+
4147+#include "ngx_http_lua_common.h"
4148+#include "ngx_http_lua_input_filters.h"
4149+#include "ngx_http_lua_util.h"
4150+#include "ngx_http_lua_pipe.h"
4151+#if (NGX_HTTP_LUA_HAVE_SIGNALFD)
4152+#include <sys/signalfd.h>
4153+#endif
4154+
4155+
4156+#ifdef HAVE_NGX_LUA_PIPE
4157+static ngx_rbtree_node_t *ngx_http_lua_pipe_lookup_pid(ngx_rbtree_key_t key);
4158+#if !(NGX_HTTP_LUA_HAVE_SIGNALFD)
4159+static void ngx_http_lua_pipe_sigchld_handler(int signo, siginfo_t *siginfo,
4160+ void *ucontext);
4161+#endif
4162+static void ngx_http_lua_pipe_sigchld_event_handler(ngx_event_t *ev);
4163+static ssize_t ngx_http_lua_pipe_fd_read(ngx_connection_t *c, u_char *buf,
4164+ size_t size);
4165+static ssize_t ngx_http_lua_pipe_fd_write(ngx_connection_t *c, u_char *buf,
4166+ size_t size);
4167+static ngx_int_t ngx_http_lua_pipe_close_helper(
4168+ ngx_http_lua_pipe_ctx_t *pipe_ctx, ngx_event_t *ev, int forced);
4169+static ngx_int_t ngx_http_lua_pipe_close_stdin(ngx_http_lua_pipe_t *pipe,
4170+ int forced);
4171+static ngx_int_t ngx_http_lua_pipe_close_stdout(ngx_http_lua_pipe_t *pipe,
4172+ int forced);
4173+static ngx_int_t ngx_http_lua_pipe_close_stderr(ngx_http_lua_pipe_t *pipe,
4174+ int forced);
4175+static void ngx_http_lua_pipe_proc_finalize(ngx_http_lua_ffi_pipe_proc_t *proc,
4176+ int forced);
4177+static ngx_int_t ngx_http_lua_pipe_get_lua_ctx(ngx_http_request_t *r,
4178+ ngx_http_lua_ctx_t **ctx, u_char *errbuf, size_t *errbuf_size);
4179+static void ngx_http_lua_pipe_put_error(ngx_http_lua_pipe_ctx_t *pipe_ctx,
4180+ u_char *errbuf, size_t *errbuf_size);
4181+static void ngx_http_lua_pipe_put_data(ngx_http_lua_pipe_t *pipe,
4182+ ngx_http_lua_pipe_ctx_t *pipe_ctx, u_char **buf, size_t *buf_size);
4183+static ngx_int_t ngx_http_lua_pipe_add_input_buffer(ngx_http_lua_pipe_t *pipe,
4184+ ngx_http_lua_pipe_ctx_t *pipe_ctx);
4185+static ngx_int_t ngx_http_lua_pipe_read_all(void *data, ssize_t bytes);
4186+static ngx_int_t ngx_http_lua_pipe_read_bytes(void *data, ssize_t bytes);
4187+static ngx_int_t ngx_http_lua_pipe_read_line(void *data, ssize_t bytes);
4188+static ngx_int_t ngx_http_lua_pipe_read_any(void *data, ssize_t bytes);
4189+static ngx_int_t ngx_http_lua_pipe_read(ngx_http_lua_pipe_t *pipe,
4190+ ngx_http_lua_pipe_ctx_t *pipe_ctx);
4191+static ngx_int_t ngx_http_lua_pipe_init_ctx(
4192+ ngx_http_lua_pipe_ctx_t **pipe_ctx_pt, int fd, ngx_pool_t *pool,
4193+ u_char *errbuf, size_t *errbuf_size);
4194+static ngx_int_t ngx_http_lua_pipe_write(ngx_http_lua_pipe_t *pipe,
4195+ ngx_http_lua_pipe_ctx_t *pipe_ctx);
4196+static int ngx_http_lua_pipe_read_stdout_retval(
4197+ ngx_http_lua_ffi_pipe_proc_t *proc, lua_State *L);
4198+static int ngx_http_lua_pipe_read_stderr_retval(
4199+ ngx_http_lua_ffi_pipe_proc_t *proc, lua_State *L);
4200+static int ngx_http_lua_pipe_read_retval_helper(
4201+ ngx_http_lua_ffi_pipe_proc_t *proc, lua_State *L, int from_stderr);
4202+static int ngx_http_lua_pipe_write_retval(ngx_http_lua_ffi_pipe_proc_t *proc,
4203+ lua_State *L);
4204+static int ngx_http_lua_pipe_wait_retval(ngx_http_lua_ffi_pipe_proc_t *proc,
4205+ lua_State *L);
4206+static void ngx_http_lua_pipe_resume_helper(ngx_event_t *ev,
4207+ ngx_http_lua_co_ctx_t *wait_co_ctx);
4208+static void ngx_http_lua_pipe_resume_read_stdout_handler(ngx_event_t *ev);
4209+static void ngx_http_lua_pipe_resume_read_stderr_handler(ngx_event_t *ev);
4210+static void ngx_http_lua_pipe_resume_write_handler(ngx_event_t *ev);
4211+static void ngx_http_lua_pipe_resume_wait_handler(ngx_event_t *ev);
4212+static ngx_int_t ngx_http_lua_pipe_resume(ngx_http_request_t *r);
4213+static void ngx_http_lua_pipe_dummy_event_handler(ngx_event_t *ev);
4214+static void ngx_http_lua_pipe_clear_event(ngx_event_t *ev);
4215+static void ngx_http_lua_pipe_proc_read_stdout_cleanup(void *data);
4216+static void ngx_http_lua_pipe_proc_read_stderr_cleanup(void *data);
4217+static void ngx_http_lua_pipe_proc_write_cleanup(void *data);
4218+static void ngx_http_lua_pipe_proc_wait_cleanup(void *data);
4219+
4220+
4221+static ngx_rbtree_t ngx_http_lua_pipe_rbtree;
4222+static ngx_rbtree_node_t ngx_http_lua_pipe_proc_sentinel;
4223+
4224+
4225+#if (NGX_HTTP_LUA_HAVE_SIGNALFD)
4226+static int ngx_http_lua_signalfd;
4227+static struct signalfd_siginfo ngx_http_lua_pipe_notification;
4228+
4229+#define ngx_http_lua_read_sigfd ngx_http_lua_signalfd
4230+
4231+#else
4232+static int ngx_http_lua_sigchldfd[2];
4233+static u_char ngx_http_lua_pipe_notification[1];
4234+
4235+#define ngx_http_lua_read_sigfd ngx_http_lua_sigchldfd[0]
4236+#define ngx_http_lua_write_sigfd ngx_http_lua_sigchldfd[1]
4237+#endif
4238+
4239+
4240+static ngx_connection_t *ngx_http_lua_sigfd_conn = NULL;
4241+
4242+
4243+/* The below signals are ignored by Nginx.
4244+ * We need to reset them for the spawned child processes. */
4245+ngx_http_lua_pipe_signal_t ngx_signals[] = {
4246+ { SIGSYS, "SIGSYS" },
4247+ { SIGPIPE, "SIGPIPE" },
4248+ { 0, NULL }
4249+};
4250+
4251+
4252+enum {
4253+ PIPE_ERR_CLOSED = 1,
4254+ PIPE_ERR_SYSCALL,
4255+ PIPE_ERR_NOMEM,
4256+ PIPE_ERR_TIMEOUT,
4257+ PIPE_ERR_ADD_READ_EV,
4258+ PIPE_ERR_ADD_WRITE_EV
4259+};
4260+
4261+
4262+enum {
4263+ PIPE_READ_ALL = 0,
4264+ PIPE_READ_BYTES,
4265+ PIPE_READ_LINE,
4266+ PIPE_READ_ANY
4267+};
4268+
4269+
4270+#define REASON_EXIT "exit"
4271+#define REASON_SIGNAL "signal"
4272+#define REASON_UNKNOWN "unknown"
4273+
4274+#define REASON_RUNNING_CODE 0
4275+#define REASON_EXIT_CODE 1
4276+#define REASON_SIGNAL_CODE 2
4277+#define REASON_UNKNOWN_CODE 3
4278+
4279+
4280+void
4281+ngx_http_lua_pipe_init(void)
4282+{
4283+ ngx_rbtree_init(&ngx_http_lua_pipe_rbtree,
4284+ &ngx_http_lua_pipe_proc_sentinel, ngx_rbtree_insert_value);
4285+}
4286+
4287+
4288+ngx_int_t
4289+ngx_http_lua_pipe_add_signal_handler(ngx_cycle_t *cycle)
4290+{
4291+ ngx_event_t *rev;
4292+#if (NGX_HTTP_LUA_HAVE_SIGNALFD)
4293+ sigset_t set;
4294+
4295+#else
4296+ int rc;
4297+ struct sigaction sa;
4298+#endif
4299+
4300+#if (NGX_HTTP_LUA_HAVE_SIGNALFD)
4301+ if (sigemptyset(&set) != 0) {
4302+ ngx_log_error(NGX_LOG_ERR, cycle->log, ngx_errno,
4303+ "lua pipe init signal set failed");
4304+ return NGX_ERROR;
4305+ }
4306+
4307+ if (sigaddset(&set, SIGCHLD) != 0) {
4308+ ngx_log_error(NGX_LOG_ERR, cycle->log, ngx_errno,
4309+ "lua pipe add SIGCHLD to signal set failed");
4310+ return NGX_ERROR;
4311+ }
4312+
4313+ if (sigprocmask(SIG_BLOCK, &set, NULL) != 0) {
4314+ ngx_log_error(NGX_LOG_ERR, cycle->log, ngx_errno,
4315+ "lua pipe block SIGCHLD failed");
4316+ return NGX_ERROR;
4317+ }
4318+
4319+ ngx_http_lua_signalfd = signalfd(-1, &set, SFD_NONBLOCK|SFD_CLOEXEC);
4320+ if (ngx_http_lua_signalfd < 0) {
4321+ ngx_log_error(NGX_LOG_ERR, cycle->log, ngx_errno,
4322+ "lua pipe create signalfd instance failed");
4323+ return NGX_ERROR;
4324+ }
4325+
4326+#else /* !(NGX_HTTP_LUA_HAVE_SIGNALFD) */
4327+# if (NGX_HTTP_LUA_HAVE_PIPE2)
4328+ rc = pipe2(ngx_http_lua_sigchldfd, O_NONBLOCK|O_CLOEXEC);
4329+# else
4330+ rc = pipe(ngx_http_lua_sigchldfd);
4331+# endif
4332+
4333+ if (rc == -1) {
4334+ ngx_log_error(NGX_LOG_ERR, cycle->log, ngx_errno,
4335+ "lua pipe init SIGCHLD fd failed");
4336+ return NGX_ERROR;
4337+ }
4338+
4339+# if !(NGX_HTTP_LUA_HAVE_PIPE2)
4340+ if (ngx_nonblocking(ngx_http_lua_read_sigfd) == -1) {
4341+ ngx_log_error(NGX_LOG_ERR, cycle->log, ngx_errno, "lua pipe "
4342+ ngx_nonblocking_n " SIGCHLD read fd failed");
4343+ goto failed;
4344+ }
4345+
4346+ if (ngx_nonblocking(ngx_http_lua_write_sigfd) == -1) {
4347+ ngx_log_error(NGX_LOG_ERR, cycle->log, ngx_errno, "lua pipe "
4348+ ngx_nonblocking_n " SIGCHLD write fd failed");
4349+ goto failed;
4350+ }
4351+
4352+ /* it's ok not to set the pipe fd with O_CLOEXEC. This requires
4353+ * extra syscall */
4354+# endif /* !(NGX_HTTP_LUA_HAVE_PIPE2) */
4355+#endif /* NGX_HTTP_LUA_HAVE_SIGNALFD */
4356+
4357+ ngx_http_lua_sigfd_conn = ngx_get_connection(ngx_http_lua_read_sigfd,
4358+ cycle->log);
4359+ if (ngx_http_lua_sigfd_conn == NULL) {
4360+ goto failed;
4361+ }
4362+
4363+ ngx_http_lua_sigfd_conn->log = cycle->log;
4364+ ngx_http_lua_sigfd_conn->recv = ngx_http_lua_pipe_fd_read;
4365+ rev = ngx_http_lua_sigfd_conn->read;
4366+ rev->log = ngx_http_lua_sigfd_conn->log;
4367+ rev->handler = ngx_http_lua_pipe_sigchld_event_handler;
4368+
4369+#ifdef HAVE_SOCKET_CLOEXEC_PATCH
4370+ rev->skip_socket_leak_check = 1;
4371+#endif
4372+
4373+ if (ngx_handle_read_event(rev, 0) == NGX_ERROR) {
4374+ goto failed;
4375+ }
4376+
4377+#if !(NGX_HTTP_LUA_HAVE_SIGNALFD)
4378+ ngx_memzero(&sa, sizeof(struct sigaction));
4379+ sa.sa_sigaction = ngx_http_lua_pipe_sigchld_handler;
4380+ sa.sa_flags = SA_SIGINFO;
4381+
4382+ if (sigemptyset(&sa.sa_mask) != 0) {
4383+ ngx_log_error(NGX_LOG_ERR, cycle->log, ngx_errno,
4384+ "lua pipe init signal mask failed");
4385+ goto failed;
4386+ }
4387+
4388+ if (sigaction(SIGCHLD, &sa, NULL) == -1) {
4389+ ngx_log_error(NGX_LOG_ERR, cycle->log, ngx_errno,
4390+ "lua pipe sigaction(SIGCHLD) failed");
4391+ goto failed;
4392+ }
4393+#endif
4394+
4395+ return NGX_OK;
4396+
4397+failed:
4398+
4399+ if (ngx_http_lua_sigfd_conn != NULL) {
4400+ ngx_close_connection(ngx_http_lua_sigfd_conn);
4401+ ngx_http_lua_sigfd_conn = NULL;
4402+ }
4403+
4404+ if (close(ngx_http_lua_read_sigfd) == -1) {
4405+ ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
4406+ "lua pipe close the read sigfd failed");
4407+ }
4408+
4409+#if !(NGX_HTTP_LUA_HAVE_SIGNALFD)
4410+ if (close(ngx_http_lua_write_sigfd) == -1) {
4411+ ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
4412+ "lua pipe close the write sigfd failed");
4413+ }
4414+#endif
4415+
4416+ return NGX_ERROR;
4417+}
4418+
4419+
4420+static ngx_rbtree_node_t *
4421+ngx_http_lua_pipe_lookup_pid(ngx_rbtree_key_t key)
4422+{
4423+ ngx_rbtree_node_t *node, *sentinel;
4424+
4425+ node = ngx_http_lua_pipe_rbtree.root;
4426+ sentinel = ngx_http_lua_pipe_rbtree.sentinel;
4427+
4428+ while (node != sentinel) {
4429+ if (key < node->key) {
4430+ node = node->left;
4431+ continue;
4432+ }
4433+
4434+ if (key > node->key) {
4435+ node = node->right;
4436+ continue;
4437+ }
4438+
4439+ return node;
4440+ }
4441+
4442+ return NULL;
4443+}
4444+
4445+
4446+#if !(NGX_HTTP_LUA_HAVE_SIGNALFD)
4447+static void
4448+ngx_http_lua_pipe_sigchld_handler(int signo, siginfo_t *siginfo,
4449+ void *ucontext)
4450+{
4451+ ngx_err_t err, saved_err;
4452+ ngx_int_t n;
4453+
4454+ saved_err = ngx_errno;
4455+
4456+ for ( ;; ) {
4457+ n = write(ngx_http_lua_write_sigfd, ngx_http_lua_pipe_notification,
4458+ sizeof(ngx_http_lua_pipe_notification));
4459+
4460+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0,
4461+ "lua pipe SIGCHLD fd write siginfo:%p", siginfo);
4462+
4463+ if (n >= 0) {
4464+ break;
4465+ }
4466+
4467+ err = ngx_errno;
4468+
4469+ if (err != NGX_EINTR) {
4470+ if (err != NGX_EAGAIN) {
4471+ ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, err,
4472+ "lua pipe SIGCHLD fd write failed");
4473+ }
4474+
4475+ break;
4476+ }
4477+
4478+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, err,
4479+ "lua pipe SIGCHLD fd write was interrupted");
4480+ }
4481+
4482+ ngx_set_errno(saved_err);
4483+}
4484+#endif
4485+
4486+
4487+static void
4488+ngx_http_lua_pipe_sigchld_event_handler(ngx_event_t *ev)
4489+{
4490+ int n;
4491+ int status;
4492+ ngx_pid_t pid;
4493+ ngx_connection_t *c = ev->data;
4494+ ngx_rbtree_node_t *node;
4495+ ngx_http_lua_pipe_node_t *pipe_node;
4496+
4497+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0,
4498+ "lua pipe reaping children");
4499+
4500+ for ( ;; ) {
4501+#if (NGX_HTTP_LUA_HAVE_SIGNALFD)
4502+ n = c->recv(c, (u_char *) &ngx_http_lua_pipe_notification,
4503+#else
4504+ n = c->recv(c, ngx_http_lua_pipe_notification,
4505+#endif
4506+ sizeof(ngx_http_lua_pipe_notification));
4507+
4508+ if (n <= 0) {
4509+ if (n == NGX_ERROR) {
4510+ ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, ngx_errno,
4511+ "lua pipe SIGCHLD fd read failed");
4512+ }
4513+
4514+ break;
4515+ }
4516+
4517+ for ( ;; ) {
4518+ pid = waitpid(-1, &status, WNOHANG);
4519+
4520+ if (pid == 0) {
4521+ break;
4522+ }
4523+
4524+ if (pid < 0) {
4525+ if (ngx_errno != NGX_ECHILD) {
4526+ ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, ngx_errno,
4527+ "lua pipe waitpid failed");
4528+ }
4529+
4530+ break;
4531+ }
4532+
4533+ /* This log is ported from Nginx's signal handler since we override
4534+ * or block it in this implementation. */
4535+ ngx_log_error(NGX_LOG_NOTICE, ngx_cycle->log, 0,
4536+ "signal %d (SIGCHLD) received from %P",
4537+ SIGCHLD, pid);
4538+
4539+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
4540+ "lua pipe SIGCHLD fd read pid:%P status:%d", pid,
4541+ status);
4542+
4543+ node = ngx_http_lua_pipe_lookup_pid(pid);
4544+ if (node != NULL) {
4545+ pipe_node = (ngx_http_lua_pipe_node_t *) &node->color;
4546+ if (pipe_node->wait_co_ctx != NULL) {
4547+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
4548+ "lua pipe resume process:%p waiting for %P",
4549+ pipe_node->proc, pid);
4550+
4551+ /*
4552+ * We need the extra parentheses around the first argument
4553+ * of ngx_post_event() just to work around macro issues in
4554+ * nginx cores older than 1.7.12 (exclusive).
4555+ */
4556+ ngx_post_event((&pipe_node->wait_co_ctx->sleep),
4557+ &ngx_posted_events);
4558+ }
4559+
4560+ pipe_node->proc->pipe->dead = 1;
4561+
4562+ if (WIFSIGNALED(status)) {
4563+ pipe_node->status = WTERMSIG(status);
4564+ pipe_node->reason_code = REASON_SIGNAL_CODE;
4565+
4566+ } else if (WIFEXITED(status)) {
4567+ pipe_node->status = WEXITSTATUS(status);
4568+ pipe_node->reason_code = REASON_EXIT_CODE;
4569+
4570+ } else {
4571+ ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, 0,
4572+ "lua pipe unknown exit status %d from "
4573+ "process %P", status, pid);
4574+ pipe_node->status = status;
4575+ pipe_node->reason_code = REASON_UNKNOWN_CODE;
4576+ }
4577+ }
4578+ }
4579+ }
4580+}
4581+
4582+
4583+static ssize_t
4584+ngx_http_lua_pipe_fd_read(ngx_connection_t *c, u_char *buf, size_t size)
4585+{
4586+ ssize_t n;
4587+ ngx_err_t err;
4588+ ngx_event_t *rev;
4589+
4590+ rev = c->read;
4591+
4592+ do {
4593+ n = read(c->fd, buf, size);
4594+
4595+ err = ngx_errno;
4596+
4597+ ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
4598+ "read: fd:%d %z of %uz", c->fd, n, size);
4599+
4600+ if (n == 0) {
4601+ rev->ready = 0;
4602+ rev->eof = 1;
4603+ return 0;
4604+ }
4605+
4606+ if (n > 0) {
4607+ if ((size_t) n < size
4608+ && !(ngx_event_flags & NGX_USE_GREEDY_EVENT))
4609+ {
4610+ rev->ready = 0;
4611+ }
4612+
4613+ return n;
4614+ }
4615+
4616+ if (err == NGX_EAGAIN || err == NGX_EINTR) {
4617+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
4618+ "read() not ready");
4619+ n = NGX_AGAIN;
4620+
4621+ } else {
4622+ n = ngx_connection_error(c, err, "read() failed");
4623+ break;
4624+ }
4625+
4626+ } while (err == NGX_EINTR);
4627+
4628+ rev->ready = 0;
4629+
4630+ if (n == NGX_ERROR) {
4631+ rev->error = 1;
4632+ }
4633+
4634+ return n;
4635+}
4636+
4637+
4638+static ssize_t
4639+ngx_http_lua_pipe_fd_write(ngx_connection_t *c, u_char *buf, size_t size)
4640+{
4641+ ssize_t n;
4642+ ngx_err_t err;
4643+ ngx_event_t *wev;
4644+
4645+ wev = c->write;
4646+
4647+ do {
4648+ n = write(c->fd, buf, size);
4649+
4650+ ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0,
4651+ "write: fd:%d %z of %uz", c->fd, n, size);
4652+
4653+ if (n >= 0) {
4654+ if ((size_t) n != size) {
4655+ wev->ready = 0;
4656+ }
4657+
4658+ return n;
4659+ }
4660+
4661+ err = ngx_errno;
4662+
4663+ if (err == NGX_EAGAIN || err == NGX_EINTR) {
4664+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
4665+ "write() not ready");
4666+ n = NGX_AGAIN;
4667+
4668+ } else if (err != NGX_EPIPE) {
4669+ n = ngx_connection_error(c, err, "write() failed");
4670+ break;
4671+ }
4672+
4673+ } while (err == NGX_EINTR);
4674+
4675+ wev->ready = 0;
4676+
4677+ if (n == NGX_ERROR) {
4678+ wev->error = 1;
4679+ }
4680+
4681+ return n;
4682+}
4683+
4684+
4685+int
4686+ngx_http_lua_ffi_pipe_spawn(ngx_http_lua_ffi_pipe_proc_t *proc,
4687+ const char *file, const char **argv, int merge_stderr, size_t buffer_size,
4688+ u_char *errbuf, size_t *errbuf_size)
4689+{
4690+ int rc;
4691+ int in[2];
4692+ int out[2];
4693+ int err[2];
4694+ int stdin_fd, stdout_fd, stderr_fd;
4695+ int errlog_fd, temp_errlog_fd;
4696+ ngx_pid_t pid;
4697+ ssize_t pool_size;
4698+ ngx_pool_t *pool;
4699+ ngx_uint_t i;
4700+ ngx_listening_t *ls;
4701+ ngx_http_lua_pipe_t *pp;
4702+ ngx_rbtree_node_t *node;
4703+ ngx_http_lua_pipe_node_t *pipe_node;
4704+ struct sigaction sa;
4705+ ngx_http_lua_pipe_signal_t *sig;
4706+ sigset_t set;
4707+
4708+ pool_size = ngx_align(NGX_MIN_POOL_SIZE + buffer_size * 2,
4709+ NGX_POOL_ALIGNMENT);
4710+
4711+ pool = ngx_create_pool(pool_size, ngx_cycle->log);
4712+ if (pool == NULL) {
4713+ *errbuf_size = ngx_snprintf(errbuf, *errbuf_size, "no memory")
4714+ - errbuf;
4715+ return NGX_ERROR;
4716+ }
4717+
4718+ pp = ngx_pcalloc(pool, sizeof(ngx_http_lua_pipe_t)
4719+ + offsetof(ngx_rbtree_node_t, color)
4720+ + sizeof(ngx_http_lua_pipe_node_t));
4721+ if (pp == NULL) {
4722+ *errbuf_size = ngx_snprintf(errbuf, *errbuf_size, "no memory")
4723+ - errbuf;
4724+ goto free_pool;
4725+ }
4726+
4727+ rc = pipe(in);
4728+ if (rc == -1) {
4729+ *errbuf_size = ngx_snprintf(errbuf, *errbuf_size, "pipe failed: %s",
4730+ strerror(errno))
4731+ - errbuf;
4732+ goto free_pool;
4733+ }
4734+
4735+ rc = pipe(out);
4736+ if (rc == -1) {
4737+ *errbuf_size = ngx_snprintf(errbuf, *errbuf_size, "pipe failed: %s",
4738+ strerror(errno))
4739+ - errbuf;
4740+ goto close_in_fd;
4741+ }
4742+
4743+ if (!merge_stderr) {
4744+ rc = pipe(err);
4745+ if (rc == -1) {
4746+ *errbuf_size = ngx_snprintf(errbuf, *errbuf_size,
4747+ "pipe failed: %s", strerror(errno))
4748+ - errbuf;
4749+ goto close_in_out_fd;
4750+ }
4751+ }
4752+
4753+ pid = fork();
4754+ if (pid == -1) {
4755+ *errbuf_size = ngx_snprintf(errbuf, *errbuf_size, "fork failed: %s",
4756+ strerror(errno))
4757+ - errbuf;
4758+ goto close_in_out_err_fd;
4759+ }
4760+
4761+ if (pid == 0) {
4762+
4763+#if (NGX_HAVE_CPU_AFFINITY)
4764+ /* reset the CPU affinity mask */
4765+ ngx_uint_t log_level;
4766+ ngx_cpuset_t child_cpu_affinity;
4767+
4768+ if (ngx_process == NGX_PROCESS_WORKER
4769+ && ngx_get_cpu_affinity(ngx_worker) != NULL)
4770+ {
4771+ CPU_ZERO(&child_cpu_affinity);
4772+
4773+ for (i = 0; i < (ngx_uint_t) ngx_min(ngx_ncpu, CPU_SETSIZE); i++) {
4774+ CPU_SET(i, &child_cpu_affinity);
4775+ }
4776+
4777+ log_level = ngx_cycle->log->log_level;
4778+ ngx_cycle->log->log_level = NGX_LOG_WARN;
4779+ ngx_setaffinity(&child_cpu_affinity, ngx_cycle->log);
4780+ ngx_cycle->log->log_level = log_level;
4781+ }
4782+#endif
4783+
4784+ /* reset the handler of ignored signals to the default */
4785+ for (sig = ngx_signals; sig->signo != 0; sig++) {
4786+ ngx_memzero(&sa, sizeof(struct sigaction));
4787+ sa.sa_handler = SIG_DFL;
4788+
4789+ if (sigemptyset(&sa.sa_mask) != 0) {
4790+ ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, ngx_errno,
4791+ "lua pipe child init signal mask failed");
4792+ exit(EXIT_FAILURE);
4793+ }
4794+
4795+ if (sigaction(sig->signo, &sa, NULL) == -1) {
4796+ ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, ngx_errno,
4797+ "lua pipe child reset signal handler for %s "
4798+ "failed", sig->signame);
4799+ exit(EXIT_FAILURE);
4800+ }
4801+ }
4802+
4803+ /* reset signal mask */
4804+ if (sigemptyset(&set) != 0) {
4805+ ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, ngx_errno,
4806+ "lua pipe child init signal set failed");
4807+ exit(EXIT_FAILURE);
4808+ }
4809+
4810+ if (sigprocmask(SIG_SETMASK, &set, NULL) != 0) {
4811+ ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, ngx_errno,
4812+ "lua pipe child reset signal mask failed");
4813+ exit(EXIT_FAILURE);
4814+ }
4815+
4816+ /* close listening socket fd */
4817+ ls = ngx_cycle->listening.elts;
4818+ for (i = 0; i < ngx_cycle->listening.nelts; i++) {
4819+ if (ngx_close_socket(ls[i].fd) == -1) {
4820+ ngx_log_error(NGX_LOG_EMERG, ngx_cycle->log, ngx_socket_errno,
4821+ "lua pipe child " ngx_close_socket_n
4822+ " %V failed", &ls[i].addr_text);
4823+ }
4824+ }
4825+
4826+ /* close and dup pipefd */
4827+ if (close(in[1]) == -1) {
4828+ ngx_log_error(NGX_LOG_EMERG, ngx_cycle->log, ngx_errno,
4829+ "lua pipe child failed to close the in[1] "
4830+ "pipe fd");
4831+ }
4832+
4833+ if (close(out[0]) == -1) {
4834+ ngx_log_error(NGX_LOG_EMERG, ngx_cycle->log, ngx_errno,
4835+ "lua pipe child failed to close the out[0] "
4836+ "pipe fd");
4837+ }
4838+
4839+ if (ngx_cycle->log->file && ngx_cycle->log->file->fd == STDERR_FILENO) {
4840+ errlog_fd = ngx_cycle->log->file->fd;
4841+ temp_errlog_fd = dup(errlog_fd);
4842+
4843+ if (temp_errlog_fd == -1) {
4844+ ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, ngx_errno,
4845+ "lua pipe child dup errlog fd failed");
4846+ exit(EXIT_FAILURE);
4847+ }
4848+
4849+ if (ngx_cloexec(temp_errlog_fd) == -1) {
4850+ ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, ngx_errno,
4851+ "lua pipe child new errlog fd " ngx_cloexec_n
4852+ " failed");
4853+ }
4854+
4855+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
4856+ "lua pipe child dup old errlog fd %d to new fd %d",
4857+ ngx_cycle->log->file->fd, temp_errlog_fd);
4858+
4859+ ngx_cycle->log->file->fd = temp_errlog_fd;
4860+ }
4861+
4862+ if (dup2(in[0], STDIN_FILENO) == -1) {
4863+ ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, ngx_errno,
4864+ "lua pipe child dup2 stdin failed");
4865+ exit(EXIT_FAILURE);
4866+ }
4867+
4868+ if (dup2(out[1], STDOUT_FILENO) == -1) {
4869+ ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, ngx_errno,
4870+ "lua pipe child dup2 stdout failed");
4871+ exit(EXIT_FAILURE);
4872+ }
4873+
4874+ if (merge_stderr) {
4875+ if (dup2(STDOUT_FILENO, STDERR_FILENO) == -1) {
4876+ ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, ngx_errno,
4877+ "lua pipe child dup2 stderr failed");
4878+ exit(EXIT_FAILURE);
4879+ }
4880+
4881+ } else {
4882+ if (close(err[0]) == -1) {
4883+ ngx_log_error(NGX_LOG_EMERG, ngx_cycle->log, ngx_errno,
4884+ "lua pipe child failed to close the err[0] "
4885+ "pipe fd");
4886+ }
4887+
4888+ if (dup2(err[1], STDERR_FILENO) == -1) {
4889+ ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, ngx_errno,
4890+ "lua pipe child dup2 stderr failed");
4891+ exit(EXIT_FAILURE);
4892+ }
4893+ }
4894+
4895+ if (execvp(file, (char * const *) argv) == -1) {
4896+ ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, ngx_errno,
4897+ "lua pipe child execvp() failed while executing %s",
4898+ file);
4899+ }
4900+
4901+ exit(EXIT_FAILURE);
4902+ }
4903+
4904+ /* parent process */
4905+ if (close(in[0]) == -1) {
4906+ ngx_log_error(NGX_LOG_EMERG, ngx_cycle->log, ngx_errno,
4907+ "lua pipe: failed to close the in[0] pipe fd");
4908+ }
4909+
4910+ stdin_fd = in[1];
4911+
4912+ if (ngx_nonblocking(stdin_fd) == -1) {
4913+ *errbuf_size = ngx_snprintf(errbuf, *errbuf_size,
4914+ ngx_nonblocking_n " failed: %s",
4915+ strerror(errno))
4916+ - errbuf;
4917+ goto close_in_out_err_fd;
4918+ }
4919+
4920+ pp->stdin_fd = stdin_fd;
4921+
4922+ if (close(out[1]) == -1) {
4923+ ngx_log_error(NGX_LOG_EMERG, ngx_cycle->log, ngx_errno,
4924+ "lua pipe: failed to close the out[1] pipe fd");
4925+ }
4926+
4927+ stdout_fd = out[0];
4928+
4929+ if (ngx_nonblocking(stdout_fd) == -1) {
4930+ *errbuf_size = ngx_snprintf(errbuf, *errbuf_size,
4931+ ngx_nonblocking_n " failed: %s",
4932+ strerror(errno))
4933+ - errbuf;
4934+ goto close_in_out_err_fd;
4935+ }
4936+
4937+ pp->stdout_fd = stdout_fd;
4938+
4939+ if (!merge_stderr) {
4940+ if (close(err[1]) == -1) {
4941+ ngx_log_error(NGX_LOG_EMERG, ngx_cycle->log, ngx_errno,
4942+ "lua pipe: failed to close the err[1] pipe fd");
4943+ }
4944+
4945+ stderr_fd = err[0];
4946+
4947+ if (ngx_nonblocking(stderr_fd) == -1) {
4948+ *errbuf_size = ngx_snprintf(errbuf, *errbuf_size,
4949+ ngx_nonblocking_n " failed: %s",
4950+ strerror(errno))
4951+ - errbuf;
4952+ goto close_in_out_err_fd;
4953+ }
4954+
4955+ pp->stderr_fd = stderr_fd;
4956+ }
4957+
4958+ node = (ngx_rbtree_node_t *) (pp + 1);
4959+ node->key = pid;
4960+ pipe_node = (ngx_http_lua_pipe_node_t *) &node->color;
4961+ pipe_node->proc = proc;
4962+ ngx_rbtree_insert(&ngx_http_lua_pipe_rbtree, node);
4963+
4964+ pp->node = node;
4965+ pp->pool = pool;
4966+ pp->merge_stderr = merge_stderr;
4967+ pp->buffer_size = buffer_size;
4968+
4969+ proc->_pid = pid;
4970+ proc->write_timeout = 10000;
4971+ proc->stdout_read_timeout = 10000;
4972+ proc->stderr_read_timeout = 10000;
4973+ proc->wait_timeout = 10000;
4974+ proc->pipe = pp;
4975+
4976+ ngx_log_debug4(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
4977+ "lua pipe spawn process:%p pid:%P merge_stderr:%d "
4978+ "buffer_size:%uz", proc, pid, merge_stderr, buffer_size);
4979+ return NGX_OK;
4980+
4981+close_in_out_err_fd:
4982+
4983+ if (!merge_stderr) {
4984+ if (close(err[0]) == -1) {
4985+ ngx_log_error(NGX_LOG_EMERG, ngx_cycle->log, ngx_errno,
4986+ "failed to close the err[0] pipe fd");
4987+ }
4988+
4989+ if (close(err[1]) == -1) {
4990+ ngx_log_error(NGX_LOG_EMERG, ngx_cycle->log, ngx_errno,
4991+ "failed to close the err[1] pipe fd");
4992+ }
4993+ }
4994+
4995+close_in_out_fd:
4996+
4997+ if (close(out[0]) == -1) {
4998+ ngx_log_error(NGX_LOG_EMERG, ngx_cycle->log, ngx_errno,
4999+ "failed to close the out[0] pipe fd");
5000+ }
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches