Merge ~paelzer/ubuntu/+source/nginx:lp-1874831-nchan-bump-lp-1893753-lua-FOCAL into ubuntu/+source/nginx:ubuntu/focal-devel

Proposed by Christian Ehrhardt 
Status: Work in progress
Proposed branch: ~paelzer/ubuntu/+source/nginx:lp-1874831-nchan-bump-lp-1893753-lua-FOCAL
Merge into: ubuntu/+source/nginx:ubuntu/focal-devel
Diff against target: 70937 lines (+38657/-9478)
312 files modified
debian/changelog (+9/-0)
debian/modules/control (+2/-1)
debian/modules/http-lua/README.markdown (+271/-95)
debian/modules/http-lua/config (+45/-0)
debian/modules/http-lua/doc/HttpLuaModule.wiki (+256/-87)
debian/modules/http-lua/src/api/ngx_http_lua_api.h (+8/-1)
debian/modules/http-lua/src/ngx_http_lua_accessby.c (+3/-1)
debian/modules/http-lua/src/ngx_http_lua_api.c (+1/-1)
debian/modules/http-lua/src/ngx_http_lua_args.c (+8/-3)
debian/modules/http-lua/src/ngx_http_lua_balancer.c (+6/-1)
debian/modules/http-lua/src/ngx_http_lua_bodyfilterby.c (+23/-27)
debian/modules/http-lua/src/ngx_http_lua_bodyfilterby.h (+1/-1)
debian/modules/http-lua/src/ngx_http_lua_cache.c (+19/-4)
debian/modules/http-lua/src/ngx_http_lua_clfactory.c (+63/-22)
debian/modules/http-lua/src/ngx_http_lua_common.h (+52/-9)
debian/modules/http-lua/src/ngx_http_lua_consts.c (+3/-0)
debian/modules/http-lua/src/ngx_http_lua_contentby.c (+2/-0)
debian/modules/http-lua/src/ngx_http_lua_control.c (+4/-1)
debian/modules/http-lua/src/ngx_http_lua_coroutine.c (+17/-1)
debian/modules/http-lua/src/ngx_http_lua_directive.c (+45/-17)
debian/modules/http-lua/src/ngx_http_lua_exception.h (+3/-3)
debian/modules/http-lua/src/ngx_http_lua_headerfilterby.c (+2/-1)
debian/modules/http-lua/src/ngx_http_lua_headers.c (+72/-90)
debian/modules/http-lua/src/ngx_http_lua_headers_in.c (+9/-1)
debian/modules/http-lua/src/ngx_http_lua_headers_out.c (+15/-5)
debian/modules/http-lua/src/ngx_http_lua_headers_out.h (+3/-3)
debian/modules/http-lua/src/ngx_http_lua_initworkerby.c (+45/-3)
debian/modules/http-lua/src/ngx_http_lua_input_filters.c (+137/-0)
debian/modules/http-lua/src/ngx_http_lua_input_filters.h (+29/-0)
debian/modules/http-lua/src/ngx_http_lua_log.c (+23/-0)
debian/modules/http-lua/src/ngx_http_lua_logby.c (+2/-1)
debian/modules/http-lua/src/ngx_http_lua_misc.c (+27/-0)
debian/modules/http-lua/src/ngx_http_lua_module.c (+59/-0)
debian/modules/http-lua/src/ngx_http_lua_ndk.c (+41/-0)
debian/modules/http-lua/src/ngx_http_lua_phase.c (+18/-0)
debian/modules/http-lua/src/ngx_http_lua_pipe.c (+2475/-0)
debian/modules/http-lua/src/ngx_http_lua_pipe.h (+95/-0)
debian/modules/http-lua/src/ngx_http_lua_probe.h (+2/-1)
debian/modules/http-lua/src/ngx_http_lua_regex.c (+8/-4)
debian/modules/http-lua/src/ngx_http_lua_req_method.c (+4/-3)
debian/modules/http-lua/src/ngx_http_lua_rewriteby.c (+13/-3)
debian/modules/http-lua/src/ngx_http_lua_script.c (+2/-2)
debian/modules/http-lua/src/ngx_http_lua_setby.c (+15/-19)
debian/modules/http-lua/src/ngx_http_lua_setby.h (+1/-1)
debian/modules/http-lua/src/ngx_http_lua_shdict.c (+37/-26)
debian/modules/http-lua/src/ngx_http_lua_socket_tcp.c (+1311/-578)
debian/modules/http-lua/src/ngx_http_lua_socket_tcp.h (+26/-3)
debian/modules/http-lua/src/ngx_http_lua_socket_udp.c (+50/-6)
debian/modules/http-lua/src/ngx_http_lua_ssl_certby.c (+78/-13)
debian/modules/http-lua/src/ngx_http_lua_ssl_ocsp.c (+4/-0)
debian/modules/http-lua/src/ngx_http_lua_ssl_session_fetchby.c (+19/-4)
debian/modules/http-lua/src/ngx_http_lua_ssl_session_fetchby.h (+5/-1)
debian/modules/http-lua/src/ngx_http_lua_ssl_session_storeby.c (+19/-3)
debian/modules/http-lua/src/ngx_http_lua_string.c (+14/-0)
debian/modules/http-lua/src/ngx_http_lua_subrequest.c (+14/-0)
debian/modules/http-lua/src/ngx_http_lua_time.c (+71/-0)
debian/modules/http-lua/src/ngx_http_lua_timer.c (+39/-5)
debian/modules/http-lua/src/ngx_http_lua_uthread.c (+2/-1)
debian/modules/http-lua/src/ngx_http_lua_util.c (+163/-19)
debian/modules/http-lua/src/ngx_http_lua_util.h (+62/-12)
debian/modules/http-lua/src/ngx_http_lua_variable.c (+22/-13)
debian/modules/http-lua/src/ngx_http_lua_worker.c (+26/-0)
debian/modules/http-lua/t/.gitignore (+2/-0)
debian/modules/http-lua/t/000--init.t (+0/-5)
debian/modules/http-lua/t/001-set.t (+15/-8)
debian/modules/http-lua/t/002-content.t (+19/-19)
debian/modules/http-lua/t/004-require.t (+6/-6)
debian/modules/http-lua/t/005-exit.t (+1/-1)
debian/modules/http-lua/t/009-log.t (+9/-3)
debian/modules/http-lua/t/011-md5_bin.t (+1/-1)
debian/modules/http-lua/t/013-base64.t (+1/-1)
debian/modules/http-lua/t/014-bugs.t (+25/-24)
debian/modules/http-lua/t/016-resp-header.t (+541/-87)
debian/modules/http-lua/t/017-exec.t (+2/-2)
debian/modules/http-lua/t/020-subrequest.t (+72/-68)
debian/modules/http-lua/t/022-redirect.t (+52/-1)
debian/modules/http-lua/t/023-rewrite/client-abort.t (+3/-3)
debian/modules/http-lua/t/023-rewrite/exec.t (+2/-2)
debian/modules/http-lua/t/023-rewrite/mixed.t (+2/-2)
debian/modules/http-lua/t/023-rewrite/multi-capture.t (+1/-1)
debian/modules/http-lua/t/023-rewrite/redirect.t (+40/-0)
debian/modules/http-lua/t/023-rewrite/req-socket.t (+3/-3)
debian/modules/http-lua/t/023-rewrite/sanity.t (+14/-14)
debian/modules/http-lua/t/023-rewrite/socket-keepalive.t (+6/-6)
debian/modules/http-lua/t/023-rewrite/subrequest.t (+21/-21)
debian/modules/http-lua/t/023-rewrite/tcp-socket-timeout.t (+6/-6)
debian/modules/http-lua/t/023-rewrite/tcp-socket.t (+16/-16)
debian/modules/http-lua/t/023-rewrite/uthread-exec.t (+6/-6)
debian/modules/http-lua/t/023-rewrite/uthread-exit.t (+20/-20)
debian/modules/http-lua/t/023-rewrite/uthread-redirect.t (+2/-2)
debian/modules/http-lua/t/023-rewrite/uthread-spawn.t (+33/-29)
debian/modules/http-lua/t/024-access/client-abort.t (+3/-3)
debian/modules/http-lua/t/024-access/exec.t (+1/-1)
debian/modules/http-lua/t/024-access/mixed.t (+5/-5)
debian/modules/http-lua/t/024-access/multi-capture.t (+1/-1)
debian/modules/http-lua/t/024-access/sanity.t (+15/-15)
debian/modules/http-lua/t/024-access/subrequest.t (+21/-21)
debian/modules/http-lua/t/024-access/uthread-exec.t (+6/-6)
debian/modules/http-lua/t/024-access/uthread-exit.t (+19/-19)
debian/modules/http-lua/t/024-access/uthread-redirect.t (+2/-2)
debian/modules/http-lua/t/024-access/uthread-spawn.t (+33/-29)
debian/modules/http-lua/t/025-codecache.t (+153/-23)
debian/modules/http-lua/t/027-multi-capture.t (+2/-2)
debian/modules/http-lua/t/028-req-header.t (+460/-74)
debian/modules/http-lua/t/030-uri-args.t (+185/-37)
debian/modules/http-lua/t/031-post-args.t (+66/-16)
debian/modules/http-lua/t/034-match.t (+33/-32)
debian/modules/http-lua/t/035-gmatch.t (+11/-11)
debian/modules/http-lua/t/036-sub.t (+2/-2)
debian/modules/http-lua/t/037-gsub.t (+1/-1)
debian/modules/http-lua/t/038-match-o.t (+22/-22)
debian/modules/http-lua/t/041-header-filter.t (+15/-6)
debian/modules/http-lua/t/043-shdict.t (+2/-2)
debian/modules/http-lua/t/044-req-body.t (+7/-1)
debian/modules/http-lua/t/047-match-jit.t (+6/-6)
debian/modules/http-lua/t/048-match-dfa.t (+6/-6)
debian/modules/http-lua/t/055-subreq-vars.t (+9/-9)
debian/modules/http-lua/t/056-flush.t (+1/-1)
debian/modules/http-lua/t/057-flush-timeout.t (+1/-1)
debian/modules/http-lua/t/058-tcp-socket.t (+419/-26)
debian/modules/http-lua/t/062-count.t (+102/-7)
debian/modules/http-lua/t/063-abort.t (+31/-31)
debian/modules/http-lua/t/064-pcall.t (+7/-7)
debian/modules/http-lua/t/065-tcp-socket-timeout.t (+12/-12)
debian/modules/http-lua/t/066-socket-receiveuntil.t (+15/-15)
debian/modules/http-lua/t/067-req-socket.t (+3/-3)
debian/modules/http-lua/t/068-socket-keepalive.t (+1436/-31)
debian/modules/http-lua/t/073-backtrace.t (+7/-7)
debian/modules/http-lua/t/075-logby.t (+7/-4)
debian/modules/http-lua/t/081-bytecode.t (+24/-21)
debian/modules/http-lua/t/082-body-filter.t (+2/-1)
debian/modules/http-lua/t/084-inclusive-receiveuntil.t (+10/-10)
debian/modules/http-lua/t/087-udp-socket.t (+77/-7)
debian/modules/http-lua/t/090-log-socket-errors.t (+5/-5)
debian/modules/http-lua/t/091-coroutine.t (+42/-39)
debian/modules/http-lua/t/093-uthread-spawn.t (+35/-31)
debian/modules/http-lua/t/094-uthread-exit.t (+23/-23)
debian/modules/http-lua/t/095-uthread-exec.t (+7/-7)
debian/modules/http-lua/t/096-uthread-redirect.t (+3/-3)
debian/modules/http-lua/t/097-uthread-rewrite.t (+6/-6)
debian/modules/http-lua/t/098-uthread-wait.t (+37/-37)
debian/modules/http-lua/t/099-c-api.t (+5/-5)
debian/modules/http-lua/t/100-client-abort.t (+3/-3)
debian/modules/http-lua/t/104-req-raw-header.t (+112/-0)
debian/modules/http-lua/t/106-timer.t (+9/-9)
debian/modules/http-lua/t/108-timer-safe.t (+8/-8)
debian/modules/http-lua/t/109-timer-hup.t (+9/-9)
debian/modules/http-lua/t/120-re-find.t (+2/-2)
debian/modules/http-lua/t/123-lua-path.t (+5/-5)
debian/modules/http-lua/t/124-init-worker.t (+205/-6)
debian/modules/http-lua/t/126-shdict-frag.t (+2/-2)
debian/modules/http-lua/t/127-uthread-kill.t (+13/-13)
debian/modules/http-lua/t/128-duplex-tcp-socket.t (+3/-3)
debian/modules/http-lua/t/129-ssl-socket.t (+179/-262)
debian/modules/http-lua/t/130-internal-api.t (+4/-13)
debian/modules/http-lua/t/132-lua-blocks.t (+124/-1)
debian/modules/http-lua/t/134-worker-count-5.t (+2/-2)
debian/modules/http-lua/t/135-worker-id.t (+1/-61)
debian/modules/http-lua/t/138-balancer.t (+3/-5)
debian/modules/http-lua/t/139-ssl-cert-by.t (+205/-2)
debian/modules/http-lua/t/140-ssl-c-api.t (+12/-11)
debian/modules/http-lua/t/142-ssl-session-store.t (+11/-13)
debian/modules/http-lua/t/143-ssl-session-fetch.t (+118/-13)
debian/modules/http-lua/t/147-tcp-socket-timeouts.t (+4/-4)
debian/modules/http-lua/t/152-timer-every.t (+2/-2)
debian/modules/http-lua/t/153-semaphore-hup.t (+1/-1)
debian/modules/http-lua/t/155-tls13.t (+106/-0)
debian/modules/http-lua/t/156-slow-network.t (+138/-0)
debian/modules/http-lua/t/157-socket-keepalive-hup.t (+91/-0)
debian/modules/http-lua/t/158-global-var.t (+508/-0)
debian/modules/http-lua/t/159-sa-restart.t (+180/-0)
debian/modules/http-lua/t/160-disable-init-by-lua.t (+194/-0)
debian/modules/http-lua/t/161-load-resty-core.t (+68/-0)
debian/modules/http-lua/t/cert/dst-ca.crt (+63/-0)
debian/modules/http-lua/t/data/fake-shm-module/ngx_http_lua_fake_shm_module.c (+13/-9)
debian/modules/http-lua/util/build.sh (+3/-1)
debian/modules/http-lua/valgrind.suppress (+33/-16)
debian/modules/nchan/README.md (+897/-134)
debian/modules/nchan/changelog.txt (+205/-0)
debian/modules/nchan/cloc-exclude.txt (+10/-11)
debian/modules/nchan/config (+69/-18)
debian/modules/nchan/src/nchan_commands.rb (+351/-32)
debian/modules/nchan/src/nchan_config_commands.c (+275/-9)
debian/modules/nchan/src/nchan_defs.c (+8/-1)
debian/modules/nchan/src/nchan_defs.h (+9/-2)
debian/modules/nchan/src/nchan_module.c (+277/-143)
debian/modules/nchan/src/nchan_module.h (+13/-21)
debian/modules/nchan/src/nchan_setup.c (+672/-33)
debian/modules/nchan/src/nchan_types.h (+157/-40)
debian/modules/nchan/src/nchan_variables.c (+6/-0)
debian/modules/nchan/src/nchan_version.h (+1/-0)
debian/modules/nchan/src/store/memory/groups.c (+570/-0)
debian/modules/nchan/src/store/memory/groups.h (+55/-0)
debian/modules/nchan/src/store/memory/ipc-handlers.c (+526/-171)
debian/modules/nchan/src/store/memory/ipc-handlers.h (+13/-3)
debian/modules/nchan/src/store/memory/ipc.c (+27/-3)
debian/modules/nchan/src/store/memory/ipc.h (+10/-1)
debian/modules/nchan/src/store/memory/memstore.c (+1013/-460)
debian/modules/nchan/src/store/memory/store-private.h (+34/-7)
debian/modules/nchan/src/store/memory/store.h (+3/-3)
debian/modules/nchan/src/store/redis/cmp.c (+927/-410)
debian/modules/nchan/src/store/redis/cmp.h (+59/-7)
debian/modules/nchan/src/store/redis/hiredis/.gitignore (+7/-0)
debian/modules/nchan/src/store/redis/hiredis/.travis.yml (+24/-0)
debian/modules/nchan/src/store/redis/hiredis/CHANGELOG.md (+110/-0)
debian/modules/nchan/src/store/redis/hiredis/COPYING (+29/-0)
debian/modules/nchan/src/store/redis/hiredis/Makefile (+217/-0)
debian/modules/nchan/src/store/redis/hiredis/README.md (+392/-0)
debian/modules/nchan/src/store/redis/hiredis/adapters/ae.h (+127/-0)
debian/modules/nchan/src/store/redis/hiredis/adapters/libev.h (+147/-0)
debian/modules/nchan/src/store/redis/hiredis/adapters/libevent.h (+108/-0)
debian/modules/nchan/src/store/redis/hiredis/adapters/libuv.h (+121/-0)
debian/modules/nchan/src/store/redis/hiredis/async.c (+687/-0)
debian/modules/nchan/src/store/redis/hiredis/async.h (+129/-0)
debian/modules/nchan/src/store/redis/hiredis/dict.c (+338/-0)
debian/modules/nchan/src/store/redis/hiredis/dict.h (+126/-0)
debian/modules/nchan/src/store/redis/hiredis/examples/example-ae.c (+62/-0)
debian/modules/nchan/src/store/redis/hiredis/examples/example-libev.c (+52/-0)
debian/modules/nchan/src/store/redis/hiredis/examples/example-libevent.c (+53/-0)
debian/modules/nchan/src/store/redis/hiredis/examples/example-libuv.c (+53/-0)
debian/modules/nchan/src/store/redis/hiredis/examples/example.c (+78/-0)
debian/modules/nchan/src/store/redis/hiredis/fmacros.h (+21/-0)
debian/modules/nchan/src/store/redis/hiredis/hiredis.c (+1021/-0)
debian/modules/nchan/src/store/redis/hiredis/hiredis.h (+226/-0)
debian/modules/nchan/src/store/redis/hiredis/net.c (+461/-0)
debian/modules/nchan/src/store/redis/hiredis/net.h (+53/-0)
debian/modules/nchan/src/store/redis/hiredis/read.c (+525/-0)
debian/modules/nchan/src/store/redis/hiredis/read.h (+116/-0)
debian/modules/nchan/src/store/redis/hiredis/sds.c (+1095/-0)
debian/modules/nchan/src/store/redis/hiredis/sds.h (+105/-0)
debian/modules/nchan/src/store/redis/hiredis/test.c (+807/-0)
debian/modules/nchan/src/store/redis/hiredis/win32.h (+42/-0)
debian/modules/nchan/src/store/redis/rdsstore.c (+923/-1208)
debian/modules/nchan/src/store/redis/redis-lua-scripts/.gitignore (+1/-0)
debian/modules/nchan/src/store/redis/redis-lua-scripts/add_fakesub.lua (+9/-4)
debian/modules/nchan/src/store/redis/redis-lua-scripts/channel_keepalive.lua (+5/-4)
debian/modules/nchan/src/store/redis/redis-lua-scripts/delete.lua (+33/-23)
debian/modules/nchan/src/store/redis/redis-lua-scripts/find_channel.lua (+33/-19)
debian/modules/nchan/src/store/redis/redis-lua-scripts/get_message.lua (+16/-17)
debian/modules/nchan/src/store/redis/redis-lua-scripts/get_message_from_key.lua (+3/-4)
debian/modules/nchan/src/store/redis/redis-lua-scripts/publish.lua (+64/-55)
debian/modules/nchan/src/store/redis/redis-lua-scripts/publish_status.lua (+4/-4)
debian/modules/nchan/src/store/redis/redis-lua-scripts/rsck.lua (+27/-10)
debian/modules/nchan/src/store/redis/redis-lua-scripts/subscriber_register.lua (+18/-6)
debian/modules/nchan/src/store/redis/redis-lua-scripts/subscriber_unregister.lua (+3/-3)
debian/modules/nchan/src/store/redis/redis-lua-scripts/testscripts.rb (+4/-3)
debian/modules/nchan/src/store/redis/redis_lua_commands.c (+1036/-0)
debian/modules/nchan/src/store/redis/redis_lua_commands.h (+17/-984)
debian/modules/nchan/src/store/redis/redis_nginx_adapter.c (+28/-36)
debian/modules/nchan/src/store/redis/redis_nginx_adapter.h (+6/-1)
debian/modules/nchan/src/store/redis/redis_nodeset.c (+2179/-0)
debian/modules/nchan/src/store/redis/redis_nodeset.h (+276/-0)
debian/modules/nchan/src/store/redis/redis_nodeset_parser.c (+241/-0)
debian/modules/nchan/src/store/redis/redis_nodeset_parser.h (+40/-0)
debian/modules/nchan/src/store/redis/store-private.h (+53/-139)
debian/modules/nchan/src/store/redis/store.h (+8/-3)
debian/modules/nchan/src/store/spool.c (+168/-122)
debian/modules/nchan/src/store/spool.h (+6/-8)
debian/modules/nchan/src/subscribers/benchmark.c (+72/-0)
debian/modules/nchan/src/subscribers/benchmark.h (+3/-0)
debian/modules/nchan/src/subscribers/common.c (+162/-411)
debian/modules/nchan/src/subscribers/common.h (+7/-10)
debian/modules/nchan/src/subscribers/eventsource.c (+87/-7)
debian/modules/nchan/src/subscribers/getmsg_proxy.c (+106/-0)
debian/modules/nchan/src/subscribers/getmsg_proxy.h (+1/-0)
debian/modules/nchan/src/subscribers/http-chunked.c (+6/-4)
debian/modules/nchan/src/subscribers/http-multipart-mixed.c (+15/-12)
debian/modules/nchan/src/subscribers/http-raw-stream.c (+9/-7)
debian/modules/nchan/src/subscribers/internal.c (+13/-6)
debian/modules/nchan/src/subscribers/longpoll-private.h (+3/-1)
debian/modules/nchan/src/subscribers/longpoll.c (+97/-143)
debian/modules/nchan/src/subscribers/memstore_ipc.c (+43/-20)
debian/modules/nchan/src/subscribers/memstore_ipc.h (+3/-0)
debian/modules/nchan/src/subscribers/memstore_multi.c (+23/-30)
debian/modules/nchan/src/subscribers/memstore_redis.c (+67/-63)
debian/modules/nchan/src/subscribers/memstore_redis.h (+0/-1)
debian/modules/nchan/src/subscribers/websocket.c (+912/-486)
debian/modules/nchan/src/subscribers/websocket.h (+2/-1)
debian/modules/nchan/src/uthash.h (+747/-489)
debian/modules/nchan/src/util/hdr_histogram.c (+1015/-0)
debian/modules/nchan/src/util/hdr_histogram.h (+427/-0)
debian/modules/nchan/src/util/nchan_benchmark.c (+804/-0)
debian/modules/nchan/src/util/nchan_benchmark.h (+91/-0)
debian/modules/nchan/src/util/nchan_bufchainpool.c (+96/-0)
debian/modules/nchan/src/util/nchan_bufchainpool.h (+17/-0)
debian/modules/nchan/src/util/nchan_channel_id.c (+74/-8)
debian/modules/nchan/src/util/nchan_channel_id.h (+4/-1)
debian/modules/nchan/src/util/nchan_debug.c (+81/-0)
debian/modules/nchan/src/util/nchan_debug.h (+13/-0)
debian/modules/nchan/src/util/nchan_fake_request.c (+267/-24)
debian/modules/nchan/src/util/nchan_fake_request.h (+55/-3)
debian/modules/nchan/src/util/nchan_list.c (+26/-0)
debian/modules/nchan/src/util/nchan_list.h (+5/-0)
debian/modules/nchan/src/util/nchan_msg.c (+291/-33)
debian/modules/nchan/src/util/nchan_msg.h (+19/-0)
debian/modules/nchan/src/util/nchan_output.c (+73/-22)
debian/modules/nchan/src/util/nchan_output.h (+4/-2)
debian/modules/nchan/src/util/nchan_output_info.c (+271/-0)
debian/modules/nchan/src/util/nchan_output_info.h (+3/-4)
debian/modules/nchan/src/util/nchan_rbtree.h (+3/-3)
debian/modules/nchan/src/util/nchan_slist.c (+164/-0)
debian/modules/nchan/src/util/nchan_slist.h (+41/-0)
debian/modules/nchan/src/util/nchan_subrequest.c (+66/-9)
debian/modules/nchan/src/util/nchan_subrequest.h (+4/-1)
debian/modules/nchan/src/util/nchan_util.c (+866/-47)
debian/modules/nchan/src/util/nchan_util.h (+47/-3)
debian/modules/nchan/src/util/ngx_nchan_hacked_slab.c (+4/-0)
debian/modules/nchan/src/util/shmem.c (+44/-5)
debian/modules/nchan/src/util/shmem.h (+5/-0)
debian/modules/patches/http-lua/disable-load_resty_core.patch (+20/-0)
debian/modules/patches/http-lua/series (+1/-1)
dev/null (+0/-838)
Reviewer Review Type Date Requested Status
Thomas Ward Pending
Canonical Server Pending
Canonical Server packageset reviewers Pending
git-ubuntu developers Pending
Review via email: mp+409830@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Christian Ehrhardt  (paelzer) wrote :

