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

Proposed by Anton Tolchanov
Status: Needs review
Proposed branch: ~knyar/ubuntu/+source/nginx:lua-0.10.15
Merge into: ubuntu/+source/nginx:ubuntu/devel
Diff against target: 21182 lines (+9614/-1958)
157 files modified
debian/changelog (+6/-0)
debian/modules/control (+1/-1)
debian/modules/http-lua/README.markdown (+173/-62)
debian/modules/http-lua/config (+45/-0)
debian/modules/http-lua/doc/HttpLuaModule.wiki (+159/-54)
debian/modules/http-lua/src/api/ngx_http_lua_api.h (+1/-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_balancer.c (+3/-0)
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 (+43/-2)
debian/modules/http-lua/src/ngx_http_lua_common.h (+44/-5)
debian/modules/http-lua/src/ngx_http_lua_contentby.c (+2/-0)
debian/modules/http-lua/src/ngx_http_lua_control.c (+2/-1)
debian/modules/http-lua/src/ngx_http_lua_coroutine.c (+17/-1)
debian/modules/http-lua/src/ngx_http_lua_directive.c (+6/-5)
debian/modules/http-lua/src/ngx_http_lua_headerfilterby.c (+2/-1)
debian/modules/http-lua/src/ngx_http_lua_headers.c (+19/-64)
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 (+19/-0)
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_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 (+56/-0)
debian/modules/http-lua/src/ngx_http_lua_ndk.c (+41/-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_regex.c (+6/-4)
debian/modules/http-lua/src/ngx_http_lua_rewriteby.c (+3/-1)
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 (+22/-22)
debian/modules/http-lua/src/ngx_http_lua_socket_tcp.c (+1221/-571)
debian/modules/http-lua/src/ngx_http_lua_socket_tcp.h (+26/-3)
debian/modules/http-lua/src/ngx_http_lua_socket_udp.c (+8/-4)
debian/modules/http-lua/src/ngx_http_lua_ssl_certby.c (+2/-0)
debian/modules/http-lua/src/ngx_http_lua_ssl_session_fetchby.c (+2/-0)
debian/modules/http-lua/src/ngx_http_lua_ssl_session_storeby.c (+3/-0)
debian/modules/http-lua/src/ngx_http_lua_string.c (+14/-0)
debian/modules/http-lua/src/ngx_http_lua_subrequest.c (+8/-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 (+153/-15)
debian/modules/http-lua/src/ngx_http_lua_util.h (+27/-1)
debian/modules/http-lua/src/ngx_http_lua_worker.c (+11/-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 (+384/-120)
debian/modules/http-lua/t/017-exec.t (+2/-2)
debian/modules/http-lua/t/020-subrequest.t (+67/-67)
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/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 (+152/-22)
debian/modules/http-lua/t/027-multi-capture.t (+2/-2)
debian/modules/http-lua/t/028-req-header.t (+23/-1)
debian/modules/http-lua/t/030-uri-args.t (+15/-8)
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 (+10/-5)
debian/modules/http-lua/t/043-shdict.t (+2/-2)
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 (+338/-26)
debian/modules/http-lua/t/062-count.t (+26/-5)
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 (+6/-6)
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/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 (+6/-4)
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 (+8/-8)
debian/modules/http-lua/t/130-internal-api.t (+4/-13)
debian/modules/http-lua/t/134-worker-count-5.t (+2/-2)
debian/modules/http-lua/t/138-balancer.t (+0/-2)
debian/modules/http-lua/t/139-ssl-cert-by.t (+1/-1)
debian/modules/http-lua/t/140-ssl-c-api.t (+12/-11)
debian/modules/http-lua/t/143-ssl-session-fetch.t (+105/-0)
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/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/data/fake-shm-module/ngx_http_lua_fake_shm_module.c (+13/-9)
debian/modules/http-lua/util/build.sh (+3/-1)
debian/modules/patches/http-lua/disable-load_resty_core.patch (+20/-0)
debian/modules/patches/http-lua/series (+1/-0)
Reviewer Review Type Date Requested Status
Ubuntu Sponsors Team Pending
git-ubuntu developers Pending
Review via email: mp+393789@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.

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.

Unmerged commits

81039ef... by Anton Tolchanov

Update package to 1.18.0-6ubuntu5

e125c27... by Anton Tolchanov

http-lua: Upgrade to 0.10.15

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

5414012... by Matthias Klose

1.18.0-6ubuntu4 (patches unapplied)

Imported using git-ubuntu import.

3939b4a... by Matthias Klose

1.18.0-6ubuntu3 (patches unapplied)

Imported using git-ubuntu import.

864ebdb... by Andreas Hasenack

changelog

c369249... by Andreas Hasenack

  * d/control: make nginx and nginx-full arch any, so that nginx-full
    is no longer pulled into main because of i386 (LP: #1893267)

915e08e... by Andreas Hasenack

update-maintainer

a9788aa... by Andreas Hasenack

reconstruct-changelog

0cef115... by Andreas Hasenack

merge-changelogs

6ca5019... by Bryce Harrington

    - d/control: drop GeoIP from nginx-core due to demotion of libgeoip
      (LP #1861101, LP #1867150):
      + remove libnginx-mod-http-geoip from nginx-core dependency
      + have nginx-core depend on libnginx-mod-stream-geoip2
        instead of libnginx-mod-stream-geoip
      + adjust package descriptions accordingly

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

Subscribers

People subscribed via source and target branches