PPA:
https://launchpad.net/~ci-train-ppa-service/+archive/ubuntu/4678/+packages

SRU Template will follow once reporters tested it.

Revision history for this message
Christian Ehrhardt  (paelzer) wrote :

FYI - things were not as easy and build fails block the PPA for now.
I'll let you know once I found some time to resolve that.

Revision history for this message
Christian Ehrhardt  (paelzer) wrote :

 /<<PKGBUILDDIR>>/debian/modules/http-lua/src/ngx_http_lua_subrequest.c
In file included from /<<PKGBUILDDIR>>/debian/modules/http-lua/src/ngx_http_lua_script.h:11,
                 from /<<PKGBUILDDIR>>/debian/modules/http-lua/src/ngx_http_lua_script.c:13:
/<<PKGBUILDDIR>>/debian/modules/http-lua/src/ngx_http_lua_common.h:20:10: fatal error: luajit.h: No such file or directory
   20 | #include <luajit.h>
      | ^~~~~~~~~~

That should be around via:
- libluajit-5.1-dev: /usr/include/luajit-2.1/luajit.h

What I found is that it fails on launchpad (for example https://launchpad.net/~ci-train-ppa-service/+archive/ubuntu/4678/+build/22267992) but the very same builds fine in local sbuild:
$ DEB_BUILD_OPTIONS="parallel=4" sbuild -Adfocal-proposed-amd64 nginx_1.18.0-0ubuntu1.3~focalppa3.dsc

I vaguely remember seeing similar issue in nginx in the past, but fail to remember what it was.
I need to ping teward for his subject matter expertise, so I subscribe him here.

Revision history for this message
Christian Ehrhardt  (paelzer) wrote :

This does actually only break on arm64 ppc64el riscv64 s390x but works on armhf and amd64.
That at least explains why local sbuild worked.

Current (bad) focal lua nginx module is available on all these architectures and in later releases removed.
 libnginx-mod-http-lua | 1.18.0-0ubuntu1.2 | focal-updates/universe | amd64, arm64, armhf, ppc64el, riscv64, s390x

s390x will never work as there the luajit lib doesn't exist:
 libluajit-5.1-dev | 2.1.0~beta3+dfsg-6 | impish/universe | amd64, arm64, armhf, i386, ppc64el

That matches the build-dep in nginx d/control (not on s390x).
The current module of 1.18.0-0ubuntu1.2 on s390x has a .so file which is odd, seems it didn't really need libluajit-5.1-dev in the past before
https://github.com/openresty/lua-nginx-module/commit/7286812116940216344ade33722c49ae47037605

In fact it is just a very-non-matching build-dep that is the problem.
libluajit-5.1-dev [i386 amd64 kfreebsd-i386 armel armhf powerpc powerpcspe mips mipsel],
It lists so many architectures that it is misleading, but not those we actually want.

Furthermore also in d/rules lua is enabled unconditionally but that won't work anymore.

I've modified everything accordingly only to find that for some extra pain on arm64 and ppc64 Focals libluajit-5.1-dev still isn't working. Even when properly installed it can't find/work with luajit correctly on those architectures for the given versions that we have.
So I'll have to disable it on those platforms as well.

Unmerged commits

5697825... by Christian Ehrhardt 

changelog add http-lua (LP: #1893753)

Signed-off-by: Christian Ehrhardt <email address hidden>

2226f49... by Anton Tolchanov

http-lua: Upgrade to 0.10.15

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

e1587cc... by Christian Ehrhardt 

changelog: nchan: Upgrade module to 1.2.7 (LP: #1874831)

Signed-off-by: Christian Ehrhardt <email address hidden>

c8c1511... by Ondřej Nový

nchan: Upgrade to 1.2.7

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

Subscribers

People subscribed via source and target branches