From 75a3ff5eaa1d1708d6c89940a36506860d5fbbbd Mon Sep 17 00:00:00 2001 From: Christos Trochalakis Date: Mon, 28 Aug 2017 15:08:10 +0300 Subject: [PATCH] Update nginx-lua to v0.10.10 Fixes an issue with LuaJIT v2.1, luaL_getn() is no longer available. --- debian/modules/README.Modules-versions | 2 +- debian/modules/nginx-lua/README.markdown | 275 ++++++--- debian/modules/nginx-lua/config | 29 +- .../modules/nginx-lua/doc/HttpLuaModule.wiki | 415 ++++++++----- .../nginx-lua/src/api/ngx_http_lua_api.h | 2 +- .../modules/nginx-lua/src/ngx_http_lua_api.c | 7 +- .../modules/nginx-lua/src/ngx_http_lua_args.c | 2 +- .../nginx-lua/src/ngx_http_lua_balancer.c | 15 +- .../nginx-lua/src/ngx_http_lua_common.h | 27 +- .../nginx-lua/src/ngx_http_lua_control.c | 4 +- .../nginx-lua/src/ngx_http_lua_directive.c | 67 ++ .../nginx-lua/src/ngx_http_lua_directive.h | 3 +- .../nginx-lua/src/ngx_http_lua_headers.c | 124 +++- .../nginx-lua/src/ngx_http_lua_headers.h | 3 + .../modules/nginx-lua/src/ngx_http_lua_log.c | 117 ++++ .../modules/nginx-lua/src/ngx_http_lua_log.h | 4 + .../nginx-lua/src/ngx_http_lua_log_ringbuf.c | 225 +++++++ .../nginx-lua/src/ngx_http_lua_log_ringbuf.h | 31 + .../nginx-lua/src/ngx_http_lua_module.c | 70 +-- .../nginx-lua/src/ngx_http_lua_regex.c | 82 ++- .../nginx-lua/src/ngx_http_lua_regex.h | 2 + .../nginx-lua/src/ngx_http_lua_semaphore.c | 11 +- .../nginx-lua/src/ngx_http_lua_sleep.c | 30 +- .../nginx-lua/src/ngx_http_lua_socket_tcp.c | 25 +- .../modules/nginx-lua/src/ngx_http_lua_ssl.h | 6 +- .../nginx-lua/src/ngx_http_lua_ssl_certby.c | 27 +- .../nginx-lua/src/ngx_http_lua_ssl_ocsp.c | 1 - .../src/ngx_http_lua_ssl_session_fetchby.c | 14 +- .../src/ngx_http_lua_ssl_session_storeby.c | 8 +- .../nginx-lua/src/ngx_http_lua_string.c | 9 +- .../nginx-lua/src/ngx_http_lua_timer.c | 209 ++++++- .../modules/nginx-lua/src/ngx_http_lua_util.c | 52 +- .../nginx-lua/src/ngx_http_lua_worker.c | 45 ++ debian/modules/nginx-lua/t/000--init.t | 1 - debian/modules/nginx-lua/t/000-sanity.t | 1 - debian/modules/nginx-lua/t/001-set.t | 1 - debian/modules/nginx-lua/t/002-content.t | 1 - debian/modules/nginx-lua/t/003-errors.t | 1 - debian/modules/nginx-lua/t/004-require.t | 1 - debian/modules/nginx-lua/t/005-exit.t | 1 - debian/modules/nginx-lua/t/006-escape.t | 20 +- debian/modules/nginx-lua/t/007-md5.t | 1 - debian/modules/nginx-lua/t/008-today.t | 1 - debian/modules/nginx-lua/t/009-log.t | 1 - debian/modules/nginx-lua/t/010-request_body.t | 1 - debian/modules/nginx-lua/t/012-now.t | 1 - debian/modules/nginx-lua/t/014-bugs.t | 3 +- debian/modules/nginx-lua/t/016-resp-header.t | 70 ++- debian/modules/nginx-lua/t/017-exec.t | 1 - debian/modules/nginx-lua/t/018-ndk.t | 1 - debian/modules/nginx-lua/t/019-const.t | 1 - debian/modules/nginx-lua/t/021-cookie-time.t | 1 - debian/modules/nginx-lua/t/022-redirect.t | 53 +- .../nginx-lua/t/023-rewrite/client-abort.t | 1 - debian/modules/nginx-lua/t/023-rewrite/exec.t | 1 - debian/modules/nginx-lua/t/023-rewrite/exit.t | 1 - .../modules/nginx-lua/t/023-rewrite/mixed.t | 1 - .../nginx-lua/t/023-rewrite/multi-capture.t | 1 - .../nginx-lua/t/023-rewrite/on-abort.t | 1 - .../nginx-lua/t/023-rewrite/redirect.t | 1 - .../nginx-lua/t/023-rewrite/req-body.t | 1 - .../nginx-lua/t/023-rewrite/req-socket.t | 1 - .../nginx-lua/t/023-rewrite/request_body.t | 1 - .../modules/nginx-lua/t/023-rewrite/sanity.t | 1 - .../modules/nginx-lua/t/023-rewrite/sleep.t | 1 - .../t/023-rewrite/socket-keepalive.t | 1 - .../nginx-lua/t/023-rewrite/subrequest.t | 1 - .../t/023-rewrite/tcp-socket-timeout.t | 29 +- .../nginx-lua/t/023-rewrite/tcp-socket.t | 9 +- .../nginx-lua/t/023-rewrite/unix-socket.t | 1 - .../t/023-rewrite/uthread-redirect.t | 1 - .../nginx-lua/t/023-rewrite/uthread-spawn.t | 1 - debian/modules/nginx-lua/t/024-access/auth.t | 1 - .../nginx-lua/t/024-access/client-abort.t | 1 - debian/modules/nginx-lua/t/024-access/exit.t | 1 - .../nginx-lua/t/024-access/multi-capture.t | 1 - .../modules/nginx-lua/t/024-access/on-abort.t | 1 - .../modules/nginx-lua/t/024-access/redirect.t | 1 - .../modules/nginx-lua/t/024-access/req-body.t | 1 - .../nginx-lua/t/024-access/request_body.t | 1 - .../modules/nginx-lua/t/024-access/sanity.t | 1 - .../modules/nginx-lua/t/024-access/satisfy.t | 1 - debian/modules/nginx-lua/t/024-access/sleep.t | 1 - .../nginx-lua/t/024-access/subrequest.t | 1 - .../nginx-lua/t/024-access/uthread-exec.t | 1 - .../nginx-lua/t/024-access/uthread-exit.t | 1 - .../nginx-lua/t/024-access/uthread-redirect.t | 1 - .../nginx-lua/t/024-access/uthread-spawn.t | 1 - debian/modules/nginx-lua/t/025-codecache.t | 1 - debian/modules/nginx-lua/t/026-mysql.t | 5 +- .../modules/nginx-lua/t/027-multi-capture.t | 1 - debian/modules/nginx-lua/t/029-http-time.t | 1 - debian/modules/nginx-lua/t/030-uri-args.t | 18 +- debian/modules/nginx-lua/t/031-post-args.t | 2 +- debian/modules/nginx-lua/t/032-iolist.t | 1 - debian/modules/nginx-lua/t/033-ctx.t | 1 - debian/modules/nginx-lua/t/034-match.t | 4 +- debian/modules/nginx-lua/t/035-gmatch.t | 5 +- debian/modules/nginx-lua/t/036-sub.t | 4 +- debian/modules/nginx-lua/t/037-gsub.t | 4 +- debian/modules/nginx-lua/t/038-match-o.t | 1 - debian/modules/nginx-lua/t/039-sub-o.t | 1 - debian/modules/nginx-lua/t/040-gsub-o.t | 1 - .../modules/nginx-lua/t/041-header-filter.t | 1 - debian/modules/nginx-lua/t/042-crc32.t | 1 - debian/modules/nginx-lua/t/045-ngx-var.t | 9 +- debian/modules/nginx-lua/t/046-hmac.t | 1 - debian/modules/nginx-lua/t/047-match-jit.t | 1 - debian/modules/nginx-lua/t/048-match-dfa.t | 1 - debian/modules/nginx-lua/t/049-gmatch-jit.t | 1 - debian/modules/nginx-lua/t/051-sub-jit.t | 1 - debian/modules/nginx-lua/t/053-gsub-jit.t | 1 - debian/modules/nginx-lua/t/055-subreq-vars.t | 1 - debian/modules/nginx-lua/t/056-flush.t | 1 - .../modules/nginx-lua/t/057-flush-timeout.t | 1 - debian/modules/nginx-lua/t/058-tcp-socket.t | 80 ++- .../modules/nginx-lua/t/060-lua-memcached.t | 1 - debian/modules/nginx-lua/t/061-lua-redis.t | 1 - debian/modules/nginx-lua/t/062-count.t | 2 +- debian/modules/nginx-lua/t/063-abort.t | 1 - debian/modules/nginx-lua/t/064-pcall.t | 1 - .../nginx-lua/t/065-tcp-socket-timeout.t | 41 +- .../nginx-lua/t/066-socket-receiveuntil.t | 1 - debian/modules/nginx-lua/t/067-req-socket.t | 1 - debian/modules/nginx-lua/t/069-null.t | 1 - debian/modules/nginx-lua/t/071-idle-socket.t | 1 - .../modules/nginx-lua/t/072-conditional-get.t | 1 - debian/modules/nginx-lua/t/073-backtrace.t | 1 - debian/modules/nginx-lua/t/074-prefix-var.t | 1 - debian/modules/nginx-lua/t/075-logby.t | 1 - debian/modules/nginx-lua/t/077-sleep.t | 99 ++- debian/modules/nginx-lua/t/078-hup-vars.t | 1 - .../nginx-lua/t/079-unused-directives.t | 1 - debian/modules/nginx-lua/t/080-hup-shdict.t | 1 - .../modules/nginx-lua/t/083-bad-sock-self.t | 1 - .../nginx-lua/t/084-inclusive-receiveuntil.t | 1 - debian/modules/nginx-lua/t/085-if.t | 1 - debian/modules/nginx-lua/t/086-init-by.t | 19 +- debian/modules/nginx-lua/t/087-udp-socket.t | 9 +- debian/modules/nginx-lua/t/088-req-method.t | 1 - debian/modules/nginx-lua/t/089-phase.t | 1 - .../nginx-lua/t/090-log-socket-errors.t | 19 +- debian/modules/nginx-lua/t/091-coroutine.t | 9 +- debian/modules/nginx-lua/t/092-eof.t | 1 - .../modules/nginx-lua/t/093-uthread-spawn.t | 1 - debian/modules/nginx-lua/t/094-uthread-exit.t | 1 - debian/modules/nginx-lua/t/095-uthread-exec.t | 1 - .../nginx-lua/t/096-uthread-redirect.t | 1 - .../modules/nginx-lua/t/097-uthread-rewrite.t | 1 - debian/modules/nginx-lua/t/098-uthread-wait.t | 1 - debian/modules/nginx-lua/t/100-client-abort.t | 1 - debian/modules/nginx-lua/t/101-on-abort.t | 1 - .../modules/nginx-lua/t/102-req-start-time.t | 1 - debian/modules/nginx-lua/t/103-req-http-ver.t | 1 - .../modules/nginx-lua/t/104-req-raw-header.t | 1 - debian/modules/nginx-lua/t/105-pressure.t | 1 - debian/modules/nginx-lua/t/106-timer.t | 1 - debian/modules/nginx-lua/t/107-timer-errors.t | 1 - debian/modules/nginx-lua/t/108-timer-safe.t | 1 - debian/modules/nginx-lua/t/109-timer-hup.t | 1 - debian/modules/nginx-lua/t/110-etag.t | 1 - .../modules/nginx-lua/t/111-req-header-ua.t | 1 - .../modules/nginx-lua/t/112-req-header-conn.t | 1 - .../nginx-lua/t/113-req-header-cookie.t | 1 - .../modules/nginx-lua/t/115-quote-sql-str.t | 1 - .../modules/nginx-lua/t/116-raw-req-socket.t | 1 - .../nginx-lua/t/117-raw-req-socket-timeout.t | 1 - .../modules/nginx-lua/t/119-config-prefix.t | 1 - debian/modules/nginx-lua/t/120-re-find.t | 30 +- debian/modules/nginx-lua/t/121-version.t | 1 - debian/modules/nginx-lua/t/122-worker.t | 1 - debian/modules/nginx-lua/t/123-lua-path.t | 1 - debian/modules/nginx-lua/t/124-init-worker.t | 2 +- .../modules/nginx-lua/t/125-configure-args.t | 1 - debian/modules/nginx-lua/t/126-shdict-frag.t | 1 - debian/modules/nginx-lua/t/127-uthread-kill.t | 3 +- .../nginx-lua/t/128-duplex-tcp-socket.t | 23 +- debian/modules/nginx-lua/t/129-ssl-socket.t | 573 +++++++++--------- debian/modules/nginx-lua/t/130-internal-api.t | 1 - debian/modules/nginx-lua/t/135-worker-id.t | 2 +- debian/modules/nginx-lua/t/137-req-misc.t | 1 - debian/modules/nginx-lua/t/138-balancer.t | 99 ++- debian/modules/nginx-lua/t/139-ssl-cert-by.t | 296 ++++++++- debian/modules/nginx-lua/t/140-ssl-c-api.t | 8 +- debian/modules/nginx-lua/t/141-luajit.t | 3 +- .../nginx-lua/t/142-ssl-session-store.t | 24 +- .../nginx-lua/t/143-ssl-session-fetch.t | 24 +- debian/modules/nginx-lua/t/146-malloc-trim.t | 41 +- .../nginx-lua/t/147-tcp-socket-timeouts.t | 2 +- .../nginx-lua/t/150-fake-delayed-load.t | 56 ++ debian/modules/nginx-lua/t/151-initby-hup.t | 168 +++++ debian/modules/nginx-lua/t/152-timer-every.t | 385 ++++++++++++ .../modules/nginx-lua/t/153-semaphore-hup.t | 154 +++++ debian/modules/nginx-lua/t/154-semaphore.t | 118 ++++ debian/modules/nginx-lua/t/cert/comodo-ca.crt | 29 + debian/modules/nginx-lua/t/cert/startcom.crt | 87 --- .../t/data/fake-delayed-load-module/config | 3 + .../ngx_http_lua_fake_delayed_load_module.c | 77 +++ .../t/data/fake-module/ngx_http_fake_module.c | 3 +- debian/modules/nginx-lua/util/build.sh | 1 + debian/modules/nginx-lua/util/gdbinit | 415 ------------- debian/modules/nginx-lua/util/reindex | 64 -- debian/modules/nginx-lua/valgrind.suppress | 15 + 203 files changed, 3745 insertions(+), 1536 deletions(-) create mode 100644 debian/modules/nginx-lua/src/ngx_http_lua_log_ringbuf.c create mode 100644 debian/modules/nginx-lua/src/ngx_http_lua_log_ringbuf.h create mode 100644 debian/modules/nginx-lua/t/150-fake-delayed-load.t create mode 100644 debian/modules/nginx-lua/t/151-initby-hup.t create mode 100644 debian/modules/nginx-lua/t/152-timer-every.t create mode 100644 debian/modules/nginx-lua/t/153-semaphore-hup.t create mode 100644 debian/modules/nginx-lua/t/154-semaphore.t create mode 100644 debian/modules/nginx-lua/t/cert/comodo-ca.crt delete mode 100644 debian/modules/nginx-lua/t/cert/startcom.crt create mode 100644 debian/modules/nginx-lua/t/data/fake-delayed-load-module/config create mode 100644 debian/modules/nginx-lua/t/data/fake-delayed-load-module/ngx_http_lua_fake_delayed_load_module.c delete mode 100644 debian/modules/nginx-lua/util/gdbinit delete mode 100755 debian/modules/nginx-lua/util/reindex diff --git a/debian/modules/README.Modules-versions b/debian/modules/README.Modules-versions index ef2bb91..6b581cd 100644 --- a/debian/modules/README.Modules-versions +++ b/debian/modules/README.Modules-versions @@ -23,7 +23,7 @@ README for Modules versions nginx-lua Homepage: https://github.com/openresty/lua-nginx-module - Version: v0.10.7 + Version: v0.10.10 Patch: openssl-1.1.0.patch Patch: build-nginx-1.11.11.patch Patch: discover-luajit-2.1.patch diff --git a/debian/modules/nginx-lua/README.markdown b/debian/modules/nginx-lua/README.markdown index 3699a72..fac3a0d 100644 --- a/debian/modules/nginx-lua/README.markdown +++ b/debian/modules/nginx-lua/README.markdown @@ -62,7 +62,7 @@ Production ready. Version ======= -This document describes ngx_lua [v0.10.7](https://github.com/openresty/lua-nginx-module/tags) released on 4 November 2016. +This document describes ngx_lua [v0.10.10](https://github.com/openresty/lua-nginx-module/tags) released on 8 August 2017. Synopsis ======== @@ -150,7 +150,7 @@ Synopsis } # use nginx var in code path - # WARNING: contents in nginx var must be carefully filtered, + # CAUTION: contents in nginx var must be carefully filtered, # otherwise there'll be great security risk! location ~ ^/app/([-_a-zA-Z0-9/]+) { set $path $1; @@ -263,7 +263,7 @@ Nginx cores older than 1.6.0 (exclusive) are *not* supported. Installation ============ -It is highly recommended to use the [OpenResty bundle](http://openresty.org) that bundles Nginx, ngx_lua, LuaJIT 2.0/2.1 (or the optional standard Lua 5.1 interpreter), as well as a package of powerful companion Nginx modules. The basic installation step is a simple command: `./configure --with-luajit && make && make install`. +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. Alternatively, ngx_lua can be manually compiled into Nginx: @@ -298,6 +298,12 @@ Build the source with this module: --add-module=/path/to/ngx_devel_kit \ --add-module=/path/to/lua-nginx-module + # Note that you may also want to add `./configure` options which are used in your + # current nginx build. + # You can get usually those options using command nginx -V + + # you can change the parallism number 2 below to fit the number of spare CPU cores in your + # machine. make -j2 make install ``` @@ -312,8 +318,9 @@ Starting from NGINX 1.9.11, you can also compile this module as a dynamic module directive, for example, ```nginx -load_module /path/to/modules/ndk_http_module.so; # assuming NDK is built as a dynamic module too -load_module /path/to/modules/ngx_http_lua_module.so; + + load_module /path/to/modules/ndk_http_module.so; # assuming NDK is built as a dynamic module too + load_module /path/to/modules/ngx_http_lua_module.so; ``` [Back to TOC](#table-of-contents) @@ -406,14 +413,14 @@ Please note that the bytecode format used by LuaJIT 2.0/2.1 is not compatible wi ```bash - /path/to/luajit/bin/luajit -b /path/to/input_file.lua /path/to/output_file.luac + /path/to/luajit/bin/luajit -b /path/to/input_file.lua /path/to/output_file.ljbc ``` The `-bg` option can be used to include debug information in the LuaJIT bytecode file: ```bash - /path/to/luajit/bin/luajit -bg /path/to/input_file.lua /path/to/output_file.luac + /path/to/luajit/bin/luajit -bg /path/to/input_file.lua /path/to/output_file.ljbc ``` Please refer to the official LuaJIT documentation on the `-b` option for more details: @@ -623,9 +630,9 @@ Known Issues TCP socket connect operation issues ----------------------------------- -The [tcpsock:connect](#tcpsockconnect) method may indicate `success` despite connection failures such as with `Connection Refused` errors. +The [tcpsock:connect](#tcpsockconnect) method may indicate `success` despite connection failures such as with `Connection Refused` errors. -However, later attempts to manipulate the cosocket object will fail and return the actual error status message generated by the failed connect operation. +However, later attempts to manipulate the cosocket object will fail and return the actual error status message generated by the failed connect operation. This issue is due to limitations in the Nginx event model and only appears to affect Mac OS X. @@ -656,15 +663,29 @@ instead of the old deprecated form: Here is the reason: by design, the global environment has exactly the same lifetime as the Nginx request handler associated with it. Each request handler has its own set of Lua global variables and that is the idea of request isolation. The Lua module is actually loaded by the first Nginx request handler and is cached by the `require()` built-in in the `package.loaded` table for later reference, and the `module()` builtin used by some Lua modules has the side effect of setting a global variable to the loaded module table. But this global variable will be cleared at the end of the request handler, and every subsequent request handler all has its own (clean) global environment. So one will get Lua exception for accessing the `nil` value. -Generally, use of Lua global variables is a really really bad idea in the context of ngx_lua because +The use of Lua global variables is a generally inadvisable in the ngx_lua context as: -1. misuse of Lua globals has very bad side effects for concurrent requests when these variables are actually supposed to be local only, -1. Lua global variables require Lua table look-up in the global environment (which is just a Lua table), which is kinda expensive, and -1. some Lua global variable references are just typos, which are hard to debug. +1. the misuse of Lua globals has detrimental side effects on concurrent requests when such variables should instead be local in scope, +1. Lua global variables require Lua table look-ups in the global environment which is computationally expensive, and +1. some Lua global variable references may include typing errors which make such difficult to debug. -It's *highly* recommended to always declare them via "local" in the scope that is reasonable. +It is therefore *highly* recommended to always declare such within an appropriate local scope instead. -To find out all the uses of Lua global variables in your Lua code, you can run the [lua-releng tool](https://github.com/openresty/nginx-devel-utils/blob/master/lua-releng) across all your .lua source files: +```lua + + -- Avoid + foo = 123 + -- Recommended + local foo = 123 + + -- Avoid + function foo() return 123 end + -- Recommended + local function foo() return 123 end +``` + + +To find all instances of Lua global variables in your Lua code, run the [lua-releng tool](https://github.com/openresty/nginx-devel-utils/blob/master/lua-releng) across all `.lua` source files: $ lua-releng Checking use of Lua global variables in file lib/foo/bar.lua ... @@ -709,28 +730,27 @@ will not work as expected. Cosockets Not Available Everywhere ---------------------------------- -Due the internal limitations in the nginx core, the cosocket API are disabled in the following contexts: [set_by_lua*](#set_by_lua), [log_by_lua*](#log_by_lua), [header_filter_by_lua*](#header_filter_by_lua), and [body_filter_by_lua](#body_filter_by_lua). +Due to internal limitations in the nginx core, the cosocket API is disabled in the following contexts: [set_by_lua*](#set_by_lua), [log_by_lua*](#log_by_lua), [header_filter_by_lua*](#header_filter_by_lua), and [body_filter_by_lua](#body_filter_by_lua). The cosockets are currently also disabled in the [init_by_lua*](#init_by_lua) and [init_worker_by_lua*](#init_worker_by_lua) directive contexts but we may add support for these contexts in the future because there is no limitation in the nginx core (or the limitation might be worked around). -There exists a work-around, however, when the original context does *not* need to wait for the cosocket results. That is, creating a 0-delay timer via the [ngx.timer.at](#ngxtimerat) API and do the cosocket results in the timer handler, which runs asynchronously as to the original context creating the timer. +There exists a work-around, however, when the original context does *not* need to wait for the cosocket results. That is, creating a zero-delay timer via the [ngx.timer.at](#ngxtimerat) API and do the cosocket results in the timer handler, which runs asynchronously as to the original context creating the timer. [Back to TOC](#table-of-contents) Special Escaping Sequences -------------------------- -**WARNING** We no longer suffer from this pitfall since the introduction of the -`*_by_lua_block {}` configuration directives. +**NOTE** Following the `v0.9.17` release, this pitfall can be avoided by using the `*_by_lua_block {}` configuration directives. -PCRE sequences such as `\d`, `\s`, or `\w`, require special attention because in string literals, the backslash character, `\`, is stripped out by both the Lua language parser and by the Nginx config file parser before processing. So the following snippet will not work as expected: +PCRE sequences such as `\d`, `\s`, or `\w`, require special attention because in string literals, the backslash character, `\`, is stripped out by both the Lua language parser and by the nginx config file parser before processing if not within a `*_by_lua_block {}` directive. So the following snippet will not work as expected: ```nginx # nginx.conf ? location /test { ? content_by_lua ' - ? local regex = "\d+" -- THIS IS WRONG!! + ? local regex = "\d+" -- THIS IS WRONG OUTSIDE OF A *_by_lua_block DIRECTIVE ? local m = ngx.re.match("hello, 1234", regex) ? if m then ngx.say(m[0]) else ngx.say("not matched!") end ? '; @@ -755,7 +775,7 @@ To avoid this, *double* escape the backslash: Here, `\\\\d+` is stripped down to `\\d+` by the Nginx config file parser and this is further stripped down to `\d+` by the Lua language parser before running. -Alternatively, the regex pattern can be presented as a long-bracketed Lua string literal by encasing it in "long brackets", `[[...]]`, in which case backslashes have to only be escaped once for the Nginx config file parser. +Alternatively, the regex pattern can be presented as a long-bracketed Lua string literal by encasing it in "long brackets", `[[...]]`, in which case backslashes have to only be escaped once for the Nginx config file parser. ```nginx @@ -772,7 +792,7 @@ Alternatively, the regex pattern can be presented as a long-bracketed Lua string Here, `[[\\d+]]` is stripped down to `[[\d+]]` by the Nginx config file parser and this is processed correctly. -Note that a longer from of the long bracket, `[=[...]=]`, may be required if the regex pattern contains `[...]` sequences. +Note that a longer from of the long bracket, `[=[...]=]`, may be required if the regex pattern contains `[...]` sequences. The `[=[...]=]` form may be used as the default form if desired. ```nginx @@ -788,7 +808,7 @@ The `[=[...]=]` form may be used as the default form if desired. # evaluates to "1234" ``` -An alternative approach to escaping PCRE sequences is to ensure that Lua code is placed in external script files and executed using the various `*_by_lua_file` directives. +An alternative approach to escaping PCRE sequences is to ensure that Lua code is placed in external script files and executed using the various `*_by_lua_file` directives. With this approach, the backslashes are only stripped by the Lua language parser and therefore only need to be escaped once each. ```lua @@ -800,8 +820,8 @@ With this approach, the backslashes are only stripped by the Lua language parser -- evaluates to "1234" ``` -Within external script files, PCRE sequences presented as long-bracketed Lua string literals do not require modification. - +Within external script files, PCRE sequences presented as long-bracketed Lua string literals do not require modification. + ```lua -- test.lua @@ -811,6 +831,22 @@ Within external script files, PCRE sequences presented as long-bracketed Lua str -- evaluates to "1234" ``` +As noted earlier, PCRE sequences presented within `*_by_lua_block {}` directives (available following the `v0.9.17` release) do not require modification. + +```nginx + + # nginx.conf + location /test { + content_by_lua_block { + local regex = "\d+" + local m = ngx.re.match("hello, 1234", regex) + if m then ngx.say(m[0]) else ngx.say("not matched!") end + } + } + # evaluates to "1234" +``` + + [Back to TOC](#table-of-contents) Mixing with SSI Not Supported @@ -871,7 +907,6 @@ servers in Lua. For example, * cosocket: pool-based backend concurrency level control: implement automatic `connect` queueing when the backend concurrency exceeds its connection pool limit. * cosocket: review and merge aviramc's [patch](https://github.com/openresty/lua-nginx-module/pull/290) for adding the `bsdrecv` method. * add new API function `ngx.resp.add_header` to emulate the standard `add_header` config directive. -* review and apply Jader H. Silva's patch for `ngx.re.split()`. * review and apply vadim-pavlov's patch for [ngx.location.capture](#ngxlocationcapture)'s `extra_headers` option * use `ngx_hash_t` to optimize the built-in header look-up process for [ngx.req.set_header](#ngxreqset_header), [ngx.header.HEADER](#ngxheaderheader), and etc. * add configure options for different strategies of handling the cosocket connection exceeding in the pools. @@ -879,14 +914,14 @@ servers in Lua. For example, * add `ignore_resp_headers`, `ignore_resp_body`, and `ignore_resp` options to [ngx.location.capture](#ngxlocationcapture) and [ngx.location.capture_multi](#ngxlocationcapture_multi) methods, to allow micro performance tuning on the user side. * add automatic Lua code time slicing support by yielding and resuming the Lua VM actively via Lua's debug hooks. * add `stat` mode similar to [mod_lua](https://httpd.apache.org/docs/trunk/mod/mod_lua.html). -* cosocket: add client SSL certificiate support. +* cosocket: add client SSL certificate support. [Back to TOC](#table-of-contents) Changes ======= -The changes of every release of this module can be obtained from the OpenResty bundle's change logs: +The changes made in every release of this module are listed in the change logs of the OpenResty bundle: @@ -955,9 +990,9 @@ Copyright and License This module is licensed under the BSD license. -Copyright (C) 2009-2016, by Xiaozhe Wang (chaoslawful) . +Copyright (C) 2009-2017, by Xiaozhe Wang (chaoslawful) . -Copyright (C) 2009-2016, by Yichun "agentzh" Zhang (章亦春) , CloudFlare Inc. +Copyright (C) 2009-2017, by Yichun "agentzh" Zhang (章亦春) , OpenResty Inc. All rights reserved. @@ -1001,6 +1036,7 @@ See Also Directives ========== +* [lua_capture_error_log](#lua_capture_error_log) * [lua_use_default_type](#lua_use_default_type) * [lua_malloc_trim](#lua_malloc_trim) * [lua_code_cache](#lua_code_cache) @@ -1074,6 +1110,56 @@ how the result will be used. Below is a diagram showing the order in which direc [Back to TOC](#table-of-contents) +lua_capture_error_log +--------------------- +**syntax:** *lua_capture_error_log size* + +**default:** *none* + +**context:** *http* + +Enables a buffer of the specified `size` for capturing all the nginx error log message data (not just those produced +by this module or the nginx http subsystem, but everything) without touching files or disks. + +You can use units like `k` and `m` in the `size` value, as in + +```nginx + + lua_capture_error_log 100k; +``` + +As a rule of thumb, a 4KB buffer can usually hold about 20 typical error log messages. So do the maths! + +This buffer never grows. If it is full, new error log messages will replace the oldest ones in the buffer. + +The size of the buffer must be bigger than the maximum length of a single error log message (which is 4K in OpenResty and 2K in stock NGINX). + +You can read the messages in the buffer on the Lua land via the +[get_logs()](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/errlog.md#get_logs) +function of the +[ngx.errlog](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/errlog.md#readme) +module of the [lua-resty-core](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/errlog.md#readme) +library. This Lua API function will return the captured error log messages and +also remove these already read from the global capturing buffer, making room +for any new error log data. For this reason, the user should not configure this +buffer to be too big if the user read the buffered error log data fast enough. + +Note that the log level specified in the standard [error_log](http://nginx.org/r/error_log) directive +*does* have effect on this capturing facility. It only captures log +messages of a level no lower than the specified log level in the [error_log](http://nginx.org/r/error_log) directive. +The user can still choose to set an even higher filtering log level on the fly via the Lua API function +[errlog.set_filter_level](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/errlog.md#set_filter_level). +So it is more flexible than the static [error_log](http://nginx.org/r/error_log) directive. + +It is worth noting that there is no way to capture the debugging logs +without building OpenResty or NGINX with the `./configure` +option `--with-debug`. And enabling debugging logs is +strongly discouraged in production builds due to high overhead. + +This directive was first introduced in the `v0.10.9` release. + +[Back to TOC](#directives) + lua_use_default_type -------------------- **syntax:** *lua_use_default_type on | off* @@ -1082,7 +1168,7 @@ lua_use_default_type **context:** *http, server, location, location if* -Specifies whether to use the MIME type specified by the [default_type](http://nginx.org/en/docs/http/ngx_http_core_module.html#default_type) directive for the default value of the `Content-Type` response header. If you do not want a default `Content-Type` response header for your Lua request handlers, then turn this directive off. +Specifies whether to use the MIME type specified by the [default_type](http://nginx.org/en/docs/http/ngx_http_core_module.html#default_type) directive for the default value of the `Content-Type` response header. Deactivate this directive if a default `Content-Type` response header for Lua request handlers is not desired. This directive is turned on by default. @@ -1153,8 +1239,8 @@ The ngx_lua module does not support the `stat` mode available with the Apache `mod_lua` module (yet). Disabling the Lua code cache is strongly -discouraged for production use and should only be used during -development as it has a significant negative impact on overall performance. For example, the performance a "hello world" Lua example can drop by an order of magnitude after disabling the Lua code cache. +discouraged for production use and should only be used during +development as it has a significant negative impact on overall performance. For example, the performance of a "hello world" Lua example can drop by an order of magnitude after disabling the Lua code cache. [Back to TOC](#directives) @@ -1176,6 +1262,8 @@ The default number of entries allowed is 1024 and when this limit is reached, ne 2011/08/27 23:18:26 [warn] 31997#0: *1 lua exceeding regex cache max entries (1024), ... +If you are using the `ngx.re.*` implementation of [lua-resty-core](https://github.com/openresty/lua-resty-core) by loading the `resty.core.regex` module (or just the `resty.core` module), then an LRU cache is used for the regex cache being used here. + Do not activate the `o` option for regular expressions (and/or `replace` string arguments for [ngx.re.sub](#ngxresub) and [ngx.re.gsub](#ngxregsub)) that are generated *on the fly* and give rise to infinite variations to avoid hitting the specified limit. [Back to TOC](#directives) @@ -1241,8 +1329,7 @@ init_by_lua **phase:** *loading-config* -**WARNING** Since the `v0.9.17` release, use of this directive is *discouraged*; -use the new [init_by_lua_block](#init_by_lua_block) directive instead. +**NOTE** Use of this directive is *discouraged* following the `v0.9.17` release. Use the [init_by_lua_block](#init_by_lua_block) directive instead. Runs the Lua code specified by the argument `` on the global Lua VM level when the Nginx master process (if any) is loading the Nginx config file. @@ -1358,7 +1445,7 @@ init_worker_by_lua **phase:** *starting-worker* -**WARNING** Since the `v0.9.17` release, use of this directive is *discouraged*; use the new [init_worker_by_lua_block](#init_worker_by_lua_block) directive instead. +**NOTE** Use of this directive is *discouraged* following the `v0.9.17` release. Use the [init_worker_by_lua_block](#init_worker_by_lua_block) directive instead. Runs the specified Lua code upon every Nginx worker process's startup when the master process is enabled. When the master process is disabled, this hook will just run after [init_by_lua*](#init_by_lua). @@ -1384,8 +1471,8 @@ This hook is often used to create per-worker reoccurring timers (via the [ngx.ti end end - local ok, err = new_timer(delay, check) - if not ok then + local hdl, err = new_timer(delay, check) + if not hdl then log(ERR, "failed to create timer: ", err) return end @@ -1447,7 +1534,7 @@ set_by_lua **phase:** *rewrite* -**WARNING** Since the `v0.9.17` release, use of this directive is *discouraged*; use the new [set_by_lua_block](#set_by_lua_block) directive instead. +**NOTE** Use of this directive is *discouraged* following the `v0.9.17` release. Use the [set_by_lua_block](#set_by_lua_block) directive instead. Executes code specified in `` with optional input arguments `$arg1 $arg2 ...`, and returns string output to `$res`. The code in `` can make [API calls](#nginx-api-for-lua) and can retrieve input arguments from the `ngx.arg` table (index starts from `1` and increases sequentially). @@ -1537,15 +1624,15 @@ set_by_lua_file **phase:** *rewrite* -Equivalent to [set_by_lua](#set_by_lua), except that the file specified by `` contains the Lua code, or, as from the `v0.5.0rc32` release, the [Lua/LuaJIT bytecode](#lualuajit-bytecode-support) to be executed. +Equivalent to [set_by_lua](#set_by_lua), except that the file specified by `` contains the Lua code, or, as from the `v0.5.0rc32` release, the [Lua/LuaJIT bytecode](#lualuajit-bytecode-support) to be executed. Nginx variable interpolation is supported in the `` argument string of this directive. But special care must be taken for injection attacks. When a relative path like `foo/bar.lua` is given, they will be turned into the absolute path relative to the `server prefix` path determined by the `-p PATH` command-line option while starting the Nginx server. -When the Lua code cache is turned on (by default), the user code is loaded once at the first request and cached +When the Lua code cache is turned on (by default), the user code is loaded once at the first request and cached and the Nginx config must be reloaded each time the Lua source file is modified. -The Lua code cache can be temporarily disabled during development by +The Lua code cache can be temporarily disabled during development by switching [lua_code_cache](#lua_code_cache) `off` in `nginx.conf` to avoid reloading Nginx. This directive requires the [ngx_devel_kit](https://github.com/simpl/ngx_devel_kit) module. @@ -1561,10 +1648,9 @@ content_by_lua **phase:** *content* -**WARNING** Since the `v0.9.17` release, use of this directive is *discouraged*; -use the new [content_by_lua_block](#content_by_lua_block) directive instead. +**NOTE** Use of this directive is *discouraged* following the `v0.9.17` release. Use the [content_by_lua_block](#content_by_lua_block) directive instead. -Acts as a "content handler" and executes Lua code string specified in `` for every request. +Acts as a "content handler" and executes Lua code string specified in `` for every request. The Lua code may make [API calls](#nginx-api-for-lua) and is executed as a new spawned coroutine in an independent global environment (i.e. a sandbox). Do not use this directive and other content handler directives in the same location. For example, this directive and the [proxy_pass](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass) directive should not be used in the same location. @@ -1613,16 +1699,16 @@ Nginx variables can be used in the `` string to provide When a relative path like `foo/bar.lua` is given, they will be turned into the absolute path relative to the `server prefix` path determined by the `-p PATH` command-line option while starting the Nginx server. -When the Lua code cache is turned on (by default), the user code is loaded once at the first request and cached +When the Lua code cache is turned on (by default), the user code is loaded once at the first request and cached and the Nginx config must be reloaded each time the Lua source file is modified. -The Lua code cache can be temporarily disabled during development by +The Lua code cache can be temporarily disabled during development by switching [lua_code_cache](#lua_code_cache) `off` in `nginx.conf` to avoid reloading Nginx. Nginx variables are supported in the file path for dynamic dispatch, for example: ```nginx - # WARNING: contents in nginx var must be carefully filtered, + # CAUTION: contents in nginx var must be carefully filtered, # otherwise there'll be great security risk! location ~ ^/app/([-_a-zA-Z0-9/]+) { set $path $1; @@ -1643,8 +1729,7 @@ rewrite_by_lua **phase:** *rewrite tail* -**WARNING** Since the `v0.9.17` release, use of this directive is *discouraged*; -use the new [rewrite_by_lua_block](#rewrite_by_lua_block) directive instead. +**NOTE** Use of this directive is *discouraged* following the `v0.9.17` release. Use the [rewrite_by_lua_block](#rewrite_by_lua_block) directive instead. Acts as a rewrite phase handler and executes Lua code string specified in `` for every request. The Lua code may make [API calls](#nginx-api-for-lua) and is executed as a new spawned coroutine in an independent global environment (i.e. a sandbox). @@ -1820,8 +1905,7 @@ access_by_lua **phase:** *access tail* -**WARNING** Since the `v0.9.17` release, use of this directive is *discouraged*; -use the new [access_by_lua_block](#access_by_lua_block) directive instead. +**NOTE** Use of this directive is *discouraged* following the `v0.9.17` release. Use the [access_by_lua_block](#access_by_lua_block) directive instead. Acts as an access phase handler and executes Lua code string specified in `` for every request. The Lua code may make [API calls](#nginx-api-for-lua) and is executed as a new spawned coroutine in an independent global environment (i.e. a sandbox). @@ -1933,7 +2017,7 @@ Nginx variables can be used in the `` string to provide When a relative path like `foo/bar.lua` is given, they will be turned into the absolute path relative to the `server prefix` path determined by the `-p PATH` command-line option while starting the Nginx server. -When the Lua code cache is turned on (by default), the user code is loaded once at the first request and cached +When the Lua code cache is turned on (by default), the user code is loaded once at the first request and cached and the Nginx config must be reloaded each time the Lua source file is modified. The Lua code cache can be temporarily disabled during development by switching [lua_code_cache](#lua_code_cache) `off` in `nginx.conf` to avoid repeatedly reloading Nginx. @@ -1950,8 +2034,7 @@ header_filter_by_lua **phase:** *output-header-filter* -**WARNING** Since the `v0.9.17` release, use of this directive is *discouraged*; -use the new [header_filter_by_lua_block](#header_filter_by_lua_block) directive instead. +**NOTE** Use of this directive is *discouraged* following the `v0.9.17` release. Use the [header_filter_by_lua_block](#header_filter_by_lua_block) directive instead. Uses Lua code specified in `` to define an output header filter. @@ -2029,8 +2112,7 @@ body_filter_by_lua **phase:** *output-body-filter* -**WARNING** Since the `v0.9.17` release, use of this directive is *discouraged*; -use the new [body_filter_by_lua_block](#body_filter_by_lua_block) directive instead. +**NOTE** Use of this directive is *discouraged* following the `v0.9.17` release. Use the [body_filter_by_lua_block](#body_filter_by_lua_block) directive instead. Uses Lua code specified in `` to define an output body filter. @@ -2166,15 +2248,14 @@ log_by_lua **phase:** *log* -**WARNING** Since the `v0.9.17` release, use of this directive is *discouraged*; -use the new [log_by_lua_block](#log_by_lua_block) directive instead. +**NOTE** Use of this directive is *discouraged* following the `v0.9.17` release. Use the [log_by_lua_block](#log_by_lua_block) directive instead. Runs the Lua source code inlined as the `` at the `log` request processing phase. This does not replace the current access logs, but runs before. Note that the following API functions are currently disabled within this context: * Output API functions (e.g., [ngx.say](#ngxsay) and [ngx.send_headers](#ngxsend_headers)) -* Control API functions (e.g., [ngx.exit](#ngxexit)) +* Control API functions (e.g., [ngx.exit](#ngxexit)) * Subrequest API functions (e.g., [ngx.location.capture](#ngxlocationcapture) and [ngx.location.capture_multi](#ngxlocationcapture_multi)) * Cosocket API functions (e.g., [ngx.socket.tcp](#ngxsockettcp) and [ngx.req.socket](#ngxreqsocket)). @@ -2883,7 +2964,7 @@ lua_http10_buffering **context:** *http, server, location, location-if* -Enables or disables automatic response buffering for HTTP 1.0 (or older) requests. This buffering mechanism is mainly used for HTTP 1.0 keep-alive which replies on a proper `Content-Length` response header. +Enables or disables automatic response buffering for HTTP 1.0 (or older) requests. This buffering mechanism is mainly used for HTTP 1.0 keep-alive which relies on a proper `Content-Length` response header. If the Lua code explicitly sets a `Content-Length` response header before sending the headers (either explicitly via [ngx.send_headers](#ngxsend_headers) or implicitly via the first [ngx.say](#ngxsay) or [ngx.print](#ngxprint) call), then the HTTP 1.0 response buffering will be disabled even when this directive is turned on. @@ -2951,7 +3032,7 @@ lua_check_client_abort This directive controls whether to check for premature client connection abortion. -When this directive is turned on, the ngx_lua module will monitor the premature connection close event on the downstream connections. And when there is such an event, it will call the user Lua function callback (registered by [ngx.on_abort](#ngxon_abort)) or just stop and clean up all the Lua "light threads" running in the current request's request handler when there is no user callback function registered. +When this directive is on, the ngx_lua module will monitor the premature connection close event on the downstream connections and when there is such an event, it will call the user Lua function callback (registered by [ngx.on_abort](#ngxon_abort)) or just stop and clean up all the Lua "light threads" running in the current request's request handler when there is no user callback function registered. According to the current implementation, however, if the client closes the connection before the Lua code finishes reading the request body data via [ngx.req.socket](#ngxreqsocket), then ngx_lua will neither stop all the running "light threads" nor call the user callback (if [ngx.on_abort](#ngxon_abort) has been called). Instead, the reading operation on [ngx.req.socket](#ngxreqsocket) will just return the error message "client aborted" as the second return value (the first return value is surely `nil`). @@ -3136,6 +3217,7 @@ Nginx API for Lua * [ngx.thread.kill](#ngxthreadkill) * [ngx.on_abort](#ngxon_abort) * [ngx.timer.at](#ngxtimerat) +* [ngx.timer.every](#ngxtimerevery) * [ngx.timer.running_count](#ngxtimerrunning_count) * [ngx.timer.pending_count](#ngxtimerpending_count) * [ngx.config.subsystem](#ngxconfigsubsystem) @@ -3280,7 +3362,7 @@ Setting `ngx.var.Foo` to a `nil` value will unset the `$Foo` Nginx variable. ngx.var.args = nil ``` -**WARNING** When reading from an Nginx variable, Nginx will allocate memory in the per-request memory pool which is freed only at request termination. So when you need to read from an Nginx variable repeatedly in your Lua code, cache the Nginx variable value to your own Lua variable, for example, +**CAUTION** When reading from an Nginx variable, Nginx will allocate memory in the per-request memory pool which is freed only at request termination. So when you need to read from an Nginx variable repeatedly in your Lua code, cache the Nginx variable value to your own Lua variable, for example, ```lua @@ -3438,7 +3520,7 @@ ngx.ctx ------- **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** -This table can be used to store per-request Lua context data and has a life time identical to the current request (as with the Nginx variables). +This table can be used to store per-request Lua context data and has a life time identical to the current request (as with the Nginx variables). Consider the following example, @@ -3541,7 +3623,7 @@ When being used in the context of [init_worker_by_lua*](#init_worker_by_lua), th The `ngx.ctx` lookup requires relatively expensive metamethod calls and it is much slower than explicitly passing per-request data along by your own function arguments. So do not abuse this API for saving your own function arguments because it usually has quite some performance impact. -Because of the metamethod magic, never "local" the `ngx.ctx` table outside your Lua function scope on the Lua module level level due to [worker-level data sharing](#data-sharing-within-an-nginx-worker). For example, the following is bad: +Because of the metamethod magic, never "local" the `ngx.ctx` table outside your Lua function scope on the Lua module level due to [worker-level data sharing](#data-sharing-within-an-nginx-worker). For example, the following is bad: ```lua @@ -3549,7 +3631,7 @@ Because of the metamethod magic, never "local" the `ngx.ctx` table outside your local _M = {} -- the following line is bad since ngx.ctx is a per-request - -- data while this `ctx` variable is on the Lua module level + -- data while this ctx variable is on the Lua module level -- and thus is per-nginx-worker. local ctx = ngx.ctx @@ -3701,7 +3783,7 @@ The `args` option can also take plain query strings: This is functionally identical to the previous examples. -The `share_all_vars` option controls whether to share nginx variables among the current request and its subrequests. +The `share_all_vars` option controls whether to share nginx variables among the current request and its subrequests. If this option is set to `true`, then the current request and associated subrequests will share the same Nginx variable scope. Hence, changes to Nginx variables made by a subrequest will affect the current request. Care should be taken in using this option as variable scope sharing can have unexpected side effects. The `args`, `vars`, or `copy_all_vars` options are generally preferable instead. @@ -3768,7 +3850,7 @@ In addition to the two settings above, it is possible to specify values for variables in the subrequest using the `vars` option. These variables are set after the sharing or copying of variables has been evaluated, and provides a more efficient method of passing specific -values to a subrequest over encoding them as URL arguments and +values to a subrequest over encoding them as URL arguments and unescaping them in the Nginx config file. ```nginx @@ -3853,7 +3935,7 @@ Note that subrequests issued by [ngx.location.capture](#ngxlocationcapture) inhe request headers of the current request by default and that this may have unexpected side effects on the subrequest responses. For example, when using the standard `ngx_proxy` module to serve subrequests, an "Accept-Encoding: gzip" header in the main request may result -in gzipped responses that cannot be handled properly in Lua code. Original request headers should be ignored by setting +in gzipped responses that cannot be handled properly in Lua code. Original request headers should be ignored by setting [proxy_pass_request_headers](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass_request_headers) to `off` in subrequest locations. When the `body` option is not specified and the `always_forward_body` option is false (the default value), the `POST` and `PUT` subrequests will inherit the request bodies of the parent request (if any). @@ -3993,7 +4075,7 @@ will yield Set-Cookie: b=4; path=/ ``` -in the response headers. +in the response headers. Only Lua tables are accepted (Only the last element in the table will take effect for standard headers such as `Content-Type` that only accept a single value). @@ -4025,7 +4107,7 @@ The same applies to assigning an empty table: 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. -Reading `ngx.header.HEADER` will return the value of the response header named `HEADER`. +Reading `ngx.header.HEADER` will return the value of the response header named `HEADER`. Underscores (`_`) in the header names will also be replaced by dashes (`-`) and the header names will be matched case-insensitively. If the response header is not present at all, `nil` will be returned. @@ -4536,7 +4618,7 @@ That is, they will take Lua boolean values `true`. However, they are different f Empty key arguments are discarded. `POST /test` with body `=hello&=world` will yield empty outputs for instance. -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. +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. However, the optional `max_args` function argument can be used to override this limit: @@ -4597,7 +4679,7 @@ the value of `ngx.req.get_headers()["Foo"]` will be a Lua (array) table such as: {"foo", "bar", "baz"} ``` -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. +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. However, the optional `max_headers` function argument can be used to override this limit: @@ -4999,6 +5081,7 @@ The optional `status` parameter specifies the HTTP status code to be used. The f * `301` * `302` (default) +* `303` * `307` It is `302` (`ngx.HTTP_MOVED_TEMPORARILY`) by default. @@ -5237,7 +5320,7 @@ Note that while this method accepts all [HTTP status constants](#http-status-con 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. -When being used in the contexts of [header_filter_by_lua](#header_filter_by_lua) and +When being used in the contexts of [header_filter_by_lua*](#header_filter_by_lua), [balancer_by_lua*](#balancer_by_lua_block), and [ssl_session_store_by_lua*](#ssl_session_store_by_lua_block), `ngx.exit()` is an asynchronous operation and will return immediately. This behavior may change in future and it is recommended that users always use `return` in combination as suggested above. @@ -5251,7 +5334,7 @@ ngx.eof Explicitly specify the end of the response output stream. In the case of HTTP 1.1 chunked encoded output, it will just trigger the Nginx core to send out the "last chunk". -When you disable the HTTP 1.1 keep-alive feature for your downstream connections, you can rely on descent HTTP clients to close the connection actively for you when you call this method. This trick can be used do back-ground jobs without letting the HTTP clients to wait on the connection, as in the following example: +When you disable the HTTP 1.1 keep-alive feature for your downstream connections, you can rely on well written HTTP clients to close the connection actively for you when you call this method. This trick can be used do back-ground jobs without letting the HTTP clients to wait on the connection, as in the following example: ```nginx @@ -5259,7 +5342,7 @@ When you disable the HTTP 1.1 keep-alive feature for your downstream connections keepalive_timeout 0; content_by_lua_block { ngx.say("got the task!") - ngx.eof() -- a descent HTTP client will close the connection at this point + ngx.eof() -- well written HTTP clients will close the connection at this point -- access MySQL, PostgreSQL, Redis, Memcached, and etc here... } } @@ -5576,7 +5659,7 @@ ngx.time Returns the elapsed seconds from the epoch for the current time stamp from the nginx cached time (no syscall involved unlike Lua's date library). -Updates of the Nginx time cache an be forced by calling [ngx.update_time](#ngxupdate_time) first. +Updates of the Nginx time cache can be forced by calling [ngx.update_time](#ngxupdate_time) first. [Back to TOC](#nginx-api-for-lua) @@ -5826,7 +5909,7 @@ The optional fourth argument, `ctx`, can be a Lua table holding an optional `pos local ctx = { pos = 2 } local m, err = ngx.re.match("1234, hello", "[0-9]+", "", ctx) - -- m[0] = "34" + -- m[0] = "234" -- ctx.pos == 5 ``` @@ -6006,7 +6089,7 @@ When the `replace` is a string, then it is treated as a special template for str where `$0` referring to the whole substring matched by the pattern and `$1` referring to the first parenthesized capturing substring. -Curly braces can also be used to disambiguate variable names from the background string literals: +Curly braces can also be used to disambiguate variable names from the background string literals: ```lua @@ -6116,6 +6199,8 @@ The resulting object `dict` has the following methods: * [flush_expired](#ngxshareddictflush_expired) * [get_keys](#ngxshareddictget_keys) +All these methods are *atomic* operations, that is, safe from concurrent accesses from multiple nginx worker processes for the same `lua_shared_dict` zone. + Here is an example: ```nginx @@ -6495,7 +6580,7 @@ Fetch a list of the keys from the dictionary, up to ``. By default, only the first 1024 keys (if any) are returned. When the `` argument is given the value `0`, then all the keys will be returned even there is more than 1024 keys in the dictionary. -**WARNING** Be careful when calling this method on dictionaries with a really huge number of keys. This method may lock the dictionary for quite a while and block all the nginx worker processes that are trying to access the dictionary. +**CAUTION** Avoid calling this method on dictionaries with a very large number of keys as it may lock the dictionary for significant amount of time and block Nginx worker processes trying to access the dictionary. This feature was first introduced in the `v0.7.3` release. @@ -7280,7 +7365,7 @@ Then it will generate the output 4 -"Light threads" are mostly useful for doing concurrent upstream requests in a single Nginx request handler, kinda like a generalized version of [ngx.location.capture_multi](#ngxlocationcapture_multi) that can work with all the [Nginx API for Lua](#nginx-api-for-lua). The following example demonstrates parallel requests to MySQL, Memcached, and upstream HTTP services in a single Lua handler, and outputting the results in the order that they actually return (very much like the Facebook BigPipe model): +"Light threads" are mostly useful for making concurrent upstream requests in a single Nginx request handler, much like a generalized version of [ngx.location.capture_multi](#ngxlocationcapture_multi) that can work with all the [Nginx API for Lua](#nginx-api-for-lua). The following example demonstrates parallel requests to MySQL, Memcached, and upstream HTTP services in a single Lua handler, and outputting the results in the order that they actually return (similar to Facebook's BigPipe model): ```lua @@ -7486,7 +7571,7 @@ See also [lua_check_client_abort](#lua_check_client_abort). ngx.timer.at ------------ -**syntax:** *ok, err = ngx.timer.at(delay, callback, user_arg1, user_arg2, ...)* +**syntax:** *hdl, err = ngx.timer.at(delay, callback, user_arg1, user_arg2, ...)* **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** @@ -7512,7 +7597,7 @@ Premature timer expiration happens when the Nginx worker process is trying to shut down, as in an Nginx configuration reload triggered by the `HUP` signal or in an Nginx server shutdown. When the Nginx worker is trying to shut down, one can no longer call `ngx.timer.at` to -create new timers with nonzero delays and in that case `ngx.timer.at` will return `nil` and +create new timers with nonzero delays and in that case `ngx.timer.at` will return a "conditional false" value and a string describing the error, that is, "process exiting". Starting from the `v0.9.3` release, it is allowed to create zero-delay timers even when the Nginx worker process starts shutting down. @@ -7571,6 +7656,9 @@ One can also create infinite re-occurring timers, for instance, a timer getting end ``` +It is recommended, however, to use the [ngx.timer.every](#ngxtimerevery) API function +instead for creating recurring timers since it is more robust. + Because timer callbacks run in the background and their running time will not add to any client request's response time, they can easily accumulate in the server and exhaust system resources due to either @@ -7610,6 +7698,25 @@ This API was first introduced in the `v0.8.0` release. [Back to TOC](#nginx-api-for-lua) +ngx.timer.every +--------------- +**syntax:** *hdl, err = ngx.timer.every(delay, callback, user_arg1, user_arg2, ...)* + +**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** + +Similar to the [ngx.timer.at](#ngxtimerat) API function, but + +1. `delay` *cannot* be zero, +1. timer will be created every `delay` seconds until the current Nginx worker process starts exiting. + +When success, returns a "conditional true" value (but not a `true`). Otherwise, returns a "conditional false" value and a string describing the error. + +This API also respect the [lua_max_pending_timers](#lua_max_pending_timers) and [lua_max_running_timers](#lua_max_running_timers). + +This API was first introduced in the `v0.10.9` release. + +[Back to TOC](#nginx-api-for-lua) + ngx.timer.running_count ----------------------- **syntax:** *count = ngx.timer.running_count()* diff --git a/debian/modules/nginx-lua/config b/debian/modules/nginx-lua/config index 01a6b3c..044deb9 100644 --- a/debian/modules/nginx-lua/config +++ b/debian/modules/nginx-lua/config @@ -360,6 +360,7 @@ HTTP_LUA_SRCS=" \ $ngx_addon_dir/src/ngx_http_lua_ssl_session_storeby.c \ $ngx_addon_dir/src/ngx_http_lua_ssl_session_fetchby.c \ $ngx_addon_dir/src/ngx_http_lua_ssl.c \ + $ngx_addon_dir/src/ngx_http_lua_log_ringbuf.c \ " HTTP_LUA_DEPS=" \ @@ -420,6 +421,7 @@ HTTP_LUA_DEPS=" \ $ngx_addon_dir/src/ngx_http_lua_ssl_session_storeby.h \ $ngx_addon_dir/src/ngx_http_lua_ssl_session_fetchby.h \ $ngx_addon_dir/src/ngx_http_lua_ssl.h \ + $ngx_addon_dir/src/ngx_http_lua_log_ringbuf.h \ " CFLAGS="$CFLAGS -DNDK_SET_VAR" @@ -472,33 +474,6 @@ ngx_feature_test='setsockopt(1, SOL_SOCKET, SO_PASSCRED, NULL, 0);' . auto/feature -ngx_feature="mmap(sbrk(0))" -ngx_feature_libs= -ngx_feature_name="NGX_HTTP_LUA_HAVE_MMAP_SBRK" -ngx_feature_run=yes -ngx_feature_incs="#include -#include -#include -#include -#define align_ptr(p, a) \ - (u_char *) (((uintptr_t) (p) + ((uintptr_t) a - 1)) & ~((uintptr_t) a - 1)) -" -ngx_feature_test=" -#if defined(__x86_64__) -exit(mmap(align_ptr(sbrk(0), getpagesize()), 1, PROT_READ, - MAP_FIXED|MAP_PRIVATE|MAP_ANON, -1, 0) < (void *) 0x40000000LL - ? 0 : 1); -#else -exit(1); -#endif -" -SAVED_CC_TEST_FLAGS="$CC_TEST_FLAGS" -CC_TEST_FLAGS="-Werror -Wall $CC_TEST_FLAGS" - -. auto/feature - -CC_TEST_FLAGS="$SAVED_CC_TEST_FLAGS" - ngx_feature="__attribute__(constructor)" ngx_feature_libs= ngx_feature_name="NGX_HTTP_LUA_HAVE_CONSTRUCTOR" diff --git a/debian/modules/nginx-lua/doc/HttpLuaModule.wiki b/debian/modules/nginx-lua/doc/HttpLuaModule.wiki index be454af..8393056 100644 --- a/debian/modules/nginx-lua/doc/HttpLuaModule.wiki +++ b/debian/modules/nginx-lua/doc/HttpLuaModule.wiki @@ -10,40 +10,40 @@ Production ready. = Version = -This document describes ngx_lua [https://github.com/openresty/lua-nginx-module/tags v0.10.7] released on 4 November 2016. +This document describes ngx_lua [https://github.com/openresty/lua-nginx-module/tags v0.10.10] released on 8 August 2017. = Synopsis = # set search paths for pure Lua external libraries (';;' is the default path): lua_package_path '/foo/bar/?.lua;/blah/?.lua;;'; - + # set search paths for Lua external libraries written in C (can also use ';;'): lua_package_cpath '/bar/baz/?.so;/blah/blah/?.so;;'; - + server { location /lua_content { # MIME type determined by default_type: default_type 'text/plain'; - + content_by_lua_block { ngx.say('Hello,world!') } } - + location /nginx_var { # MIME type determined by default_type: default_type 'text/plain'; - + # try access /nginx_var?a=hello,world content_by_lua_block { ngx.say(ngx.var.arg_a) } } - + location = /request_body { client_max_body_size 50k; client_body_buffer_size 50k; - + content_by_lua_block { ngx.req.read_body() -- explicitly read the req body local data = ngx.req.get_body_data() @@ -62,13 +62,13 @@ This document describes ngx_lua [https://github.com/openresty/lua-nginx-module/t end } } - + # transparent non-blocking I/O in Lua via subrequests # (well, a better way is to use cosockets) location = /lua { # MIME type determined by default_type: default_type 'text/plain'; - + content_by_lua_block { local res = ngx.location.capture("/some_other_location") if res then @@ -78,51 +78,51 @@ This document describes ngx_lua [https://github.com/openresty/lua-nginx-module/t end } } - + location = /foo { rewrite_by_lua_block { res = ngx.location.capture("/memc", { args = { cmd = "incr", key = ngx.var.uri } } ) } - + proxy_pass http://blah.blah.com; } - + location = /mixed { rewrite_by_lua_file /path/to/rewrite.lua; access_by_lua_file /path/to/access.lua; content_by_lua_file /path/to/content.lua; } - + # use nginx var in code path - # WARNING: contents in nginx var must be carefully filtered, + # CAUTION: contents in nginx var must be carefully filtered, # otherwise there'll be great security risk! location ~ ^/app/([-_a-zA-Z0-9/]+) { set $path $1; content_by_lua_file /path/to/lua/app/root/$path.lua; } - + location / { client_max_body_size 100k; client_body_buffer_size 100k; - + access_by_lua_block { -- check the client IP address is in our black list if ngx.var.remote_addr == "132.5.72.3" then ngx.exit(ngx.HTTP_FORBIDDEN) end - + -- check if the URI contains bad words if ngx.var.uri and string.match(ngx.var.request_body, "evil") then return ngx.redirect("/terms_of_use.html") end - + -- tests passed } - + # proxy_pass/fastcgi_pass/etc settings } } @@ -197,7 +197,7 @@ Nginx cores older than 1.6.0 (exclusive) are *not* supported. = Installation = -It is highly recommended to use the [http://openresty.org OpenResty bundle] that bundles Nginx, ngx_lua, LuaJIT 2.0/2.1 (or the optional standard Lua 5.1 interpreter), as well as a package of powerful companion Nginx modules. The basic installation step is a simple command: ./configure --with-luajit && make && make install. +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. Alternatively, ngx_lua can be manually compiled into Nginx: @@ -220,31 +220,37 @@ Build the source with this module: # tell nginx's build system where to find LuaJIT 2.1: export LUAJIT_LIB=/path/to/luajit/lib export LUAJIT_INC=/path/to/luajit/include/luajit-2.1 - + # or tell where to find Lua if using Lua instead: #export LUA_LIB=/path/to/lua/lib #export LUA_INC=/path/to/lua/include - + # Here we assume Nginx is to be installed under /opt/nginx/. ./configure --prefix=/opt/nginx \ --with-ld-opt="-Wl,-rpath,/path/to/luajit-or-lua/lib" \ --add-module=/path/to/ngx_devel_kit \ --add-module=/path/to/lua-nginx-module - + + # Note that you may also want to add `./configure` options which are used in your + # current nginx build. + # You can get usually those options using command nginx -V + + # you can change the parallism number 2 below to fit the number of spare CPU cores in your + # machine. make -j2 make install == Building as a dynamic module == -Starting from NGINX 1.9.11, you can also compile this module as a dynamic module, by using the `--add-dynamic-module=PATH` option instead of `--add-module=PATH` on the -`./configure` command line above. And then you can explicitly load the module in your `nginx.conf` via the [load_module](http://nginx.org/en/docs/ngx_core_module.html#load_module) +Starting from NGINX 1.9.11, you can also compile this module as a dynamic module, by using the --add-dynamic-module=PATH option instead of --add-module=PATH on the +./configure command line above. And then you can explicitly load the module in your nginx.conf via the [load_module](http://nginx.org/en/docs/ngx_core_module.html#load_module) directive, for example, -```nginx + load_module /path/to/modules/ndk_http_module.so; # assuming NDK is built as a dynamic module too load_module /path/to/modules/ngx_http_lua_module.so; -``` + == C Macro Configurations == @@ -309,13 +315,13 @@ As from the v0.5.0rc32 release, all *_by_lua_file conf 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: - /path/to/luajit/bin/luajit -b /path/to/input_file.lua /path/to/output_file.luac + /path/to/luajit/bin/luajit -b /path/to/input_file.lua /path/to/output_file.ljbc The -bg option can be used to include debug information in the LuaJIT bytecode file: - /path/to/luajit/bin/luajit -bg /path/to/input_file.lua /path/to/output_file.luac + /path/to/luajit/bin/luajit -bg /path/to/input_file.lua /path/to/output_file.ljbc Please refer to the official LuaJIT documentation on the -b option for more details: @@ -451,7 +457,7 @@ Here is a complete small example: cat = 4, pig = 5, } - + function _M.get_age(name) return data[name] end @@ -495,9 +501,9 @@ If server-wide data sharing is required, then use one or more of the following a = Known Issues = == TCP socket connect operation issues == -The [[#tcpsock:connect|tcpsock:connect]] method may indicate success despite connection failures such as with Connection Refused errors. +The [[#tcpsock:connect|tcpsock:connect]] method may indicate success despite connection failures such as with Connection Refused errors. -However, later attempts to manipulate the cosocket object will fail and return the actual error status message generated by the failed connect operation. +However, later attempts to manipulate the cosocket object will fail and return the actual error status message generated by the failed connect operation. This issue is due to limitations in the Nginx event model and only appears to affect Mac OS X. @@ -520,15 +526,28 @@ instead of the old deprecated form: Here is the reason: by design, the global environment has exactly the same lifetime as the Nginx request handler associated with it. Each request handler has its own set of Lua global variables and that is the idea of request isolation. The Lua module is actually loaded by the first Nginx request handler and is cached by the require() built-in in the package.loaded table for later reference, and the module() builtin used by some Lua modules has the side effect of setting a global variable to the loaded module table. But this global variable will be cleared at the end of the request handler, and every subsequent request handler all has its own (clean) global environment. So one will get Lua exception for accessing the nil value. -Generally, use of Lua global variables is a really really bad idea in the context of ngx_lua because +The use of Lua global variables is a generally inadvisable in the ngx_lua context as: -# misuse of Lua globals has very bad side effects for concurrent requests when these variables are actually supposed to be local only, -# Lua global variables require Lua table look-up in the global environment (which is just a Lua table), which is kinda expensive, and -# some Lua global variable references are just typos, which are hard to debug. +# the misuse of Lua globals has detrimental side effects on concurrent requests when such variables should instead be local in scope, +# Lua global variables require Lua table look-ups in the global environment which is computationally expensive, and +# some Lua global variable references may include typing errors which make such difficult to debug. -It's *highly* recommended to always declare them via "local" in the scope that is reasonable. +It is therefore *highly* recommended to always declare such within an appropriate local scope instead. -To find out all the uses of Lua global variables in your Lua code, you can run the [https://github.com/openresty/nginx-devel-utils/blob/master/lua-releng lua-releng tool] across all your .lua source files: + + -- Avoid + foo = 123 + -- Recommended + local foo = 123 + + -- Avoid + function foo() return 123 end + -- Recommended + local function foo() return 123 end + + + +To find all instances of Lua global variables in your Lua code, run the [https://github.com/openresty/nginx-devel-utils/blob/master/lua-releng lua-releng tool] across all .lua source files: $ lua-releng Checking use of Lua global variables in file lib/foo/bar.lua ... @@ -565,24 +584,23 @@ will not work as expected. == Cosockets Not Available Everywhere == -Due the internal limitations in the nginx core, the cosocket API are disabled in the following contexts: [[#set_by_lua|set_by_lua*]], [[#log_by_lua|log_by_lua*]], [[#header_filter_by_lua|header_filter_by_lua*]], and [[#body_filter_by_lua|body_filter_by_lua]]. +Due to internal limitations in the nginx core, the cosocket API is disabled in the following contexts: [[#set_by_lua|set_by_lua*]], [[#log_by_lua|log_by_lua*]], [[#header_filter_by_lua|header_filter_by_lua*]], and [[#body_filter_by_lua|body_filter_by_lua]]. The cosockets are currently also disabled in the [[#init_by_lua|init_by_lua*]] and [[#init_worker_by_lua|init_worker_by_lua*]] directive contexts but we may add support for these contexts in the future because there is no limitation in the nginx core (or the limitation might be worked around). -There exists a work-around, however, when the original context does *not* need to wait for the cosocket results. That is, creating a 0-delay timer via the [[#ngx.timer.at|ngx.timer.at]] API and do the cosocket results in the timer handler, which runs asynchronously as to the original context creating the timer. +There exists a work-around, however, when the original context does *not* need to wait for the cosocket results. That is, creating a zero-delay timer via the [[#ngx.timer.at|ngx.timer.at]] API and do the cosocket results in the timer handler, which runs asynchronously as to the original context creating the timer. == Special Escaping Sequences == -'''WARNING''' We no longer suffer from this pitfall since the introduction of the -*_by_lua_block {} configuration directives. +'''NOTE''' Following the v0.9.17 release, this pitfall can be avoided by using the *_by_lua_block {} configuration directives. -PCRE sequences such as \d, \s, or \w, require special attention because in string literals, the backslash character, \, is stripped out by both the Lua language parser and by the Nginx config file parser before processing. So the following snippet will not work as expected: +PCRE sequences such as \d, \s, or \w, require special attention because in string literals, the backslash character, \, is stripped out by both the Lua language parser and by the nginx config file parser before processing if not within a *_by_lua_block {} directive. So the following snippet will not work as expected: # nginx.conf ? location /test { ? content_by_lua ' - ? local regex = "\d+" -- THIS IS WRONG!! + ? local regex = "\d+" -- THIS IS WRONG OUTSIDE OF A *_by_lua_block DIRECTIVE ? local m = ngx.re.match("hello, 1234", regex) ? if m then ngx.say(m[0]) else ngx.say("not matched!") end ? '; @@ -606,7 +624,7 @@ To avoid this, ''double'' escape the backslash: Here, \\\\d+ is stripped down to \\d+ by the Nginx config file parser and this is further stripped down to \d+ by the Lua language parser before running. -Alternatively, the regex pattern can be presented as a long-bracketed Lua string literal by encasing it in "long brackets", [[...]], in which case backslashes have to only be escaped once for the Nginx config file parser. +Alternatively, the regex pattern can be presented as a long-bracketed Lua string literal by encasing it in "long brackets", [[...]], in which case backslashes have to only be escaped once for the Nginx config file parser. # nginx.conf @@ -622,7 +640,7 @@ Alternatively, the regex pattern can be presented as a long-bracketed Lua string Here, [[\\d+]] is stripped down to [[\d+]] by the Nginx config file parser and this is processed correctly. -Note that a longer from of the long bracket, [=[...]=], may be required if the regex pattern contains [...] sequences. +Note that a longer from of the long bracket, [=[...]=], may be required if the regex pattern contains [...] sequences. The [=[...]=] form may be used as the default form if desired. @@ -637,7 +655,7 @@ The [=[...]=] form may be used as the default form if desired. # evaluates to "1234" -An alternative approach to escaping PCRE sequences is to ensure that Lua code is placed in external script files and executed using the various *_by_lua_file directives. +An alternative approach to escaping PCRE sequences is to ensure that Lua code is placed in external script files and executed using the various *_by_lua_file directives. With this approach, the backslashes are only stripped by the Lua language parser and therefore only need to be escaped once each. @@ -648,8 +666,8 @@ With this approach, the backslashes are only stripped by the Lua language parser -- evaluates to "1234" -Within external script files, PCRE sequences presented as long-bracketed Lua string literals do not require modification. - +Within external script files, PCRE sequences presented as long-bracketed Lua string literals do not require modification. + -- test.lua local regex = [[\d+]] @@ -658,6 +676,21 @@ Within external script files, PCRE sequences presented as long-bracketed Lua str -- evaluates to "1234" +As noted earlier, PCRE sequences presented within *_by_lua_block {} directives (available following the v0.9.17 release) do not require modification. + + + # nginx.conf + location /test { + content_by_lua_block { + local regex = "\d+" + local m = ngx.re.match("hello, 1234", regex) + if m then ngx.say(m[0]) else ngx.say("not matched!") end + } + } + # evaluates to "1234" + + + == Mixing with SSI Not Supported == Mixing SSI with ngx_lua in the same Nginx request is not supported at all. Just use ngx_lua exclusively. Everything you can do with SSI can be done atop ngx_lua anyway and it can be more efficient when using ngx_lua. @@ -705,7 +738,6 @@ servers in Lua. For example, * cosocket: pool-based backend concurrency level control: implement automatic connect queueing when the backend concurrency exceeds its connection pool limit. * cosocket: review and merge aviramc's [https://github.com/openresty/lua-nginx-module/pull/290 patch] for adding the bsdrecv method. * add new API function ngx.resp.add_header to emulate the standard add_header config directive. -* review and apply Jader H. Silva's patch for ngx.re.split(). * review and apply vadim-pavlov's patch for [[#ngx.location.capture|ngx.location.capture]]'s extra_headers option * use ngx_hash_t to optimize the built-in header look-up process for [[#ngx.req.set_header|ngx.req.set_header]], [[#ngx.header.HEADER|ngx.header.HEADER]], and etc. * add configure options for different strategies of handling the cosocket connection exceeding in the pools. @@ -713,11 +745,11 @@ servers in Lua. For example, * add ignore_resp_headers, ignore_resp_body, and ignore_resp options to [[#ngx.location.capture|ngx.location.capture]] and [[#ngx.location.capture_multi|ngx.location.capture_multi]] methods, to allow micro performance tuning on the user side. * add automatic Lua code time slicing support by yielding and resuming the Lua VM actively via Lua's debug hooks. * add stat mode similar to [https://httpd.apache.org/docs/trunk/mod/mod_lua.html mod_lua]. -* cosocket: add client SSL certificiate support. +* cosocket: add client SSL certificate support. = Changes = -The changes of every release of this module can be obtained from the OpenResty bundle's change logs: +The changes made in every release of this module are listed in the change logs of the OpenResty bundle: http://openresty.org/#Changes @@ -772,7 +804,7 @@ To run specific test files: prove -I/path/to/test-nginx/lib t/002-content.t t/003-errors.t -To run a specific test block in a particular test file, add the line --- ONLY to the test block you want to run, and then use the `prove` utility to run that .t file. +To run a specific test block in a particular test file, add the line --- ONLY to the test block you want to run, and then use the prove utility to run that .t file. There are also various testing modes based on mockeagain, valgrind, and etc. Refer to the [http://search.cpan.org/perldoc?Test::Nginx Test::Nginx documentation] for more details for various advanced testing modes. See also the test reports for the Nginx test cluster running on Amazon EC2: http://qa.openresty.org. @@ -780,9 +812,9 @@ There are also various testing modes based on mockeagain, valgrind, and etc. Ref This module is licensed under the BSD license. -Copyright (C) 2009-2016, by Xiaozhe Wang (chaoslawful) . +Copyright (C) 2009-2017, by Xiaozhe Wang (chaoslawful) . -Copyright (C) 2009-2016, by Yichun "agentzh" Zhang (章亦春) , CloudFlare Inc. +Copyright (C) 2009-2017, by Yichun "agentzh" Zhang (章亦春) , OpenResty Inc. All rights reserved. @@ -827,6 +859,52 @@ how the result will be used. Below is a diagram showing the order in which direc ![Lua Nginx Modules Directives](https://cloud.githubusercontent.com/assets/2137369/15272097/77d1c09e-1a37-11e6-97ef-d9767035fc3e.png) +== lua_capture_error_log == +'''syntax:''' ''lua_capture_error_log size'' + +'''default:''' ''none'' + +'''context:''' ''http'' + +Enables a buffer of the specified size for capturing all the nginx error log message data (not just those produced +by this module or the nginx http subsystem, but everything) without touching files or disks. + +You can use units like `k` and `m` in the size value, as in + + + lua_capture_error_log 100k; + + +As a rule of thumb, a 4KB buffer can usually hold about 20 typical error log messages. So do the maths! + +This buffer never grows. If it is full, new error log messages will replace the oldest ones in the buffer. + +The size of the buffer must be bigger than the maximum length of a single error log message (which is 4K in OpenResty and 2K in stock NGINX). + +You can read the messages in the buffer on the Lua land via the +[https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/errlog.md#get_logs get_logs()] +function of the +[https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/errlog.md#readme ngx.errlog] +module of the [https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/errlog.md#readme lua-resty-core] +library. This Lua API function will return the captured error log messages and +also remove these already read from the global capturing buffer, making room +for any new error log data. For this reason, the user should not configure this +buffer to be too big if the user read the buffered error log data fast enough. + +Note that the log level specified in the standard [http://nginx.org/r/error_log error_log] directive +''does'' have effect on this capturing facility. It only captures log +messages of a level no lower than the specified log level in the [http://nginx.org/r/error_log error_log] directive. +The user can still choose to set an even higher filtering log level on the fly via the Lua API function +[https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/errlog.md#set_filter_level errlog.set_filter_level]. +So it is more flexible than the static [http://nginx.org/r/error_log error_log] directive. + +It is worth noting that there is no way to capture the debugging logs +without building OpenResty or NGINX with the ./configure +option --with-debug. And enabling debugging logs is +strongly discouraged in production builds due to high overhead. + +This directive was first introduced in the v0.10.9 release. + == lua_use_default_type == '''syntax:''' ''lua_use_default_type on | off'' @@ -834,7 +912,7 @@ how the result will be used. Below is a diagram showing the order in which direc '''context:''' ''http, server, location, location if'' -Specifies whether to use the MIME type specified by the [http://nginx.org/en/docs/http/ngx_http_core_module.html#default_type default_type] directive for the default value of the Content-Type response header. If you do not want a default Content-Type response header for your Lua request handlers, then turn this directive off. +Specifies whether to use the MIME type specified by the [http://nginx.org/en/docs/http/ngx_http_core_module.html#default_type default_type] directive for the default value of the Content-Type response header. Deactivate this directive if a default Content-Type response header for Lua request handlers is not desired. This directive is turned on by default. @@ -898,8 +976,8 @@ The ngx_lua module does not support the stat mode available with th Apache mod_lua module (yet). Disabling the Lua code cache is strongly -discouraged for production use and should only be used during -development as it has a significant negative impact on overall performance. For example, the performance a "hello world" Lua example can drop by an order of magnitude after disabling the Lua code cache. +discouraged for production use and should only be used during +development as it has a significant negative impact on overall performance. For example, the performance of a "hello world" Lua example can drop by an order of magnitude after disabling the Lua code cache. == lua_regex_cache_max_entries == '''syntax:''' ''lua_regex_cache_max_entries '' @@ -918,6 +996,8 @@ The default number of entries allowed is 1024 and when this limit is reached, ne 2011/08/27 23:18:26 [warn] 31997#0: *1 lua exceeding regex cache max entries (1024), ... +If you are using the ngx.re.* implementation of [lua-resty-core](https://github.com/openresty/lua-resty-core) by loading the resty.core.regex module (or just the resty.core module), then an LRU cache is used for the regex cache being used here. + Do not activate the o option for regular expressions (and/or replace string arguments for [[#ngx.re.sub|ngx.re.sub]] and [[#ngx.re.gsub|ngx.re.gsub]]) that are generated ''on the fly'' and give rise to infinite variations to avoid hitting the specified limit. == lua_regex_match_limit == @@ -971,8 +1051,7 @@ As from the v0.5.0rc29 release, the special notation $prefix< '''phase:''' ''loading-config'' -'''WARNING''' Since the v0.9.17 release, use of this directive is ''discouraged''; -use the new [[#init_by_lua_block|init_by_lua_block]] directive instead. +'''NOTE''' Use of this directive is ''discouraged'' following the v0.9.17 release. Use the [[#init_by_lua_block|init_by_lua_block]] directive instead. Runs the Lua code specified by the argument on the global Lua VM level when the Nginx master process (if any) is loading the Nginx config file. @@ -1041,7 +1120,7 @@ This directive was first introduced in the v0.5.5 release. Similar to the [[#init_by_lua|init_by_lua]] directive except that this directive inlines the Lua source directly -inside a pair of curly braces (`{}`) instead of in an NGINX string literal (which requires +inside a pair of curly braces ({}) instead of in an NGINX string literal (which requires special character escaping). For instance, @@ -1076,7 +1155,7 @@ This directive was first introduced in the v0.5.5 release. '''phase:''' ''starting-worker'' -'''WARNING''' Since the v0.9.17 release, use of this directive is ''discouraged''; use the new [[#init_worker_by_lua_block|init_worker_by_lua_block]] directive instead. +'''NOTE''' Use of this directive is ''discouraged'' following the v0.9.17 release. Use the [[#init_worker_by_lua_block|init_worker_by_lua_block]] directive instead. Runs the specified Lua code upon every Nginx worker process's startup when the master process is enabled. When the master process is disabled, this hook will just run after [[#init_by_lua|init_by_lua*]]. @@ -1101,8 +1180,8 @@ This hook is often used to create per-worker reoccurring timers (via the [[#ngx. end end - local ok, err = new_timer(delay, check) - if not ok then + local hdl, err = new_timer(delay, check) + if not hdl then log(ERR, "failed to create timer: ", err) return end @@ -1121,7 +1200,7 @@ This directive was first introduced in the v0.9.5 release. Similar to the [[#init_worker_by_lua|init_worker_by_lua]] directive except that this directive inlines the Lua source directly -inside a pair of curly braces (`{}`) instead of in an NGINX string literal (which requires +inside a pair of curly braces ({}) instead of in an NGINX string literal (which requires special character escaping). For instance, @@ -1154,7 +1233,7 @@ This directive was first introduced in the v0.9.5 release. '''phase:''' ''rewrite'' -'''WARNING''' Since the v0.9.17 release, use of this directive is ''discouraged''; use the new [[#set_by_lua_block|set_by_lua_block]] directive instead. +'''NOTE''' Use of this directive is ''discouraged'' following the v0.9.17 release. Use the [[#set_by_lua_block|set_by_lua_block]] directive instead. Executes code specified in with optional input arguments $arg1 $arg2 ..., and returns string output to $res. The code in can make [[#Nginx API for Lua|API calls]] and can retrieve input arguments from the ngx.arg table (index starts from 1 and increases sequentially). @@ -1177,15 +1256,15 @@ a time. However, a workaround is possible using the [[#ngx.var.VARIABLE|ngx.var. location /foo { set $diff ''; # we have to predefine the $diff variable here - + set_by_lua $sum ' local a = 32 local b = 56 - + ngx.var.diff = a - b; -- write to $diff directly return a + b; -- return the $sum value normally '; - + echo "sum = $sum, diff = $diff"; } @@ -1213,7 +1292,7 @@ This directive requires the [https://github.com/simpl/ngx_devel_kit ngx_devel_ki Similar to the [[#set_by_lua|set_by_lua]] directive except that # this directive inlines the Lua source directly -inside a pair of curly braces (`{}`) instead of in an NGINX string literal (which requires +inside a pair of curly braces ({}) instead of in an NGINX string literal (which requires special character escaping), and # this directive does not support extra arguments after the Lua script as in [[#set_by_lua|set_by_lua]]. @@ -1235,15 +1314,15 @@ This directive was first introduced in the v0.9.17 release. '''phase:''' ''rewrite'' -Equivalent to [[#set_by_lua|set_by_lua]], except that the file specified by contains the Lua code, or, as from the v0.5.0rc32 release, the [[#Lua/LuaJIT bytecode support|Lua/LuaJIT bytecode]] to be executed. +Equivalent to [[#set_by_lua|set_by_lua]], except that the file specified by contains the Lua code, or, as from the v0.5.0rc32 release, the [[#Lua/LuaJIT bytecode support|Lua/LuaJIT bytecode]] to be executed. Nginx variable interpolation is supported in the argument string of this directive. But special care must be taken for injection attacks. When a relative path like foo/bar.lua is given, they will be turned into the absolute path relative to the server prefix path determined by the -p PATH command-line option while starting the Nginx server. -When the Lua code cache is turned on (by default), the user code is loaded once at the first request and cached +When the Lua code cache is turned on (by default), the user code is loaded once at the first request and cached and the Nginx config must be reloaded each time the Lua source file is modified. -The Lua code cache can be temporarily disabled during development by +The Lua code cache can be temporarily disabled during development by switching [[#lua_code_cache|lua_code_cache]] off in nginx.conf to avoid reloading Nginx. This directive requires the [https://github.com/simpl/ngx_devel_kit ngx_devel_kit] module. @@ -1256,10 +1335,9 @@ This directive requires the [https://github.com/simpl/ngx_devel_kit ngx_devel_ki '''phase:''' ''content'' -'''WARNING''' Since the v0.9.17 release, use of this directive is ''discouraged''; -use the new [[#content_by_lua_block|content_by_lua_block]] directive instead. +'''NOTE''' Use of this directive is ''discouraged'' following the v0.9.17 release. Use the [[#content_by_lua_block|content_by_lua_block]] directive instead. -Acts as a "content handler" and executes Lua code string specified in for every request. +Acts as a "content handler" and executes Lua code string specified in for every request. The Lua code may make [[#Nginx API for Lua|API calls]] and is executed as a new spawned coroutine in an independent global environment (i.e. a sandbox). Do not use this directive and other content handler directives in the same location. For example, this directive and the [[HttpProxyModule#proxy_pass|proxy_pass]] directive should not be used in the same location. @@ -1274,7 +1352,7 @@ Do not use this directive and other content handler directives in the same locat Similar to the [[#content_by_lua|content_by_lua]] directive except that this directive inlines the Lua source directly -inside a pair of curly braces (`{}`) instead of in an NGINX string literal (which requires +inside a pair of curly braces ({}) instead of in an NGINX string literal (which requires special character escaping). For instance, @@ -1301,15 +1379,15 @@ Nginx variables can be used in the string When a relative path like foo/bar.lua is given, they will be turned into the absolute path relative to the server prefix path determined by the -p PATH command-line option while starting the Nginx server. -When the Lua code cache is turned on (by default), the user code is loaded once at the first request and cached +When the Lua code cache is turned on (by default), the user code is loaded once at the first request and cached and the Nginx config must be reloaded each time the Lua source file is modified. -The Lua code cache can be temporarily disabled during development by +The Lua code cache can be temporarily disabled during development by switching [[#lua_code_cache|lua_code_cache]] off in nginx.conf to avoid reloading Nginx. Nginx variables are supported in the file path for dynamic dispatch, for example: - # WARNING: contents in nginx var must be carefully filtered, + # CAUTION: contents in nginx var must be carefully filtered, # otherwise there'll be great security risk! location ~ ^/app/([-_a-zA-Z0-9/]+) { set $path $1; @@ -1327,8 +1405,7 @@ But be very careful about malicious user inputs and always carefully validate or '''phase:''' ''rewrite tail'' -'''WARNING''' Since the v0.9.17 release, use of this directive is ''discouraged''; -use the new [[#rewrite_by_lua_block|rewrite_by_lua_block]] directive instead. +'''NOTE''' Use of this directive is ''discouraged'' following the v0.9.17 release. Use the [[#rewrite_by_lua_block|rewrite_by_lua_block]] directive instead. Acts as a rewrite phase handler and executes Lua code string specified in for every request. The Lua code may make [[#Nginx API for Lua|API calls]] and is executed as a new spawned coroutine in an independent global environment (i.e. a sandbox). @@ -1376,7 +1453,7 @@ The right way of doing this is as follows: return ngx.redirect("/bar"); end '; - + echo "res = $b"; } @@ -1388,11 +1465,11 @@ Note that the [http://www.grid.net.ru/nginx/eval.en.html ngx_eval] module can be eval $res { proxy_pass http://foo.com/check-spam; } - + if ($res = 'spam') { rewrite ^ /terms-of-use.html redirect; } - + fastcgi_pass ...; } @@ -1404,7 +1481,7 @@ can be implemented in ngx_lua as: internal; proxy_pass http://foo.com/check-spam; } - + location / { rewrite_by_lua ' local res = ngx.location.capture("/check-spam") @@ -1412,7 +1489,7 @@ can be implemented in ngx_lua as: return ngx.redirect("/terms-of-use.html") end '; - + fastcgi_pass ...; } @@ -1447,7 +1524,7 @@ The rewrite_by_lua code will always run at the end of the rew Similar to the [[#rewrite_by_lua|rewrite_by_lua]] directive except that this directive inlines the Lua source directly -inside a pair of curly braces (`{}`) instead of in an NGINX string literal (which requires +inside a pair of curly braces ({}) instead of in an NGINX string literal (which requires special character escaping). For instance, @@ -1488,8 +1565,7 @@ Nginx variables are supported in the file path for dynamic dispatch just as in [ '''phase:''' ''access tail'' -'''WARNING''' Since the v0.9.17 release, use of this directive is ''discouraged''; -use the new [[#access_by_lua_block|access_by_lua_block]] directive instead. +'''NOTE''' Use of this directive is ''discouraged'' following the v0.9.17 release. Use the [[#access_by_lua_block|access_by_lua_block]] directive instead. Acts as an access phase handler and executes Lua code string specified in for every request. The Lua code may make [[#Nginx API for Lua|API calls]] and is executed as a new spawned coroutine in an independent global environment (i.e. a sandbox). @@ -1502,12 +1578,12 @@ Note that this handler always runs ''after'' the standard [[HttpAccessModule]]. allow 192.168.1.0/24; allow 10.1.1.0/16; deny all; - + access_by_lua ' local res = ngx.location.capture("/mysql", { ... }) ... '; - + # proxy_pass/fastcgi_pass/... } @@ -1519,7 +1595,7 @@ Note that the [http://mdounin.ru/hg/ngx_http_auth_request_module/ ngx_auth_reque location / { auth_request /auth; - + # proxy_pass/fastcgi_pass/postgres_pass/... } @@ -1530,18 +1606,18 @@ can be implemented in ngx_lua as: location / { access_by_lua ' local res = ngx.location.capture("/auth") - + if res.status == ngx.HTTP_OK then return end - + if res.status == ngx.HTTP_FORBIDDEN then ngx.exit(res.status) end - + ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) '; - + # proxy_pass/fastcgi_pass/postgres_pass/... } @@ -1564,7 +1640,7 @@ of NGINX. Similar to the [[#access_by_lua|access_by_lua]] directive except that this directive inlines the Lua source directly -inside a pair of curly braces (`{}`) instead of in an NGINX string literal (which requires +inside a pair of curly braces ({}) instead of in an NGINX string literal (which requires special character escaping). For instance, @@ -1591,7 +1667,7 @@ Nginx variables can be used in the string When a relative path like foo/bar.lua is given, they will be turned into the absolute path relative to the server prefix path determined by the -p PATH command-line option while starting the Nginx server. -When the Lua code cache is turned on (by default), the user code is loaded once at the first request and cached +When the Lua code cache is turned on (by default), the user code is loaded once at the first request and cached and the Nginx config must be reloaded each time the Lua source file is modified. The Lua code cache can be temporarily disabled during development by switching [[#lua_code_cache|lua_code_cache]] off in nginx.conf to avoid repeatedly reloading Nginx. @@ -1605,8 +1681,7 @@ Nginx variables are supported in the file path for dynamic dispatch just as in [ '''phase:''' ''output-header-filter'' -'''WARNING''' Since the v0.9.17 release, use of this directive is ''discouraged''; -use the new [[#header_filter_by_lua_block|header_filter_by_lua_block]] directive instead. +'''NOTE''' Use of this directive is ''discouraged'' following the v0.9.17 release. Use the [[#header_filter_by_lua_block|header_filter_by_lua_block]] directive instead. Uses Lua code specified in to define an output header filter. @@ -1638,7 +1713,7 @@ This directive was first introduced in the v0.2.1rc20 release. Similar to the [[#header_filter_by_lua|header_filter_by_lua]] directive except that this directive inlines the Lua source directly -inside a pair of curly braces (`{}`) instead of in an NGINX string literal (which requires +inside a pair of curly braces ({}) instead of in an NGINX string literal (which requires special character escaping). For instance, @@ -1673,8 +1748,7 @@ This directive was first introduced in the v0.2.1rc20 release. '''phase:''' ''output-body-filter'' -'''WARNING''' Since the v0.9.17 release, use of this directive is ''discouraged''; -use the new [[#body_filter_by_lua_block|body_filter_by_lua_block]] directive instead. +'''NOTE''' Use of this directive is ''discouraged'' following the v0.9.17 release. Use the [[#body_filter_by_lua_block|body_filter_by_lua_block]] directive instead. Uses Lua code specified in to define an output body filter. @@ -1761,7 +1835,7 @@ This directive was first introduced in the v0.5.0rc32 release. Similar to the [[#body_filter_by_lua|body_filter_by_lua]] directive except that this directive inlines the Lua source directly -inside a pair of curly braces (`{}`) instead of in an NGINX string literal (which requires +inside a pair of curly braces ({}) instead of in an NGINX string literal (which requires special character escaping). For instance, @@ -1796,15 +1870,14 @@ This directive was first introduced in the v0.5.0rc32 release. '''phase:''' ''log'' -'''WARNING''' Since the v0.9.17 release, use of this directive is ''discouraged''; -use the new [[#log_by_lua_block|log_by_lua_block]] directive instead. +'''NOTE''' Use of this directive is ''discouraged'' following the v0.9.17 release. Use the [[#log_by_lua_block|log_by_lua_block]] directive instead. Runs the Lua source code inlined as the at the log request processing phase. This does not replace the current access logs, but runs before. Note that the following API functions are currently disabled within this context: * Output API functions (e.g., [[#ngx.say|ngx.say]] and [[#ngx.send_headers|ngx.send_headers]]) -* Control API functions (e.g., [[#ngx.exit|ngx.exit]]) +* Control API functions (e.g., [[#ngx.exit|ngx.exit]]) * Subrequest API functions (e.g., [[#ngx.location.capture|ngx.location.capture]] and [[#ngx.location.capture_multi|ngx.location.capture_multi]]) * Cosocket API functions (e.g., [[#ngx.socket.tcp|ngx.socket.tcp]] and [[#ngx.req.socket|ngx.req.socket]]). @@ -1838,7 +1911,7 @@ Here is an example of gathering average data for [[HttpUpstreamModule#$upstream_ local log_dict = ngx.shared.log_dict local sum = log_dict:get("upstream_time-sum") local nb = log_dict:get("upstream_time-nb") - + if nb and sum then ngx.say("average upstream response time: ", sum / nb, " (", nb, " reqs)") @@ -1862,7 +1935,7 @@ This directive was first introduced in the v0.5.0rc31 release. Similar to the [[#log_by_lua|log_by_lua]] directive except that this directive inlines the Lua source directly -inside a pair of curly braces (`{}`) instead of in an NGINX string literal (which requires +inside a pair of curly braces ({}) instead of in an NGINX string literal (which requires special character escaping). For instance, @@ -2430,7 +2503,7 @@ See also [[#lua_ssl_trusted_certificate|lua_ssl_trusted_certificate]]. '''context:''' ''http, server, location, location-if'' -Enables or disables automatic response buffering for HTTP 1.0 (or older) requests. This buffering mechanism is mainly used for HTTP 1.0 keep-alive which replies on a proper Content-Length response header. +Enables or disables automatic response buffering for HTTP 1.0 (or older) requests. This buffering mechanism is mainly used for HTTP 1.0 keep-alive which relies on a proper Content-Length response header. If the Lua code explicitly sets a Content-Length response header before sending the headers (either explicitly via [[#ngx.send_headers|ngx.send_headers]] or implicitly via the first [[#ngx.say|ngx.say]] or [[#ngx.print|ngx.print]] call), then the HTTP 1.0 response buffering will be disabled even when this directive is turned on. @@ -2486,7 +2559,7 @@ This directive was first introduced in the v0.5.0rc32 release. This directive controls whether to check for premature client connection abortion. -When this directive is turned on, the ngx_lua module will monitor the premature connection close event on the downstream connections. And when there is such an event, it will call the user Lua function callback (registered by [[#ngx.on_abort|ngx.on_abort]]) or just stop and clean up all the Lua "light threads" running in the current request's request handler when there is no user callback function registered. +When this directive is on, the ngx_lua module will monitor the premature connection close event on the downstream connections and when there is such an event, it will call the user Lua function callback (registered by [[#ngx.on_abort|ngx.on_abort]]) or just stop and clean up all the Lua "light threads" running in the current request's request handler when there is no user callback function registered. According to the current implementation, however, if the client closes the connection before the Lua code finishes reading the request body data via [[#ngx.req.socket|ngx.req.socket]], then ngx_lua will neither stop all the running "light threads" nor call the user callback (if [[#ngx.on_abort|ngx.on_abort]] has been called). Instead, the reading operation on [[#ngx.req.socket|ngx.req.socket]] will just return the error message "client aborted" as the second return value (the first return value is surely nil). @@ -2592,11 +2665,11 @@ Here is an example location /foo { set $a 32; set $b 56; - + set_by_lua $sum 'return tonumber(ngx.arg[1]) + tonumber(ngx.arg[2])' $a $b; - + echo $sum; } @@ -2646,7 +2719,7 @@ Setting ngx.var.Foo to a nil value will unset the -'''WARNING''' When reading from an Nginx variable, Nginx will allocate memory in the per-request memory pool which is freed only at request termination. So when you need to read from an Nginx variable repeatedly in your Lua code, cache the Nginx variable value to your own Lua variable, for example, +'''CAUTION''' When reading from an Nginx variable, Nginx will allocate memory in the per-request memory pool which is freed only at request termination. So when you need to read from an Nginx variable repeatedly in your Lua code, cache the Nginx variable value to your own Lua variable, for example, local val = ngx.var.some_var @@ -2655,7 +2728,7 @@ Setting ngx.var.Foo to a nil value will unset the nil while uninitialized (but defined) NGINX variables are evaluated to an empty Lua string. This API requires a relatively expensive metamethod call and it is recommended to avoid using it on hot code paths. @@ -2780,7 +2853,7 @@ There is a hard coded 2048 byte limitation on error message lengths == ngx.ctx == '''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*'' -This table can be used to store per-request Lua context data and has a life time identical to the current request (as with the Nginx variables). +This table can be used to store per-request Lua context data and has a life time identical to the current request (as with the Nginx variables). Consider the following example, @@ -2816,7 +2889,7 @@ Every request, including subrequests, has its own copy of the table. For example ngx.say("sub post: ", ngx.ctx.blah) } } - + location /main { content_by_lua_block { ngx.ctx.blah = 73 @@ -2847,7 +2920,7 @@ Internal redirection will destroy the original request ngx.ctx data ngx.say(ngx.ctx.foo) } } - + location /orig { content_by_lua_block { ngx.ctx.foo = "hello" @@ -2876,14 +2949,14 @@ When being used in the context of [[#init_worker_by_lua|init_worker_by_lua*]], t The ngx.ctx lookup requires relatively expensive metamethod calls and it is much slower than explicitly passing per-request data along by your own function arguments. So do not abuse this API for saving your own function arguments because it usually has quite some performance impact. -Because of the metamethod magic, never "local" the ngx.ctx table outside your Lua function scope on the Lua module level level due to [[#Data_Sharing_within_an_Nginx_Worker|worker-level data sharing]]. For example, the following is bad: +Because of the metamethod magic, never "local" the ngx.ctx table outside your Lua function scope on the Lua module level due to [[#Data_Sharing_within_an_Nginx_Worker|worker-level data sharing]]. For example, the following is bad: -- mymodule.lua local _M = {} -- the following line is bad since ngx.ctx is a per-request --- data while this `ctx` variable is on the Lua module level +-- data while this ctx variable is on the Lua module level -- and thus is per-nginx-worker. local ctx = ngx.ctx @@ -2907,7 +2980,7 @@ end return _M -That is, let the caller pass the `ctx` table explicitly via a function argument. +That is, let the caller pass the ctx table explicitly via a function argument. == ngx.location.capture == '''syntax:''' ''res = ngx.location.capture(uri, options?)'' @@ -3024,7 +3097,7 @@ The args option can also take plain query strings: This is functionally identical to the previous examples. -The share_all_vars option controls whether to share nginx variables among the current request and its subrequests. +The share_all_vars option controls whether to share nginx variables among the current request and its subrequests. If this option is set to true, then the current request and associated subrequests will share the same Nginx variable scope. Hence, changes to Nginx variables made by a subrequest will affect the current request. Care should be taken in using this option as variable scope sharing can have unexpected side effects. The args, vars, or copy_all_vars options are generally preferable instead. @@ -3089,7 +3162,7 @@ In addition to the two settings above, it is possible to specify values for variables in the subrequest using the vars option. These variables are set after the sharing or copying of variables has been evaluated, and provides a more efficient method of passing specific -values to a subrequest over encoding them as URL arguments and +values to a subrequest over encoding them as URL arguments and unescaping them in the Nginx config file. @@ -3171,7 +3244,7 @@ Note that subrequests issued by [[#ngx.location.capture|ngx.location.capture]] i request headers of the current request by default and that this may have unexpected side effects on the subrequest responses. For example, when using the standard ngx_proxy module to serve subrequests, an "Accept-Encoding: gzip" header in the main request may result -in gzipped responses that cannot be handled properly in Lua code. Original request headers should be ignored by setting +in gzipped responses that cannot be handled properly in Lua code. Original request headers should be ignored by setting [[HttpProxyModule#proxy_pass_request_headers|proxy_pass_request_headers]] to off in subrequest locations. When the body option is not specified and the always_forward_body option is false (the default value), the POST and PUT subrequests will inherit the request bodies of the parent request (if any). @@ -3201,11 +3274,11 @@ This function issues several parallel subrequests specified by the input table a { "/bar" }, { "/baz", { method = ngx.HTTP_POST, body = "hello" } }, } - + if res1.status == ngx.HTTP_OK then ... end - + if res2.body == "BLAH" then ... end @@ -3223,10 +3296,10 @@ Lua tables can be used for both requests and responses when the number of subreq table.insert(reqs, { "/postgres" }) table.insert(reqs, { "/redis" }) table.insert(reqs, { "/memcached" }) - + -- issue all the requests at once and wait until they all return local resps = { ngx.location.capture_multi(reqs) } - + -- loop over the responses table for i, resp in ipairs(resps) do -- process the response table "resp" @@ -3278,7 +3351,7 @@ The header names are matched case-insensitively. -- equivalent to ngx.header["Content-Type"] = 'text/plain' ngx.header.content_type = 'text/plain'; - + ngx.header["X-My-Header"] = 'blah blah'; @@ -3295,7 +3368,7 @@ will yield Set-Cookie: b=4; path=/ -in the response headers. +in the response headers. Only Lua tables are accepted (Only the last element in the table will take effect for standard headers such as Content-Type that only accept a single value). @@ -3323,7 +3396,7 @@ The same applies to assigning an empty table: Setting ngx.header.HEADER 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. -Reading ngx.header.HEADER will return the value of the response header named HEADER. +Reading ngx.header.HEADER will return the value of the response header named HEADER. Underscores (_) in the header names will also be replaced by dashes (-) and the header names will be matched case-insensitively. If the response header is not present at all, nil will be returned. @@ -3655,8 +3728,8 @@ Arguments without the = parts are treated as boolean argumen That is, they will take Lua boolean values true. However, they are different from arguments taking empty string values. GET /test?foo=&bar= will give something like - foo: - bar: + foo: + bar: Empty key arguments are discarded. GET /test?=hello&=world will yield an empty output for instance. @@ -3760,13 +3833,13 @@ Arguments without the = parts are treated as boolean argumen That is, they will take Lua boolean values true. However, they are different from arguments taking empty string values. POST /test with request body foo=&bar= will return something like - foo: - bar: + foo: + bar: Empty key arguments are discarded. POST /test with body =hello&=world will yield empty outputs for instance. -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. +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. However, the optional max_args function argument can be used to override this limit: @@ -3818,7 +3891,7 @@ the value of ngx.req.get_headers()["Foo"] will be a Lua (array) tab {"foo", "bar", "baz"} -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. +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. However, the optional max_headers function argument can be used to override this limit: @@ -4164,6 +4237,7 @@ The optional status parameter specifies the HTTP status code to be * 301 * 302 (default) +* 303 * 307 It is 302 (ngx.HTTP_MOVED_TEMPORARILY) by default. @@ -4367,7 +4441,7 @@ Note that while this method accepts all [[#HTTP status constants|HTTP status con 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. -When being used in the contexts of [[#header_filter_by_lua|header_filter_by_lua]] and +When being used in the contexts of [[#header_filter_by_lua|header_filter_by_lua*]], [[#balancer_by_lua_block|balancer_by_lua*]], and [[#ssl_session_store_by_lua_block|ssl_session_store_by_lua*]], ngx.exit() is an asynchronous operation and will return immediately. This behavior may change in future and it is recommended that users always use return in combination as suggested above. @@ -4378,14 +4452,14 @@ an asynchronous operation and will return immediately. This behavior may change Explicitly specify the end of the response output stream. In the case of HTTP 1.1 chunked encoded output, it will just trigger the Nginx core to send out the "last chunk". -When you disable the HTTP 1.1 keep-alive feature for your downstream connections, you can rely on descent HTTP clients to close the connection actively for you when you call this method. This trick can be used do back-ground jobs without letting the HTTP clients to wait on the connection, as in the following example: +When you disable the HTTP 1.1 keep-alive feature for your downstream connections, you can rely on well written HTTP clients to close the connection actively for you when you call this method. This trick can be used do back-ground jobs without letting the HTTP clients to wait on the connection, as in the following example: location = /async { keepalive_timeout 0; content_by_lua_block { ngx.say("got the task!") - ngx.eof() -- a descent HTTP client will close the connection at this point + ngx.eof() -- well written HTTP clients will close the connection at this point -- access MySQL, PostgreSQL, Redis, Memcached, and etc here... } } @@ -4646,7 +4720,7 @@ This is the local time. Returns the elapsed seconds from the epoch for the current time stamp from the nginx cached time (no syscall involved unlike Lua's date library). -Updates of the Nginx time cache an be forced by calling [[#ngx.update_time|ngx.update_time]] first. +Updates of the Nginx time cache can be forced by calling [[#ngx.update_time|ngx.update_time]] first. == ngx.now == '''syntax:''' ''secs = ngx.now()'' @@ -4858,7 +4932,7 @@ The optional fourth argument, ctx, can be a Lua table holding an op local ctx = { pos = 2 } local m, err = ngx.re.match("1234, hello", "[0-9]+", "", ctx) - -- m[0] = "34" + -- m[0] = "234" -- ctx.pos == 5 @@ -5024,7 +5098,7 @@ When the replace is a string, then it is treated as a special templ where $0 referring to the whole substring matched by the pattern and $1 referring to the first parenthesized capturing substring. -Curly braces can also be used to disambiguate variable names from the background string literals: +Curly braces can also be used to disambiguate variable names from the background string literals: local newstr, n, err = ngx.re.sub("hello, 1234", "[0-9]", "${0}00") @@ -5123,6 +5197,8 @@ The resulting object dict has the following methods: * [[#ngx.shared.DICT.flush_expired|flush_expired]] * [[#ngx.shared.DICT.get_keys|get_keys]] +All these methods are ''atomic'' operations, that is, safe from concurrent accesses from multiple nginx worker processes for the same lua_shared_dict zone. + Here is an example: @@ -5343,7 +5419,7 @@ The value argument and init argument can be any valid This method was first introduced in the v0.3.1rc22 release. -The optional `init` parameter was first added in the v0.10.6 release. +The optional init parameter was first added in the v0.10.6 release. See also [[#ngx.shared.DICT|ngx.shared.DICT]]. @@ -5445,7 +5521,7 @@ Fetch a list of the keys from the dictionary, up to . By default, only the first 1024 keys (if any) are returned. When the argument is given the value 0, then all the keys will be returned even there is more than 1024 keys in the dictionary. -'''WARNING''' Be careful when calling this method on dictionaries with a really huge number of keys. This method may lock the dictionary for quite a while and block all the nginx worker processes that are trying to access the dictionary. +'''CAUTION''' Avoid calling this method on dictionaries with a very large number of keys as it may lock the dictionary for significant amount of time and block Nginx worker processes trying to access the dictionary. This feature was first introduced in the v0.7.3 release. @@ -5724,7 +5800,7 @@ session userdata returned by a previous sslhandshake call for exactly the same target. For short-lived connections, reusing SSL sessions can usually speed up the handshake by one order by magnitude but it is not so useful if the connection pool is enabled. This argument defaults to -`nil`. If this argument takes the boolean `false` value, no SSL session +nil. If this argument takes the boolean false value, no SSL session userdata would return by this call and only a Lua boolean will be returned as the first return value; otherwise the current SSL session will always be returned as the first argument in case of successes. @@ -5737,7 +5813,7 @@ also used to validate the server name specified in the server certificate sent f the remote. The optional ssl_verify argument takes a Lua boolean value to -control whether to perform SSL verification. When set to `true`, the server +control whether to perform SSL verification. When set to true, the server certificate will be verified according to the CA certificates specified by the [[#lua_ssl_trusted_certificate|lua_ssl_trusted_certificate]] directive. You may also need to adjust the [[#lua_ssl_verify_depth|lua_ssl_verify_depth]] @@ -6148,7 +6224,7 @@ Then it will generate the output 4 -"Light threads" are mostly useful for doing concurrent upstream requests in a single Nginx request handler, kinda like a generalized version of [[#ngx.location.capture_multi|ngx.location.capture_multi]] that can work with all the [[#Nginx API for Lua|Nginx API for Lua]]. The following example demonstrates parallel requests to MySQL, Memcached, and upstream HTTP services in a single Lua handler, and outputting the results in the order that they actually return (very much like the Facebook BigPipe model): +"Light threads" are mostly useful for making concurrent upstream requests in a single Nginx request handler, much like a generalized version of [[#ngx.location.capture_multi|ngx.location.capture_multi]] that can work with all the [[#Nginx API for Lua|Nginx API for Lua]]. The following example demonstrates parallel requests to MySQL, Memcached, and upstream HTTP services in a single Lua handler, and outputting the results in the order that they actually return (similar to Facebook's BigPipe model): -- query mysql, memcached, and a remote http service at the same time, @@ -6187,7 +6263,7 @@ Then it will generate the output ngx.thread.spawn(query_mysql) -- create thread 1 ngx.thread.spawn(query_memcached) -- create thread 2 - ngx.thread.spawn(query_http) -- create thread 3 + ngx.thread.spawn(query_http) -- create thread 3 This API was first enabled in the v0.7.0 release. @@ -6338,7 +6414,7 @@ This API was first introduced in the v0.7.4 release. See also [[#lua_check_client_abort|lua_check_client_abort]]. == ngx.timer.at == -'''syntax:''' ''ok, err = ngx.timer.at(delay, callback, user_arg1, user_arg2, ...)'' +'''syntax:''' ''hdl, err = ngx.timer.at(delay, callback, user_arg1, user_arg2, ...)'' '''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*'' @@ -6364,7 +6440,7 @@ Premature timer expiration happens when the Nginx worker process is trying to shut down, as in an Nginx configuration reload triggered by the HUP signal or in an Nginx server shutdown. When the Nginx worker is trying to shut down, one can no longer call ngx.timer.at to -create new timers with nonzero delays and in that case ngx.timer.at will return nil and +create new timers with nonzero delays and in that case ngx.timer.at will return a "conditional false" value and a string describing the error, that is, "process exiting". Starting from the v0.9.3 release, it is allowed to create zero-delay timers even when the Nginx worker process starts shutting down. @@ -6413,7 +6489,7 @@ One can also create infinite re-occurring timers, for instance, a timer getting return end end - + local ok, err = ngx.timer.at(delay, handler) if not ok then ngx.log(ngx.ERR, "failed to create the timer: ", err) @@ -6421,6 +6497,9 @@ One can also create infinite re-occurring timers, for instance, a timer getting end +It is recommended, however, to use the [[#ngx.timer.every|ngx.timer.every]] API function +instead for creating recurring timers since it is more robust. + Because timer callbacks run in the background and their running time will not add to any client request's response time, they can easily accumulate in the server and exhaust system resources due to either @@ -6458,6 +6537,22 @@ You can pass most of the standard Lua values (nils, booleans, numbers, strings, This API was first introduced in the v0.8.0 release. +== ngx.timer.every == +'''syntax:''' ''hdl, err = ngx.timer.every(delay, callback, user_arg1, user_arg2, ...)'' + +'''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*'' + +Similar to the [[#ngx.timer.at|ngx.timer.at]] API function, but + +# delay ''cannot'' be zero, +# timer will be created every delay seconds until the current Nginx worker process starts exiting. + +When success, returns a "conditional true" value (but not a true). Otherwise, returns a "conditional false" value and a string describing the error. + +This API also respect the [[#lua_max_pending_timers|lua_max_pending_timers]] and [[#lua_max_running_timers|lua_max_running_timers]]. + +This API was first introduced in the v0.10.9 release. + == ngx.timer.running_count == '''syntax:''' ''count = ngx.timer.running_count()'' @@ -6481,8 +6576,8 @@ This directive was first introduced in the v0.9.20 release. '''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.*, init_by_lua*, init_worker_by_lua*'' -This string field indicates the current NGINX subsystem the current Lua environment is based on. For this module, this field always takes the string value `"http"`. For -[https://github.com/openresty/stream-lua-nginx-module#readme ngx_stream_lua_module], however, this field takes the value `"stream"`. +This string field indicates the current NGINX subsystem the current Lua environment is based on. For this module, this field always takes the string value "http". For +[https://github.com/openresty/stream-lua-nginx-module#readme ngx_stream_lua_module], however, this field takes the value "stream". This field was first introduced in the 0.10.1. @@ -6563,7 +6658,7 @@ This API was first introduced in the 0.9.5 release. Returns the total number of the Nginx worker processes (i.e., the value configured by the [http://nginx.org/en/docs/ngx_core_module.html#worker_processes worker_processes] -directive in `nginx.conf`). +directive in nginx.conf). This API was first introduced in the 0.9.20 release. @@ -6575,11 +6670,11 @@ This API was first introduced in the 0.9.20 release. Returns the ordinal number of the current Nginx worker processes (starting from number 0). -So if the total number of workers is `N`, then this method may return a number between 0 -and `N - 1` (inclusive). +So if the total number of workers is N, then this method may return a number between 0 +and N - 1 (inclusive). This function returns meaningful values only for NGINX 1.9.1+. With earlier versions of NGINX, it -always returns `nil`. +always returns nil. See also [[#ngx.worker.count|ngx.worker.count]]. diff --git a/debian/modules/nginx-lua/src/api/ngx_http_lua_api.h b/debian/modules/nginx-lua/src/api/ngx_http_lua_api.h index 3737149..cd64fc8 100644 --- a/debian/modules/nginx-lua/src/api/ngx_http_lua_api.h +++ b/debian/modules/nginx-lua/src/api/ngx_http_lua_api.h @@ -19,7 +19,7 @@ /* Public API for other Nginx modules */ -#define ngx_http_lua_version 10007 +#define ngx_http_lua_version 10010 typedef struct { diff --git a/debian/modules/nginx-lua/src/ngx_http_lua_api.c b/debian/modules/nginx-lua/src/ngx_http_lua_api.c index b72c707..7b590e7 100644 --- a/debian/modules/nginx-lua/src/ngx_http_lua_api.c +++ b/debian/modules/nginx-lua/src/ngx_http_lua_api.c @@ -56,11 +56,10 @@ ngx_http_lua_add_package_preload(ngx_conf_t *cf, const char *package, lua_pushcfunction(L, func); lua_setfield(L, -2, package); lua_pop(L, 2); - - return NGX_OK; } - /* L == NULL */ + /* we always register preload_hooks since we always create new Lua VMs + * when lua code cache is off. */ if (lmcf->preload_hooks == NULL) { lmcf->preload_hooks = @@ -176,7 +175,9 @@ ngx_http_lua_shared_memory_init(ngx_shm_zone_t *shm_zone, void *data) } zone->shm = shm_zone->shm; +#if defined(nginx_version) && nginx_version >= 1009000 zone->noreuse = shm_zone->noreuse; +#endif if (zone->init(zone, odata) != NGX_OK) { return NGX_ERROR; diff --git a/debian/modules/nginx-lua/src/ngx_http_lua_args.c b/debian/modules/nginx-lua/src/ngx_http_lua_args.c index 0c307d6..b43697c 100644 --- a/debian/modules/nginx-lua/src/ngx_http_lua_args.c +++ b/debian/modules/nginx-lua/src/ngx_http_lua_args.c @@ -184,7 +184,7 @@ ngx_http_lua_ngx_req_get_post_args(lua_State *L) if (r->request_body->temp_file) { lua_pushnil(L); - lua_pushliteral(L, "requesty body in temp file not supported"); + lua_pushliteral(L, "request body in temp file not supported"); return 2; } diff --git a/debian/modules/nginx-lua/src/ngx_http_lua_balancer.c b/debian/modules/nginx-lua/src/ngx_http_lua_balancer.c index 0adf787..2fa634e 100644 --- a/debian/modules/nginx-lua/src/ngx_http_lua_balancer.c +++ b/debian/modules/nginx-lua/src/ngx_http_lua_balancer.c @@ -314,7 +314,13 @@ ngx_http_lua_balancer_get_peer(ngx_peer_connection_t *pc, void *data) if (ctx->exited && ctx->exit_code != NGX_OK) { rc = ctx->exit_code; - if (rc == NGX_ERROR || rc == NGX_BUSY || rc == NGX_DECLINED) { + if (rc == NGX_ERROR + || rc == NGX_BUSY + || rc == NGX_DECLINED +#ifdef HAVE_BALANCER_STATUS_CODE_PATCH + || rc >= NGX_HTTP_SPECIAL_RESPONSE +#endif + ) { return rc; } @@ -640,7 +646,7 @@ ngx_http_lua_ffi_balancer_set_more_tries(ngx_http_request_t *r, int count, char **err) { #if (nginx_version >= 1007005) - ngx_uint_t max_tries; + ngx_uint_t max_tries, total; #endif ngx_http_lua_ctx_t *ctx; ngx_http_upstream_t *u; @@ -681,9 +687,10 @@ ngx_http_lua_ffi_balancer_set_more_tries(ngx_http_request_t *r, #if (nginx_version >= 1007005) max_tries = r->upstream->conf->next_upstream_tries; + total = bp->total_tries + r->upstream->peer.tries - 1; - if (bp->total_tries + count > max_tries) { - count = max_tries - bp->total_tries; + if (max_tries && total + count > max_tries) { + count = max_tries - total; *err = "reduced tries due to limit"; } else { diff --git a/debian/modules/nginx-lua/src/ngx_http_lua_common.h b/debian/modules/nginx-lua/src/ngx_http_lua_common.h index 267952b..e389783 100644 --- a/debian/modules/nginx-lua/src/ngx_http_lua_common.h +++ b/debian/modules/nginx-lua/src/ngx_http_lua_common.h @@ -22,6 +22,19 @@ #include +#if (NGX_PCRE) + +#include + +#if (PCRE_MAJOR > 8) || (PCRE_MAJOR == 8 && PCRE_MINOR >= 21) +# define LUA_HAVE_PCRE_JIT 1 +#else +# define LUA_HAVE_PCRE_JIT 0 +#endif + +#endif + + #if !defined(nginx_version) || (nginx_version < 1006000) #error at least nginx 1.6.0 is required but found an older version #endif @@ -138,7 +151,7 @@ typedef struct ngx_http_lua_sema_mm_s ngx_http_lua_sema_mm_t; typedef ngx_int_t (*ngx_http_lua_main_conf_handler_pt)(ngx_log_t *log, ngx_http_lua_main_conf_t *lmcf, lua_State *L); typedef ngx_int_t (*ngx_http_lua_srv_conf_handler_pt)(ngx_http_request_t *r, - ngx_http_lua_srv_conf_t *lmcf, lua_State *L); + ngx_http_lua_srv_conf_t *lscf, lua_State *L); typedef struct { @@ -168,6 +181,11 @@ struct ngx_http_lua_main_conf_s { ngx_int_t regex_cache_entries; ngx_int_t regex_cache_max_entries; ngx_int_t regex_match_limit; + +#if (LUA_HAVE_PCRE_JIT) + pcre_jit_stack *jit_stack; +#endif + #endif ngx_array_t *shm_zones; /* of ngx_shm_zone_t* */ @@ -199,6 +217,12 @@ struct ngx_http_lua_main_conf_s { of reqeusts */ ngx_uint_t malloc_trim_req_count; +#if nginx_version >= 1011011 + /* the following 2 fields are only used by ngx.req.raw_headers() for now */ + ngx_buf_t **busy_buf_ptrs; + ngx_int_t busy_buf_ptr_count; +#endif + unsigned requires_header_filter:1; unsigned requires_body_filter:1; unsigned requires_capture_filter:1; @@ -206,6 +230,7 @@ struct ngx_http_lua_main_conf_s { unsigned requires_access:1; unsigned requires_log:1; unsigned requires_shm:1; + unsigned requires_capture_log:1; }; diff --git a/debian/modules/nginx-lua/src/ngx_http_lua_control.c b/debian/modules/nginx-lua/src/ngx_http_lua_control.c index 249d763..ae36505 100644 --- a/debian/modules/nginx-lua/src/ngx_http_lua_control.c +++ b/debian/modules/nginx-lua/src/ngx_http_lua_control.c @@ -212,10 +212,12 @@ ngx_http_lua_ngx_redirect(lua_State *L) if (rc != NGX_HTTP_MOVED_TEMPORARILY && rc != NGX_HTTP_MOVED_PERMANENTLY + && rc != NGX_HTTP_SEE_OTHER && rc != NGX_HTTP_TEMPORARY_REDIRECT) { return luaL_error(L, "only ngx.HTTP_MOVED_TEMPORARILY, " - "ngx.HTTP_MOVED_PERMANENTLY, and " + "ngx.HTTP_MOVED_PERMANENTLY, " + "ngx.HTTP_SEE_OTHER, and " "ngx.HTTP_TEMPORARY_REDIRECT are allowed"); } diff --git a/debian/modules/nginx-lua/src/ngx_http_lua_directive.c b/debian/modules/nginx-lua/src/ngx_http_lua_directive.c index 862edda..6a562f4 100644 --- a/debian/modules/nginx-lua/src/ngx_http_lua_directive.c +++ b/debian/modules/nginx-lua/src/ngx_http_lua_directive.c @@ -27,6 +27,8 @@ #include "ngx_http_lua_ssl_certby.h" #include "ngx_http_lua_lex.h" #include "api/ngx_http_lua_api.h" +#include "ngx_http_lua_log_ringbuf.h" +#include "ngx_http_lua_log.h" typedef struct ngx_http_lua_block_parser_ctx_s @@ -1700,6 +1702,71 @@ ngx_http_lua_conf_read_lua_token(ngx_conf_t *cf, } +char * +ngx_http_lua_capture_error_log(ngx_conf_t *cf, ngx_command_t *cmd, + void *conf) +{ +#ifndef HAVE_INTERCEPT_ERROR_LOG_PATCH + return "not found: missing the capture error log patch for nginx"; +#else + ngx_str_t *value; + ssize_t size; + u_char *data; + ngx_cycle_t *cycle; + ngx_http_lua_main_conf_t *lmcf = conf; + ngx_http_lua_log_ringbuf_t *ringbuf; + + value = cf->args->elts; + cycle = cf->cycle; + + if (lmcf->requires_capture_log) { + return "is duplicate"; + } + + if (value[1].len == 0) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid capture error log size \"%V\"", + &value[1]); + return NGX_CONF_ERROR; + } + + size = ngx_parse_size(&value[1]); + + if (size < NGX_MAX_ERROR_STR) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid capture error log size \"%V\", " + "minimum size is %d", &value[1], + NGX_MAX_ERROR_STR); + return NGX_CONF_ERROR; + } + + if (cycle->intercept_error_log_handler) { + return "capture error log handler has been hooked"; + } + + ringbuf = (ngx_http_lua_log_ringbuf_t *) + ngx_palloc(cf->pool, sizeof(ngx_http_lua_log_ringbuf_t)); + if (ringbuf == NULL) { + return NGX_CONF_ERROR; + } + + data = ngx_palloc(cf->pool, size); + if (data == NULL) { + return NGX_CONF_ERROR; + } + + ngx_http_lua_log_ringbuf_init(ringbuf, data, size); + + lmcf->requires_capture_log = 1; + cycle->intercept_error_log_handler = (ngx_log_intercept_pt) + ngx_http_lua_capture_log_handler; + cycle->intercept_error_log_data = ringbuf; + + return NGX_CONF_OK; +#endif +} + + /* * ngx_http_lua_strlstrn() is intended to search for static substring * with known length in string until the argument last. The argument n diff --git a/debian/modules/nginx-lua/src/ngx_http_lua_directive.h b/debian/modules/nginx-lua/src/ngx_http_lua_directive.h index be591f3..5abfe4d 100644 --- a/debian/modules/nginx-lua/src/ngx_http_lua_directive.h +++ b/debian/modules/nginx-lua/src/ngx_http_lua_directive.h @@ -67,9 +67,10 @@ ngx_int_t ngx_http_lua_filter_set_by_lua_file(ngx_http_request_t *r, char *ngx_http_lua_rewrite_no_postpone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); - char *ngx_http_lua_conf_lua_block_parse(ngx_conf_t *cf, ngx_command_t *cmd); +char *ngx_http_lua_capture_error_log(ngx_conf_t *cf, ngx_command_t *cmd, + void *conf); #endif /* _NGX_HTTP_LUA_DIRECTIVE_H_INCLUDED_ */ diff --git a/debian/modules/nginx-lua/src/ngx_http_lua_headers.c b/debian/modules/nginx-lua/src/ngx_http_lua_headers.c index 0af56f6..6700ce8 100644 --- a/debian/modules/nginx-lua/src/ngx_http_lua_headers.c +++ b/debian/modules/nginx-lua/src/ngx_http_lua_headers.c @@ -26,6 +26,9 @@ static int ngx_http_lua_ngx_req_get_headers(lua_State *L); static int ngx_http_lua_ngx_req_header_clear(lua_State *L); static int ngx_http_lua_ngx_req_header_set(lua_State *L); static int ngx_http_lua_ngx_resp_get_headers(lua_State *L); +#if nginx_version >= 1011011 +void ngx_http_lua_ngx_raw_header_cleanup(void *data); +#endif static int @@ -77,6 +80,11 @@ ngx_http_lua_ngx_req_raw_header(lua_State *L) size_t size; ngx_buf_t *b, *first = NULL; ngx_int_t i, j; +#if nginx_version >= 1011011 + ngx_buf_t **bb; + ngx_chain_t *cl; + ngx_http_lua_main_conf_t *lmcf; +#endif ngx_connection_t *c; ngx_http_request_t *r, *mr; ngx_http_connection_t *hc; @@ -93,6 +101,10 @@ ngx_http_lua_ngx_req_raw_header(lua_State *L) return luaL_error(L, "no request object found"); } +#if nginx_version >= 1011011 + lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module); +#endif + ngx_http_lua_check_fake_request(L, r); mr = r->main; @@ -109,8 +121,13 @@ ngx_http_lua_ngx_req_raw_header(lua_State *L) dd("hc->nbusy: %d", (int) hc->nbusy); if (hc->nbusy) { +#if nginx_version >= 1011011 + dd("hc->busy: %p %p %p %p", hc->busy->buf->start, hc->busy->buf->pos, + hc->busy->buf->last, hc->busy->buf->end); +#else dd("hc->busy: %p %p %p %p", hc->busy[0]->start, hc->busy[0]->pos, hc->busy[0]->last, hc->busy[0]->end); +#endif } dd("request line: %p %p", mr->request_line.data, @@ -146,9 +163,37 @@ ngx_http_lua_ngx_req_raw_header(lua_State *L) dd("size: %d", (int) size); if (hc->nbusy) { +#if nginx_version >= 1011011 + if (hc->nbusy > lmcf->busy_buf_ptr_count) { + if (lmcf->busy_buf_ptrs) { + ngx_free(lmcf->busy_buf_ptrs); + } + + lmcf->busy_buf_ptrs = ngx_alloc(hc->nbusy * sizeof(ngx_buf_t *), + r->connection->log); + + if (lmcf->busy_buf_ptrs == NULL) { + return luaL_error(L, "no memory"); + } + + lmcf->busy_buf_ptr_count = hc->nbusy; + } + + bb = lmcf->busy_buf_ptrs; + for (cl = hc->busy; cl; cl = cl->next) { + *bb++ = cl->buf; + } +#endif b = NULL; + +#if nginx_version >= 1011011 + bb = lmcf->busy_buf_ptrs; + for (i = hc->nbusy; i > 0; i--) { + b = bb[i - 1]; +#else for (i = 0; i < hc->nbusy; i++) { b = hc->busy[i]; +#endif dd("busy buf: %d: [%.*s]", (int) i, (int) (b->pos - b->start), b->start); @@ -223,8 +268,15 @@ ngx_http_lua_ngx_req_raw_header(lua_State *L) } if (hc->nbusy) { + +#if nginx_version >= 1011011 + bb = lmcf->busy_buf_ptrs; + for (i = hc->nbusy - 1; i >= 0; i--) { + b = bb[i]; +#else for (i = 0; i < hc->nbusy; i++) { b = hc->busy[i]; +#endif if (!found) { if (b != first) { @@ -444,6 +496,8 @@ ngx_http_lua_ngx_resp_get_headers(lua_State *L) ngx_list_part_t *part; ngx_table_elt_t *header; ngx_http_request_t *r; + ngx_http_lua_ctx_t *ctx; + ngx_int_t rc; u_char *lowcase_key = NULL; size_t lowcase_key_sz = 0; ngx_uint_t i; @@ -475,6 +529,22 @@ ngx_http_lua_ngx_resp_get_headers(lua_State *L) return luaL_error(L, "no request object found"); } + ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); + if (ctx == NULL) { + return luaL_error(L, "no ctx found"); + } + + if (!ctx->headers_set) { + rc = ngx_http_lua_set_content_type(r); + if (rc != NGX_OK) { + return luaL_error(L, + "failed to set default content type: %d", + (int) rc); + } + + ctx->headers_set = 1; + } + ngx_http_lua_check_fake_request(L, r); part = &r->headers_out.headers.part; @@ -603,12 +673,19 @@ ngx_http_lua_ngx_header_get(lua_State *L) ngx_uint_t i; size_t len; ngx_http_lua_loc_conf_t *llcf; + ngx_http_lua_ctx_t *ctx; + ngx_int_t rc; r = ngx_http_lua_get_req(L); if (r == NULL) { return luaL_error(L, "no request object found"); } + ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); + if (ctx == NULL) { + return luaL_error(L, "no ctx found"); + } + ngx_http_lua_check_fake_request(L, r); /* we skip the first argument that is the table */ @@ -640,6 +717,17 @@ ngx_http_lua_ngx_header_get(lua_State *L) key.len = len; + if (!ctx->headers_set) { + rc = ngx_http_lua_set_content_type(r); + if (rc != NGX_OK) { + return luaL_error(L, + "failed to set default content type: %d", + (int) rc); + } + + ctx->headers_set = 1; + } + return ngx_http_lua_get_output_header(L, r, &key); } @@ -718,7 +806,7 @@ ngx_http_lua_ngx_header_set(lua_State *L) ngx_str_null(&value); } else if (lua_type(L, 3) == LUA_TTABLE) { - n = luaL_getn(L, 3); + n = lua_objlen(L, 3); if (n == 0) { ngx_str_null(&value); @@ -852,7 +940,7 @@ ngx_http_lua_ngx_req_header_set_helper(lua_State *L) ngx_str_null(&value); } else if (lua_type(L, 2) == LUA_TTABLE) { - n = luaL_getn(L, 2); + n = lua_objlen(L, 2); if (n == 0) { ngx_str_null(&value); @@ -1262,6 +1350,7 @@ ngx_http_lua_ffi_get_resp_header(ngx_http_request_t *r, ngx_uint_t i; ngx_table_elt_t *h; ngx_list_part_t *part; + ngx_http_lua_ctx_t *ctx; ngx_http_lua_loc_conf_t *llcf; @@ -1269,6 +1358,21 @@ ngx_http_lua_ffi_get_resp_header(ngx_http_request_t *r, return NGX_HTTP_LUA_FFI_BAD_CONTEXT; } + ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); + if (ctx == NULL) { + /* *errmsg = "no ctx found"; */ + return NGX_ERROR; + } + + if (!ctx->headers_set) { + if (ngx_http_lua_set_content_type(r) != NGX_OK) { + /* *errmsg = "failed to set default content type"; */ + return NGX_ERROR; + } + + ctx->headers_set = 1; + } + llcf = ngx_http_get_module_loc_conf(r, ngx_http_lua_module); if (llcf->transform_underscores_in_resp_headers && memchr(key, '_', key_len) != NULL) @@ -1379,4 +1483,20 @@ ngx_http_lua_ffi_get_resp_header(ngx_http_request_t *r, #endif /* NGX_LUA_NO_FFI_API */ +#if nginx_version >= 1011011 +void +ngx_http_lua_ngx_raw_header_cleanup(void *data) +{ + ngx_http_lua_main_conf_t *lmcf; + + lmcf = (ngx_http_lua_main_conf_t *) data; + + if (lmcf->busy_buf_ptrs) { + ngx_free(lmcf->busy_buf_ptrs); + lmcf->busy_buf_ptrs = NULL; + } +} +#endif + + /* vi:set ft=c ts=4 sw=4 et fdm=marker: */ diff --git a/debian/modules/nginx-lua/src/ngx_http_lua_headers.h b/debian/modules/nginx-lua/src/ngx_http_lua_headers.h index 39f1114..ee4d21c 100644 --- a/debian/modules/nginx-lua/src/ngx_http_lua_headers.h +++ b/debian/modules/nginx-lua/src/ngx_http_lua_headers.h @@ -15,6 +15,9 @@ void ngx_http_lua_inject_resp_header_api(lua_State *L); void ngx_http_lua_inject_req_header_api(lua_State *L); void ngx_http_lua_create_headers_metatable(ngx_log_t *log, lua_State *L); +#if nginx_version >= 1011011 +void ngx_http_lua_ngx_raw_header_cleanup(void *data); +#endif #endif /* _NGX_HTTP_LUA_HEADERS_H_INCLUDED_ */ diff --git a/debian/modules/nginx-lua/src/ngx_http_lua_log.c b/debian/modules/nginx-lua/src/ngx_http_lua_log.c index c2b2269..c18e6b0 100644 --- a/debian/modules/nginx-lua/src/ngx_http_lua_log.c +++ b/debian/modules/nginx-lua/src/ngx_http_lua_log.c @@ -13,6 +13,7 @@ #include "ngx_http_lua_log.h" #include "ngx_http_lua_util.h" +#include "ngx_http_lua_log_ringbuf.h" static int ngx_http_lua_print(lua_State *L); @@ -313,4 +314,120 @@ ngx_http_lua_inject_log_consts(lua_State *L) /* }}} */ } + +#ifdef HAVE_INTERCEPT_ERROR_LOG_PATCH +ngx_int_t +ngx_http_lua_capture_log_handler(ngx_log_t *log, + ngx_uint_t level, u_char *buf, size_t n) +{ + ngx_http_lua_log_ringbuf_t *ringbuf; + + dd("enter"); + + ringbuf = (ngx_http_lua_log_ringbuf_t *) + ngx_cycle->intercept_error_log_data; + + if (level > ringbuf->filter_level) { + return NGX_OK; + } + + ngx_http_lua_log_ringbuf_write(ringbuf, level, buf, n); + + dd("capture log: %s\n", buf); + + return NGX_OK; +} +#endif + + +#ifndef NGX_LUA_NO_FFI_API +int +ngx_http_lua_ffi_errlog_set_filter_level(int level, u_char *err, size_t *errlen) +{ +#ifdef HAVE_INTERCEPT_ERROR_LOG_PATCH + ngx_http_lua_log_ringbuf_t *ringbuf; + + ringbuf = ngx_cycle->intercept_error_log_data; + + if (ringbuf == NULL) { + *errlen = ngx_snprintf(err, *errlen, + "directive \"lua_capture_error_log\" is not set") + - err; + return NGX_ERROR; + } + + if (level > NGX_LOG_DEBUG || level < NGX_LOG_STDERR) { + *errlen = ngx_snprintf(err, *errlen, "bad log level: %d", level) + - err; + return NGX_ERROR; + } + + ringbuf->filter_level = level; + return NGX_OK; +#else + *errlen = ngx_snprintf(err, *errlen, + "missing the capture error log patch for nginx") + - err; + return NGX_ERROR; +#endif +} + + +int +ngx_http_lua_ffi_errlog_get_msg(char **log, int *loglevel, u_char *err, + size_t *errlen, double *log_time) +{ +#ifdef HAVE_INTERCEPT_ERROR_LOG_PATCH + ngx_uint_t loglen; + + ngx_http_lua_log_ringbuf_t *ringbuf; + + ringbuf = ngx_cycle->intercept_error_log_data; + + if (ringbuf == NULL) { + *errlen = ngx_snprintf(err, *errlen, + "directive \"lua_capture_error_log\" is not set") + - err; + return NGX_ERROR; + } + + if (ringbuf->count == 0) { + return NGX_DONE; + } + + ngx_http_lua_log_ringbuf_read(ringbuf, loglevel, (void **) log, &loglen, + log_time); + return loglen; +#else + *errlen = ngx_snprintf(err, *errlen, + "missing the capture error log patch for nginx") + - err; + return NGX_ERROR; +#endif +} + + +int +ngx_http_lua_ffi_errlog_get_sys_filter_level(ngx_http_request_t *r) +{ + ngx_log_t *log; + int log_level; + + if (r && r->connection && r->connection->log) { + log = r->connection->log; + + } else { + log = ngx_cycle->log; + } + + log_level = log->log_level; + if (log_level == NGX_LOG_DEBUG_ALL) { + log_level = NGX_LOG_DEBUG; + } + + return log_level; +} + +#endif + /* vi:set ft=c ts=4 sw=4 et fdm=marker: */ diff --git a/debian/modules/nginx-lua/src/ngx_http_lua_log.h b/debian/modules/nginx-lua/src/ngx_http_lua_log.h index 42f1839..56cd771 100644 --- a/debian/modules/nginx-lua/src/ngx_http_lua_log.h +++ b/debian/modules/nginx-lua/src/ngx_http_lua_log.h @@ -13,6 +13,10 @@ void ngx_http_lua_inject_log_api(lua_State *L); +#ifdef HAVE_INTERCEPT_ERROR_LOG_PATCH +ngx_int_t ngx_http_lua_capture_log_handler(ngx_log_t *log, + ngx_uint_t level, u_char *buf, size_t n); +#endif #endif /* _NGX_HTTP_LUA_LOG_H_INCLUDED_ */ diff --git a/debian/modules/nginx-lua/src/ngx_http_lua_log_ringbuf.c b/debian/modules/nginx-lua/src/ngx_http_lua_log_ringbuf.c new file mode 100644 index 0000000..0464069 --- /dev/null +++ b/debian/modules/nginx-lua/src/ngx_http_lua_log_ringbuf.c @@ -0,0 +1,225 @@ + +#ifndef DDEBUG +#define DDEBUG 0 +#endif +#include "ddebug.h" + + +#include "ngx_http_lua_common.h" +#include "ngx_http_lua_log_ringbuf.h" + + +typedef struct { + double time; + unsigned len; + unsigned log_level; +} ngx_http_lua_log_ringbuf_header_t; + + +enum { + HEADER_LEN = sizeof(ngx_http_lua_log_ringbuf_header_t) +}; + + +static void *ngx_http_lua_log_ringbuf_next_header( + ngx_http_lua_log_ringbuf_t *rb); +static void ngx_http_lua_log_ringbuf_append( + ngx_http_lua_log_ringbuf_t *rb, int log_level, void *buf, int n); +static size_t ngx_http_lua_log_ringbuf_free_spaces( + ngx_http_lua_log_ringbuf_t *rb); + + +void +ngx_http_lua_log_ringbuf_init(ngx_http_lua_log_ringbuf_t *rb, void *buf, + size_t len) +{ + rb->data = buf; + rb->size = len; + + rb->tail = rb->data; + rb->head = rb->data; + rb->sentinel = rb->data + rb->size; + rb->count = 0; + rb->filter_level = NGX_LOG_DEBUG; + + return; +} + + +void +ngx_http_lua_log_ringbuf_reset(ngx_http_lua_log_ringbuf_t *rb) +{ + rb->tail = rb->data; + rb->head = rb->data; + rb->sentinel = rb->data + rb->size; + rb->count = 0; + + return; +} + + +/* + * get the next data header, it'll skip the useless data space or + * placehold data + */ +static void * +ngx_http_lua_log_ringbuf_next_header(ngx_http_lua_log_ringbuf_t *rb) +{ + /* useless data */ + if (rb->size - (rb->head - rb->data) < HEADER_LEN) + { + return rb->data; + } + + /* placehold data */ + if (rb->head >= rb->sentinel) { + return rb->data; + } + + return rb->head; +} + + +/* append data to ring buffer directly */ +static void +ngx_http_lua_log_ringbuf_append(ngx_http_lua_log_ringbuf_t *rb, + int log_level, void *buf, int n) +{ + ngx_http_lua_log_ringbuf_header_t *head; + ngx_time_t *tp; + + head = (ngx_http_lua_log_ringbuf_header_t *) rb->tail; + head->len = n; + head->log_level = log_level; + + tp = ngx_timeofday(); + head->time = tp->sec + tp->msec / 1000.0L; + + rb->tail += HEADER_LEN; + ngx_memcpy(rb->tail, buf, n); + rb->tail += n; + rb->count++; + + if (rb->tail > rb->sentinel) { + rb->sentinel = rb->tail; + } + + return; +} + + +/* throw away data at head */ +static void +ngx_http_lua_log_ringbuf_throw_away(ngx_http_lua_log_ringbuf_t *rb) +{ + ngx_http_lua_log_ringbuf_header_t *head; + + if (rb->count == 0) { + return; + } + + head = (ngx_http_lua_log_ringbuf_header_t *) rb->head; + + rb->head += HEADER_LEN + head->len; + rb->count--; + + if (rb->count == 0) { + ngx_http_lua_log_ringbuf_reset(rb); + } + + rb->head = ngx_http_lua_log_ringbuf_next_header(rb); + + return; +} + + +/* size of free spaces */ +static size_t +ngx_http_lua_log_ringbuf_free_spaces(ngx_http_lua_log_ringbuf_t *rb) +{ + if (rb->count == 0) { + return rb->size; + } + + if (rb->tail > rb->head) { + return rb->data + rb->size - rb->tail; + } + + return rb->head - rb->tail; +} + + +/* + * try to write log data to ring buffer, throw away old data + * if there was not enough free spaces. + */ +ngx_int_t +ngx_http_lua_log_ringbuf_write(ngx_http_lua_log_ringbuf_t *rb, int log_level, + void *buf, size_t n) +{ + if (n + HEADER_LEN > rb->size) { + return NGX_ERROR; + } + + if (ngx_http_lua_log_ringbuf_free_spaces(rb) < n + HEADER_LEN) { + /* if the right space is not enough, mark it as placehold data */ + if ((size_t)(rb->data + rb->size - rb->tail) < n + HEADER_LEN) { + + while (rb->head >= rb->tail && rb->count) { + /* head is after tail, so we will throw away all data between + * head and sentinel */ + ngx_http_lua_log_ringbuf_throw_away(rb); + } + + rb->sentinel = rb->tail; + rb->tail = rb->data; + } + + while (ngx_http_lua_log_ringbuf_free_spaces(rb) < n + HEADER_LEN) { + ngx_http_lua_log_ringbuf_throw_away(rb); + } + } + + ngx_http_lua_log_ringbuf_append(rb, log_level, buf, n); + + return NGX_OK; +} + + +/* read log from ring buffer, do reset if all of the logs were readed. */ +ngx_int_t +ngx_http_lua_log_ringbuf_read(ngx_http_lua_log_ringbuf_t *rb, int *log_level, + void **buf, size_t *n, double *log_time) +{ + ngx_http_lua_log_ringbuf_header_t *head; + + if (rb->count == 0) { + return NGX_ERROR; + } + + head = (ngx_http_lua_log_ringbuf_header_t *) rb->head; + + if (rb->head >= rb->sentinel) { + return NGX_ERROR; + } + + *log_level = head->log_level; + *n = head->len; + rb->head += HEADER_LEN; + *buf = rb->head; + rb->head += head->len; + + if (log_time) { + *log_time = head->time; + } + + rb->count--; + + if (rb->count == 0) { + ngx_http_lua_log_ringbuf_reset(rb); + } + + rb->head = ngx_http_lua_log_ringbuf_next_header(rb); + + return NGX_OK; +} diff --git a/debian/modules/nginx-lua/src/ngx_http_lua_log_ringbuf.h b/debian/modules/nginx-lua/src/ngx_http_lua_log_ringbuf.h new file mode 100644 index 0000000..c9c2c2d --- /dev/null +++ b/debian/modules/nginx-lua/src/ngx_http_lua_log_ringbuf.h @@ -0,0 +1,31 @@ + +#ifndef _NGX_HTTP_LUA_RINGBUF_H_INCLUDED_ +#define _NGX_HTTP_LUA_RINGBUF_H_INCLUDED_ + + +#include "ngx_http_lua_common.h" + + +typedef struct { + ngx_uint_t filter_level; + char *tail; /* writed point */ + char *head; /* readed point */ + char *data; /* buffer */ + char *sentinel; + size_t size; /* buffer total size */ + size_t count; /* count of logs */ +} ngx_http_lua_log_ringbuf_t; + + +void ngx_http_lua_log_ringbuf_init(ngx_http_lua_log_ringbuf_t *rb, + void *buf, size_t len); +void ngx_http_lua_log_ringbuf_reset(ngx_http_lua_log_ringbuf_t *rb); +ngx_int_t ngx_http_lua_log_ringbuf_read(ngx_http_lua_log_ringbuf_t *rb, + int *log_level, void **buf, size_t *n, double *log_time); +ngx_int_t ngx_http_lua_log_ringbuf_write(ngx_http_lua_log_ringbuf_t *rb, + int log_level, void *buf, size_t n); + + +#endif /* _NGX_HTTP_LUA_RINGBUF_H_INCLUDED_ */ + +/* vi:set ft=c ts=4 sw=4 et fdm=marker: */ diff --git a/debian/modules/nginx-lua/src/ngx_http_lua_module.c b/debian/modules/nginx-lua/src/ngx_http_lua_module.c index 6e93c8e..9d914e8 100644 --- a/debian/modules/nginx-lua/src/ngx_http_lua_module.c +++ b/debian/modules/nginx-lua/src/ngx_http_lua_module.c @@ -28,6 +28,7 @@ #include "ngx_http_lua_ssl_certby.h" #include "ngx_http_lua_ssl_session_storeby.h" #include "ngx_http_lua_ssl_session_fetchby.h" +#include "ngx_http_lua_headers.h" static void *ngx_http_lua_create_main_conf(ngx_conf_t *cf); @@ -45,14 +46,6 @@ static char *ngx_http_lua_lowat_check(ngx_conf_t *cf, void *post, void *data); static ngx_int_t ngx_http_lua_set_ssl(ngx_conf_t *cf, ngx_http_lua_loc_conf_t *llcf); #endif -#if (NGX_HTTP_LUA_HAVE_MMAP_SBRK) && (NGX_LINUX) -/* we cannot use "static" for this function since it may lead to compiler - * warnings */ -void ngx_http_lua_limit_data_segment(void); -# if !(NGX_HTTP_LUA_HAVE_CONSTRUCTOR) -static ngx_int_t ngx_http_lua_pre_config(ngx_conf_t *cf); -# endif -#endif static char *ngx_http_lua_malloc_trim(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); @@ -101,6 +94,13 @@ static ngx_command_t ngx_http_lua_cmds[] = { 0, NULL }, + { ngx_string("lua_capture_error_log"), + NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1, + ngx_http_lua_capture_error_log, + 0, + 0, + NULL }, + #if (NGX_PCRE) { ngx_string("lua_regex_cache_max_entries"), NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1, @@ -592,13 +592,7 @@ static ngx_command_t ngx_http_lua_cmds[] = { ngx_http_module_t ngx_http_lua_module_ctx = { -#if (NGX_HTTP_LUA_HAVE_MMAP_SBRK) \ - && (NGX_LINUX) \ - && !(NGX_HTTP_LUA_HAVE_CONSTRUCTOR) - ngx_http_lua_pre_config, /* preconfiguration */ -#else NULL, /* preconfiguration */ -#endif ngx_http_lua_init, /* postconfiguration */ ngx_http_lua_create_main_conf, /* create main configuration */ @@ -638,7 +632,7 @@ ngx_http_lua_init(ngx_conf_t *cf) volatile ngx_cycle_t *saved_cycle; ngx_http_core_main_conf_t *cmcf; ngx_http_lua_main_conf_t *lmcf; -#ifndef NGX_LUA_NO_FFI_API +#if !defined(NGX_LUA_NO_FFI_API) || nginx_version >= 1011011 ngx_pool_cleanup_t *cln; #endif @@ -730,6 +724,16 @@ ngx_http_lua_init(ngx_conf_t *cf) cln->handler = ngx_http_lua_sema_mm_cleanup; #endif +#if nginx_version >= 1011011 + cln = ngx_pool_cleanup_add(cf->pool, 0); + if (cln == NULL) { + return NGX_ERROR; + } + + cln->data = lmcf; + cln->handler = ngx_http_lua_ngx_raw_header_cleanup; +#endif + if (lmcf->lua == NULL) { dd("initializing lua vm"); @@ -817,6 +821,7 @@ ngx_http_lua_create_main_conf(ngx_conf_t *cf) * lmcf->running_timers = 0; * lmcf->watcher = NULL; * lmcf->regex_cache_entries = 0; + * lmcf->jit_stack = NULL; * lmcf->shm_zones = NULL; * lmcf->init_handler = NULL; * lmcf->init_src = { 0, NULL }; @@ -955,7 +960,7 @@ ngx_http_lua_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) #ifdef LIBRESSL_VERSION_NUMBER ngx_log_error(NGX_LOG_EMERG, cf->log, 0, - "LibreSSL does not support ssl_ceritificate_by_lua*"); + "LibreSSL does not support ssl_certificate_by_lua*"); return NGX_CONF_ERROR; #else @@ -967,7 +972,7 @@ ngx_http_lua_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) # else ngx_log_error(NGX_LOG_EMERG, cf->log, 0, - "OpenSSL too old to support ssl_ceritificate_by_lua*"); + "OpenSSL too old to support ssl_certificate_by_lua*"); return NGX_CONF_ERROR; # endif @@ -1267,37 +1272,6 @@ ngx_http_lua_set_ssl(ngx_conf_t *cf, ngx_http_lua_loc_conf_t *llcf) #endif /* NGX_HTTP_SSL */ -#if (NGX_HTTP_LUA_HAVE_MMAP_SBRK) \ - && (NGX_LINUX) \ - && !(NGX_HTTP_LUA_HAVE_CONSTRUCTOR) -static ngx_int_t -ngx_http_lua_pre_config(ngx_conf_t *cf) -{ - ngx_http_lua_limit_data_segment(); - return NGX_OK; -} -#endif - - -/* - * we simply assume that LuaJIT is used. it does little harm when the - * standard Lua 5.1 interpreter is used instead. - */ -#if (NGX_HTTP_LUA_HAVE_MMAP_SBRK) && (NGX_LINUX) -# if (NGX_HTTP_LUA_HAVE_CONSTRUCTOR) -__attribute__((constructor)) -# endif -void -ngx_http_lua_limit_data_segment(void) -{ - if (sbrk(0) < (void *) 0x40000000LL) { - mmap(ngx_align_ptr(sbrk(0), getpagesize()), 1, PROT_READ, - MAP_FIXED|MAP_PRIVATE|MAP_ANON, -1, 0); - } -} -#endif - - static char * ngx_http_lua_malloc_trim(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { diff --git a/debian/modules/nginx-lua/src/ngx_http_lua_regex.c b/debian/modules/nginx-lua/src/ngx_http_lua_regex.c index d882061..80519ec 100644 --- a/debian/modules/nginx-lua/src/ngx_http_lua_regex.c +++ b/debian/modules/nginx-lua/src/ngx_http_lua_regex.c @@ -17,14 +17,6 @@ #include "ngx_http_lua_script.h" #include "ngx_http_lua_pcrefix.h" #include "ngx_http_lua_util.h" -#include - - -#if (PCRE_MAJOR > 8) || (PCRE_MAJOR == 8 && PCRE_MINOR >= 21) -# define LUA_HAVE_PCRE_JIT 1 -#else -# define LUA_HAVE_PCRE_JIT 0 -#endif #if (PCRE_MAJOR >= 6) @@ -42,6 +34,8 @@ #define NGX_LUA_RE_DFA_MODE_WORKSPACE_COUNT (100) +#define NGX_LUA_RE_MIN_JIT_STACK_SIZE 32 * 1024 + typedef struct { #ifndef NGX_LUA_NO_FFI_API @@ -364,6 +358,10 @@ ngx_http_lua_ngx_re_match_helper(lua_State *L, int wantcaps) sd = pcre_study(re_comp.regex, PCRE_STUDY_JIT_COMPILE, &msg); + if (sd && lmcf->jit_stack) { + pcre_assign_jit_stack(sd, NULL, lmcf->jit_stack); + } + ngx_http_lua_pcre_malloc_done(old_pool); # if (NGX_DEBUG) @@ -826,6 +824,10 @@ ngx_http_lua_ngx_re_gmatch(lua_State *L) sd = pcre_study(re_comp.regex, PCRE_STUDY_JIT_COMPILE, &msg); + if (sd && lmcf->jit_stack) { + pcre_assign_jit_stack(sd, NULL, lmcf->jit_stack); + } + ngx_http_lua_pcre_malloc_done(old_pool); # if (NGX_DEBUG) @@ -1922,6 +1924,60 @@ error: } +ngx_int_t +ngx_http_lua_ffi_set_jit_stack_size(int size, u_char *errstr, + size_t *errstr_size) +{ +#if LUA_HAVE_PCRE_JIT + + ngx_http_lua_main_conf_t *lmcf; + ngx_pool_t *pool, *old_pool; + + lmcf = ngx_http_cycle_get_module_main_conf(ngx_cycle, + ngx_http_lua_module); + + if (size < NGX_LUA_RE_MIN_JIT_STACK_SIZE) { + size = NGX_LUA_RE_MIN_JIT_STACK_SIZE; + } + + pool = lmcf->pool; + + dd("server pool %p", lmcf->pool); + + if (lmcf->jit_stack) { + old_pool = ngx_http_lua_pcre_malloc_init(pool); + + pcre_jit_stack_free(lmcf->jit_stack); + + ngx_http_lua_pcre_malloc_done(old_pool); + } + + old_pool = ngx_http_lua_pcre_malloc_init(pool); + + lmcf->jit_stack = pcre_jit_stack_alloc(NGX_LUA_RE_MIN_JIT_STACK_SIZE, + size); + + ngx_http_lua_pcre_malloc_done(old_pool); + + if (lmcf->jit_stack == NULL) { + *errstr_size = ngx_snprintf(errstr, *errstr_size, + "pcre jit stack allocation failed") + - errstr; + return NGX_ERROR; + } + + return NGX_OK; + +#else /* LUA_HAVE_PCRE_JIT */ + + *errstr_size = ngx_snprintf(errstr, *errstr_size, + "no pcre jit support found") - errstr; + return NGX_ERROR; + +#endif /* LUA_HAVE_PCRE_JIT */ +} + + void ngx_http_lua_inject_regex_api(lua_State *L) { @@ -2170,6 +2226,9 @@ ngx_http_lua_ffi_compile_regex(const unsigned char *pat, size_t pat_len, goto error; } + lmcf = ngx_http_cycle_get_module_main_conf(ngx_cycle, + ngx_http_lua_module); + #if (LUA_HAVE_PCRE_JIT) if (flags & NGX_LUA_RE_MODE_JIT) { @@ -2205,10 +2264,11 @@ ngx_http_lua_ffi_compile_regex(const unsigned char *pat, size_t pat_len, ngx_http_lua_pcre_malloc_done(old_pool); } -#endif /* LUA_HAVE_PCRE_JIT */ + if (sd && lmcf->jit_stack) { + pcre_assign_jit_stack(sd, NULL, lmcf->jit_stack); + } - lmcf = ngx_http_cycle_get_module_main_conf(ngx_cycle, - ngx_http_lua_module); +#endif /* LUA_HAVE_PCRE_JIT */ if (sd && lmcf && lmcf->regex_match_limit > 0) { sd->flags |= PCRE_EXTRA_MATCH_LIMIT; diff --git a/debian/modules/nginx-lua/src/ngx_http_lua_regex.h b/debian/modules/nginx-lua/src/ngx_http_lua_regex.h index f5f8e2f..03dffb8 100644 --- a/debian/modules/nginx-lua/src/ngx_http_lua_regex.h +++ b/debian/modules/nginx-lua/src/ngx_http_lua_regex.h @@ -14,6 +14,8 @@ #if (NGX_PCRE) void ngx_http_lua_inject_regex_api(lua_State *L); +ngx_int_t ngx_http_lua_ffi_set_jit_stack_size(int size, u_char *errstr, + size_t *errstr_size); #endif diff --git a/debian/modules/nginx-lua/src/ngx_http_lua_semaphore.c b/debian/modules/nginx-lua/src/ngx_http_lua_semaphore.c index 8a3f832..eda0141 100644 --- a/debian/modules/nginx-lua/src/ngx_http_lua_semaphore.c +++ b/debian/modules/nginx-lua/src/ngx_http_lua_semaphore.c @@ -387,8 +387,8 @@ ngx_http_lua_ffi_sema_wait(ngx_http_request_t *r, return NGX_ERROR; } - /* we keep the order, will resume the older waited firtly - * in ngx_http_lua_sema_handler + /* we keep the order, will first resume the thread waiting for the + * longest time in ngx_http_lua_sema_handler */ if (ngx_queue_empty(&sem->wait_queue) && sem->resource_count > 0) { @@ -557,8 +557,11 @@ ngx_http_lua_ffi_sema_gc(ngx_http_lua_sema_t *sem) return; } - if (!ngx_queue_empty(&sem->wait_queue)) { - ngx_log_error(NGX_LOG_CRIT, ngx_cycle->log, 0, + if (!ngx_terminate + && !ngx_quit + && !ngx_queue_empty(&sem->wait_queue)) + { + ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, 0, "in lua semaphore gc wait queue is" " not empty while the semaphore %p is being " "destroyed", sem); diff --git a/debian/modules/nginx-lua/src/ngx_http_lua_sleep.c b/debian/modules/nginx-lua/src/ngx_http_lua_sleep.c index 4c0d016..ffee97f 100644 --- a/debian/modules/nginx-lua/src/ngx_http_lua_sleep.c +++ b/debian/modules/nginx-lua/src/ngx_http_lua_sleep.c @@ -72,10 +72,25 @@ ngx_http_lua_ngx_sleep(lua_State *L) coctx->sleep.data = coctx; coctx->sleep.log = r->connection->log; - dd("adding timer with delay %lu ms, r:%.*s", (unsigned long) delay, - (int) r->uri.len, r->uri.data); + if (delay == 0) { +#ifdef HAVE_POSTED_DELAYED_EVENTS_PATCH + dd("posting 0 sec sleep event to head of delayed queue"); - ngx_add_timer(&coctx->sleep, (ngx_msec_t) delay); + coctx->sleep.delayed = 1; + ngx_post_event(&coctx->sleep, &ngx_posted_delayed_events); +#else + ngx_log_error(NGX_LOG_WARN, r->connection->log, 0, "ngx.sleep(0)" + " called without delayed events patch, this will" + " hurt performance"); + ngx_add_timer(&coctx->sleep, (ngx_msec_t) delay); +#endif + + } else { + dd("adding timer with delay %lu ms, r:%.*s", (unsigned long) delay, + (int) r->uri.len, r->uri.data); + + ngx_add_timer(&coctx->sleep, (ngx_msec_t) delay); + } ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "lua ready to sleep for %d ms", delay); @@ -147,6 +162,15 @@ ngx_http_lua_sleep_cleanup(void *data) ngx_del_timer(&coctx->sleep); } + +#ifdef HAVE_POSTED_DELAYED_EVENTS_PATCH + if (coctx->sleep.posted) { + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, + "lua clean up the posted event for pending ngx.sleep"); + + ngx_delete_posted_event(&coctx->sleep); + } +#endif } diff --git a/debian/modules/nginx-lua/src/ngx_http_lua_socket_tcp.c b/debian/modules/nginx-lua/src/ngx_http_lua_socket_tcp.c index 6db6e2d..382a94d 100644 --- a/debian/modules/nginx-lua/src/ngx_http_lua_socket_tcp.c +++ b/debian/modules/nginx-lua/src/ngx_http_lua_socket_tcp.c @@ -69,8 +69,6 @@ static void ngx_http_lua_socket_dummy_handler(ngx_http_request_t *r, ngx_http_lua_socket_tcp_upstream_t *u); static ngx_int_t ngx_http_lua_socket_tcp_read(ngx_http_request_t *r, ngx_http_lua_socket_tcp_upstream_t *u); -static void ngx_http_lua_socket_read_handler(ngx_http_request_t *r, - ngx_http_lua_socket_tcp_upstream_t *u); static int ngx_http_lua_socket_tcp_receive_retval_handler(ngx_http_request_t *r, ngx_http_lua_socket_tcp_upstream_t *u, lua_State *L); static ngx_int_t ngx_http_lua_socket_read_line(void *data, ssize_t bytes); @@ -501,6 +499,12 @@ ngx_http_lua_socket_tcp_connect(lua_State *L) n--; } + /* the fourth argument is not a table */ + if (n == 4) { + lua_pop(L, 1); + n--; + } + if (n == 3) { port = luaL_checkinteger(L, 3); @@ -1208,11 +1212,12 @@ ngx_http_lua_socket_tcp_sslhandshake(lua_State *L) ngx_http_lua_socket_tcp_upstream_t *u; - /* Lua function arguments: self [,session] [,host] [,verify] */ + /* Lua function arguments: self [,session] [,host] [,verify] + [,send_status_req] */ n = lua_gettop(L); if (n < 1 || n > 5) { - return luaL_error(L, "ngx.socket connect: expecting 1 ~ 5 " + return luaL_error(L, "ngx.socket sslhandshake: expecting 1 ~ 5 " "arguments (including the object), but seen %d", n); } @@ -1327,7 +1332,8 @@ ngx_http_lua_socket_tcp_sslhandshake(lua_State *L) #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME - if (SSL_set_tlsext_host_name(c->ssl->connection, name.data) + if (SSL_set_tlsext_host_name(c->ssl->connection, + (char *) name.data) == 0) { lua_pushnil(L); @@ -4412,15 +4418,18 @@ ngx_http_lua_req_socket_rev_handler(ngx_http_request_t *r) ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); if (ctx == NULL) { + r->read_event_handler = ngx_http_block_reading; return; } u = ctx->downstream; - if (u) { - u->read_event_handler(r, u); + if (u == NULL || u->peer.connection == NULL) { + r->read_event_handler = ngx_http_block_reading; + return; } -} + u->read_event_handler(r, u); +} static int ngx_http_lua_socket_tcp_getreusedtimes(lua_State *L) diff --git a/debian/modules/nginx-lua/src/ngx_http_lua_ssl.h b/debian/modules/nginx-lua/src/ngx_http_lua_ssl.h index 7a245ff..acb8c4b 100644 --- a/debian/modules/nginx-lua/src/ngx_http_lua_ssl.h +++ b/debian/modules/nginx-lua/src/ngx_http_lua_ssl.h @@ -12,6 +12,8 @@ #if (NGX_HTTP_SSL) + + typedef struct { ngx_connection_t *connection; /* original true connection */ ngx_http_request_t *request; /* fake request */ @@ -31,7 +33,6 @@ typedef struct { unsigned entered_cert_handler:1; unsigned entered_sess_fetch_handler:1; } ngx_http_lua_ssl_ctx_t; -#endif ngx_int_t ngx_http_lua_ssl_init(ngx_log_t *log); @@ -40,4 +41,7 @@ ngx_int_t ngx_http_lua_ssl_init(ngx_log_t *log); extern int ngx_http_lua_ssl_ctx_index; +#endif + + #endif /* _NGX_HTTP_LUA_SSL_H_INCLUDED_ */ diff --git a/debian/modules/nginx-lua/src/ngx_http_lua_ssl_certby.c b/debian/modules/nginx-lua/src/ngx_http_lua_ssl_certby.c index aca4735..c3591d1 100644 --- a/debian/modules/nginx-lua/src/ngx_http_lua_ssl_certby.c +++ b/debian/modules/nginx-lua/src/ngx_http_lua_ssl_certby.c @@ -193,6 +193,7 @@ ngx_http_lua_ssl_cert_handler(ngx_ssl_conn_t *ssl_conn, void *data) ngx_http_lua_srv_conf_t *lscf; ngx_http_core_loc_conf_t *clcf; ngx_http_lua_ssl_ctx_t *cctx; + ngx_http_core_srv_conf_t *cscf; c = ngx_ssl_get_connection(ssl_conn); @@ -298,6 +299,16 @@ ngx_http_lua_ssl_cert_handler(ngx_ssl_conn_t *ssl_conn, void *data) c->log->action = "loading SSL certificate by lua"; + if (lscf->srv.ssl_cert_handler == NULL) { + cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); + + ngx_log_error(NGX_LOG_ALERT, c->log, 0, + "no ssl_certificate_by_lua* defined in " + "server %V", &cscf->server_name); + + goto failed; + } + rc = lscf->srv.ssl_cert_handler(r, lscf, L); if (rc >= NGX_OK || rc == NGX_ERROR) { @@ -453,7 +464,9 @@ ngx_http_lua_ssl_cert_by_chunk(lua_State *L, ngx_http_request_t *r) if (ctx == NULL) { ctx = ngx_http_lua_create_ctx(r); if (ctx == NULL) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; + rc = NGX_ERROR; + ngx_http_lua_finalize_request(r, rc); + return rc; } } else { @@ -470,7 +483,9 @@ ngx_http_lua_ssl_cert_by_chunk(lua_State *L, ngx_http_request_t *r) ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "lua: failed to create new coroutine to handle request"); - return NGX_HTTP_INTERNAL_SERVER_ERROR; + rc = NGX_ERROR; + ngx_http_lua_finalize_request(r, rc); + return rc; } /* move code closure to new coroutine */ @@ -494,7 +509,9 @@ ngx_http_lua_ssl_cert_by_chunk(lua_State *L, ngx_http_request_t *r) if (ctx->cleanup == NULL) { cln = ngx_http_cleanup_add(r, 0); if (cln == NULL) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; + rc = NGX_ERROR; + ngx_http_lua_finalize_request(r, rc); + return rc; } cln->handler = ngx_http_lua_request_cleanup_handler; @@ -1129,7 +1146,11 @@ ngx_http_lua_ffi_set_cert(ngx_http_request_t *r, # else +#ifdef OPENSSL_IS_BORINGSSL + size_t i; +#else int i; +#endif X509 *x509 = NULL; ngx_ssl_conn_t *ssl_conn; STACK_OF(X509) *chain = cdata; diff --git a/debian/modules/nginx-lua/src/ngx_http_lua_ssl_ocsp.c b/debian/modules/nginx-lua/src/ngx_http_lua_ssl_ocsp.c index 3904aa8..31b4f24 100644 --- a/debian/modules/nginx-lua/src/ngx_http_lua_ssl_ocsp.c +++ b/debian/modules/nginx-lua/src/ngx_http_lua_ssl_ocsp.c @@ -490,7 +490,6 @@ ngx_http_lua_ffi_ssl_set_ocsp_status_resp(ngx_http_request_t *r, dd("set ocsp resp: resp_len=%d", (int) resp_len); (void) SSL_set_tlsext_status_ocsp_resp(ssl_conn, p, resp_len); - ssl_conn->tlsext_status_expected = 1; return NGX_OK; diff --git a/debian/modules/nginx-lua/src/ngx_http_lua_ssl_session_fetchby.c b/debian/modules/nginx-lua/src/ngx_http_lua_ssl_session_fetchby.c index 4c450b5..556b732 100644 --- a/debian/modules/nginx-lua/src/ngx_http_lua_ssl_session_fetchby.c +++ b/debian/modules/nginx-lua/src/ngx_http_lua_ssl_session_fetchby.c @@ -107,7 +107,7 @@ ngx_http_lua_ssl_sess_fetch_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, dd("enter"); - /* must specifiy a content handler */ + /* must specify a content handler */ if (cmd->post == NULL) { return NGX_CONF_ERROR; } @@ -468,7 +468,9 @@ ngx_http_lua_ssl_sess_fetch_by_chunk(lua_State *L, ngx_http_request_t *r) if (ctx == NULL) { ctx = ngx_http_lua_create_ctx(r); if (ctx == NULL) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; + rc = NGX_ERROR; + ngx_http_lua_finalize_request(r, rc); + return rc; } } else { @@ -485,7 +487,9 @@ ngx_http_lua_ssl_sess_fetch_by_chunk(lua_State *L, ngx_http_request_t *r) ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "lua: failed to create new coroutine to handle request"); - return NGX_HTTP_INTERNAL_SERVER_ERROR; + rc = NGX_ERROR; + ngx_http_lua_finalize_request(r, rc); + return rc; } /* move code closure to new coroutine */ @@ -509,7 +513,9 @@ ngx_http_lua_ssl_sess_fetch_by_chunk(lua_State *L, ngx_http_request_t *r) if (ctx->cleanup == NULL) { cln = ngx_http_cleanup_add(r, 0); if (cln == NULL) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; + rc = NGX_ERROR; + ngx_http_lua_finalize_request(r, rc); + return rc; } cln->handler = ngx_http_lua_request_cleanup_handler; diff --git a/debian/modules/nginx-lua/src/ngx_http_lua_ssl_session_storeby.c b/debian/modules/nginx-lua/src/ngx_http_lua_ssl_session_storeby.c index b5596bc..bae8273 100644 --- a/debian/modules/nginx-lua/src/ngx_http_lua_ssl_session_storeby.c +++ b/debian/modules/nginx-lua/src/ngx_http_lua_ssl_session_storeby.c @@ -105,7 +105,7 @@ ngx_http_lua_ssl_sess_store_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, dd("enter"); - /* must specifiy a content handler */ + /* must specify a content handler */ if (cmd->post == NULL) { return NGX_CONF_ERROR; } @@ -351,7 +351,9 @@ ngx_http_lua_ssl_sess_store_by_chunk(lua_State *L, ngx_http_request_t *r) if (ctx == NULL) { ctx = ngx_http_lua_create_ctx(r); if (ctx == NULL) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; + rc = NGX_ERROR; + ngx_http_lua_finalize_request(r, rc); + return rc; } } else { @@ -386,7 +388,7 @@ ngx_http_lua_ssl_sess_store_by_chunk(lua_State *L, ngx_http_request_t *r) dd("rc == %d", (int) rc); if (rc != 0) { - /* error occured when running loaded code */ + /* error occurred when running loaded code */ err_msg = (u_char *) lua_tolstring(L, -1, &len); if (err_msg == NULL) { diff --git a/debian/modules/nginx-lua/src/ngx_http_lua_string.c b/debian/modules/nginx-lua/src/ngx_http_lua_string.c index 22b4c00..239b232 100644 --- a/debian/modules/nginx-lua/src/ngx_http_lua_string.c +++ b/debian/modules/nginx-lua/src/ngx_http_lua_string.c @@ -125,12 +125,13 @@ ngx_http_lua_ngx_escape_uri(lua_State *L) return 1; } - escape = 2 * ngx_http_lua_escape_uri(NULL, src, len, NGX_ESCAPE_URI); + escape = 2 * ngx_http_lua_escape_uri(NULL, src, len, + NGX_ESCAPE_URI_COMPONENT); if (escape) { dlen = escape + len; dst = lua_newuserdata(L, dlen); - ngx_http_lua_escape_uri(dst, src, len, NGX_ESCAPE_URI); + ngx_http_lua_escape_uri(dst, src, len, NGX_ESCAPE_URI_COMPONENT); lua_pushlstring(L, (char *) dst, dlen); } @@ -751,14 +752,14 @@ size_t ngx_http_lua_ffi_uri_escaped_length(const u_char *src, size_t len) { return len + 2 * ngx_http_lua_escape_uri(NULL, (u_char *) src, len, - NGX_ESCAPE_URI); + NGX_ESCAPE_URI_COMPONENT); } void ngx_http_lua_ffi_escape_uri(const u_char *src, size_t len, u_char *dst) { - ngx_http_lua_escape_uri(dst, (u_char *) src, len, NGX_ESCAPE_URI); + ngx_http_lua_escape_uri(dst, (u_char *) src, len, NGX_ESCAPE_URI_COMPONENT); } #endif diff --git a/debian/modules/nginx-lua/src/ngx_http_lua_timer.c b/debian/modules/nginx-lua/src/ngx_http_lua_timer.c index 01b4777..596b2f7 100644 --- a/debian/modules/nginx-lua/src/ngx_http_lua_timer.c +++ b/debian/modules/nginx-lua/src/ngx_http_lua_timer.c @@ -21,11 +21,6 @@ typedef struct { void **srv_conf; void **loc_conf; - /* event ident must be after 3 words (i.e. 3 pointers' size) as in - * ngx_connection_t. and we use the Lua coroutine reference number as - * the event ident */ - int co_ref; - unsigned premature; /* :1 */ lua_State *co; ngx_pool_t *pool; @@ -36,12 +31,18 @@ typedef struct { ngx_http_lua_main_conf_t *lmcf; ngx_http_lua_vm_state_t *vm_state; + int co_ref; + unsigned delay:31; + unsigned premature:1; } ngx_http_lua_timer_ctx_t; static int ngx_http_lua_ngx_timer_at(lua_State *L); +static int ngx_http_lua_ngx_timer_every(lua_State *L); +static int ngx_http_lua_ngx_timer_helper(lua_State *L, int every); static int ngx_http_lua_ngx_timer_running_count(lua_State *L); static int ngx_http_lua_ngx_timer_pending_count(lua_State *L); +static ngx_int_t ngx_http_lua_timer_copy(ngx_http_lua_timer_ctx_t *old_tctx); static void ngx_http_lua_timer_handler(ngx_event_t *ev); static u_char *ngx_http_lua_log_timer_error(ngx_log_t *log, u_char *buf, size_t len); @@ -51,11 +52,14 @@ static void ngx_http_lua_abort_pending_timers(ngx_event_t *ev); void ngx_http_lua_inject_timer_api(lua_State *L) { - lua_createtable(L, 0 /* narr */, 3 /* nrec */); /* ngx.timer. */ + lua_createtable(L, 0 /* narr */, 4 /* nrec */); /* ngx.timer. */ lua_pushcfunction(L, ngx_http_lua_ngx_timer_at); lua_setfield(L, -2, "at"); + lua_pushcfunction(L, ngx_http_lua_ngx_timer_every); + lua_setfield(L, -2, "every"); + lua_pushcfunction(L, ngx_http_lua_ngx_timer_running_count); lua_setfield(L, -2, "running_count"); @@ -106,6 +110,24 @@ ngx_http_lua_ngx_timer_pending_count(lua_State *L) static int ngx_http_lua_ngx_timer_at(lua_State *L) +{ + return ngx_http_lua_ngx_timer_helper(L, 0); +} + + +/* + * TODO: return a timer handler instead which can be passed to + * the ngx.timer.cancel method to cancel the timer. + */ +static int +ngx_http_lua_ngx_timer_every(lua_State *L) +{ + return ngx_http_lua_ngx_timer_helper(L, 1); +} + + +static int +ngx_http_lua_ngx_timer_helper(lua_State *L, int every) { int nargs, co_ref; u_char *p; @@ -134,6 +156,10 @@ ngx_http_lua_ngx_timer_at(lua_State *L) delay = (ngx_msec_t) (luaL_checknumber(L, 1) * 1000); + if (every && delay == 0) { + return luaL_error(L, "delay cannot be zero"); + } + luaL_argcheck(L, lua_isfunction(L, 2) && !lua_iscfunction(L, 2), 2, "Lua function expected"); @@ -233,7 +259,7 @@ ngx_http_lua_ngx_timer_at(lua_State *L) lua_pushlightuserdata(L, &ngx_http_lua_coroutines_key); lua_rawget(L, LUA_REGISTRYINDEX); - /* L stack: time func [args] thread corountines */ + /* L stack: time func [args] thread coroutines */ lua_pushvalue(L, -2); @@ -265,6 +291,8 @@ ngx_http_lua_ngx_timer_at(lua_State *L) tctx = (ngx_http_lua_timer_ctx_t *) p; + tctx->delay = every ? delay : 0; + tctx->premature = 0; tctx->co_ref = co_ref; tctx->co = co; @@ -338,6 +366,164 @@ nomem: } +static ngx_int_t +ngx_http_lua_timer_copy(ngx_http_lua_timer_ctx_t *old_tctx) +{ + int nargs, co_ref, i; + u_char *p; + lua_State *vm; /* the main thread */ + lua_State *co; + lua_State *L; + ngx_event_t *ev = NULL; + ngx_http_lua_timer_ctx_t *tctx = NULL; + ngx_http_lua_main_conf_t *lmcf; + + /* L stack: func [args] */ + L = old_tctx->co; + + lmcf = old_tctx->lmcf; + + vm = old_tctx->vm_state ? old_tctx->vm_state->vm : lmcf->lua; + + co = lua_newthread(vm); + + lua_createtable(co, 0, 0); /* the new globals table */ + + /* co stack: global_tb */ + + lua_createtable(co, 0, 1); /* the metatable */ + ngx_http_lua_get_globals_table(co); + lua_setfield(co, -2, "__index"); + lua_setmetatable(co, -2); + + /* co stack: global_tb */ + + ngx_http_lua_set_globals_table(co); + + /* co stack: */ + + dd("stack top: %d", lua_gettop(L)); + + lua_xmove(vm, L, 1); /* move coroutine from main thread to L */ + + /* L stack: func [args] thread */ + /* vm stack: empty */ + + lua_pushvalue(L, 1); /* copy entry function to top of L*/ + + /* L stack: func [args] thread func */ + + lua_xmove(L, co, 1); /* move entry function from L to co */ + + /* L stack: func [args] thread */ + /* co stack: func */ + + ngx_http_lua_get_globals_table(co); + lua_setfenv(co, -2); + + /* co stack: func */ + + lua_pushlightuserdata(L, &ngx_http_lua_coroutines_key); + lua_rawget(L, LUA_REGISTRYINDEX); + + /* L stack: func [args] thread coroutines */ + + lua_pushvalue(L, -2); + + /* L stack: func [args] thread coroutines thread */ + + co_ref = luaL_ref(L, -2); + lua_pop(L, 2); + + /* L stack: func [args] */ + + nargs = lua_gettop(L); + if (nargs > 1) { + for (i = 2; i <= nargs; i++) { + lua_pushvalue(L, i); + } + + /* L stack: func [args] [args] */ + + lua_xmove(L, co, nargs - 1); + + /* L stack: func [args] */ + /* co stack: func [args] */ + } + + p = ngx_alloc(sizeof(ngx_event_t) + sizeof(ngx_http_lua_timer_ctx_t), + ngx_cycle->log); + if (p == NULL) { + goto nomem; + } + + ev = (ngx_event_t *) p; + + ngx_memzero(ev, sizeof(ngx_event_t)); + + p += sizeof(ngx_event_t); + + tctx = (ngx_http_lua_timer_ctx_t *) p; + + ngx_memcpy(tctx, old_tctx, sizeof(ngx_http_lua_timer_ctx_t)); + + tctx->co_ref = co_ref; + tctx->co = co; + + tctx->pool = ngx_create_pool(128, ngx_cycle->log); + if (tctx->pool == NULL) { + goto nomem; + } + + if (tctx->client_addr_text.len) { + tctx->client_addr_text.data = ngx_palloc(tctx->pool, + tctx->client_addr_text.len); + if (tctx->client_addr_text.data == NULL) { + goto nomem; + } + + ngx_memcpy(tctx->client_addr_text.data, old_tctx->client_addr_text.data, + tctx->client_addr_text.len); + } + + if (tctx->vm_state) { + tctx->vm_state->count++; + } + + ev->handler = ngx_http_lua_timer_handler; + ev->data = tctx; + ev->log = ngx_cycle->log; + + lmcf->pending_timers++; + + ngx_add_timer(ev, tctx->delay); + + return NGX_OK; + +nomem: + + if (tctx && tctx->pool) { + ngx_destroy_pool(tctx->pool); + } + + if (ev) { + ngx_free(ev); + } + + /* L stack: func [args] */ + + lua_pushlightuserdata(L, &ngx_http_lua_coroutines_key); + lua_rawget(L, LUA_REGISTRYINDEX); + luaL_unref(L, -1, co_ref); + + /* L stack: func [args] coroutines */ + + lua_pop(L, 1); + + return NGX_ERROR; +} + + static void ngx_http_lua_timer_handler(ngx_event_t *ev) { @@ -364,6 +550,15 @@ ngx_http_lua_timer_handler(ngx_event_t *ev) lmcf->pending_timers--; + if (!ngx_exiting && tctx.delay > 0) { + rc = ngx_http_lua_timer_copy(&tctx); + if (rc != NGX_OK) { + ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, + "failed to create the next timer of delay %ud ms", + (unsigned) tctx.delay); + } + } + if (lmcf->running_timers >= lmcf->max_running_timers) { ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "%i lua_max_running_timers are not enough", diff --git a/debian/modules/nginx-lua/src/ngx_http_lua_util.c b/debian/modules/nginx-lua/src/ngx_http_lua_util.c index 7f59833..c7bee3e 100644 --- a/debian/modules/nginx-lua/src/ngx_http_lua_util.c +++ b/debian/modules/nginx-lua/src/ngx_http_lua_util.c @@ -51,6 +51,7 @@ #include "ngx_http_lua_socket_tcp.h" #include "ngx_http_lua_ssl_certby.h" #include "ngx_http_lua_ssl.h" +#include "ngx_http_lua_log_ringbuf.h" #if 1 @@ -918,7 +919,11 @@ ngx_http_lua_request_cleanup(ngx_http_lua_ctx_t *ctx, int forcible) #if 1 if (r->connection->fd == (ngx_socket_t) -1) { /* being a fake request */ - lmcf->running_timers--; + + if (ctx->context == NGX_HTTP_LUA_CONTEXT_TIMER) { + /* being a timer handler */ + lmcf->running_timers--; + } } #endif @@ -1835,6 +1840,26 @@ ngx_http_lua_escape_uri(u_char *dst, u_char *src, size_t size, ngx_uint_t type) /* ~}| {zyx wvut srqp onml kjih gfed cba` */ 0x80000000, /* 1000 0000 0000 0000 0000 0000 0000 0000 */ + 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ + 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ + 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ + 0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */ + }; + + /* not ALPHA, DIGIT, "-", ".", "_", "~" */ + + static uint32_t uri_component[] = { + 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ + + /* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */ + 0xfc00987d, /* 1111 1100 0000 0000 1001 1000 0111 1101 */ + + /* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */ + 0x78000001, /* 0111 1000 0000 0000 0000 0000 0000 0001 */ + + /* ~}| {zyx wvut srqp onml kjih gfed cba` */ + 0xb8000001, /* 1011 1000 0000 0000 0000 0000 0000 0001 */ + 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ @@ -1904,8 +1929,7 @@ ngx_http_lua_escape_uri(u_char *dst, u_char *src, size_t size, ngx_uint_t type) /* mail_auth is the same as memcached */ static uint32_t *map[] = - { uri, args, html, refresh, memcached, memcached }; - + { uri, args, uri_component, html, refresh, memcached, memcached }; escape = map[type]; @@ -2316,7 +2340,7 @@ ngx_http_lua_process_args_option(ngx_http_request_t *r, lua_State *L, key = (u_char *) lua_tolstring(L, -2, &key_len); key_escape = 2 * ngx_http_lua_escape_uri(NULL, key, key_len, - NGX_ESCAPE_URI); + NGX_ESCAPE_URI_COMPONENT); total_escape += key_escape; switch (lua_type(L, -1)) { @@ -2325,7 +2349,7 @@ ngx_http_lua_process_args_option(ngx_http_request_t *r, lua_State *L, value = (u_char *) lua_tolstring(L, -1, &value_len); total_escape += 2 * ngx_http_lua_escape_uri(NULL, value, value_len, - NGX_ESCAPE_URI); + NGX_ESCAPE_URI_COMPONENT); len += key_len + value_len + (sizeof("=") - 1); n++; @@ -2366,7 +2390,7 @@ ngx_http_lua_process_args_option(ngx_http_request_t *r, lua_State *L, total_escape += 2 * ngx_http_lua_escape_uri(NULL, value, value_len, - NGX_ESCAPE_URI); + NGX_ESCAPE_URI_COMPONENT); len += key_len + value_len + (sizeof("=") - 1); } @@ -2423,7 +2447,8 @@ ngx_http_lua_process_args_option(ngx_http_request_t *r, lua_State *L, if (total_escape) { p = (u_char *) ngx_http_lua_escape_uri(p, key, key_len, - NGX_ESCAPE_URI); + NGX_ESCAPE_URI_COMPONENT + ); } else { dd("shortcut: no escape required"); @@ -2437,7 +2462,8 @@ ngx_http_lua_process_args_option(ngx_http_request_t *r, lua_State *L, if (total_escape) { p = (u_char *) ngx_http_lua_escape_uri(p, value, value_len, - NGX_ESCAPE_URI); + NGX_ESCAPE_URI_COMPONENT + ); } else { p = ngx_copy(p, value, value_len); @@ -2456,7 +2482,7 @@ ngx_http_lua_process_args_option(ngx_http_request_t *r, lua_State *L, if (lua_toboolean(L, -1)) { if (total_escape) { p = (u_char *) ngx_http_lua_escape_uri(p, key, key_len, - NGX_ESCAPE_URI); + NGX_ESCAPE_URI_COMPONENT); } else { dd("shortcut: no escape required"); @@ -2484,7 +2510,7 @@ ngx_http_lua_process_args_option(ngx_http_request_t *r, lua_State *L, if (total_escape) { p = (u_char *) ngx_http_lua_escape_uri(p, key, key_len, - NGX_ESCAPE_URI); + NGX_ESCAPE_URI_COMPONENT); } else { dd("shortcut: no escape required"); @@ -2503,7 +2529,8 @@ ngx_http_lua_process_args_option(ngx_http_request_t *r, lua_State *L, p = (u_char *) ngx_http_lua_escape_uri(p, key, key_len, - NGX_ESCAPE_URI); + NGX_ESCAPE_URI_COMPONENT + ); } else { dd("shortcut: no escape required"); @@ -2519,7 +2546,8 @@ ngx_http_lua_process_args_option(ngx_http_request_t *r, lua_State *L, p = (u_char *) ngx_http_lua_escape_uri(p, value, value_len, - NGX_ESCAPE_URI); + NGX_ESCAPE_URI_COMPONENT + ); } else { p = ngx_copy(p, value, value_len); diff --git a/debian/modules/nginx-lua/src/ngx_http_lua_worker.c b/debian/modules/nginx-lua/src/ngx_http_lua_worker.c index ff09b5b..e1cfec4 100644 --- a/debian/modules/nginx-lua/src/ngx_http_lua_worker.c +++ b/debian/modules/nginx-lua/src/ngx_http_lua_worker.c @@ -13,6 +13,9 @@ #include "ngx_http_lua_worker.h" +#define NGX_PROCESS_PRIVILEGED_AGENT 99 + + static int ngx_http_lua_ngx_worker_exiting(lua_State *L); static int ngx_http_lua_ngx_worker_pid(lua_State *L); static int ngx_http_lua_ngx_worker_id(lua_State *L); @@ -130,4 +133,46 @@ ngx_http_lua_ffi_worker_count(void) return (int) ccf->worker_processes; } + + +int +ngx_http_lua_ffi_get_process_type(void) +{ +#if defined(HAVE_PRIVILEGED_PROCESS_PATCH) && !NGX_WIN32 + if (ngx_process == NGX_PROCESS_HELPER) { + if (ngx_is_privileged_agent) { + return NGX_PROCESS_PRIVILEGED_AGENT; + } + } +#endif + + return ngx_process; +} + + +int +ngx_http_lua_ffi_enable_privileged_agent(char **err) +{ +#ifdef HAVE_PRIVILEGED_PROCESS_PATCH + ngx_core_conf_t *ccf; + + ccf = (ngx_core_conf_t *) ngx_get_conf(ngx_cycle->conf_ctx, + ngx_core_module); + + ccf->privileged_agent = 1; + + return NGX_OK; + +#else + *err = "missing privileged agent process patch in the nginx core"; + return NGX_ERROR; +#endif +} + + +void +ngx_http_lua_ffi_process_signal_graceful_exit(void) +{ + ngx_quit = 1; +} #endif diff --git a/debian/modules/nginx-lua/t/000--init.t b/debian/modules/nginx-lua/t/000--init.t index 364334f..ad2d70e 100644 --- a/debian/modules/nginx-lua/t/000--init.t +++ b/debian/modules/nginx-lua/t/000--init.t @@ -84,4 +84,3 @@ GET /flush --- timeout: 10 --- no_error_log [error] - diff --git a/debian/modules/nginx-lua/t/000-sanity.t b/debian/modules/nginx-lua/t/000-sanity.t index 3f66752..87854ef 100644 --- a/debian/modules/nginx-lua/t/000-sanity.t +++ b/debian/modules/nginx-lua/t/000-sanity.t @@ -31,4 +31,3 @@ GET /lua GET /lua --- response_body helloworld - diff --git a/debian/modules/nginx-lua/t/001-set.t b/debian/modules/nginx-lua/t/001-set.t index 2295a2d..ba8f22c 100644 --- a/debian/modules/nginx-lua/t/001-set.t +++ b/debian/modules/nginx-lua/t/001-set.t @@ -795,4 +795,3 @@ GET /lua?a=1&b=2 --- error_code: 500 --- error_log eval qr/failed to load external Lua file ".*?test2\.lua": cannot open .*? No such file or directory/ - diff --git a/debian/modules/nginx-lua/t/002-content.t b/debian/modules/nginx-lua/t/002-content.t index e6cb62d..3f2460e 100644 --- a/debian/modules/nginx-lua/t/002-content.t +++ b/debian/modules/nginx-lua/t/002-content.t @@ -836,4 +836,3 @@ GET /lua --- error_code: 500 --- error_log eval qr/failed to load inlined Lua code: / - diff --git a/debian/modules/nginx-lua/t/003-errors.t b/debian/modules/nginx-lua/t/003-errors.t index 764300a..ad3a506 100644 --- a/debian/modules/nginx-lua/t/003-errors.t +++ b/debian/modules/nginx-lua/t/003-errors.t @@ -126,4 +126,3 @@ GET /main GET /main --- response_body 500 - diff --git a/debian/modules/nginx-lua/t/004-require.t b/debian/modules/nginx-lua/t/004-require.t index 3250b2f..ec74116 100644 --- a/debian/modules/nginx-lua/t/004-require.t +++ b/debian/modules/nginx-lua/t/004-require.t @@ -208,4 +208,3 @@ GET /ndk GET /ndk --- response_body %20 - diff --git a/debian/modules/nginx-lua/t/005-exit.t b/debian/modules/nginx-lua/t/005-exit.t index 781531f..a5a28b3 100644 --- a/debian/modules/nginx-lua/t/005-exit.t +++ b/debian/modules/nginx-lua/t/005-exit.t @@ -723,4 +723,3 @@ GET /t --- response_body --- no_error_log [error] - diff --git a/debian/modules/nginx-lua/t/006-escape.t b/debian/modules/nginx-lua/t/006-escape.t index 7b26bba..a21d3cb 100644 --- a/debian/modules/nginx-lua/t/006-escape.t +++ b/debian/modules/nginx-lua/t/006-escape.t @@ -3,9 +3,8 @@ use Test::Nginx::Socket::Lua; repeat_each(2); -#repeat_each(1); -plan tests => repeat_each() * (blocks() * 2 + 1); +plan tests => repeat_each() * (blocks() * 2 + 2); no_long_string(); @@ -181,3 +180,20 @@ GET /t --- response_body [32] + + +=== TEST 14: reserved chars +--- config + location /lua { + content_by_lua_block { + ngx.say(ngx.escape_uri("-_.!~*'()")) + ngx.say(ngx.escape_uri(",$@|`")) + } + } +--- request +GET /lua +--- response_body +-_.!~*'() +%2C%24%40%7C%60 +--- no_error_log +[error] diff --git a/debian/modules/nginx-lua/t/007-md5.t b/debian/modules/nginx-lua/t/007-md5.t index 501e3af..2ae9efb 100644 --- a/debian/modules/nginx-lua/t/007-md5.t +++ b/debian/modules/nginx-lua/t/007-md5.t @@ -100,4 +100,3 @@ d41d8cd98f00b204e9800998ecf8427e GET /md5 --- response_body 6c8349cc7260ae62e3b1396831a8398f - diff --git a/debian/modules/nginx-lua/t/008-today.t b/debian/modules/nginx-lua/t/008-today.t index 54bd949..ec2f433 100644 --- a/debian/modules/nginx-lua/t/008-today.t +++ b/debian/modules/nginx-lua/t/008-today.t @@ -36,4 +36,3 @@ GET /today --- request GET /today --- response_body_like: ^\d{4}-\d{2}-\d{2}$ - diff --git a/debian/modules/nginx-lua/t/009-log.t b/debian/modules/nginx-lua/t/009-log.t index 0c6a9a5..68c057f 100644 --- a/debian/modules/nginx-lua/t/009-log.t +++ b/debian/modules/nginx-lua/t/009-log.t @@ -542,4 +542,3 @@ ok [error] --- error_log eval "2: hello\0world, client: " - diff --git a/debian/modules/nginx-lua/t/010-request_body.t b/debian/modules/nginx-lua/t/010-request_body.t index 2640a54..e669d94 100644 --- a/debian/modules/nginx-lua/t/010-request_body.t +++ b/debian/modules/nginx-lua/t/010-request_body.t @@ -270,4 +270,3 @@ Expect: 100-Continue http finalize request: 500, "/echo_body?" a:1, c:2 http finalize request: 500, "/echo_body?" a:1, c:0 --- log_level: debug - diff --git a/debian/modules/nginx-lua/t/012-now.t b/debian/modules/nginx-lua/t/012-now.t index abcb735..5885187 100644 --- a/debian/modules/nginx-lua/t/012-now.t +++ b/debian/modules/nginx-lua/t/012-now.t @@ -116,4 +116,3 @@ GET /time --- request GET /time --- response_body_like: ^\d{10,}(\.\d{1,3})?$ - diff --git a/debian/modules/nginx-lua/t/014-bugs.t b/debian/modules/nginx-lua/t/014-bugs.t index 44337e3..9aadff0 100644 --- a/debian/modules/nginx-lua/t/014-bugs.t +++ b/debian/modules/nginx-lua/t/014-bugs.t @@ -849,7 +849,7 @@ ok "lua_package_path '$::HtmlDir/?.lua;./?.lua';" --- config location /t { - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; set $myhost 'agentzh.org.'; proxy_pass http://$myhost/misc/.vimrc; } @@ -1018,4 +1018,3 @@ write timer set: 1 --- no_error_log [error] [alert] - diff --git a/debian/modules/nginx-lua/t/016-resp-header.t b/debian/modules/nginx-lua/t/016-resp-header.t index 179b411..1fae292 100644 --- a/debian/modules/nginx-lua/t/016-resp-header.t +++ b/debian/modules/nginx-lua/t/016-resp-header.t @@ -8,7 +8,7 @@ use Test::Nginx::Socket::Lua; repeat_each(2); -plan tests => repeat_each() * (blocks() * 3 + 38); +plan tests => repeat_each() * (blocks() * 3 + 41); #no_diff(); no_long_string(); @@ -1441,3 +1441,71 @@ Content-Type: ; blah test --- no_error_log [error] + + + +=== TEST 69: return the matched content-type instead of default_type +--- http_config +types { + image/png png; +} +--- config +location /set/ { + default_type text/html; + content_by_lua_block { + ngx.say(ngx.header["content-type"]) + } +} +--- request +GET /set/hello.png +--- response_headers +Content-Type: image/png +--- response_body +image/png +--- no_error_log +[error] + + + +=== TEST 70: always return the matched content-type +--- config + location /set/ { + default_type "image/png"; + content_by_lua_block { + ngx.say(ngx.header["content-type"]) + ngx.say(ngx.header["content-type"]) + } + } +--- request +GET /set/hello.png +--- response_headers +Content-Type: image/png +--- response_body +image/png +image/png +--- no_error_log +[error] + + + +=== TEST 71: return the matched content-type after ngx.resp.get_headers() +--- http_config +types { + image/png png; +} +--- config + location /set/ { + default_type text/html; + content_by_lua_block { + local h = ngx.resp.get_headers() + ngx.say(h["content-type"]) + } + } +--- request +GET /set/hello.png +--- response_headers +Content-Type: image/png +--- response_body +image/png +--- no_error_log +[error] diff --git a/debian/modules/nginx-lua/t/017-exec.t b/debian/modules/nginx-lua/t/017-exec.t index 4c7a918..535c4ab 100644 --- a/debian/modules/nginx-lua/t/017-exec.t +++ b/debian/modules/nginx-lua/t/017-exec.t @@ -572,4 +572,3 @@ hello, bah ["dummy", "dummy"] --- no_error_log [error] - diff --git a/debian/modules/nginx-lua/t/018-ndk.t b/debian/modules/nginx-lua/t/018-ndk.t index d68306b..1429377 100644 --- a/debian/modules/nginx-lua/t/018-ndk.t +++ b/debian/modules/nginx-lua/t/018-ndk.t @@ -171,4 +171,3 @@ ok foo = a b --- no_error_log [error] - diff --git a/debian/modules/nginx-lua/t/019-const.t b/debian/modules/nginx-lua/t/019-const.t index fe79bfb..4f9c764 100644 --- a/debian/modules/nginx-lua/t/019-const.t +++ b/debian/modules/nginx-lua/t/019-const.t @@ -44,4 +44,3 @@ GET /read GET /read --- response_body 504 - diff --git a/debian/modules/nginx-lua/t/021-cookie-time.t b/debian/modules/nginx-lua/t/021-cookie-time.t index c00bbea..b05e401 100644 --- a/debian/modules/nginx-lua/t/021-cookie-time.t +++ b/debian/modules/nginx-lua/t/021-cookie-time.t @@ -43,4 +43,3 @@ Thu, 18-Nov-10 11:27:35 GMT GET /lua --- response_body Thu, 18-Nov-10 11:27:35 GMT - diff --git a/debian/modules/nginx-lua/t/022-redirect.t b/debian/modules/nginx-lua/t/022-redirect.t index 57c7add..fae39e3 100644 --- a/debian/modules/nginx-lua/t/022-redirect.t +++ b/debian/modules/nginx-lua/t/022-redirect.t @@ -84,7 +84,7 @@ GET /read --- response_body_like: 500 Internal Server Error --- error_code: 500 --- error_log -only ngx.HTTP_MOVED_TEMPORARILY, ngx.HTTP_MOVED_PERMANENTLY, and ngx.HTTP_TEMPORARY_REDIRECT are allowed +only ngx.HTTP_MOVED_TEMPORARILY, ngx.HTTP_MOVED_PERMANENTLY, ngx.HTTP_SEE_OTHER, and ngx.HTTP_TEMPORARY_REDIRECT are allowed @@ -218,3 +218,54 @@ GET /read Location: http://agentzh.org/foo?a=b&c=d --- response_body_like: 307 Temporary Redirect --- error_code: 307 + + + +=== TEST 12: explicit 303 +--- config + location /read { + content_by_lua_block { + ngx.redirect("http://agentzh.org/foo", ngx.HTTP_SEE_OTHER); + ngx.say("hi") + } + } +--- request +GET /read +--- response_headers +Location: http://agentzh.org/foo +--- response_body_like: 303 See Other +--- error_code: 303 + + + +=== TEST 13: explicit 303 with args +--- config + location /read { + content_by_lua_block { + ngx.redirect("http://agentzh.org/foo?a=b&c=d", ngx.HTTP_SEE_OTHER); + ngx.say("hi") + } + } +--- request +GET /read +--- response_headers +Location: http://agentzh.org/foo?a=b&c=d +--- response_body_like: 303 See Other +--- error_code: 303 + + + +=== TEST 14: explicit 303 +--- config + location /read { + content_by_lua_block { + ngx.redirect("http://agentzh.org/foo?a=b&c=d", 303); + ngx.say("hi") + } + } +--- request +GET /read +--- response_headers +Location: http://agentzh.org/foo?a=b&c=d +--- response_body_like: 303 See Other +--- error_code: 303 diff --git a/debian/modules/nginx-lua/t/023-rewrite/client-abort.t b/debian/modules/nginx-lua/t/023-rewrite/client-abort.t index e970802..117d17e 100644 --- a/debian/modules/nginx-lua/t/023-rewrite/client-abort.t +++ b/debian/modules/nginx-lua/t/023-rewrite/client-abort.t @@ -848,4 +848,3 @@ delete thread 1 --- no_error_log [error] [alert] - diff --git a/debian/modules/nginx-lua/t/023-rewrite/exec.t b/debian/modules/nginx-lua/t/023-rewrite/exec.t index a063b5b..bd97968 100644 --- a/debian/modules/nginx-lua/t/023-rewrite/exec.t +++ b/debian/modules/nginx-lua/t/023-rewrite/exec.t @@ -376,4 +376,3 @@ ngx.exec("@proxy") GET /main --- response_body hello, bah - diff --git a/debian/modules/nginx-lua/t/023-rewrite/exit.t b/debian/modules/nginx-lua/t/023-rewrite/exit.t index 9d292f7..39ea5cb 100644 --- a/debian/modules/nginx-lua/t/023-rewrite/exit.t +++ b/debian/modules/nginx-lua/t/023-rewrite/exit.t @@ -595,4 +595,3 @@ F(ngx_http_send_header) { --- error_code: 204 --- no_error_log [error] - diff --git a/debian/modules/nginx-lua/t/023-rewrite/mixed.t b/debian/modules/nginx-lua/t/023-rewrite/mixed.t index 1156567..0f742b2 100644 --- a/debian/modules/nginx-lua/t/023-rewrite/mixed.t +++ b/debian/modules/nginx-lua/t/023-rewrite/mixed.t @@ -167,4 +167,3 @@ world\x03\x04\xff hello\x00\x01\x02 world\x03\x04\xff " - diff --git a/debian/modules/nginx-lua/t/023-rewrite/multi-capture.t b/debian/modules/nginx-lua/t/023-rewrite/multi-capture.t index 44629b0..083ec78 100644 --- a/debian/modules/nginx-lua/t/023-rewrite/multi-capture.t +++ b/debian/modules/nginx-lua/t/023-rewrite/multi-capture.t @@ -392,4 +392,3 @@ res4.status = 201 res4.body = STORED\r " - diff --git a/debian/modules/nginx-lua/t/023-rewrite/on-abort.t b/debian/modules/nginx-lua/t/023-rewrite/on-abort.t index aca2ab6..336b7ce 100644 --- a/debian/modules/nginx-lua/t/023-rewrite/on-abort.t +++ b/debian/modules/nginx-lua/t/023-rewrite/on-abort.t @@ -654,4 +654,3 @@ delete thread 2 --- no_error_log [error] - diff --git a/debian/modules/nginx-lua/t/023-rewrite/redirect.t b/debian/modules/nginx-lua/t/023-rewrite/redirect.t index 8843f1a..99f3fd4 100644 --- a/debian/modules/nginx-lua/t/023-rewrite/redirect.t +++ b/debian/modules/nginx-lua/t/023-rewrite/redirect.t @@ -122,4 +122,3 @@ GET /read --- raw_response_headers_like: Location: /foo\r\n --- response_body_like: 302 Found --- error_code: 302 - diff --git a/debian/modules/nginx-lua/t/023-rewrite/req-body.t b/debian/modules/nginx-lua/t/023-rewrite/req-body.t index 2f42e0a..13bdcb2 100644 --- a/debian/modules/nginx-lua/t/023-rewrite/req-body.t +++ b/debian/modules/nginx-lua/t/023-rewrite/req-body.t @@ -221,4 +221,3 @@ hiya, world"] --- no_error_log [error] [alert] - diff --git a/debian/modules/nginx-lua/t/023-rewrite/req-socket.t b/debian/modules/nginx-lua/t/023-rewrite/req-socket.t index 34aedaa..87cbbbe 100644 --- a/debian/modules/nginx-lua/t/023-rewrite/req-socket.t +++ b/debian/modules/nginx-lua/t/023-rewrite/req-socket.t @@ -532,4 +532,3 @@ Expect: 100-Continue \breceived: hello\b.*?\breceived: worl\b --- no_error_log [error] - diff --git a/debian/modules/nginx-lua/t/023-rewrite/request_body.t b/debian/modules/nginx-lua/t/023-rewrite/request_body.t index 0594001..b867d3a 100644 --- a/debian/modules/nginx-lua/t/023-rewrite/request_body.t +++ b/debian/modules/nginx-lua/t/023-rewrite/request_body.t @@ -170,4 +170,3 @@ Expect: 100-Continue http finalize request: 500, "/echo_body?" a:1, c:2 http finalize request: 500, "/echo_body?" a:1, c:0 --- log_level: debug - diff --git a/debian/modules/nginx-lua/t/023-rewrite/sanity.t b/debian/modules/nginx-lua/t/023-rewrite/sanity.t index 20b00e2..b90aa0e 100644 --- a/debian/modules/nginx-lua/t/023-rewrite/sanity.t +++ b/debian/modules/nginx-lua/t/023-rewrite/sanity.t @@ -799,4 +799,3 @@ test test --- no_error_log [alert] - diff --git a/debian/modules/nginx-lua/t/023-rewrite/sleep.t b/debian/modules/nginx-lua/t/023-rewrite/sleep.t index 1719784..8d4c2da 100644 --- a/debian/modules/nginx-lua/t/023-rewrite/sleep.t +++ b/debian/modules/nginx-lua/t/023-rewrite/sleep.t @@ -219,4 +219,3 @@ hello world hello world --- no_error_log [error] - diff --git a/debian/modules/nginx-lua/t/023-rewrite/socket-keepalive.t b/debian/modules/nginx-lua/t/023-rewrite/socket-keepalive.t index 50de0b3..489a70f 100644 --- a/debian/modules/nginx-lua/t/023-rewrite/socket-keepalive.t +++ b/debian/modules/nginx-lua/t/023-rewrite/socket-keepalive.t @@ -1007,4 +1007,3 @@ Not found, dear... --- error_code: 404 --- no_error_log [error] - diff --git a/debian/modules/nginx-lua/t/023-rewrite/subrequest.t b/debian/modules/nginx-lua/t/023-rewrite/subrequest.t index a307388..5d1e8f0 100644 --- a/debian/modules/nginx-lua/t/023-rewrite/subrequest.t +++ b/debian/modules/nginx-lua/t/023-rewrite/subrequest.t @@ -639,4 +639,3 @@ the nginx core requires the patch https://github.com/agentzh/ngx_openresty/blob/ GET /t --- response_body done - diff --git a/debian/modules/nginx-lua/t/023-rewrite/tcp-socket-timeout.t b/debian/modules/nginx-lua/t/023-rewrite/tcp-socket-timeout.t index 79cd0b9..15bec7f 100644 --- a/debian/modules/nginx-lua/t/023-rewrite/tcp-socket-timeout.t +++ b/debian/modules/nginx-lua/t/023-rewrite/tcp-socket-timeout.t @@ -41,7 +41,7 @@ __DATA__ --- config server_tokens off; lua_socket_connect_timeout 100ms; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; resolver_timeout 3s; location /t1 { rewrite_by_lua ' @@ -73,7 +73,7 @@ lua tcp socket connect timed out server_tokens off; lua_socket_connect_timeout 60s; lua_socket_log_errors off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; resolver_timeout 3s; location /t2 { rewrite_by_lua ' @@ -108,7 +108,7 @@ lua tcp socket connect timeout: 150 server_tokens off; lua_socket_log_errors off; lua_socket_connect_timeout 102ms; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; #resolver_timeout 3s; location /t3 { rewrite_by_lua ' @@ -143,7 +143,7 @@ lua tcp socket connect timeout: 102 server_tokens off; lua_socket_connect_timeout 102ms; lua_socket_log_errors off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; resolver_timeout 3s; location /t4 { rewrite_by_lua ' @@ -179,7 +179,7 @@ lua tcp socket connect timeout: 102 server_tokens off; lua_socket_connect_timeout 102ms; lua_socket_log_errors off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; resolver_timeout 3s; location /t5 { rewrite_by_lua ' @@ -251,7 +251,7 @@ lua tcp socket read timed out --- config server_tokens off; lua_socket_read_timeout 60s; - #resolver $TEST_NGINX_RESOLVER; + #resolver $TEST_NGINX_RESOLVER ipv6=off; location /t { rewrite_by_lua ' local sock = ngx.socket.tcp() @@ -292,7 +292,7 @@ lua tcp socket read timed out --- config server_tokens off; lua_socket_read_timeout 102ms; - #resolver $TEST_NGINX_RESOLVER; + #resolver $TEST_NGINX_RESOLVER ipv6=off; location /t { rewrite_by_lua ' local sock = ngx.socket.tcp() @@ -333,7 +333,7 @@ lua tcp socket read timed out --- config server_tokens off; lua_socket_read_timeout 102ms; - #resolver $TEST_NGINX_RESOLVER; + #resolver $TEST_NGINX_RESOLVER ipv6=off; location /t { rewrite_by_lua ' local sock = ngx.socket.tcp() @@ -375,7 +375,7 @@ lua tcp socket read timed out --- config server_tokens off; lua_socket_read_timeout 102ms; - #resolver $TEST_NGINX_RESOLVER; + #resolver $TEST_NGINX_RESOLVER ipv6=off; location /t { rewrite_by_lua ' local sock = ngx.socket.tcp() @@ -416,7 +416,7 @@ lua tcp socket read timed out --- config server_tokens off; lua_socket_send_timeout 100ms; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; location /t { rewrite_by_lua ' local sock = ngx.socket.tcp() @@ -455,7 +455,7 @@ lua tcp socket write timed out --- config server_tokens off; lua_socket_send_timeout 60s; - #resolver $TEST_NGINX_RESOLVER; + #resolver $TEST_NGINX_RESOLVER ipv6=off; location /t { rewrite_by_lua ' local sock = ngx.socket.tcp() @@ -496,7 +496,7 @@ lua tcp socket write timed out --- config server_tokens off; lua_socket_send_timeout 102ms; - #resolver $TEST_NGINX_RESOLVER; + #resolver $TEST_NGINX_RESOLVER ipv6=off; location /t { rewrite_by_lua ' local sock = ngx.socket.tcp() @@ -537,7 +537,7 @@ lua tcp socket write timed out --- config server_tokens off; lua_socket_send_timeout 102ms; - #resolver $TEST_NGINX_RESOLVER; + #resolver $TEST_NGINX_RESOLVER ipv6=off; location /t { rewrite_by_lua ' local sock = ngx.socket.tcp() @@ -578,7 +578,7 @@ lua tcp socket write timed out --- config server_tokens off; lua_socket_send_timeout 102ms; - #resolver $TEST_NGINX_RESOLVER; + #resolver $TEST_NGINX_RESOLVER ipv6=off; location /t { rewrite_by_lua ' local sock = ngx.socket.tcp() @@ -612,4 +612,3 @@ failed to send: timeout lua tcp socket send timeout: 102 lua tcp socket connect timeout: 60000 lua tcp socket write timed out - diff --git a/debian/modules/nginx-lua/t/023-rewrite/tcp-socket.t b/debian/modules/nginx-lua/t/023-rewrite/tcp-socket.t index cf9d80a..bff69a5 100644 --- a/debian/modules/nginx-lua/t/023-rewrite/tcp-socket.t +++ b/debian/modules/nginx-lua/t/023-rewrite/tcp-socket.t @@ -204,7 +204,7 @@ attempt to send data on a closed socket: --- timeout: 10 --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; resolver_timeout 3s; location /t { rewrite_by_lua ' @@ -296,7 +296,7 @@ qr/connect\(\) failed \(\d+: Connection refused\)/ === TEST 6: connection timeout (tcp) --- config - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; lua_socket_connect_timeout 100ms; lua_socket_send_timeout 100ms; lua_socket_read_timeout 100ms; @@ -372,7 +372,7 @@ connected: 1 === TEST 8: resolver error (host not found) --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; resolver_timeout 3s; location /t { rewrite_by_lua ' @@ -415,7 +415,7 @@ attempt to send data on a closed socket === TEST 9: resolver error (timeout) --- config server_tokens off; - resolver 8.8.8.8; + resolver $TEST_NGINX_RESOLVER ipv6=off; resolver_timeout 1ms; location /t { rewrite_by_lua ' @@ -2390,4 +2390,3 @@ qr/runtime error: rewrite_by_lua\(nginx\.conf:\d+\):16: bad request/ --- no_error_log [alert] - diff --git a/debian/modules/nginx-lua/t/023-rewrite/unix-socket.t b/debian/modules/nginx-lua/t/023-rewrite/unix-socket.t index 098dd67..8a5f000 100644 --- a/debian/modules/nginx-lua/t/023-rewrite/unix-socket.t +++ b/debian/modules/nginx-lua/t/023-rewrite/unix-socket.t @@ -150,4 +150,3 @@ received: received: foo failed to receive a line: closed close: 1 nil - diff --git a/debian/modules/nginx-lua/t/023-rewrite/uthread-redirect.t b/debian/modules/nginx-lua/t/023-rewrite/uthread-redirect.t index 0f125e0..83de1a3 100644 --- a/debian/modules/nginx-lua/t/023-rewrite/uthread-redirect.t +++ b/debian/modules/nginx-lua/t/023-rewrite/uthread-redirect.t @@ -186,4 +186,3 @@ free request --- error_code: 302 --- no_error_log [error] - diff --git a/debian/modules/nginx-lua/t/023-rewrite/uthread-spawn.t b/debian/modules/nginx-lua/t/023-rewrite/uthread-spawn.t index 58af7d0..5552107 100644 --- a/debian/modules/nginx-lua/t/023-rewrite/uthread-spawn.t +++ b/debian/modules/nginx-lua/t/023-rewrite/uthread-spawn.t @@ -1449,4 +1449,3 @@ status: 204 --- no_error_log [error] --- timeout: 3 - diff --git a/debian/modules/nginx-lua/t/024-access/auth.t b/debian/modules/nginx-lua/t/024-access/auth.t index 5da09cb..56e9862 100644 --- a/debian/modules/nginx-lua/t/024-access/auth.t +++ b/debian/modules/nginx-lua/t/024-access/auth.t @@ -107,4 +107,3 @@ Location: /terms_of_use\.html GET /lua --- response_body_like: 403 Forbidden --- error_code: 403 - diff --git a/debian/modules/nginx-lua/t/024-access/client-abort.t b/debian/modules/nginx-lua/t/024-access/client-abort.t index a94f822..c16f4ea 100644 --- a/debian/modules/nginx-lua/t/024-access/client-abort.t +++ b/debian/modules/nginx-lua/t/024-access/client-abort.t @@ -850,4 +850,3 @@ delete thread 1 --- no_error_log [error] [alert] - diff --git a/debian/modules/nginx-lua/t/024-access/exit.t b/debian/modules/nginx-lua/t/024-access/exit.t index 8470ab9..d6d66b8 100644 --- a/debian/modules/nginx-lua/t/024-access/exit.t +++ b/debian/modules/nginx-lua/t/024-access/exit.t @@ -545,4 +545,3 @@ Not found, dear... --- response_body Not found, dear... --- error_code: 404 - diff --git a/debian/modules/nginx-lua/t/024-access/multi-capture.t b/debian/modules/nginx-lua/t/024-access/multi-capture.t index 368d401..930b74d 100644 --- a/debian/modules/nginx-lua/t/024-access/multi-capture.t +++ b/debian/modules/nginx-lua/t/024-access/multi-capture.t @@ -392,4 +392,3 @@ res4.status = 201 res4.body = STORED\r " - diff --git a/debian/modules/nginx-lua/t/024-access/on-abort.t b/debian/modules/nginx-lua/t/024-access/on-abort.t index 0c17b55..5bb948b 100644 --- a/debian/modules/nginx-lua/t/024-access/on-abort.t +++ b/debian/modules/nginx-lua/t/024-access/on-abort.t @@ -649,4 +649,3 @@ delete thread 2 --- no_error_log [error] - diff --git a/debian/modules/nginx-lua/t/024-access/redirect.t b/debian/modules/nginx-lua/t/024-access/redirect.t index c7ce512..b45fac7 100644 --- a/debian/modules/nginx-lua/t/024-access/redirect.t +++ b/debian/modules/nginx-lua/t/024-access/redirect.t @@ -122,4 +122,3 @@ GET /read --- raw_response_headers_like: Location: /foo\r\n --- response_body_like: 302 Found --- error_code: 302 - diff --git a/debian/modules/nginx-lua/t/024-access/req-body.t b/debian/modules/nginx-lua/t/024-access/req-body.t index fd33aff..70db85c 100644 --- a/debian/modules/nginx-lua/t/024-access/req-body.t +++ b/debian/modules/nginx-lua/t/024-access/req-body.t @@ -218,4 +218,3 @@ hiya, world"] --- no_error_log [error] [alert] - diff --git a/debian/modules/nginx-lua/t/024-access/request_body.t b/debian/modules/nginx-lua/t/024-access/request_body.t index a6fead2..fa03195 100644 --- a/debian/modules/nginx-lua/t/024-access/request_body.t +++ b/debian/modules/nginx-lua/t/024-access/request_body.t @@ -170,4 +170,3 @@ Expect: 100-Continue http finalize request: 500, "/echo_body?" a:1, c:2 http finalize request: 500, "/echo_body?" a:1, c:0 --- log_level: debug - diff --git a/debian/modules/nginx-lua/t/024-access/sanity.t b/debian/modules/nginx-lua/t/024-access/sanity.t index de63a68..7ff177f 100644 --- a/debian/modules/nginx-lua/t/024-access/sanity.t +++ b/debian/modules/nginx-lua/t/024-access/sanity.t @@ -741,4 +741,3 @@ test test --- no_error_log [alert] - diff --git a/debian/modules/nginx-lua/t/024-access/satisfy.t b/debian/modules/nginx-lua/t/024-access/satisfy.t index 10d3ece..7902f49 100644 --- a/debian/modules/nginx-lua/t/024-access/satisfy.t +++ b/debian/modules/nginx-lua/t/024-access/satisfy.t @@ -209,4 +209,3 @@ something important --- error_code: 200 --- no_error_log [error] - diff --git a/debian/modules/nginx-lua/t/024-access/sleep.t b/debian/modules/nginx-lua/t/024-access/sleep.t index 2eb0822..fc1fc02 100644 --- a/debian/modules/nginx-lua/t/024-access/sleep.t +++ b/debian/modules/nginx-lua/t/024-access/sleep.t @@ -219,4 +219,3 @@ hello world hello world --- no_error_log [error] - diff --git a/debian/modules/nginx-lua/t/024-access/subrequest.t b/debian/modules/nginx-lua/t/024-access/subrequest.t index bfe96d6..b6ccf11 100644 --- a/debian/modules/nginx-lua/t/024-access/subrequest.t +++ b/debian/modules/nginx-lua/t/024-access/subrequest.t @@ -599,4 +599,3 @@ the nginx core requires the patch https://github.com/agentzh/ngx_openresty/blob/ GET /t --- response_body done - diff --git a/debian/modules/nginx-lua/t/024-access/uthread-exec.t b/debian/modules/nginx-lua/t/024-access/uthread-exec.t index d7c2321..7add3d4 100644 --- a/debian/modules/nginx-lua/t/024-access/uthread-exec.t +++ b/debian/modules/nginx-lua/t/024-access/uthread-exec.t @@ -344,4 +344,3 @@ free request end --- error_log attempt to abort with pending subrequests - diff --git a/debian/modules/nginx-lua/t/024-access/uthread-exit.t b/debian/modules/nginx-lua/t/024-access/uthread-exit.t index da4a9db..7c146ae 100644 --- a/debian/modules/nginx-lua/t/024-access/uthread-exit.t +++ b/debian/modules/nginx-lua/t/024-access/uthread-exit.t @@ -1311,4 +1311,3 @@ free request end --- error_log attempt to abort with pending subrequests - diff --git a/debian/modules/nginx-lua/t/024-access/uthread-redirect.t b/debian/modules/nginx-lua/t/024-access/uthread-redirect.t index 8b030ac..4eb4759 100644 --- a/debian/modules/nginx-lua/t/024-access/uthread-redirect.t +++ b/debian/modules/nginx-lua/t/024-access/uthread-redirect.t @@ -187,4 +187,3 @@ free request --- error_code: 302 --- no_error_log [error] - diff --git a/debian/modules/nginx-lua/t/024-access/uthread-spawn.t b/debian/modules/nginx-lua/t/024-access/uthread-spawn.t index 415e4c0..7c7ba3b 100644 --- a/debian/modules/nginx-lua/t/024-access/uthread-spawn.t +++ b/debian/modules/nginx-lua/t/024-access/uthread-spawn.t @@ -1116,4 +1116,3 @@ body: hello world)$ --- no_error_log [error] - diff --git a/debian/modules/nginx-lua/t/025-codecache.t b/debian/modules/nginx-lua/t/025-codecache.t index f33452a..0b02a27 100644 --- a/debian/modules/nginx-lua/t/025-codecache.t +++ b/debian/modules/nginx-lua/t/025-codecache.t @@ -1244,4 +1244,3 @@ qr/\[alert\] \S+ lua_code_cache is off; this will hurt performance/, "decrementing the reference count for Lua VM: 1", "lua close the global Lua VM", ] - diff --git a/debian/modules/nginx-lua/t/026-mysql.t b/debian/modules/nginx-lua/t/026-mysql.t index e14ffb6..569f96f 100644 --- a/debian/modules/nginx-lua/t/026-mysql.t +++ b/debian/modules/nginx-lua/t/026-mysql.t @@ -66,7 +66,7 @@ __DATA__ ^status = 504 thread id = \d+ kill status = 200 -kill body = {"errcode":0}$ +kill body = \{"errcode":0\}$ --- error_log eval qr{upstream timed out \(\d+: Connection timed out\) while sending query to drizzle upstream} @@ -126,6 +126,5 @@ qr{upstream timed out \(\d+: Connection timed out\) while sending query to drizz ^status = 504 thread id = \d+ kill status = 200 -kill body = {"errcode":0}$ +kill body = \{"errcode":0\}$ --- SKIP - diff --git a/debian/modules/nginx-lua/t/027-multi-capture.t b/debian/modules/nginx-lua/t/027-multi-capture.t index 3588c69..9227fe5 100644 --- a/debian/modules/nginx-lua/t/027-multi-capture.t +++ b/debian/modules/nginx-lua/t/027-multi-capture.t @@ -752,4 +752,3 @@ proxy_cache_path conf/cache levels=1:2 keys_zone=STATIC:10m inactive=10m max_siz GET /foo --- response_body ok - diff --git a/debian/modules/nginx-lua/t/029-http-time.t b/debian/modules/nginx-lua/t/029-http-time.t index 71a7758..ecef492 100644 --- a/debian/modules/nginx-lua/t/029-http-time.t +++ b/debian/modules/nginx-lua/t/029-http-time.t @@ -85,4 +85,3 @@ GET /lua GET /lua --- response_body nil - diff --git a/debian/modules/nginx-lua/t/030-uri-args.t b/debian/modules/nginx-lua/t/030-uri-args.t index 8ee8401..96e216c 100644 --- a/debian/modules/nginx-lua/t/030-uri-args.t +++ b/debian/modules/nginx-lua/t/030-uri-args.t @@ -9,7 +9,7 @@ log_level('warn'); repeat_each(2); #repeat_each(1); -plan tests => repeat_each() * (blocks() * 2 + 17); +plan tests => repeat_each() * (blocks() * 2 + 18); no_root_location(); @@ -1390,3 +1390,19 @@ GET /lua --- response_body_like ^HTTP/1.0 (a=3&b|b&a=3)$ + + +=== TEST 57: ngx.encode_args (escaping) +--- config + location /lua { + content_by_lua_block { + local t = {bar = "-_.!~*'()", foo = ",$@|`"} + ngx.say("args: ", ngx.encode_args(t)) + } + } +--- request +GET /lua +--- response_body +args: foo=%2C%24%40%7C%60&bar=-_.!~*'() +--- no_error_log +[error] diff --git a/debian/modules/nginx-lua/t/031-post-args.t b/debian/modules/nginx-lua/t/031-post-args.t index c2b6b8f..62c88c1 100644 --- a/debian/modules/nginx-lua/t/031-post-args.t +++ b/debian/modules/nginx-lua/t/031-post-args.t @@ -351,6 +351,6 @@ CORE::join("", @k); POST /lua a=3&b=4&c --- response_body -requesty body in temp file not supported +request body in temp file not supported --- no_error_log [error] diff --git a/debian/modules/nginx-lua/t/032-iolist.t b/debian/modules/nginx-lua/t/032-iolist.t index ddf3d7f..3c56032 100644 --- a/debian/modules/nginx-lua/t/032-iolist.t +++ b/debian/modules/nginx-lua/t/032-iolist.t @@ -76,4 +76,3 @@ GET /lua GET /lua --- response_body_like: 500 Internal Server Error --- error_code: 500 - diff --git a/debian/modules/nginx-lua/t/033-ctx.t b/debian/modules/nginx-lua/t/033-ctx.t index eefb216..8fc50aa 100644 --- a/debian/modules/nginx-lua/t/033-ctx.t +++ b/debian/modules/nginx-lua/t/033-ctx.t @@ -440,4 +440,3 @@ lua release ngx.ctx at ref --- response_body --- no_error_log [error] - diff --git a/debian/modules/nginx-lua/t/034-match.t b/debian/modules/nginx-lua/t/034-match.t index 35149f1..ebe5762 100644 --- a/debian/modules/nginx-lua/t/034-match.t +++ b/debian/modules/nginx-lua/t/034-match.t @@ -1017,7 +1017,7 @@ exec opts: 0 === TEST 45: just hit match limit --- http_config - lua_regex_match_limit 5600; + lua_regex_match_limit 5000; --- config location /re { content_by_lua_file html/a.lua; @@ -1057,7 +1057,7 @@ error: pcre_exec() failed: -8 === TEST 46: just not hit match limit --- http_config - lua_regex_match_limit 5700; + lua_regex_match_limit 5100; --- config location /re { content_by_lua_file html/a.lua; diff --git a/debian/modules/nginx-lua/t/035-gmatch.t b/debian/modules/nginx-lua/t/035-gmatch.t index 69b9512..5b63ae4 100644 --- a/debian/modules/nginx-lua/t/035-gmatch.t +++ b/debian/modules/nginx-lua/t/035-gmatch.t @@ -814,7 +814,7 @@ exec opts: 0 === TEST 30: just hit match limit --- http_config - lua_regex_match_limit 5600; + lua_regex_match_limit 5000; --- config location /re { content_by_lua_file html/a.lua; @@ -860,7 +860,7 @@ error: pcre_exec() failed: -8 === TEST 31: just not hit match limit --- http_config - lua_regex_match_limit 5700; + lua_regex_match_limit 5100; --- config location /re { content_by_lua_file html/a.lua; @@ -901,4 +901,3 @@ end GET /re --- response_body failed to match - diff --git a/debian/modules/nginx-lua/t/036-sub.t b/debian/modules/nginx-lua/t/036-sub.t index f08c50f..2b4b075 100644 --- a/debian/modules/nginx-lua/t/036-sub.t +++ b/debian/modules/nginx-lua/t/036-sub.t @@ -580,7 +580,7 @@ s: a好 === TEST 28: just hit match limit --- http_config - lua_regex_match_limit 5600; + lua_regex_match_limit 5000; --- config location /re { content_by_lua_file html/a.lua; @@ -617,7 +617,7 @@ error: pcre_exec() failed: -8 === TEST 29: just not hit match limit --- http_config - lua_regex_match_limit 5700; + lua_regex_match_limit 5100; --- config location /re { content_by_lua_file html/a.lua; diff --git a/debian/modules/nginx-lua/t/037-gsub.t b/debian/modules/nginx-lua/t/037-gsub.t index 2a1e00f..4c5810d 100644 --- a/debian/modules/nginx-lua/t/037-gsub.t +++ b/debian/modules/nginx-lua/t/037-gsub.t @@ -501,7 +501,7 @@ s: aa === TEST 23: just hit match limit --- http_config - lua_regex_match_limit 5600; + lua_regex_match_limit 5000; --- config location /re { content_by_lua_file html/a.lua; @@ -538,7 +538,7 @@ error: pcre_exec() failed: -8 === TEST 24: just not hit match limit --- http_config - lua_regex_match_limit 5700; + lua_regex_match_limit 5100; --- config location /re { content_by_lua_file html/a.lua; diff --git a/debian/modules/nginx-lua/t/038-match-o.t b/debian/modules/nginx-lua/t/038-match-o.t index 628e27f..d61ff1f 100644 --- a/debian/modules/nginx-lua/t/038-match-o.t +++ b/debian/modules/nginx-lua/t/038-match-o.t @@ -740,4 +740,3 @@ false hello false false - diff --git a/debian/modules/nginx-lua/t/039-sub-o.t b/debian/modules/nginx-lua/t/039-sub-o.t index a861b6c..580a671 100644 --- a/debian/modules/nginx-lua/t/039-sub-o.t +++ b/debian/modules/nginx-lua/t/039-sub-o.t @@ -578,4 +578,3 @@ a [b c] [b] [c] [] [] d --- response_body a [b c] [b] [c] d 1 - diff --git a/debian/modules/nginx-lua/t/040-gsub-o.t b/debian/modules/nginx-lua/t/040-gsub-o.t index 90619b0..5347266 100644 --- a/debian/modules/nginx-lua/t/040-gsub-o.t +++ b/debian/modules/nginx-lua/t/040-gsub-o.t @@ -198,4 +198,3 @@ hello, world --- response_body [hello,h], [world,w] 2 - diff --git a/debian/modules/nginx-lua/t/041-header-filter.t b/debian/modules/nginx-lua/t/041-header-filter.t index 553ee43..9cca3b7 100644 --- a/debian/modules/nginx-lua/t/041-header-filter.t +++ b/debian/modules/nginx-lua/t/041-header-filter.t @@ -790,4 +790,3 @@ GET /t --- error_code: 302 --- no_error_log [error] - diff --git a/debian/modules/nginx-lua/t/042-crc32.t b/debian/modules/nginx-lua/t/042-crc32.t index 86d9201..73aa1f4 100644 --- a/debian/modules/nginx-lua/t/042-crc32.t +++ b/debian/modules/nginx-lua/t/042-crc32.t @@ -54,4 +54,3 @@ GET /test GET /test --- response_body 0 - diff --git a/debian/modules/nginx-lua/t/045-ngx-var.t b/debian/modules/nginx-lua/t/045-ngx-var.t index 8f2dcb3..6475f1e 100644 --- a/debian/modules/nginx-lua/t/045-ngx-var.t +++ b/debian/modules/nginx-lua/t/045-ngx-var.t @@ -154,14 +154,15 @@ invalid referer: 1 -=== TEST 8: $proxy_host & $proxy_port +=== TEST 8: $proxy_host & $proxy_port & $proxy_add_x_forwarded_for --- config location = /t { proxy_pass http://127.0.0.1:$server_port/back; - header_filter_by_lua ' + header_filter_by_lua_block { ngx.header["Proxy-Host"] = ngx.var.proxy_host ngx.header["Proxy-Port"] = ngx.var.proxy_port - '; + ngx.header["Proxy-Add-X-Forwarded-For"] = ngx.var.proxy_add_x_forwarded_for + } } location = /back { @@ -172,6 +173,7 @@ GET /t --- raw_response_headers_like Proxy-Host: 127.0.0.1\:\d+\r Proxy-Port: \d+\r +Proxy-Add-X-Forwarded-For: 127.0.0.1\r --- response_body hello --- no_error_log @@ -226,4 +228,3 @@ GET /test?hello --- error_log variable "query_string" not changeable --- error_code: 500 - diff --git a/debian/modules/nginx-lua/t/046-hmac.t b/debian/modules/nginx-lua/t/046-hmac.t index 686b479..32e222b 100644 --- a/debian/modules/nginx-lua/t/046-hmac.t +++ b/debian/modules/nginx-lua/t/046-hmac.t @@ -29,4 +29,3 @@ __DATA__ GET /lua --- response_body R/pvxzHC4NLtj7S+kXFg/NePTmk= - diff --git a/debian/modules/nginx-lua/t/047-match-jit.t b/debian/modules/nginx-lua/t/047-match-jit.t index 077ebb6..2417a63 100644 --- a/debian/modules/nginx-lua/t/047-match-jit.t +++ b/debian/modules/nginx-lua/t/047-match-jit.t @@ -212,4 +212,3 @@ end GET /re --- response_body failed to match - diff --git a/debian/modules/nginx-lua/t/048-match-dfa.t b/debian/modules/nginx-lua/t/048-match-dfa.t index 8a0a328..28b5a60 100644 --- a/debian/modules/nginx-lua/t/048-match-dfa.t +++ b/debian/modules/nginx-lua/t/048-match-dfa.t @@ -207,4 +207,3 @@ exec opts: 0 你 --- no_error_log [error] - diff --git a/debian/modules/nginx-lua/t/049-gmatch-jit.t b/debian/modules/nginx-lua/t/049-gmatch-jit.t index 614c440..5134d52 100644 --- a/debian/modules/nginx-lua/t/049-gmatch-jit.t +++ b/debian/modules/nginx-lua/t/049-gmatch-jit.t @@ -226,4 +226,3 @@ qr/pcre JIT compiling result: \d+/ error: pcre_compile() failed: missing ) in "(abc" --- no_error_log [error] - diff --git a/debian/modules/nginx-lua/t/051-sub-jit.t b/debian/modules/nginx-lua/t/051-sub-jit.t index 789e897..c8a49c0 100644 --- a/debian/modules/nginx-lua/t/051-sub-jit.t +++ b/debian/modules/nginx-lua/t/051-sub-jit.t @@ -147,4 +147,3 @@ error: pcre_compile() failed: missing ) in "(abc" error: pcre_compile() failed: missing ) in "(abc" --- no_error_log [error] - diff --git a/debian/modules/nginx-lua/t/053-gsub-jit.t b/debian/modules/nginx-lua/t/053-gsub-jit.t index 3a2a1aa..3efc0a2 100644 --- a/debian/modules/nginx-lua/t/053-gsub-jit.t +++ b/debian/modules/nginx-lua/t/053-gsub-jit.t @@ -147,4 +147,3 @@ error: pcre_compile() failed: missing ) in "(abc" error: pcre_compile() failed: missing ) in "(abc" --- no_error_log [error] - diff --git a/debian/modules/nginx-lua/t/055-subreq-vars.t b/debian/modules/nginx-lua/t/055-subreq-vars.t index 2fc6960..eb5e24d 100644 --- a/debian/modules/nginx-lua/t/055-subreq-vars.t +++ b/debian/modules/nginx-lua/t/055-subreq-vars.t @@ -336,4 +336,3 @@ dog = hiya cat = 56 parent dog: blah parent cat: foo - diff --git a/debian/modules/nginx-lua/t/056-flush.t b/debian/modules/nginx-lua/t/056-flush.t index d189cd5..6b697a4 100644 --- a/debian/modules/nginx-lua/t/056-flush.t +++ b/debian/modules/nginx-lua/t/056-flush.t @@ -520,4 +520,3 @@ qr/lua flush requires waiting: buffered 0x[0-9a-f]+, delayed:1/, --- no_error_log [error] --- timeout: 4 - diff --git a/debian/modules/nginx-lua/t/057-flush-timeout.t b/debian/modules/nginx-lua/t/057-flush-timeout.t index d6e0f86..a046539 100644 --- a/debian/modules/nginx-lua/t/057-flush-timeout.t +++ b/debian/modules/nginx-lua/t/057-flush-timeout.t @@ -318,4 +318,3 @@ qr/failed to flush: client aborted/, --- timeout: 0.2 --- abort --- wait: 1 - diff --git a/debian/modules/nginx-lua/t/058-tcp-socket.t b/debian/modules/nginx-lua/t/058-tcp-socket.t index acf69f0..1ee113b 100644 --- a/debian/modules/nginx-lua/t/058-tcp-socket.t +++ b/debian/modules/nginx-lua/t/058-tcp-socket.t @@ -4,7 +4,7 @@ use Test::Nginx::Socket::Lua; repeat_each(2); -plan tests => repeat_each() * 187; +plan tests => repeat_each() * 190; our $HtmlDir = html_dir; @@ -200,7 +200,7 @@ attempt to send data on a closed socket: --- timeout: 10 --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; resolver_timeout 3s; location /t { content_by_lua ' @@ -290,7 +290,7 @@ qr/connect\(\) failed \(\d+: Connection refused\)/ === TEST 6: connection timeout (tcp) --- config - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; lua_socket_connect_timeout 100ms; lua_socket_send_timeout 100ms; lua_socket_read_timeout 100ms; @@ -362,7 +362,7 @@ connected: 1 === TEST 8: resolver error (host not found) --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; resolver_timeout 3s; location /t { content_by_lua ' @@ -403,7 +403,7 @@ attempt to send data on a closed socket === TEST 9: resolver error (timeout) --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; resolver_timeout 1ms; location /t { content_by_lua ' @@ -1995,7 +1995,7 @@ close: 1 nil === TEST 33: github issue #215: Handle the posted requests in lua cosocket api (failed to resolve) --- config - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; location = /sub { content_by_lua ' @@ -2038,7 +2038,7 @@ resolve name done === TEST 34: github issue #215: Handle the posted requests in lua cosocket api (successfully resolved) --- config - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; resolver_timeout 5s; location = /sub { @@ -2136,7 +2136,7 @@ close: nil closed --- config server_tokens off; lua_socket_read_timeout 100ms; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; location /t { content_by_lua ' local sock = ngx.socket.tcp() @@ -2178,7 +2178,7 @@ lua tcp socket read timed out === TEST 37: successful reread after a read time out happen (receive -> receive) --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; location /t { content_by_lua ' local sock = ngx.socket.tcp() @@ -2255,7 +2255,7 @@ lua tcp socket read timed out === TEST 38: successful reread after a read time out happen (receive -> receiveuntil) --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; location /t { content_by_lua ' local sock = ngx.socket.tcp() @@ -2335,7 +2335,7 @@ lua tcp socket read timed out === TEST 39: successful reread after a read time out happen (receiveuntil -> receiveuntil) --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; location /t { content_by_lua ' local sock = ngx.socket.tcp() @@ -2417,7 +2417,7 @@ lua tcp socket read timed out === TEST 40: successful reread after a read time out happen (receiveuntil -> receive) --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; location /t { content_by_lua ' local sock = ngx.socket.tcp() @@ -3015,7 +3015,7 @@ qr/runtime error: content_by_lua\(nginx\.conf:\d+\):16: bad request/ === TEST 50: cosocket resolving aborted by coroutine yielding failures (require) --- http_config lua_package_path "$prefix/html/?.lua;;"; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; --- config location = /t { @@ -3049,7 +3049,7 @@ runtime error: attempt to yield across C-call boundary === TEST 51: cosocket resolving aborted by coroutine yielding failures (xpcall err) --- http_config lua_package_path "$prefix/html/?.lua;;"; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; --- config location = /t { @@ -3307,7 +3307,7 @@ close: 1 nil --- config server_tokens off; lua_socket_connect_timeout 1s; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; resolver_timeout 3s; location /t { content_by_lua ' @@ -3640,3 +3640,53 @@ failed to receive a line: closed [] close: 1 nil --- error_log lua http cleanup reuse + + + +=== TEST 60: options_table is nil +--- config + location /t { + set $port $TEST_NGINX_MEMCACHED_PORT; + + content_by_lua_block { + local sock = ngx.socket.tcp() + local port = ngx.var.port + + local ok, err = sock:connect("127.0.0.1", port, nil) + if not ok then + ngx.say("failed to connect: ", err) + return + end + + ngx.say("connected: ", ok) + + local req = "flush_all\r\n" + + local bytes, err = sock:send(req) + if not bytes then + ngx.say("failed to send request: ", err) + return + end + ngx.say("request sent: ", bytes) + + local line, err, part = sock:receive() + if line then + ngx.say("received: ", line) + + else + ngx.say("failed to receive a line: ", err, " [", part, "]") + end + + ok, err = sock:close() + ngx.say("close: ", ok, " ", err) + } + } +--- request +GET /t +--- response_body +connected: 1 +request sent: 11 +received: OK +close: 1 nil +--- no_error_log +[error] diff --git a/debian/modules/nginx-lua/t/060-lua-memcached.t b/debian/modules/nginx-lua/t/060-lua-memcached.t index e1ebb92..0751238 100644 --- a/debian/modules/nginx-lua/t/060-lua-memcached.t +++ b/debian/modules/nginx-lua/t/060-lua-memcached.t @@ -166,4 +166,3 @@ some_key: hello 1234 [error] --- error_log lua reuse free buf memory - diff --git a/debian/modules/nginx-lua/t/061-lua-redis.t b/debian/modules/nginx-lua/t/061-lua-redis.t index d7b1876..ebfa6d1 100644 --- a/debian/modules/nginx-lua/t/061-lua-redis.t +++ b/debian/modules/nginx-lua/t/061-lua-redis.t @@ -182,4 +182,3 @@ abort: function msg type: nil --- no_error_log [error] - diff --git a/debian/modules/nginx-lua/t/062-count.t b/debian/modules/nginx-lua/t/062-count.t index c3973ad..a69c33e 100644 --- a/debian/modules/nginx-lua/t/062-count.t +++ b/debian/modules/nginx-lua/t/062-count.t @@ -323,7 +323,7 @@ ngx. entry count: 116 --- request GET /test --- response_body -n = 3 +n = 4 --- no_error_log [error] diff --git a/debian/modules/nginx-lua/t/063-abort.t b/debian/modules/nginx-lua/t/063-abort.t index c112ee1..411a07e 100644 --- a/debian/modules/nginx-lua/t/063-abort.t +++ b/debian/modules/nginx-lua/t/063-abort.t @@ -1017,4 +1017,3 @@ foo --- no_error_log [error] --- timeout: 2 - diff --git a/debian/modules/nginx-lua/t/064-pcall.t b/debian/modules/nginx-lua/t/064-pcall.t index cf90a07..3011f3e 100644 --- a/debian/modules/nginx-lua/t/064-pcall.t +++ b/debian/modules/nginx-lua/t/064-pcall.t @@ -104,4 +104,3 @@ $/ --- no_error_log [error] - diff --git a/debian/modules/nginx-lua/t/065-tcp-socket-timeout.t b/debian/modules/nginx-lua/t/065-tcp-socket-timeout.t index ec79891..212766e 100644 --- a/debian/modules/nginx-lua/t/065-tcp-socket-timeout.t +++ b/debian/modules/nginx-lua/t/065-tcp-socket-timeout.t @@ -46,7 +46,7 @@ __DATA__ --- config server_tokens off; lua_socket_connect_timeout 100ms; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; resolver_timeout 3s; location /t { content_by_lua ' @@ -75,7 +75,7 @@ lua tcp socket connect timed out --- config server_tokens off; lua_socket_connect_timeout 60s; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; resolver_timeout 3s; location /t { content_by_lua ' @@ -105,7 +105,7 @@ lua tcp socket connect timed out --- config server_tokens off; lua_socket_connect_timeout 102ms; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; location /t { content_by_lua ' local sock = ngx.socket.tcp() @@ -133,7 +133,7 @@ lua tcp socket connect timed out --- config server_tokens off; lua_socket_connect_timeout 102ms; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; resolver_timeout 3s; location /t { content_by_lua ' @@ -163,7 +163,7 @@ lua tcp socket connect timed out --- config server_tokens off; lua_socket_connect_timeout 102ms; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; location /t { content_by_lua ' local sock = ngx.socket.tcp() @@ -191,7 +191,7 @@ lua tcp socket connect timed out --- config server_tokens off; lua_socket_read_timeout 100ms; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; location /t { content_by_lua ' local sock = ngx.socket.tcp() @@ -228,7 +228,7 @@ lua tcp socket read timed out --- config server_tokens off; lua_socket_read_timeout 60s; - #resolver $TEST_NGINX_RESOLVER; + #resolver $TEST_NGINX_RESOLVER ipv6=off; location /t { content_by_lua ' local sock = ngx.socket.tcp() @@ -267,7 +267,7 @@ lua tcp socket read timed out --- config server_tokens off; lua_socket_read_timeout 102ms; - #resolver $TEST_NGINX_RESOLVER; + #resolver $TEST_NGINX_RESOLVER ipv6=off; location /t { content_by_lua ' local sock = ngx.socket.tcp() @@ -306,7 +306,7 @@ lua tcp socket read timed out --- config server_tokens off; lua_socket_read_timeout 102ms; - #resolver $TEST_NGINX_RESOLVER; + #resolver $TEST_NGINX_RESOLVER ipv6=off; location /t { content_by_lua ' local sock = ngx.socket.tcp() @@ -346,7 +346,7 @@ lua tcp socket read timed out --- config server_tokens off; lua_socket_read_timeout 102ms; - #resolver $TEST_NGINX_RESOLVER; + #resolver $TEST_NGINX_RESOLVER ipv6=off; location /t { content_by_lua ' local sock = ngx.socket.tcp() @@ -385,7 +385,7 @@ lua tcp socket read timed out --- config server_tokens off; lua_socket_send_timeout 100ms; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; location /t { content_by_lua ' local sock = ngx.socket.tcp() @@ -436,7 +436,7 @@ lua tcp socket write timed out --- config server_tokens off; lua_socket_send_timeout 60s; - #resolver $TEST_NGINX_RESOLVER; + #resolver $TEST_NGINX_RESOLVER ipv6=off; location /t { content_by_lua ' local sock = ngx.socket.tcp() @@ -475,7 +475,7 @@ lua tcp socket write timed out --- config server_tokens off; lua_socket_send_timeout 102ms; - #resolver $TEST_NGINX_RESOLVER; + #resolver $TEST_NGINX_RESOLVER ipv6=off; location /t { content_by_lua ' local sock = ngx.socket.tcp() @@ -514,7 +514,7 @@ lua tcp socket write timed out --- config server_tokens off; lua_socket_send_timeout 102ms; - #resolver $TEST_NGINX_RESOLVER; + #resolver $TEST_NGINX_RESOLVER ipv6=off; location /t { content_by_lua ' local sock = ngx.socket.tcp() @@ -553,7 +553,7 @@ lua tcp socket write timed out --- config server_tokens off; lua_socket_send_timeout 102ms; - #resolver $TEST_NGINX_RESOLVER; + #resolver $TEST_NGINX_RESOLVER ipv6=off; location /t { content_by_lua ' local sock = ngx.socket.tcp() @@ -686,7 +686,7 @@ after --- config server_tokens off; lua_socket_connect_timeout 100ms; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; resolver_timeout 3s; location /t { content_by_lua ' @@ -724,7 +724,7 @@ lua tcp socket connect timed out --- config server_tokens off; lua_socket_send_timeout 100ms; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; location /t { content_by_lua ' local sock = ngx.socket.tcp() @@ -779,7 +779,7 @@ lua tcp socket write timed out === TEST 19: abort when upstream sockets pending on writes --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; location /t { content_by_lua ' local sock = ngx.socket.tcp() @@ -832,7 +832,7 @@ lua tcp socket write timed out === TEST 20: abort when downstream socket pending on writes --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; location /t { content_by_lua ' ngx.send_headers() @@ -888,7 +888,7 @@ lua tcp socket write timed out --- config server_tokens off; lua_socket_read_timeout 100ms; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; location /t { content_by_lua ' local sock = ngx.socket.tcp() @@ -994,4 +994,3 @@ close: 1 nil --- no_error_log [error] - diff --git a/debian/modules/nginx-lua/t/066-socket-receiveuntil.t b/debian/modules/nginx-lua/t/066-socket-receiveuntil.t index 3bf5229..ffe74aa 100644 --- a/debian/modules/nginx-lua/t/066-socket-receiveuntil.t +++ b/debian/modules/nginx-lua/t/066-socket-receiveuntil.t @@ -1329,4 +1329,3 @@ this exposed a memory leak in receiveuntil ok --- no_error_log [error] - diff --git a/debian/modules/nginx-lua/t/067-req-socket.t b/debian/modules/nginx-lua/t/067-req-socket.t index 30a653a..229d5cc 100644 --- a/debian/modules/nginx-lua/t/067-req-socket.t +++ b/debian/modules/nginx-lua/t/067-req-socket.t @@ -1096,4 +1096,3 @@ done --- grep_error_log_out lua finalize socket GC cycle done - diff --git a/debian/modules/nginx-lua/t/069-null.t b/debian/modules/nginx-lua/t/069-null.t index 7761c91..e4c26af 100644 --- a/debian/modules/nginx-lua/t/069-null.t +++ b/debian/modules/nginx-lua/t/069-null.t @@ -93,4 +93,3 @@ done ngx.null: null --- no_error_log [error] - diff --git a/debian/modules/nginx-lua/t/071-idle-socket.t b/debian/modules/nginx-lua/t/071-idle-socket.t index 55d25c6..c9002be 100644 --- a/debian/modules/nginx-lua/t/071-idle-socket.t +++ b/debian/modules/nginx-lua/t/071-idle-socket.t @@ -431,4 +431,3 @@ failed to set keepalive: unread data in buffer } --- no_error_log [error] - diff --git a/debian/modules/nginx-lua/t/072-conditional-get.t b/debian/modules/nginx-lua/t/072-conditional-get.t index 4bb567a..7cf2dcd 100644 --- a/debian/modules/nginx-lua/t/072-conditional-get.t +++ b/debian/modules/nginx-lua/t/072-conditional-get.t @@ -88,4 +88,3 @@ delete thread 1 say failed: nginx output filter error --- no_error_log [error] - diff --git a/debian/modules/nginx-lua/t/073-backtrace.t b/debian/modules/nginx-lua/t/073-backtrace.t index aae4bae..6c54692 100644 --- a/debian/modules/nginx-lua/t/073-backtrace.t +++ b/debian/modules/nginx-lua/t/073-backtrace.t @@ -187,4 +187,3 @@ probe process("$LIBLUA_PATH").function("lua_concat") { :79: in function 'func20' :83: in function 'func21' ... - diff --git a/debian/modules/nginx-lua/t/074-prefix-var.t b/debian/modules/nginx-lua/t/074-prefix-var.t index 3cc4587..c116d84 100644 --- a/debian/modules/nginx-lua/t/074-prefix-var.t +++ b/debian/modules/nginx-lua/t/074-prefix-var.t @@ -64,4 +64,3 @@ GET /t Greetings from module foo. --- no_error_log [error] - diff --git a/debian/modules/nginx-lua/t/075-logby.t b/debian/modules/nginx-lua/t/075-logby.t index f987c8e..520c62e 100644 --- a/debian/modules/nginx-lua/t/075-logby.t +++ b/debian/modules/nginx-lua/t/075-logby.t @@ -581,4 +581,3 @@ qr{log_by_lua\(nginx\.conf:\d+\):1: content-type: text/plain} --- no_error_log [error] - diff --git a/debian/modules/nginx-lua/t/077-sleep.t b/debian/modules/nginx-lua/t/077-sleep.t index a7c251a..96f04bd 100644 --- a/debian/modules/nginx-lua/t/077-sleep.t +++ b/debian/modules/nginx-lua/t/077-sleep.t @@ -9,10 +9,10 @@ log_level('debug'); repeat_each(2); -plan tests => repeat_each() * 63; +plan tests => repeat_each() * 71; #no_diff(); -#no_long_string(); +no_long_string(); run_tests(); __DATA__ @@ -405,3 +405,98 @@ ok [error] [alert] + + +=== TEST 16: sleep 0 +--- config + location /t { + content_by_lua_block { + local function f (n) + print("f begin ", n) + ngx.sleep(0) + print("f middle ", n) + ngx.sleep(0) + print("f end ", n) + ngx.sleep(0) + end + + for i = 1, 3 do + assert(ngx.thread.spawn(f, i)) + end + + ngx.say("ok") + } + } +--- request +GET /t +--- response_body +ok +--- no_error_log +[error] +--- grep_error_log eval: qr/\bf (?:begin|middle|end)\b|\bworker cycle$|\be?poll timer: \d+$/ +--- grep_error_log_out eval +qr/f begin +f begin +f begin +worker cycle +e?poll timer: 0 +f middle +f middle +f middle +worker cycle +e?poll timer: 0 +f end +f end +f end +worker cycle +e?poll timer: 0 +/ + + + +=== TEST 17: sleep short times less than 1ms +--- config + location /t { + content_by_lua_block { + local delay = 0.0005 + + local function f (n) + print("f begin ", n) + ngx.sleep(delay) + print("f middle ", n) + ngx.sleep(delay) + print("f end ", n) + ngx.sleep(delay) + end + + for i = 1, 3 do + assert(ngx.thread.spawn(f, i)) + end + + ngx.say("ok") + } + } +--- request +GET /t +--- response_body +ok +--- no_error_log +[error] +--- grep_error_log eval: qr/\bf (?:begin|middle|end)\b|\bworker cycle$|\be?poll timer: \d+$/ +--- grep_error_log_out eval +qr/f begin +f begin +f begin +worker cycle +e?poll timer: 0 +f middle +f middle +f middle +worker cycle +e?poll timer: 0 +f end +f end +f end +worker cycle +e?poll timer: 0 +/ diff --git a/debian/modules/nginx-lua/t/078-hup-vars.t b/debian/modules/nginx-lua/t/078-hup-vars.t index 8acc346..5072c4d 100644 --- a/debian/modules/nginx-lua/t/078-hup-vars.t +++ b/debian/modules/nginx-lua/t/078-hup-vars.t @@ -62,4 +62,3 @@ GET /t localhost --- no_error_log [error] - diff --git a/debian/modules/nginx-lua/t/079-unused-directives.t b/debian/modules/nginx-lua/t/079-unused-directives.t index cba0e41..aacd0d3 100644 --- a/debian/modules/nginx-lua/t/079-unused-directives.t +++ b/debian/modules/nginx-lua/t/079-unused-directives.t @@ -340,4 +340,3 @@ GET /t sub: sub --- no_error_log [error] - diff --git a/debian/modules/nginx-lua/t/080-hup-shdict.t b/debian/modules/nginx-lua/t/080-hup-shdict.t index f9a0278..c762556 100644 --- a/debian/modules/nginx-lua/t/080-hup-shdict.t +++ b/debian/modules/nginx-lua/t/080-hup-shdict.t @@ -82,4 +82,3 @@ GET /test 10502 number --- no_error_log [error] - diff --git a/debian/modules/nginx-lua/t/083-bad-sock-self.t b/debian/modules/nginx-lua/t/083-bad-sock-self.t index b93849f..7a76752 100644 --- a/debian/modules/nginx-lua/t/083-bad-sock-self.t +++ b/debian/modules/nginx-lua/t/083-bad-sock-self.t @@ -136,4 +136,3 @@ bad argument #1 to 'close' (table expected, got number) --- error_code: 500 --- error_log bad argument #1 to 'setkeepalive' (table expected, got number) - diff --git a/debian/modules/nginx-lua/t/084-inclusive-receiveuntil.t b/debian/modules/nginx-lua/t/084-inclusive-receiveuntil.t index c966015..f7d5d3d 100644 --- a/debian/modules/nginx-lua/t/084-inclusive-receiveuntil.t +++ b/debian/modules/nginx-lua/t/084-inclusive-receiveuntil.t @@ -743,4 +743,3 @@ close: 1 nil } --- no_error_log [error] - diff --git a/debian/modules/nginx-lua/t/085-if.t b/debian/modules/nginx-lua/t/085-if.t index e08b43c..33f57ca 100644 --- a/debian/modules/nginx-lua/t/085-if.t +++ b/debian/modules/nginx-lua/t/085-if.t @@ -198,4 +198,3 @@ GET /proxy-pass-uri --- response_body_like: It works! --- no_error_log [error] - diff --git a/debian/modules/nginx-lua/t/086-init-by.t b/debian/modules/nginx-lua/t/086-init-by.t index 3a474fe..bea34a4 100644 --- a/debian/modules/nginx-lua/t/086-init-by.t +++ b/debian/modules/nginx-lua/t/086-init-by.t @@ -8,7 +8,7 @@ use Test::Nginx::Socket::Lua; repeat_each(2); -plan tests => repeat_each() * (blocks() * 3 + 3); +plan tests => repeat_each() * (blocks() * 3 + 2); #no_diff(); #no_long_string(); @@ -304,3 +304,20 @@ INIT 2: foo = 3 ", "", ] + + + +=== TEST 12: error in init +--- http_config + init_by_lua_block { + error("failed to init") + } +--- config + location /t { + echo ok; + } +--- must_die +--- error_log +failed to init +--- error_log +[error] diff --git a/debian/modules/nginx-lua/t/087-udp-socket.t b/debian/modules/nginx-lua/t/087-udp-socket.t index 79ba452..a847031 100644 --- a/debian/modules/nginx-lua/t/087-udp-socket.t +++ b/debian/modules/nginx-lua/t/087-udp-socket.t @@ -596,6 +596,7 @@ received a good response. --- log_level: debug --- error_log lua udp socket receive buffer size: 8192 +--- no_check_leak @@ -662,12 +663,14 @@ received a good response. --- log_level: debug --- error_log lua udp socket receive buffer size: 8192 +--- no_check_leak === TEST 12: github issue #215: Handle the posted requests in lua cosocket api (failed to resolve) --- config - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; + resolver_timeout 5s; location = /sub { content_by_lua ' @@ -704,12 +707,13 @@ resolve name done --- no_error_log [error] +--- timeout: 10 === TEST 13: github issue #215: Handle the posted requests in lua cosocket api (successfully resolved) --- config - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; resolver_timeout 5s; location = /sub { @@ -1100,4 +1104,3 @@ qr/runtime error: content_by_lua\(nginx\.conf:\d+\):14: bad request/ --- no_error_log [alert] - diff --git a/debian/modules/nginx-lua/t/088-req-method.t b/debian/modules/nginx-lua/t/088-req-method.t index 9ced40c..198b3b3 100644 --- a/debian/modules/nginx-lua/t/088-req-method.t +++ b/debian/modules/nginx-lua/t/088-req-method.t @@ -262,4 +262,3 @@ method: PATCH method: TRACE --- no_error_log [error] - diff --git a/debian/modules/nginx-lua/t/089-phase.t b/debian/modules/nginx-lua/t/089-phase.t index 57921fc..94b7619 100644 --- a/debian/modules/nginx-lua/t/089-phase.t +++ b/debian/modules/nginx-lua/t/089-phase.t @@ -176,4 +176,3 @@ GET /lua init_worker --- no_error_log [error] - diff --git a/debian/modules/nginx-lua/t/090-log-socket-errors.t b/debian/modules/nginx-lua/t/090-log-socket-errors.t index a5943c2..8e498cd 100644 --- a/debian/modules/nginx-lua/t/090-log-socket-errors.t +++ b/debian/modules/nginx-lua/t/090-log-socket-errors.t @@ -11,6 +11,8 @@ repeat_each(2); plan tests => repeat_each() * (blocks() * 3); +$ENV{TEST_NGINX_RESOLVER} ||= '8.8.8.8'; + #no_diff(); #no_long_string(); run_tests(); @@ -19,12 +21,14 @@ __DATA__ === TEST 1: log socket errors off (tcp) --- config + resolver $TEST_NGINX_RESOLVER ipv6=off; + location /t { lua_socket_connect_timeout 1ms; lua_socket_log_errors off; content_by_lua ' local sock = ngx.socket.tcp() - local ok, err = sock:connect("8.8.8.8", 80) + local ok, err = sock:connect("agentzh.org", 12345) ngx.say(err) '; } @@ -39,12 +43,14 @@ timeout === TEST 2: log socket errors on (tcp) --- config + resolver $TEST_NGINX_RESOLVER ipv6=off; + location /t { lua_socket_connect_timeout 1ms; lua_socket_log_errors on; content_by_lua ' local sock = ngx.socket.tcp() - local ok, err = sock:connect("8.8.8.8", 80) + local ok, err = sock:connect("agentzh.org", 12345) ngx.say(err) '; } @@ -59,12 +65,14 @@ lua tcp socket connect timed out === TEST 3: log socket errors on (udp) --- config + resolver $TEST_NGINX_RESOLVER ipv6=off; + location /t { lua_socket_log_errors on; lua_socket_read_timeout 1ms; content_by_lua ' local sock = ngx.socket.udp() - local ok, err = sock:setpeername("8.8.8.8", 80) + local ok, err = sock:setpeername("agentzh.org", 12345) ok, err = sock:receive() ngx.say(err) '; @@ -80,12 +88,14 @@ lua udp socket read timed out === TEST 4: log socket errors off (udp) --- config + resolver $TEST_NGINX_RESOLVER ipv6=off; + location /t { lua_socket_log_errors off; lua_socket_read_timeout 1ms; content_by_lua ' local sock = ngx.socket.udp() - local ok, err = sock:setpeername("8.8.8.8", 80) + local ok, err = sock:setpeername("agentzh.org", 12345) ok, err = sock:receive() ngx.say(err) '; @@ -96,4 +106,3 @@ GET /t timeout --- no_error_log [error] - diff --git a/debian/modules/nginx-lua/t/091-coroutine.t b/debian/modules/nginx-lua/t/091-coroutine.t index b047ccb..bceb512 100644 --- a/debian/modules/nginx-lua/t/091-coroutine.t +++ b/debian/modules/nginx-lua/t/091-coroutine.t @@ -160,7 +160,7 @@ cc3: 2 === TEST 3: basic coroutine and cosocket --- config - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; location /lua { content_by_lua ' function worker(url) @@ -359,7 +359,7 @@ GET /lua === TEST 7: coroutine wrap and cosocket --- config - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; location /lua { content_by_lua ' function worker(url) @@ -987,7 +987,7 @@ test10 --- http_config init_by_lua 'return'; --- config - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; location /lua { content_by_lua ' function worker(url) @@ -1041,7 +1041,7 @@ successfully connected to: agentzh.org init_by_lua_file html/init.lua; --- config - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; location /lua { content_by_lua ' function worker(url) @@ -1315,4 +1315,3 @@ co yield: 2 --- no_error_log [error] - diff --git a/debian/modules/nginx-lua/t/092-eof.t b/debian/modules/nginx-lua/t/092-eof.t index a75711f..86778de 100644 --- a/debian/modules/nginx-lua/t/092-eof.t +++ b/debian/modules/nginx-lua/t/092-eof.t @@ -80,4 +80,3 @@ GET /t --- error_log hello, tom hello, jim - diff --git a/debian/modules/nginx-lua/t/093-uthread-spawn.t b/debian/modules/nginx-lua/t/093-uthread-spawn.t index 772e866..b622d30 100644 --- a/debian/modules/nginx-lua/t/093-uthread-spawn.t +++ b/debian/modules/nginx-lua/t/093-uthread-spawn.t @@ -1672,4 +1672,3 @@ delete thread 2 f --- no_error_log [error] - diff --git a/debian/modules/nginx-lua/t/094-uthread-exit.t b/debian/modules/nginx-lua/t/094-uthread-exit.t index cd678c0..a623773 100644 --- a/debian/modules/nginx-lua/t/094-uthread-exit.t +++ b/debian/modules/nginx-lua/t/094-uthread-exit.t @@ -1648,4 +1648,3 @@ free request [alert] [error] [warn] - diff --git a/debian/modules/nginx-lua/t/095-uthread-exec.t b/debian/modules/nginx-lua/t/095-uthread-exec.t index 4459360..56156c4 100644 --- a/debian/modules/nginx-lua/t/095-uthread-exec.t +++ b/debian/modules/nginx-lua/t/095-uthread-exec.t @@ -423,4 +423,3 @@ attempt to abort with pending subrequests --- no_error_log [alert] [warn] - diff --git a/debian/modules/nginx-lua/t/096-uthread-redirect.t b/debian/modules/nginx-lua/t/096-uthread-redirect.t index b0258fb..003c642 100644 --- a/debian/modules/nginx-lua/t/096-uthread-redirect.t +++ b/debian/modules/nginx-lua/t/096-uthread-redirect.t @@ -277,4 +277,3 @@ attempt to abort with pending subrequests --- no_error_log [alert] [warn] - diff --git a/debian/modules/nginx-lua/t/097-uthread-rewrite.t b/debian/modules/nginx-lua/t/097-uthread-rewrite.t index 178a374..a93adc8 100644 --- a/debian/modules/nginx-lua/t/097-uthread-rewrite.t +++ b/debian/modules/nginx-lua/t/097-uthread-rewrite.t @@ -344,4 +344,3 @@ free request end --- error_log attempt to abort with pending subrequests - diff --git a/debian/modules/nginx-lua/t/098-uthread-wait.t b/debian/modules/nginx-lua/t/098-uthread-wait.t index aaf020a..4948596 100644 --- a/debian/modules/nginx-lua/t/098-uthread-wait.t +++ b/debian/modules/nginx-lua/t/098-uthread-wait.t @@ -1321,4 +1321,3 @@ $s; --- no_error_log [error] [alert] - diff --git a/debian/modules/nginx-lua/t/100-client-abort.t b/debian/modules/nginx-lua/t/100-client-abort.t index cd46859..89c1f6a 100644 --- a/debian/modules/nginx-lua/t/100-client-abort.t +++ b/debian/modules/nginx-lua/t/100-client-abort.t @@ -1064,4 +1064,3 @@ GET /t eof succeeded --- error_log eof failed: nginx output filter error - diff --git a/debian/modules/nginx-lua/t/101-on-abort.t b/debian/modules/nginx-lua/t/101-on-abort.t index 81cec78..182d12c 100644 --- a/debian/modules/nginx-lua/t/101-on-abort.t +++ b/debian/modules/nginx-lua/t/101-on-abort.t @@ -846,4 +846,3 @@ done client prematurely closed connection on abort called main handler done - diff --git a/debian/modules/nginx-lua/t/102-req-start-time.t b/debian/modules/nginx-lua/t/102-req-start-time.t index 1d5fe28..3b041af 100644 --- a/debian/modules/nginx-lua/t/102-req-start-time.t +++ b/debian/modules/nginx-lua/t/102-req-start-time.t @@ -113,4 +113,3 @@ true$ --- no_error_log [error] --- SKIP - diff --git a/debian/modules/nginx-lua/t/103-req-http-ver.t b/debian/modules/nginx-lua/t/103-req-http-ver.t index 6ded75a..e6de238 100644 --- a/debian/modules/nginx-lua/t/103-req-http-ver.t +++ b/debian/modules/nginx-lua/t/103-req-http-ver.t @@ -46,4 +46,3 @@ GET /t HTTP/1.0 1 --- no_error_log [error] - diff --git a/debian/modules/nginx-lua/t/104-req-raw-header.t b/debian/modules/nginx-lua/t/104-req-raw-header.t index 439b9de..efea03c 100644 --- a/debian/modules/nginx-lua/t/104-req-raw-header.t +++ b/debian/modules/nginx-lua/t/104-req-raw-header.t @@ -876,4 +876,3 @@ Foo: bar\r --- no_error_log [error] --- timeout: 5 - diff --git a/debian/modules/nginx-lua/t/105-pressure.t b/debian/modules/nginx-lua/t/105-pressure.t index 10f495e..9d1ba1f 100644 --- a/debian/modules/nginx-lua/t/105-pressure.t +++ b/debian/modules/nginx-lua/t/105-pressure.t @@ -51,4 +51,3 @@ $::Id = int rand 10000; --- no_error_log [error] - diff --git a/debian/modules/nginx-lua/t/106-timer.t b/debian/modules/nginx-lua/t/106-timer.t index d0f6f36..04a532e 100644 --- a/debian/modules/nginx-lua/t/106-timer.t +++ b/debian/modules/nginx-lua/t/106-timer.t @@ -2193,4 +2193,3 @@ ok --- error_log Bad bad bad --- skip_nginx: 4: < 1.7.1 - diff --git a/debian/modules/nginx-lua/t/107-timer-errors.t b/debian/modules/nginx-lua/t/107-timer-errors.t index 9ed1334..3201612 100644 --- a/debian/modules/nginx-lua/t/107-timer-errors.t +++ b/debian/modules/nginx-lua/t/107-timer-errors.t @@ -1420,4 +1420,3 @@ qr/\[error\] .*? runtime error: content_by_lua\(nginx\.conf:\d+\):3: API disable "lua ngx.timer expired", "http lua close fake http connection" ] - diff --git a/debian/modules/nginx-lua/t/108-timer-safe.t b/debian/modules/nginx-lua/t/108-timer-safe.t index 19c9f6d..2795998 100644 --- a/debian/modules/nginx-lua/t/108-timer-safe.t +++ b/debian/modules/nginx-lua/t/108-timer-safe.t @@ -1395,4 +1395,3 @@ registered timer lua ngx.timer expired http lua close fake http connection trace: [m][f][g] - diff --git a/debian/modules/nginx-lua/t/109-timer-hup.t b/debian/modules/nginx-lua/t/109-timer-hup.t index 15aaa0e..0864046 100644 --- a/debian/modules/nginx-lua/t/109-timer-hup.t +++ b/debian/modules/nginx-lua/t/109-timer-hup.t @@ -500,4 +500,3 @@ ok --- grep_error_log_out lua found 8191 pending timers --- timeout: 20 - diff --git a/debian/modules/nginx-lua/t/110-etag.t b/debian/modules/nginx-lua/t/110-etag.t index 351fec4..0a94d3d 100644 --- a/debian/modules/nginx-lua/t/110-etag.t +++ b/debian/modules/nginx-lua/t/110-etag.t @@ -81,4 +81,3 @@ If-Modified-Since: Thu, 10 May 2012 07:50:59 GMT --- no_error_log [error] --- skip_nginx: 3: < 1.3.3 - diff --git a/debian/modules/nginx-lua/t/111-req-header-ua.t b/debian/modules/nginx-lua/t/111-req-header-ua.t index 7c980d0..9e501e3 100644 --- a/debian/modules/nginx-lua/t/111-req-header-ua.t +++ b/debian/modules/nginx-lua/t/111-req-header-ua.t @@ -673,4 +673,3 @@ content: konqueror: 1 User-Agent: Mozilla/5.0 (compatible; Konqueror/3.5; Linux) KHTML/3.5.10 (like Gecko) (Kubuntu) --- no_error_log [error] - diff --git a/debian/modules/nginx-lua/t/112-req-header-conn.t b/debian/modules/nginx-lua/t/112-req-header-conn.t index 51df730..51bc8a4 100644 --- a/debian/modules/nginx-lua/t/112-req-header-conn.t +++ b/debian/modules/nginx-lua/t/112-req-header-conn.t @@ -146,4 +146,3 @@ content: conn type: 0 connection: bad --- no_error_log [error] - diff --git a/debian/modules/nginx-lua/t/113-req-header-cookie.t b/debian/modules/nginx-lua/t/113-req-header-cookie.t index b26b709..4a93053 100644 --- a/debian/modules/nginx-lua/t/113-req-header-cookie.t +++ b/debian/modules/nginx-lua/t/113-req-header-cookie.t @@ -247,4 +247,3 @@ Cookie: boo=123; foo=bar --- no_error_log [error] - diff --git a/debian/modules/nginx-lua/t/115-quote-sql-str.t b/debian/modules/nginx-lua/t/115-quote-sql-str.t index 0c20dfb..66553b1 100644 --- a/debian/modules/nginx-lua/t/115-quote-sql-str.t +++ b/debian/modules/nginx-lua/t/115-quote-sql-str.t @@ -74,4 +74,3 @@ GET /set 'a\Zb\Z' --- no_error_log [error] - diff --git a/debian/modules/nginx-lua/t/116-raw-req-socket.t b/debian/modules/nginx-lua/t/116-raw-req-socket.t index 6518f0e..ab06ee4 100644 --- a/debian/modules/nginx-lua/t/116-raw-req-socket.t +++ b/debian/modules/nginx-lua/t/116-raw-req-socket.t @@ -876,4 +876,3 @@ request body: hey, hello world --- no_error_log [error] [alert] - diff --git a/debian/modules/nginx-lua/t/117-raw-req-socket-timeout.t b/debian/modules/nginx-lua/t/117-raw-req-socket-timeout.t index 4e3929b..07abadc 100644 --- a/debian/modules/nginx-lua/t/117-raw-req-socket-timeout.t +++ b/debian/modules/nginx-lua/t/117-raw-req-socket-timeout.t @@ -114,4 +114,3 @@ lua tcp socket write timed out server: failed to send: timeout --- no_error_log [alert] - diff --git a/debian/modules/nginx-lua/t/119-config-prefix.t b/debian/modules/nginx-lua/t/119-config-prefix.t index 4581aa1..3f79320 100644 --- a/debian/modules/nginx-lua/t/119-config-prefix.t +++ b/debian/modules/nginx-lua/t/119-config-prefix.t @@ -30,4 +30,3 @@ GET /lua ^prefix: \/\S+$ --- no_error_log [error] - diff --git a/debian/modules/nginx-lua/t/120-re-find.t b/debian/modules/nginx-lua/t/120-re-find.t index 34c0207..73e6134 100644 --- a/debian/modules/nginx-lua/t/120-re-find.t +++ b/debian/modules/nginx-lua/t/120-re-find.t @@ -612,7 +612,7 @@ matched: 你 === TEST 22: just hit match limit --- http_config - lua_regex_match_limit 5600; + lua_regex_match_limit 5000; --- config location /re { content_by_lua_file html/a.lua; @@ -654,7 +654,7 @@ error: pcre_exec() failed: -8 === TEST 23: just not hit match limit --- http_config - lua_regex_match_limit 5700; + lua_regex_match_limit 5100; --- config location /re { content_by_lua_file html/a.lua; @@ -891,3 +891,29 @@ not matched! --- no_error_log [error] + + +=== TEST 31: match with ctx and a pos (anchored by \G) +--- config + location /re { + content_by_lua ' + local ctx = { pos = 3 } + local from, to, err = ngx.re.find("1234, hello", [[(\G[0-9]+)]], "", ctx) + if from then + ngx.say("from: ", from) + ngx.say("to: ", to) + ngx.say("pos: ", ctx.pos) + else + ngx.say("not matched!") + ngx.say("pos: ", ctx.pos) + end + '; + } +--- request + GET /re +--- response_body +from: 3 +to: 4 +pos: 5 +--- no_error_log +[error] diff --git a/debian/modules/nginx-lua/t/121-version.t b/debian/modules/nginx-lua/t/121-version.t index 2b7a306..9000eb3 100644 --- a/debian/modules/nginx-lua/t/121-version.t +++ b/debian/modules/nginx-lua/t/121-version.t @@ -46,4 +46,3 @@ GET /lua ^version: \d+$ --- no_error_log [error] - diff --git a/debian/modules/nginx-lua/t/122-worker.t b/debian/modules/nginx-lua/t/122-worker.t index fa42b1d..b74c81f 100644 --- a/debian/modules/nginx-lua/t/122-worker.t +++ b/debian/modules/nginx-lua/t/122-worker.t @@ -79,4 +79,3 @@ worker pid: \d+ worker pid is correct\. --- no_error_log [error] - diff --git a/debian/modules/nginx-lua/t/123-lua-path.t b/debian/modules/nginx-lua/t/123-lua-path.t index da97909..23681a9 100644 --- a/debian/modules/nginx-lua/t/123-lua-path.t +++ b/debian/modules/nginx-lua/t/123-lua-path.t @@ -68,4 +68,3 @@ GET /lua [error] --- error_log eval qr/\[alert\] .*? lua_code_cache is off/ - diff --git a/debian/modules/nginx-lua/t/124-init-worker.t b/debian/modules/nginx-lua/t/124-init-worker.t index d6ea675..22a943e 100644 --- a/debian/modules/nginx-lua/t/124-init-worker.t +++ b/debian/modules/nginx-lua/t/124-init-worker.t @@ -447,7 +447,7 @@ warn(): Thu, 01 Jan 1970 01:34:38 GMT --- timeout: 10 --- http_config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; resolver_timeout 3s; init_worker_by_lua ' -- global diff --git a/debian/modules/nginx-lua/t/125-configure-args.t b/debian/modules/nginx-lua/t/125-configure-args.t index adec129..4160d4e 100644 --- a/debian/modules/nginx-lua/t/125-configure-args.t +++ b/debian/modules/nginx-lua/t/125-configure-args.t @@ -29,4 +29,3 @@ GET /configure_args ^\s*\-\-[^-]+ --- no_error_log [error] - diff --git a/debian/modules/nginx-lua/t/126-shdict-frag.t b/debian/modules/nginx-lua/t/126-shdict-frag.t index 94422fb..5a2aff8 100644 --- a/debian/modules/nginx-lua/t/126-shdict-frag.t +++ b/debian/modules/nginx-lua/t/126-shdict-frag.t @@ -1264,4 +1264,3 @@ ok --- no_error_log [error] --- timeout: 60 - diff --git a/debian/modules/nginx-lua/t/127-uthread-kill.t b/debian/modules/nginx-lua/t/127-uthread-kill.t index 2ab8abe..cc43c62 100644 --- a/debian/modules/nginx-lua/t/127-uthread-kill.t +++ b/debian/modules/nginx-lua/t/127-uthread-kill.t @@ -190,7 +190,7 @@ resolve name done: -2 === TEST 4: kill pending connect --- config - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; location /lua { content_by_lua ' local ready = false @@ -505,4 +505,3 @@ thread created: zombie [alert] lua tcp socket abort resolver --- error_log - diff --git a/debian/modules/nginx-lua/t/128-duplex-tcp-socket.t b/debian/modules/nginx-lua/t/128-duplex-tcp-socket.t index d3ef3f5..e8434a3 100644 --- a/debian/modules/nginx-lua/t/128-duplex-tcp-socket.t +++ b/debian/modules/nginx-lua/t/128-duplex-tcp-socket.t @@ -315,19 +315,24 @@ failed to send request: closed)$ local data = "" local ntm = 0 - local done = false + local aborted = false for i = 1, 3 do - local res, err, part = sock:receive(1) - if not res then - ngx.say("failed to receive: ", err) - return - else - data = data .. res + if not aborted then + local res, err, part = sock:receive(1) + if not res then + ngx.say("failed to receive: ", err) + aborted = true + else + data = data .. res + end end + ngx.sleep(0.001) end - ngx.say("received: ", data) + if not aborted then + ngx.say("received: ", data) + end '; } @@ -350,6 +355,7 @@ F(ngx_http_lua_socket_tcp_finalize_write_part) { --- tcp_query_len: 11 --- no_error_log [error] +--- wait: 0.05 @@ -623,4 +629,3 @@ close: 1 nil --- no_error_log [error] - diff --git a/debian/modules/nginx-lua/t/129-ssl-socket.t b/debian/modules/nginx-lua/t/129-ssl-socket.t index 9da9a5c..1c3f7cd 100644 --- a/debian/modules/nginx-lua/t/129-ssl-socket.t +++ b/debian/modules/nginx-lua/t/129-ssl-socket.t @@ -4,7 +4,7 @@ use Test::Nginx::Socket::Lua; repeat_each(2); -plan tests => repeat_each() * 219; +plan tests => repeat_each() * 217; $ENV{TEST_NGINX_HTML_DIR} ||= html_dir(); @@ -26,7 +26,7 @@ sub read_file { $cert; } -our $StartComRootCertificate = read_file("t/cert/startcom.crt"); +our $ComodoRootCertificate = read_file("t/cert/comodo-ca.crt"); our $EquifaxRootCertificate = read_file("t/cert/equifax.crt"); our $TestCertificate = read_file("t/cert/test.crt"); our $TestCertificateKey = read_file("t/cert/test.key"); @@ -125,7 +125,7 @@ SSL reused session === TEST 2: no SNI, no verify --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; location /t { #set $port 5000; set $port $TEST_NGINX_MEMCACHED_PORT; @@ -135,7 +135,7 @@ SSL reused session sock:settimeout(2000) do - local ok, err = sock:connect("g.sregex.org", 443) + local ok, err = sock:connect("openresty.org", 443) if not ok then ngx.say("failed to connect: ", err) return @@ -151,7 +151,7 @@ SSL reused session ngx.say("ssl handshake: ", type(session)) - local req = "GET / HTTP/1.1\\r\\nHost: g.sregex.org\\r\\nConnection: close\\r\\n\\r\\n" + local req = "GET / HTTP/1.1\\r\\nHost: openresty.org\\r\\nConnection: close\\r\\n\\r\\n" local bytes, err = sock:send(req) if not bytes then ngx.say("failed to send http request: ", err) @@ -179,21 +179,14 @@ SSL reused session GET /t --- response_body connected: 1 -ssl handshake: userdata -sent http request: 57 bytes. -received: HTTP/1.1 401 Unauthorized -close: 1 nil +failed to do SSL handshake: handshake failed --- log_level: debug --- grep_error_log eval: qr/lua ssl (?:set|save|free) session: [0-9A-F]+:\d+/ ---- grep_error_log_out eval -qr/^lua ssl save session: ([0-9A-F]+):2 -lua ssl free session: ([0-9A-F]+):1 -$/ +--- grep_error_log_out --- no_error_log lua ssl server name: SSL reused session -[error] [alert] --- timeout: 5 @@ -202,17 +195,17 @@ SSL reused session === TEST 3: SNI, no verify --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; location /t { #set $port 5000; set $port $TEST_NGINX_MEMCACHED_PORT; - content_by_lua ' + content_by_lua_block { local sock = ngx.socket.tcp() sock:settimeout(2000) do - local ok, err = sock:connect("iscribblet.org", 443) + local ok, err = sock:connect("openresty.org", 443) if not ok then ngx.say("failed to connect: ", err) return @@ -220,7 +213,7 @@ SSL reused session ngx.say("connected: ", ok) - local session, err = sock:sslhandshake(nil, "iscribblet.org") + local session, err = sock:sslhandshake(nil, "openresty.org") if not session then ngx.say("failed to do SSL handshake: ", err) return @@ -228,7 +221,7 @@ SSL reused session ngx.say("ssl handshake: ", type(session)) - local req = "GET / HTTP/1.1\\r\\nHost: iscribblet.org\\r\\nConnection: close\\r\\n\\r\\n" + local req = "GET / HTTP/1.1\r\nHost: openresty.org\r\nConnection: close\r\n\r\n" local bytes, err = sock:send(req) if not bytes then ngx.say("failed to send http request: ", err) @@ -249,7 +242,7 @@ SSL reused session ngx.say("close: ", ok, " ", err) end -- do collectgarbage() - '; + } } --- request @@ -257,8 +250,8 @@ GET /t --- response_body connected: 1 ssl handshake: userdata -sent http request: 59 bytes. -received: HTTP/1.1 200 OK +sent http request: 58 bytes. +received: HTTP/1.1 302 Moved Temporarily close: 1 nil --- log_level: debug @@ -268,7 +261,7 @@ qr/^lua ssl save session: ([0-9A-F]+):2 lua ssl free session: ([0-9A-F]+):1 $/ --- error_log -lua ssl server name: "iscribblet.org" +lua ssl server name: "openresty.org" --- no_error_log SSL reused session [error] @@ -280,7 +273,8 @@ SSL reused session === TEST 4: ssl session reuse --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; + lua_ssl_protocols TLSv1.2; location /t { #set $port 5000; set $port $TEST_NGINX_MEMCACHED_PORT; @@ -293,7 +287,7 @@ SSL reused session local session for i = 1, 2 do - local ok, err = sock:connect("iscribblet.org", 443) + local ok, err = sock:connect("agentzh.org", 443) if not ok then ngx.say("failed to connect: ", err) return @@ -301,7 +295,7 @@ SSL reused session ngx.say("connected: ", ok) - session, err = sock:sslhandshake(session, "iscribblet.org") + session, err = sock:sslhandshake(session, "agentzh.org") if not session then ngx.say("failed to do SSL handshake: ", err) return @@ -309,7 +303,7 @@ SSL reused session ngx.say("ssl handshake: ", type(session)) - local req = "GET / HTTP/1.1\\r\\nHost: iscribblet.org\\r\\nConnection: close\\r\\n\\r\\n" + local req = "GET / HTTP/1.1\\r\\nHost: agentzh.org\\r\\nConnection: close\\r\\n\\r\\n" local bytes, err = sock:send(req) if not bytes then ngx.say("failed to send http request: ", err) @@ -340,12 +334,12 @@ GET /t --- response_body connected: 1 ssl handshake: userdata -sent http request: 59 bytes. +sent http request: 56 bytes. received: HTTP/1.1 200 OK close: 1 nil connected: 1 ssl handshake: userdata -sent http request: 59 bytes. +sent http request: 56 bytes. received: HTTP/1.1 200 OK close: 1 nil @@ -371,10 +365,10 @@ lua ssl free session === TEST 5: certificate does not match host name (verify) -The certificate for "blah.agentzh.org" does not contain the name "blah.agentzh.org". +The certificate of "openresty.org" does not contain the name "blah.openresty.org". --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; lua_ssl_trusted_certificate ../html/trusted.crt; lua_ssl_verify_depth 5; location /t { @@ -386,7 +380,7 @@ The certificate for "blah.agentzh.org" does not contain the name "blah.agentzh.o sock:settimeout(2000) do - local ok, err = sock:connect("agentzh.org", 443) + local ok, err = sock:connect("openresty.org", 443) if not ok then ngx.say("failed to connect: ", err) return @@ -394,13 +388,171 @@ The certificate for "blah.agentzh.org" does not contain the name "blah.agentzh.o ngx.say("connected: ", ok) - local session, err = sock:sslhandshake(nil, "blah.agentzh.org", true) + local session, err = sock:sslhandshake(nil, "blah.openresty.org", true) if not session then ngx.say("failed to do SSL handshake: ", err) else ngx.say("ssl handshake: ", type(session)) end + local req = "GET / HTTP/1.1\\r\\nHost: openresty.org\\r\\nConnection: close\\r\\n\\r\\n" + local bytes, err = sock:send(req) + if not bytes then + ngx.say("failed to send http request: ", err) + return + end + + ngx.say("sent http request: ", bytes, " bytes.") + + local line, err = sock:receive() + if not line then + ngx.say("failed to receive response status line: ", err) + return + end + + ngx.say("received: ", line) + + local ok, err = sock:close() + ngx.say("close: ", ok, " ", err) + end -- do + collectgarbage() + '; + } + +--- user_files eval +">>> trusted.crt +$::ComodoRootCertificate" + +--- request +GET /t +--- response_body_like chomp +\Aconnected: 1 +failed to do SSL handshake: (?:handshake failed|certificate host mismatch) +failed to send http request: closed +\z + +--- log_level: debug +--- grep_error_log eval: qr/lua ssl (?:set|save|free) session: [0-9A-F]+:\d+/ +--- grep_error_log_out +--- error_log +lua ssl server name: "blah.openresty.org" +--- no_error_log +SSL reused session +[alert] +--- timeout: 5 + + + +=== TEST 6: certificate does not match host name (verify, no log socket errors) +The certificate for "openresty.org" does not contain the name "blah.openresty.org". +--- config + server_tokens off; + resolver $TEST_NGINX_RESOLVER ipv6=off; + lua_ssl_trusted_certificate ../html/trusted.crt; + lua_socket_log_errors off; + lua_ssl_verify_depth 2; + location /t { + #set $port 5000; + set $port $TEST_NGINX_MEMCACHED_PORT; + + content_by_lua ' + local sock = ngx.socket.tcp() + sock:settimeout(2000) + + do + local ok, err = sock:connect("openresty.org", 443) + if not ok then + ngx.say("failed to connect: ", err) + return + end + + ngx.say("connected: ", ok) + + local session, err = sock:sslhandshake(nil, "blah.openresty.org", true) + if not session then + ngx.say("failed to do SSL handshake: ", err) + else + ngx.say("ssl handshake: ", type(session)) + end + + local req = "GET / HTTP/1.1\\r\\nHost: blah.openresty.org\\r\\nConnection: close\\r\\n\\r\\n" + local bytes, err = sock:send(req) + if not bytes then + ngx.say("failed to send http request: ", err) + return + end + + ngx.say("sent http request: ", bytes, " bytes.") + + local line, err = sock:receive() + if not line then + ngx.say("failed to receive response status line: ", err) + return + end + + ngx.say("received: ", line) + + local ok, err = sock:close() + ngx.say("close: ", ok, " ", err) + end -- do + collectgarbage() + '; + } + +--- user_files eval +">>> trusted.crt +$::ComodoRootCertificate" + +--- request +GET /t +--- response_body_like chomp +\Aconnected: 1 +failed to do SSL handshake: (?:handshake failed|certificate host mismatch) +failed to send http request: closed +\z + +--- log_level: debug +--- grep_error_log eval: qr/lua ssl (?:set|save|free) session: [0-9A-F]+:\d+/ +--- grep_error_log_out +--- error_log +lua ssl server name: "blah.openresty.org" +--- no_error_log +lua ssl certificate does not match host +SSL reused session +[alert] +--- timeout: 5 + + + +=== TEST 7: certificate does not match host name (no verify) +--- config + server_tokens off; + resolver $TEST_NGINX_RESOLVER ipv6=off; + location /t { + #set $port 5000; + set $port $TEST_NGINX_MEMCACHED_PORT; + + content_by_lua ' + local sock = ngx.socket.tcp() + sock:settimeout(2000) + + do + local ok, err = sock:connect("openresty.org", 443) + if not ok then + ngx.say("failed to connect: ", err) + return + end + + ngx.say("connected: ", ok) + + local session, err = sock:sslhandshake(nil, "openresty.org", false) + if not session then + ngx.say("failed to do SSL handshake: ", err) + return + end + + ngx.say("ssl handshake: ", type(session)) + local req = "GET / HTTP/1.1\\r\\nHost: agentzh.org\\r\\nConnection: close\\r\\n\\r\\n" local bytes, err = sock:send(req) if not bytes then @@ -425,170 +577,13 @@ The certificate for "blah.agentzh.org" does not contain the name "blah.agentzh.o '; } ---- user_files eval -">>> trusted.crt -$::StartComRootCertificate" - ---- request -GET /t ---- response_body -connected: 1 -failed to do SSL handshake: certificate host mismatch -failed to send http request: closed - ---- log_level: debug ---- grep_error_log eval: qr/lua ssl (?:set|save|free) session: [0-9A-F]+:\d+/ ---- grep_error_log_out ---- error_log -lua ssl server name: "blah.agentzh.org" -lua ssl certificate does not match host "blah.agentzh.org" ---- no_error_log -SSL reused session -[alert] ---- timeout: 5 - - - -=== TEST 6: certificate does not match host name (verify, no log socket errors) -The certificate for "blah.agentzh.org" does not contain the name "blah.agentzh.org". ---- config - server_tokens off; - resolver $TEST_NGINX_RESOLVER; - lua_ssl_trusted_certificate ../html/trusted.crt; - lua_socket_log_errors off; - lua_ssl_verify_depth 2; - location /t { - #set $port 5000; - set $port $TEST_NGINX_MEMCACHED_PORT; - - content_by_lua ' - local sock = ngx.socket.tcp() - sock:settimeout(2000) - - do - local ok, err = sock:connect("agentzh.org", 443) - if not ok then - ngx.say("failed to connect: ", err) - return - end - - ngx.say("connected: ", ok) - - local session, err = sock:sslhandshake(nil, "blah.agentzh.org", true) - if not session then - ngx.say("failed to do SSL handshake: ", err) - else - ngx.say("ssl handshake: ", type(session)) - end - - local req = "GET / HTTP/1.1\\r\\nHost: blah.agentzh.org\\r\\nConnection: close\\r\\n\\r\\n" - local bytes, err = sock:send(req) - if not bytes then - ngx.say("failed to send http request: ", err) - return - end - - ngx.say("sent http request: ", bytes, " bytes.") - - local line, err = sock:receive() - if not line then - ngx.say("failed to receive response status line: ", err) - return - end - - ngx.say("received: ", line) - - local ok, err = sock:close() - ngx.say("close: ", ok, " ", err) - end -- do - collectgarbage() - '; - } - ---- user_files eval -">>> trusted.crt -$::StartComRootCertificate" - ---- request -GET /t ---- response_body -connected: 1 -failed to do SSL handshake: certificate host mismatch -failed to send http request: closed - ---- log_level: debug ---- grep_error_log eval: qr/lua ssl (?:set|save|free) session: [0-9A-F]+:\d+/ ---- grep_error_log_out ---- error_log -lua ssl server name: "blah.agentzh.org" ---- no_error_log -lua ssl certificate does not match host -SSL reused session -[alert] ---- timeout: 5 - - - -=== TEST 7: certificate does not match host name (no verify) ---- config - server_tokens off; - resolver $TEST_NGINX_RESOLVER; - location /t { - #set $port 5000; - set $port $TEST_NGINX_MEMCACHED_PORT; - - content_by_lua ' - local sock = ngx.socket.tcp() - sock:settimeout(2000) - - do - local ok, err = sock:connect("agentzh.org", 443) - if not ok then - ngx.say("failed to connect: ", err) - return - end - - ngx.say("connected: ", ok) - - local session, err = sock:sslhandshake(nil, "agentzh.org", false) - if not session then - ngx.say("failed to do SSL handshake: ", err) - return - end - - ngx.say("ssl handshake: ", type(session)) - - local req = "GET / HTTP/1.1\\r\\nHost: iscribblet.org\\r\\nConnection: close\\r\\n\\r\\n" - local bytes, err = sock:send(req) - if not bytes then - ngx.say("failed to send http request: ", err) - return - end - - ngx.say("sent http request: ", bytes, " bytes.") - - local line, err = sock:receive() - if not line then - ngx.say("failed to receive response status line: ", err) - return - end - - ngx.say("received: ", line) - - local ok, err = sock:close() - ngx.say("close: ", ok, " ", err) - end -- do - collectgarbage() - '; - } - --- request GET /t --- response_body connected: 1 ssl handshake: userdata -sent http request: 59 bytes. -received: HTTP/1.1 200 OK +sent http request: 56 bytes. +received: HTTP/1.1 404 Not Found close: 1 nil --- log_level: debug @@ -599,7 +594,7 @@ lua ssl free session: ([0-9A-F]+):1 $/ --- error_log -lua ssl server name: "agentzh.org" +lua ssl server name: "openresty.org" --- no_error_log SSL reused session [error] @@ -608,10 +603,10 @@ SSL reused session -=== TEST 8: iscribblet.org: passing SSL verify +=== TEST 8: openresty.org: passing SSL verify --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; lua_ssl_trusted_certificate ../html/trusted.crt; lua_ssl_verify_depth 2; location /t { @@ -623,7 +618,7 @@ SSL reused session sock:settimeout(2000) do - local ok, err = sock:connect("iscribblet.org", 443) + local ok, err = sock:connect("openresty.org", 443) if not ok then ngx.say("failed to connect: ", err) return @@ -631,7 +626,7 @@ SSL reused session ngx.say("connected: ", ok) - local session, err = sock:sslhandshake(nil, "iscribblet.org", true) + local session, err = sock:sslhandshake(nil, "openresty.org", true) if not session then ngx.say("failed to do SSL handshake: ", err) return @@ -639,7 +634,7 @@ SSL reused session ngx.say("ssl handshake: ", type(session)) - local req = "GET / HTTP/1.1\\r\\nHost: iscribblet.org\\r\\nConnection: close\\r\\n\\r\\n" + local req = "GET / HTTP/1.1\\r\\nHost: openresty.org\\r\\nConnection: close\\r\\n\\r\\n" local bytes, err = sock:send(req) if not bytes then ngx.say("failed to send http request: ", err) @@ -665,15 +660,15 @@ SSL reused session --- user_files eval ">>> trusted.crt -$::StartComRootCertificate" +$::ComodoRootCertificate" --- request GET /t --- response_body connected: 1 ssl handshake: userdata -sent http request: 59 bytes. -received: HTTP/1.1 200 OK +sent http request: 58 bytes. +received: HTTP/1.1 302 Moved Temporarily close: 1 nil --- log_level: debug @@ -684,7 +679,7 @@ lua ssl free session: ([0-9A-F]+):1 $/ --- error_log -lua ssl server name: "iscribblet.org" +lua ssl server name: "openresty.org" --- no_error_log SSL reused session [error] @@ -696,7 +691,7 @@ SSL reused session === TEST 9: ssl verify depth not enough (with automatic error logging) --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; lua_ssl_trusted_certificate ../html/trusted.crt; lua_ssl_verify_depth 1; location /t { @@ -708,7 +703,7 @@ SSL reused session sock:settimeout(2000) do - local ok, err = sock:connect("iscribblet.org", 443) + local ok, err = sock:connect("openresty.org", 443) if not ok then ngx.say("failed to connect: ", err) return @@ -716,14 +711,14 @@ SSL reused session ngx.say("connected: ", ok) - local session, err = sock:sslhandshake(nil, "iscribblet.org", true) + local session, err = sock:sslhandshake(nil, "openresty.org", true) if not session then ngx.say("failed to do SSL handshake: ", err) else ngx.say("ssl handshake: ", type(session)) end - local req = "GET / HTTP/1.1\\r\\nHost: iscribblet.org\\r\\nConnection: close\\r\\n\\r\\n" + local req = "GET / HTTP/1.1\\r\\nHost: openresty.org\\r\\nConnection: close\\r\\n\\r\\n" local bytes, err = sock:send(req) if not bytes then ngx.say("failed to send http request: ", err) @@ -749,7 +744,7 @@ SSL reused session --- user_files eval ">>> trusted.crt -$::StartComRootCertificate" +$::ComodoRootCertificate" --- request GET /t @@ -762,7 +757,7 @@ failed to send http request: closed --- grep_error_log eval: qr/lua ssl (?:set|save|free) session: [0-9A-F]+:\d+/ --- grep_error_log_out --- error_log -lua ssl server name: "iscribblet.org" +lua ssl server name: "openresty.org" lua ssl certificate verify error: (20: unable to get local issuer certificate) --- no_error_log SSL reused session @@ -774,7 +769,7 @@ SSL reused session === TEST 10: ssl verify depth not enough (without automatic error logging) --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; lua_ssl_trusted_certificate ../html/trusted.crt; lua_ssl_verify_depth 1; lua_socket_log_errors off; @@ -787,7 +782,7 @@ SSL reused session sock:settimeout(2000) do - local ok, err = sock:connect("iscribblet.org", 443) + local ok, err = sock:connect("openresty.org", 443) if not ok then ngx.say("failed to connect: ", err) return @@ -795,14 +790,14 @@ SSL reused session ngx.say("connected: ", ok) - local session, err = sock:sslhandshake(nil, "iscribblet.org", true) + local session, err = sock:sslhandshake(nil, "openresty.org", true) if not session then ngx.say("failed to do SSL handshake: ", err) else ngx.say("ssl handshake: ", type(session)) end - local req = "GET / HTTP/1.1\\r\\nHost: iscribblet.org\\r\\nConnection: close\\r\\n\\r\\n" + local req = "GET / HTTP/1.1\\r\\nHost: openresty.org\\r\\nConnection: close\\r\\n\\r\\n" local bytes, err = sock:send(req) if not bytes then ngx.say("failed to send http request: ", err) @@ -828,7 +823,7 @@ SSL reused session --- user_files eval ">>> trusted.crt -$::StartComRootCertificate" +$::ComodoRootCertificate" --- request GET /t @@ -841,7 +836,7 @@ failed to send http request: closed --- grep_error_log eval: qr/lua ssl (?:set|save|free) session: [0-9A-F]+:\d+/ --- grep_error_log_out --- error_log -lua ssl server name: "iscribblet.org" +lua ssl server name: "openresty.org" --- no_error_log lua ssl certificate verify error SSL reused session @@ -1010,7 +1005,7 @@ SSL reused session --- user_files eval ">>> trusted.crt -$::StartComRootCertificate" +$::ComodoRootCertificate" --- request GET /t @@ -1030,10 +1025,10 @@ SSL reused session -=== TEST 13: iscribblet.org: passing SSL verify with multiple certificates +=== TEST 13: openresty.org: passing SSL verify with multiple certificates --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; lua_ssl_trusted_certificate ../html/trusted.crt; lua_ssl_verify_depth 2; location /t { @@ -1045,7 +1040,7 @@ SSL reused session sock:settimeout(2000) do - local ok, err = sock:connect("iscribblet.org", 443) + local ok, err = sock:connect("openresty.org", 443) if not ok then ngx.say("failed to connect: ", err) return @@ -1053,7 +1048,7 @@ SSL reused session ngx.say("connected: ", ok) - local session, err = sock:sslhandshake(nil, "iscribblet.org", true) + local session, err = sock:sslhandshake(nil, "openresty.org", true) if not session then ngx.say("failed to do SSL handshake: ", err) return @@ -1061,7 +1056,7 @@ SSL reused session ngx.say("ssl handshake: ", type(session)) - local req = "GET / HTTP/1.1\\r\\nHost: iscribblet.org\\r\\nConnection: close\\r\\n\\r\\n" + local req = "GET / HTTP/1.1\\r\\nHost: openresty.org\\r\\nConnection: close\\r\\n\\r\\n" local bytes, err = sock:send(req) if not bytes then ngx.say("failed to send http request: ", err) @@ -1088,15 +1083,15 @@ SSL reused session --- user_files eval ">>> trusted.crt $::EquifaxRootCertificate -$::StartComRootCertificate" +$::ComodoRootCertificate" --- request GET /t --- response_body connected: 1 ssl handshake: userdata -sent http request: 59 bytes. -received: HTTP/1.1 200 OK +sent http request: 58 bytes. +received: HTTP/1.1 302 Moved Temporarily close: 1 nil --- log_level: debug @@ -1107,7 +1102,7 @@ lua ssl free session: ([0-9A-F]+):1 $/ --- error_log -lua ssl server name: "iscribblet.org" +lua ssl server name: "openresty.org" --- no_error_log SSL reused session [error] @@ -1119,7 +1114,7 @@ SSL reused session === TEST 14: default cipher --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; location /t { #set $port 5000; set $port $TEST_NGINX_MEMCACHED_PORT; @@ -1129,7 +1124,7 @@ SSL reused session sock:settimeout(2000) do - local ok, err = sock:connect("iscribblet.org", 443) + local ok, err = sock:connect("openresty.org", 443) if not ok then ngx.say("failed to connect: ", err) return @@ -1137,7 +1132,7 @@ SSL reused session ngx.say("connected: ", ok) - local session, err = sock:sslhandshake(nil, "iscribblet.org") + local session, err = sock:sslhandshake(nil, "openresty.org") if not session then ngx.say("failed to do SSL handshake: ", err) return @@ -1145,7 +1140,7 @@ SSL reused session ngx.say("ssl handshake: ", type(session)) - local req = "GET / HTTP/1.1\\r\\nHost: iscribblet.org\\r\\nConnection: close\\r\\n\\r\\n" + local req = "GET / HTTP/1.1\\r\\nHost: openresty.org\\r\\nConnection: close\\r\\n\\r\\n" local bytes, err = sock:send(req) if not bytes then ngx.say("failed to send http request: ", err) @@ -1174,8 +1169,8 @@ GET /t --- response_body connected: 1 ssl handshake: userdata -sent http request: 59 bytes. -received: HTTP/1.1 200 OK +sent http request: 58 bytes. +received: HTTP/1.1 302 Moved Temporarily close: 1 nil --- log_level: debug @@ -1185,8 +1180,8 @@ qr/^lua ssl save session: ([0-9A-F]+):2 lua ssl free session: ([0-9A-F]+):1 $/ --- error_log -lua ssl server name: "iscribblet.org" -SSL: TLSv1.2, cipher: "ECDHE-RSA-RC4-SHA SSLv3 +lua ssl server name: "openresty.org" +SSL: TLSv1.2, cipher: "ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 --- no_error_log SSL reused session [error] @@ -1198,8 +1193,8 @@ SSL reused session === TEST 15: explicit cipher configuration --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; - lua_ssl_ciphers RC4-SHA; + resolver $TEST_NGINX_RESOLVER ipv6=off; + lua_ssl_ciphers ECDHE-RSA-AES256-SHA; location /t { #set $port 5000; set $port $TEST_NGINX_MEMCACHED_PORT; @@ -1209,7 +1204,7 @@ SSL reused session sock:settimeout(2000) do - local ok, err = sock:connect("iscribblet.org", 443) + local ok, err = sock:connect("openresty.org", 443) if not ok then ngx.say("failed to connect: ", err) return @@ -1217,7 +1212,7 @@ SSL reused session ngx.say("connected: ", ok) - local session, err = sock:sslhandshake(nil, "iscribblet.org") + local session, err = sock:sslhandshake(nil, "openresty.org") if not session then ngx.say("failed to do SSL handshake: ", err) return @@ -1225,7 +1220,7 @@ SSL reused session ngx.say("ssl handshake: ", type(session)) - local req = "GET / HTTP/1.1\\r\\nHost: iscribblet.org\\r\\nConnection: close\\r\\n\\r\\n" + local req = "GET / HTTP/1.1\\r\\nHost: openresty.org\\r\\nConnection: close\\r\\n\\r\\n" local bytes, err = sock:send(req) if not bytes then ngx.say("failed to send http request: ", err) @@ -1254,8 +1249,8 @@ GET /t --- response_body connected: 1 ssl handshake: userdata -sent http request: 59 bytes. -received: HTTP/1.1 200 OK +sent http request: 58 bytes. +received: HTTP/1.1 302 Moved Temporarily close: 1 nil --- log_level: debug @@ -1265,8 +1260,8 @@ qr/^lua ssl save session: ([0-9A-F]+):2 lua ssl free session: ([0-9A-F]+):1 $/ --- error_log -lua ssl server name: "iscribblet.org" -SSL: TLSv1.2, cipher: "RC4-SHA SSLv3 +lua ssl server name: "openresty.org" +SSL: TLSv1.2, cipher: "ECDHE-RSA-AES256-SHA --- no_error_log SSL reused session [error] @@ -1278,7 +1273,7 @@ SSL reused session === TEST 16: explicit ssl protocol configuration --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; lua_ssl_protocols TLSv1; location /t { #set $port 5000; @@ -1289,7 +1284,7 @@ SSL reused session sock:settimeout(2000) do - local ok, err = sock:connect("iscribblet.org", 443) + local ok, err = sock:connect("openresty.org", 443) if not ok then ngx.say("failed to connect: ", err) return @@ -1297,7 +1292,7 @@ SSL reused session ngx.say("connected: ", ok) - local session, err = sock:sslhandshake(nil, "iscribblet.org") + local session, err = sock:sslhandshake(nil, "openresty.org") if not session then ngx.say("failed to do SSL handshake: ", err) return @@ -1305,7 +1300,7 @@ SSL reused session ngx.say("ssl handshake: ", type(session)) - local req = "GET / HTTP/1.1\\r\\nHost: iscribblet.org\\r\\nConnection: close\\r\\n\\r\\n" + local req = "GET / HTTP/1.1\\r\\nHost: openresty.org\\r\\nConnection: close\\r\\n\\r\\n" local bytes, err = sock:send(req) if not bytes then ngx.say("failed to send http request: ", err) @@ -1334,8 +1329,8 @@ GET /t --- response_body connected: 1 ssl handshake: userdata -sent http request: 59 bytes. -received: HTTP/1.1 200 OK +sent http request: 58 bytes. +received: HTTP/1.1 302 Moved Temporarily close: 1 nil --- log_level: debug @@ -1345,8 +1340,8 @@ qr/^lua ssl save session: ([0-9A-F]+):2 lua ssl free session: ([0-9A-F]+):1 $/ --- error_log -lua ssl server name: "iscribblet.org" -SSL: TLSv1, cipher: "ECDHE-RSA-RC4-SHA SSLv3 +lua ssl server name: "openresty.org" +SSL: TLSv1, cipher: "ECDHE-RSA-AES256-SHA --- no_error_log SSL reused session [error] @@ -1358,7 +1353,7 @@ SSL reused session === TEST 17: unsupported ssl protocol --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; lua_ssl_protocols SSLv2; lua_socket_log_errors off; location /t { @@ -1370,7 +1365,7 @@ SSL reused session sock:settimeout(2000) do - local ok, err = sock:connect("iscribblet.org", 443) + local ok, err = sock:connect("openresty.org", 443) if not ok then ngx.say("failed to connect: ", err) return @@ -1378,14 +1373,14 @@ SSL reused session ngx.say("connected: ", ok) - local session, err = sock:sslhandshake(nil, "iscribblet.org") + local session, err = sock:sslhandshake(nil, "openresty.org") if not session then ngx.say("failed to do SSL handshake: ", err) else ngx.say("ssl handshake: ", type(session)) end - local req = "GET / HTTP/1.1\\r\\nHost: iscribblet.org\\r\\nConnection: close\\r\\n\\r\\n" + local req = "GET / HTTP/1.1\\r\\nHost: openresty.org\\r\\nConnection: close\\r\\n\\r\\n" local bytes, err = sock:send(req) if not bytes then ngx.say("failed to send http request: ", err) @@ -1422,7 +1417,7 @@ failed to send http request: closed --- error_log eval [ qr/\[crit\] .*?SSL_do_handshake\(\) failed .*?unsupported protocol/, -'lua ssl server name: "iscribblet.org"', +'lua ssl server name: "openresty.org"', ] --- no_error_log SSL reused session @@ -1432,10 +1427,10 @@ SSL reused session -=== TEST 18: iscribblet.org: passing SSL verify: keepalive (reuse the ssl session) +=== TEST 18: openresty.org: passing SSL verify: keepalive (reuse the ssl session) --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; lua_ssl_trusted_certificate ../html/trusted.crt; lua_ssl_verify_depth 2; location /t { @@ -1450,7 +1445,7 @@ SSL reused session local session for i = 1, 3 do - local ok, err = sock:connect("iscribblet.org", 443) + local ok, err = sock:connect("openresty.org", 443) if not ok then ngx.say("failed to connect: ", err) return @@ -1458,7 +1453,7 @@ SSL reused session ngx.say("connected: ", ok) - session, err = sock:sslhandshake(session, "iscribblet.org", true) + session, err = sock:sslhandshake(session, "openresty.org", true) if not session then ngx.say("failed to do SSL handshake: ", err) return @@ -1477,7 +1472,7 @@ SSL reused session --- user_files eval ">>> trusted.crt -$::StartComRootCertificate" +$::ComodoRootCertificate" --- request GET /t @@ -1509,10 +1504,10 @@ SSL reused session -=== TEST 19: iscribblet.org: passing SSL verify: keepalive (no reusing the ssl session) +=== TEST 19: openresty.org: passing SSL verify: keepalive (no reusing the ssl session) --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; lua_ssl_trusted_certificate ../html/trusted.crt; lua_ssl_verify_depth 2; location /t { @@ -1526,7 +1521,7 @@ SSL reused session do for i = 1, 3 do - local ok, err = sock:connect("iscribblet.org", 443) + local ok, err = sock:connect("openresty.org", 443) if not ok then ngx.say("failed to connect: ", err) return @@ -1534,7 +1529,7 @@ SSL reused session ngx.say("connected: ", ok) - local session, err = sock:sslhandshake(nil, "iscribblet.org", true) + local session, err = sock:sslhandshake(nil, "openresty.org", true) if not session then ngx.say("failed to do SSL handshake: ", err) return @@ -1553,7 +1548,7 @@ SSL reused session --- user_files eval ">>> trusted.crt -$::StartComRootCertificate" +$::ComodoRootCertificate" --- request GET /t @@ -1592,7 +1587,7 @@ SSL reused session === TEST 20: downstream cosockets do not support ssl handshake --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; lua_ssl_trusted_certificate ../html/trusted.crt; lua_ssl_verify_depth 2; location /t { @@ -1612,7 +1607,7 @@ SSL reused session --- user_files eval ">>> trusted.crt -$::StartComRootCertificate" +$::ComodoRootCertificate" --- request POST /t @@ -1647,7 +1642,7 @@ attempt to call method 'sslhandshake' (a nil value) } --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; location /t { #set $port 5000; set $port $TEST_NGINX_MEMCACHED_PORT; @@ -1750,7 +1745,7 @@ SSL reused session } --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; lua_ssl_trusted_certificate ../html/test.crt; location /t { @@ -1854,7 +1849,7 @@ SSL reused session } --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; location /t { #set $port 5000; set $port $TEST_NGINX_MEMCACHED_PORT; @@ -1946,7 +1941,7 @@ SSL reused session } --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; lua_ssl_crl ../html/test.crl; lua_ssl_trusted_certificate ../html/test.crt; lua_socket_log_errors off; @@ -2031,7 +2026,7 @@ SSL reused session === TEST 25: multiple handshake calls --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; location /t { #set $port 5000; set $port $TEST_NGINX_MEMCACHED_PORT; @@ -2042,7 +2037,7 @@ SSL reused session sock:settimeout(2000) do - local ok, err = sock:connect("iscribblet.org", 443) + local ok, err = sock:connect("openresty.org", 443) if not ok then ngx.say("failed to connect: ", err) return @@ -2051,7 +2046,7 @@ SSL reused session ngx.say("connected: ", ok) for i = 1, 2 do - local session, err = sock:sslhandshake(nil, "iscribblet.org") + local session, err = sock:sslhandshake(nil, "openresty.org") if not session then ngx.say("failed to do SSL handshake: ", err) return @@ -2060,7 +2055,7 @@ SSL reused session ngx.say("ssl handshake: ", type(session)) end - local req = "GET / HTTP/1.1\\r\\nHost: iscribblet.org\\r\\nConnection: close\\r\\n\\r\\n" + local req = "GET / HTTP/1.1\\r\\nHost: openresty.org\\r\\nConnection: close\\r\\n\\r\\n" local bytes, err = sock:send(req) if not bytes then ngx.say("failed to send http request: ", err) @@ -2090,8 +2085,8 @@ GET /t connected: 1 ssl handshake: userdata ssl handshake: userdata -sent http request: 59 bytes. -received: HTTP/1.1 200 OK +sent http request: 58 bytes. +received: HTTP/1.1 302 Moved Temporarily close: 1 nil --- log_level: debug @@ -2103,7 +2098,7 @@ lua ssl free session: ([0-9A-F]+):2 lua ssl free session: ([0-9A-F]+):1 $/ --- error_log -lua ssl server name: "iscribblet.org" +lua ssl server name: "openresty.org" --- no_error_log SSL reused session [error] @@ -2115,7 +2110,7 @@ SSL reused session === TEST 26: handshake timed out --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; location /t { #set $port 5000; set $port $TEST_NGINX_MEMCACHED_PORT; @@ -2126,7 +2121,7 @@ SSL reused session sock:settimeout(2000) do - local ok, err = sock:connect("iscribblet.org", 443) + local ok, err = sock:connect("openresty.org", 443) if not ok then ngx.say("failed to connect: ", err) return @@ -2135,7 +2130,7 @@ SSL reused session ngx.say("connected: ", ok) sock:settimeout(1); -- should timeout immediately - local session, err = sock:sslhandshake(nil, "iscribblet.org") + local session, err = sock:sslhandshake(nil, "openresty.org") if not session then ngx.say("failed to do SSL handshake: ", err) return @@ -2157,7 +2152,7 @@ failed to do SSL handshake: timeout --- grep_error_log eval: qr/lua ssl (?:set|save|free) session: [0-9A-F]+:\d+/ --- grep_error_log_out --- error_log -lua ssl server name: "iscribblet.org" +lua ssl server name: "openresty.org" --- no_error_log SSL reused session [error] @@ -2183,7 +2178,7 @@ SSL reused session } --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; location /t { #set $port 5000; set $port $TEST_NGINX_MEMCACHED_PORT; @@ -2254,7 +2249,7 @@ SSL reused session } --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; location /t { #set $port 5000; set $port $TEST_NGINX_MEMCACHED_PORT; @@ -2328,7 +2323,7 @@ SSL reused session } --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; location /t { #set $port 5000; set $port $TEST_NGINX_MEMCACHED_PORT; @@ -2405,7 +2400,7 @@ SSL reused session } --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; lua_ssl_trusted_certificate ../html/test.crt; location /t { @@ -2510,7 +2505,7 @@ SSL reused session } --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; #lua_ssl_trusted_certificate ../html/test.crt; location /t { @@ -2589,7 +2584,7 @@ SSL reused session === TEST 32: handshake, too many arguments --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; location /t { #set $port 5000; set $port $TEST_NGINX_MEMCACHED_PORT; @@ -2598,7 +2593,7 @@ SSL reused session local sock = ngx.socket.tcp() sock:settimeout(2000) - local ok, err = sock:connect("g.sregex.org", 443) + local ok, err = sock:connect("openresty.org", 443) if not ok then ngx.say("failed to connect: ", err) return @@ -2614,7 +2609,7 @@ SSL reused session GET /t --- ignore_response --- error_log eval -qr/\[error\] .* ngx.socket connect: expecting 1 ~ 5 arguments \(including the object\), but seen 0/ +qr/\[error\] .* ngx.socket sslhandshake: expecting 1 ~ 5 arguments \(including the object\), but seen 0/ --- no_error_log [alert] --- timeout: 5 diff --git a/debian/modules/nginx-lua/t/130-internal-api.t b/debian/modules/nginx-lua/t/130-internal-api.t index d641ab5..eba0980 100644 --- a/debian/modules/nginx-lua/t/130-internal-api.t +++ b/debian/modules/nginx-lua/t/130-internal-api.t @@ -47,4 +47,3 @@ content req=0x[a-f0-9]{4,} $ --- no_error_log [error] - diff --git a/debian/modules/nginx-lua/t/135-worker-id.t b/debian/modules/nginx-lua/t/135-worker-id.t index 3c1f24d..984f446 100644 --- a/debian/modules/nginx-lua/t/135-worker-id.t +++ b/debian/modules/nginx-lua/t/135-worker-id.t @@ -54,7 +54,7 @@ GET /lua content_by_lua_block { local counters = ngx.shared.counters local ok, c - for i = 1, 45 do + for i = 1, 100 do c = counters:get("c") if c >= 4 then ok = true diff --git a/debian/modules/nginx-lua/t/137-req-misc.t b/debian/modules/nginx-lua/t/137-req-misc.t index 20ada3c..d56f80e 100644 --- a/debian/modules/nginx-lua/t/137-req-misc.t +++ b/debian/modules/nginx-lua/t/137-req-misc.t @@ -59,4 +59,3 @@ not internal GET /test --- response_body internal - diff --git a/debian/modules/nginx-lua/t/138-balancer.t b/debian/modules/nginx-lua/t/138-balancer.t index 8d45c24..ddd0da5 100644 --- a/debian/modules/nginx-lua/t/138-balancer.t +++ b/debian/modules/nginx-lua/t/138-balancer.t @@ -58,8 +58,8 @@ qr{\[crit\] .*? connect\(\) to 0\.0\.0\.1:80 failed .*?, upstream: "http://0\.0\ } --- request GET /t ---- response_body_like: 500 Internal Server Error ---- error_code: 500 +--- response_body_like: 403 Forbidden +--- error_code: 403 --- error_log [lua] balancer_by_lua:2: hello from balancer by lua! while connecting to upstream, --- no_error_log eval @@ -431,3 +431,98 @@ qr{\[crit\] .*? connect\(\) to 0\.0\.0\.1:80 failed .*?, upstream: "http://0\.0\ ] --- no_error_log [warn] + + + +=== TEST 15: test if execeed proxy_next_upstream_limit +--- http_config + lua_package_path "../lua-resty-core/lib/?.lua;;"; + + proxy_next_upstream_tries 5; + upstream backend { + server 0.0.0.1; + balancer_by_lua_block { + local b = require "ngx.balancer" + + if not ngx.ctx.tries then + ngx.ctx.tries = 0 + end + + if ngx.ctx.tries >= 6 then + ngx.log(ngx.ERR, "retry count exceed limit") + ngx.exit(500) + end + + ngx.ctx.tries = ngx.ctx.tries + 1 + print("retry counter: ", ngx.ctx.tries) + + local ok, err = b.set_more_tries(2) + if not ok then + return error("failed to set more tries: ", err) + elseif err then + ngx.log(ngx.WARN, "set more tries: ", err) + end + + assert(b.set_current_peer("127.0.0.1", 81)) + } + } +--- config + location = /t { + proxy_pass http://backend/back; + } + + location = /back { + return 404; + } +--- request + GET /t +--- response_body_like: 502 Bad Gateway +--- error_code: 502 +--- grep_error_log eval: qr/\bretry counter: \w+/ +--- grep_error_log_out +retry counter: 1 +retry counter: 2 +retry counter: 3 +retry counter: 4 +retry counter: 5 + +--- error_log +set more tries: reduced tries due to limit + + + +=== TEST 16: set_more_tries bugfix +--- http_config + lua_package_path "../lua-resty-core/lib/?.lua;;"; + proxy_next_upstream_tries 0; + upstream backend { + server 0.0.0.1; + balancer_by_lua_block { + local balancer = require "ngx.balancer" + local ctx = ngx.ctx + if not ctx.has_run then + ctx.has_run = true + local _, err = balancer.set_more_tries(3) + if err then + ngx.log(ngx.ERR, "failed to set more tries: ", err) + end + end + balancer.set_current_peer("127.0.0.1", 81) + } + } +--- config + location = /t { + proxy_pass http://backend; + } +--- request + GET /t +--- error_code: 502 +--- grep_error_log eval: qr/http next upstream, \d+/ +--- grep_error_log_out +http next upstream, 2 +http next upstream, 2 +http next upstream, 2 +http next upstream, 2 +--- no_error_log +failed to set more tries: reduced tries due to limit +[alert] diff --git a/debian/modules/nginx-lua/t/139-ssl-cert-by.t b/debian/modules/nginx-lua/t/139-ssl-cert-by.t index b9fd60d..c13044f 100644 --- a/debian/modules/nginx-lua/t/139-ssl-cert-by.t +++ b/debian/modules/nginx-lua/t/139-ssl-cert-by.t @@ -11,7 +11,7 @@ my $openssl_version = eval { `$NginxBinary -V 2>&1` }; if ($openssl_version =~ m/built with OpenSSL (0|1\.0\.(?:0|1[^\d]|2[a-d]).*)/) { plan(skip_all => "too old OpenSSL, need 1.0.2e, was $1"); } else { - plan tests => repeat_each() * (blocks() * 6 + 10); + plan tests => repeat_each() * (blocks() * 6 + 6); } $ENV{TEST_NGINX_HTML_DIR} ||= html_dir(); @@ -1383,7 +1383,7 @@ uthread: done -=== TEST 17: simple logging - use ssl_certificiate_by_lua* on the http {} level +=== TEST 17: simple logging - use ssl_certificate_by_lua* on the http {} level GitHub openresty/lua-resty-core#42 --- http_config ssl_certificate_by_lua_block { print("ssl cert by lua is running!") } @@ -1574,3 +1574,295 @@ qr/\[error\] .*? send\(\) failed/, --- no_error_log [alert] ssl_certificate_by_lua:1: ssl cert by lua is running! + + + +=== TEST 19: check the count of running timers +--- http_config + server { + listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl; + server_name test.com; + + ssl_certificate_by_lua_block { print("ssl cert by lua is running!") } + ssl_certificate ../../cert/test.crt; + ssl_certificate_key ../../cert/test.key; + + server_tokens off; + location /timers { + default_type 'text/plain'; + content_by_lua_block { + ngx.timer.at(0.1, function() ngx.sleep(0.3) end) + ngx.timer.at(0.11, function() ngx.sleep(0.3) end) + ngx.timer.at(0.09, function() ngx.sleep(0.3) end) + ngx.sleep(0.2) + ngx.say(ngx.timer.running_count()) + } + more_clear_headers Date; + } + } +--- config + server_tokens off; + lua_ssl_trusted_certificate ../../cert/test.crt; + + location /t { + content_by_lua_block { + do + local sock = ngx.socket.tcp() + + sock:settimeout(2000) + + local ok, err = sock:connect("unix:$TEST_NGINX_HTML_DIR/nginx.sock") + if not ok then + ngx.say("failed to connect: ", err) + return + end + + ngx.say("connected: ", ok) + + local sess, err = sock:sslhandshake(nil, "test.com", true) + if not sess then + ngx.say("failed to do SSL handshake: ", err) + return + end + + ngx.say("ssl handshake: ", type(sess)) + + local req = "GET /timers HTTP/1.0\r\nHost: test.com\r\nConnection: close\r\n\r\n" + local bytes, err = sock:send(req) + if not bytes then + ngx.say("failed to send http request: ", err) + return + end + + ngx.say("sent http request: ", bytes, " bytes.") + + while true do + local line, err = sock:receive() + if not line then + -- ngx.say("failed to receive response status line: ", err) + break + end + + ngx.say("received: ", line) + end + + local ok, err = sock:close() + ngx.say("close: ", ok, " ", err) + end -- do + -- collectgarbage() + } + } + +--- request +GET /t +--- response_body +connected: 1 +ssl handshake: userdata +sent http request: 59 bytes. +received: HTTP/1.1 200 OK +received: Server: nginx +received: Content-Type: text/plain +received: Content-Length: 2 +received: Connection: close +received: +received: 3 +close: 1 nil + +--- error_log eval +[ +'ssl_certificate_by_lua:1: ssl cert by lua is running!', +'lua ssl server name: "test.com"', +] +--- no_error_log +[error] +[alert] + + + +=== TEST 20: some server {} block missing ssl_certificate_by_lua* handlers (literal server name) +--- http_config + server { + listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl; + server_name test.com; + + ssl_certificate_by_lua_block { print("ssl cert by lua is running!") } + ssl_certificate ../../cert/test.crt; + ssl_certificate_key ../../cert/test.key; + + server_tokens off; + location /timers { + default_type 'text/plain'; + content_by_lua_block { + ngx.timer.at(0.1, function() ngx.sleep(0.3) end) + ngx.timer.at(0.11, function() ngx.sleep(0.3) end) + ngx.timer.at(0.09, function() ngx.sleep(0.3) end) + ngx.sleep(0.2) + ngx.say(ngx.timer.running_count()) + } + more_clear_headers Date; + } + } + + server { + listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl; + server_name test2.com; + } +--- config + server_tokens off; + lua_ssl_trusted_certificate ../../cert/test.crt; + + location /t { + content_by_lua_block { + do + local sock = ngx.socket.tcp() + + sock:settimeout(2000) + + local ok, err = sock:connect("unix:$TEST_NGINX_HTML_DIR/nginx.sock") + if not ok then + ngx.say("failed to connect: ", err) + return + end + + ngx.say("connected: ", ok) + + local sess, err = sock:sslhandshake(nil, "test2.com", true) + if not sess then + ngx.say("failed to do SSL handshake: ", err) + return + end + + ngx.say("ssl handshake: ", type(sess)) + + local req = "GET /timers HTTP/1.0\r\nHost: test.com\r\nConnection: close\r\n\r\n" + local bytes, err = sock:send(req) + if not bytes then + ngx.say("failed to send http request: ", err) + return + end + + ngx.say("sent http request: ", bytes, " bytes.") + + while true do + local line, err = sock:receive() + if not line then + -- ngx.say("failed to receive response status line: ", err) + break + end + + ngx.say("received: ", line) + end + + local ok, err = sock:close() + ngx.say("close: ", ok, " ", err) + end -- do + -- collectgarbage() + } + } + +--- request +GET /t +--- response_body +connected: 1 +failed to do SSL handshake: handshake failed + +--- error_log eval +[ +qr/\[alert\] .*? no ssl_certificate_by_lua\* defined in server test2\.com\b/, +qr/\[crit\] .*? SSL_do_handshake\(\) failed\b/, +] + + + +=== TEST 21: some server {} block missing ssl_certificate_by_lua* handlers (regex server name) +--- http_config + server { + listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl; + server_name test.com; + + ssl_certificate_by_lua_block { print("ssl cert by lua is running!") } + ssl_certificate ../../cert/test.crt; + ssl_certificate_key ../../cert/test.key; + + server_tokens off; + location /timers { + default_type 'text/plain'; + content_by_lua_block { + ngx.timer.at(0.1, function() ngx.sleep(0.3) end) + ngx.timer.at(0.11, function() ngx.sleep(0.3) end) + ngx.timer.at(0.09, function() ngx.sleep(0.3) end) + ngx.sleep(0.2) + ngx.say(ngx.timer.running_count()) + } + more_clear_headers Date; + } + } + + server { + listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl; + server_name ~test2\.com; + } +--- config + server_tokens off; + lua_ssl_trusted_certificate ../../cert/test.crt; + + location /t { + content_by_lua_block { + do + local sock = ngx.socket.tcp() + + sock:settimeout(2000) + + local ok, err = sock:connect("unix:$TEST_NGINX_HTML_DIR/nginx.sock") + if not ok then + ngx.say("failed to connect: ", err) + return + end + + ngx.say("connected: ", ok) + + local sess, err = sock:sslhandshake(nil, "test2.com", true) + if not sess then + ngx.say("failed to do SSL handshake: ", err) + return + end + + ngx.say("ssl handshake: ", type(sess)) + + local req = "GET /timers HTTP/1.0\r\nHost: test.com\r\nConnection: close\r\n\r\n" + local bytes, err = sock:send(req) + if not bytes then + ngx.say("failed to send http request: ", err) + return + end + + ngx.say("sent http request: ", bytes, " bytes.") + + while true do + local line, err = sock:receive() + if not line then + -- ngx.say("failed to receive response status line: ", err) + break + end + + ngx.say("received: ", line) + end + + local ok, err = sock:close() + ngx.say("close: ", ok, " ", err) + end -- do + -- collectgarbage() + } + } + +--- request +GET /t +--- response_body +connected: 1 +failed to do SSL handshake: handshake failed + +--- error_log eval +[ +qr/\[alert\] .*? no ssl_certificate_by_lua\* defined in server ~test2\\\.com\b/, +qr/\[crit\] .*? SSL_do_handshake\(\) failed\b/, +] diff --git a/debian/modules/nginx-lua/t/140-ssl-c-api.t b/debian/modules/nginx-lua/t/140-ssl-c-api.t index 44ad93d..8734d14 100644 --- a/debian/modules/nginx-lua/t/140-ssl-c-api.t +++ b/debian/modules/nginx-lua/t/140-ssl-c-api.t @@ -561,7 +561,7 @@ failed to parse PEM priv key: PEM_read_bio_PrivateKey() failed f:close() local pkey = ffi.C.ngx_http_lua_ffi_parse_pem_priv_key(pkey_data, #pkey_data, errmsg) - if not pkey then + if pkey == nil then ngx.log(ngx.ERR, "failed to parse PEM priv key: ", ffi.string(errmsg[0])) return @@ -626,7 +626,7 @@ failed to parse PEM priv key: PEM_read_bio_PrivateKey() failed while true do local line, err = sock:receive() if not line then - -- ngx.say("failed to recieve response status line: ", err) + -- ngx.say("failed to receive response status line: ", err) break end @@ -711,7 +711,7 @@ lua ssl server name: "test.com" f:close() local pkey = ffi.C.ngx_http_lua_ffi_parse_pem_priv_key(pkey_data, #pkey_data, errmsg) - if not pkey then + if pkey == nil then ngx.log(ngx.ERR, "failed to parse PEM priv key: ", ffi.string(errmsg[0])) return @@ -776,7 +776,7 @@ lua ssl server name: "test.com" while true do local line, err = sock:receive() if not line then - -- ngx.say("failed to recieve response status line: ", err) + -- ngx.say("failed to receive response status line: ", err) break end diff --git a/debian/modules/nginx-lua/t/141-luajit.t b/debian/modules/nginx-lua/t/141-luajit.t index be03fe3..36418d1 100644 --- a/debian/modules/nginx-lua/t/141-luajit.t +++ b/debian/modules/nginx-lua/t/141-luajit.t @@ -1,6 +1,7 @@ # vim:set ft= ts=4 sw=4 et fdm=marker: -use Test::Nginx::Socket::Lua; +use Test::Nginx::Socket::Lua + skip_all => 'no mmap(sbrk(0)) trick since glibc leaks memory in this case'; #worker_connections(1014); #master_on(); diff --git a/debian/modules/nginx-lua/t/142-ssl-session-store.t b/debian/modules/nginx-lua/t/142-ssl-session-store.t index 5c9fad3..73b6e19 100644 --- a/debian/modules/nginx-lua/t/142-ssl-session-store.t +++ b/debian/modules/nginx-lua/t/142-ssl-session-store.t @@ -38,7 +38,7 @@ __DATA__ } --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; lua_ssl_trusted_certificate $TEST_NGINX_CERT_DIR/cert/test.crt; location /t { @@ -108,7 +108,7 @@ ssl_session_store_by_lua_block:1: ssl session store by lua is running! } --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; lua_ssl_trusted_certificate $TEST_NGINX_CERT_DIR/cert/test.crt; location /t { @@ -183,7 +183,7 @@ API disabled in the context of ssl_session_store_by_lua* } --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; lua_ssl_trusted_certificate $TEST_NGINX_CERT_DIR/cert/test.crt; location /t { @@ -275,7 +275,7 @@ my timer run! } --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; lua_ssl_trusted_certificate $TEST_NGINX_CERT_DIR/cert/test.crt; location /t { @@ -343,7 +343,7 @@ API disabled in the context of ssl_session_store_by_lua* } --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; lua_ssl_trusted_certificate $TEST_NGINX_CERT_DIR/cert/test.crt; lua_ssl_verify_depth 3; @@ -415,7 +415,7 @@ ngx.exit does not yield and the error code is eaten. } --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; lua_ssl_trusted_certificate $TEST_NGINX_CERT_DIR/cert/test.crt; lua_ssl_verify_depth 3; @@ -488,7 +488,7 @@ ssl_session_store_by_lua*: handler return value: 0, sess new cb exit code: 0 } --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; lua_ssl_trusted_certificate $TEST_NGINX_CERT_DIR/cert/test.crt; lua_ssl_verify_depth 3; @@ -556,7 +556,7 @@ should never reached here } --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; lua_ssl_trusted_certificate $TEST_NGINX_CERT_DIR/cert/test.crt; lua_ssl_verify_depth 3; @@ -627,7 +627,7 @@ get_phase: ssl_session_store } --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; lua_ssl_trusted_certificate $TEST_NGINX_CERT_DIR/cert/test.crt; location /t { @@ -696,7 +696,7 @@ qr/elapsed in ssl cert by lua: 0.(?:09|1[01])\d+,/, } --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; lua_ssl_trusted_certificate $TEST_NGINX_CERT_DIR/cert/test.crt; location /t { @@ -778,7 +778,7 @@ a.lua:1: ssl store session by lua is running! } --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; lua_ssl_trusted_certificate $TEST_NGINX_CERT_DIR/cert/test.crt; lua_ssl_verify_depth 3; @@ -849,7 +849,7 @@ qr/\[emerg\] .*? "ssl_session_store_by_lua_block" directive is not allowed here } --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; lua_ssl_trusted_certificate $TEST_NGINX_CERT_DIR/cert/test.crt; location /t { diff --git a/debian/modules/nginx-lua/t/143-ssl-session-fetch.t b/debian/modules/nginx-lua/t/143-ssl-session-fetch.t index bd800ff..701ead7 100644 --- a/debian/modules/nginx-lua/t/143-ssl-session-fetch.t +++ b/debian/modules/nginx-lua/t/143-ssl-session-fetch.t @@ -39,7 +39,7 @@ __DATA__ } --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; lua_ssl_trusted_certificate $TEST_NGINX_CERT_DIR/cert/test.crt; location /t { @@ -120,7 +120,7 @@ qr/ssl_session_fetch_by_lua_block:1: ssl fetch sess by lua is running!/s } --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; lua_ssl_trusted_certificate $TEST_NGINX_CERT_DIR/cert/test.crt; location /t { @@ -204,7 +204,7 @@ qr/elapsed in ssl fetch session by lua: 0.(?:09|1[01])\d+,/, } --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; lua_ssl_trusted_certificate $TEST_NGINX_CERT_DIR/cert/test.crt; location /t { @@ -305,7 +305,7 @@ qr/my timer run!/s } --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; lua_ssl_trusted_certificate $TEST_NGINX_CERT_DIR/cert/test.crt; location /t { @@ -385,7 +385,7 @@ qr/received memc reply: OK/s } --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; lua_ssl_trusted_certificate $TEST_NGINX_CERT_DIR/cert/test.crt; lua_ssl_verify_depth 3; @@ -466,7 +466,7 @@ should never reached here } --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; lua_ssl_trusted_certificate $TEST_NGINX_CERT_DIR/cert/test.crt; lua_ssl_verify_depth 3; @@ -548,7 +548,7 @@ should never reached here } --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; lua_ssl_trusted_certificate $TEST_NGINX_CERT_DIR/cert/test.crt; lua_ssl_verify_depth 3; @@ -629,7 +629,7 @@ should never reached here } --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; lua_ssl_trusted_certificate $TEST_NGINX_CERT_DIR/cert/test.crt; lua_ssl_verify_depth 3; @@ -712,7 +712,7 @@ should never reached here } --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; lua_ssl_trusted_certificate $TEST_NGINX_CERT_DIR/cert/test.crt; lua_ssl_verify_depth 3; @@ -793,7 +793,7 @@ should never reached here } --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; lua_ssl_trusted_certificate $TEST_NGINX_CERT_DIR/cert/test.crt; location /t { @@ -879,7 +879,7 @@ qr/get_phase: ssl_session_fetch/s --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; lua_ssl_trusted_certificate $TEST_NGINX_CERT_DIR/cert/test.crt; location /t { @@ -1049,7 +1049,7 @@ qr/\S+:\d+: ssl fetch sess by lua is running!/s } --- config server_tokens off; - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; lua_ssl_trusted_certificate $TEST_NGINX_CERT_DIR/cert/test.crt; location /t { diff --git a/debian/modules/nginx-lua/t/146-malloc-trim.t b/debian/modules/nginx-lua/t/146-malloc-trim.t index 45fb9f2..fc425ce 100644 --- a/debian/modules/nginx-lua/t/146-malloc-trim.t +++ b/debian/modules/nginx-lua/t/146-malloc-trim.t @@ -43,8 +43,9 @@ ok ok ok --- grep_error_log eval: qr/malloc_trim\(\d+\) returned \d+/ ---- grep_error_log_out -malloc_trim(1) returned 0 +--- grep_error_log_out eval +qr/\Amalloc_trim\(1\) returned [01] +\z/ --- wait: 0.2 --- no_error_log [error] @@ -76,13 +77,14 @@ ok ok ok --- grep_error_log eval: qr/malloc_trim\(\d+\) returned \d+/ ---- grep_error_log_out -malloc_trim(1) returned 0 -malloc_trim(1) returned 0 -malloc_trim(1) returned 0 -malloc_trim(1) returned 0 -malloc_trim(1) returned 0 -malloc_trim(1) returned 0 +--- grep_error_log_out eval +qr/\Amalloc_trim\(1\) returned [01] +malloc_trim\(1\) returned [01] +malloc_trim\(1\) returned [01] +malloc_trim\(1\) returned [01] +malloc_trim\(1\) returned [01] +malloc_trim\(1\) returned [01] +\z/ --- wait: 0.2 --- no_error_log [error] @@ -114,10 +116,11 @@ ok ok ok --- grep_error_log eval: qr/malloc_trim\(\d+\) returned \d+/ ---- grep_error_log_out -malloc_trim(1) returned 0 -malloc_trim(1) returned 0 -malloc_trim(1) returned 0 +--- grep_error_log_out eval +qr/\Amalloc_trim\(1\) returned [01] +malloc_trim\(1\) returned [01] +malloc_trim\(1\) returned [01] +\z/ --- wait: 0.2 --- no_error_log [error] @@ -149,9 +152,10 @@ ok ok ok --- grep_error_log eval: qr/malloc_trim\(\d+\) returned \d+/ ---- grep_error_log_out -malloc_trim(1) returned 0 -malloc_trim(1) returned 0 +--- grep_error_log_out eval +qr/\Amalloc_trim\(1\) returned [01] +malloc_trim\(1\) returned [01] +\z/ --- wait: 0.2 --- no_error_log [error] @@ -330,8 +334,9 @@ ok ok ok --- grep_error_log eval: qr/malloc_trim\(\d+\) returned \d+/ ---- grep_error_log_out -malloc_trim(1) returned 0 +--- grep_error_log_out eval +qr/\Amalloc_trim\(1\) returned [01] +\z/ --- wait: 0.2 --- no_error_log [error] diff --git a/debian/modules/nginx-lua/t/147-tcp-socket-timeouts.t b/debian/modules/nginx-lua/t/147-tcp-socket-timeouts.t index 52f015a..0689a9b 100644 --- a/debian/modules/nginx-lua/t/147-tcp-socket-timeouts.t +++ b/debian/modules/nginx-lua/t/147-tcp-socket-timeouts.t @@ -315,7 +315,7 @@ lua tcp socket write timed out === TEST 5: connection timeout (tcp) --- config - resolver $TEST_NGINX_RESOLVER; + resolver $TEST_NGINX_RESOLVER ipv6=off; resolver_timeout 3s; location /test { content_by_lua_block { diff --git a/debian/modules/nginx-lua/t/150-fake-delayed-load.t b/debian/modules/nginx-lua/t/150-fake-delayed-load.t new file mode 100644 index 0000000..232bbf3 --- /dev/null +++ b/debian/modules/nginx-lua/t/150-fake-delayed-load.t @@ -0,0 +1,56 @@ +# vim:set ft= ts=4 sw=4 et fdm=marker: +use lib 'lib'; +use Test::Nginx::Socket::Lua; + +#worker_connections(1014); +#master_process_enabled(1); +#log_level('warn'); + +#repeat_each(2); + +plan tests => repeat_each() * (blocks() * 3); + +#no_diff(); +no_long_string(); +#master_on(); +#workers(2); + +run_tests(); + +__DATA__ + +=== TEST 1: lua code cache on +--- http_config + lua_code_cache on; +--- config + location = /cache_on { + content_by_lua_block { + local delayed_load = require("ngx.delayed_load") + ngx.say(type(delayed_load.get_function)) + } + } +--- request +GET /cache_on +--- response_body +function +--- no_error_log +[error] + + + +=== TEST 2: lua code cache off +--- http_config + lua_code_cache off; +--- config + location = /cache_off { + content_by_lua_block { + local delayed_load = require("ngx.delayed_load") + ngx.say(type(delayed_load.get_function)) + } + } +--- request +GET /cache_off +--- response_body +function +--- no_error_log +[error] diff --git a/debian/modules/nginx-lua/t/151-initby-hup.t b/debian/modules/nginx-lua/t/151-initby-hup.t new file mode 100644 index 0000000..f278867 --- /dev/null +++ b/debian/modules/nginx-lua/t/151-initby-hup.t @@ -0,0 +1,168 @@ +# vim:set ft= ts=4 sw=4 et fdm=marker: + +our $SkipReason; + +BEGIN { + if ($ENV{TEST_NGINX_CHECK_LEAK}) { + $SkipReason = "unavailable for the hup tests"; + + } else { + $ENV{TEST_NGINX_USE_HUP} = 1; + undef $ENV{TEST_NGINX_USE_STAP}; + } +} + +use Test::Nginx::Socket::Lua 'no_plan'; + +#worker_connections(1014); +#master_on(); +#workers(2); +#log_level('warn'); + +repeat_each(1); + +#plan tests => repeat_each() * (blocks() * 3 + 3); + +#no_diff(); +#no_long_string(); +no_shuffle(); + +run_tests(); + +__DATA__ + +=== TEST 1: no error in init before HUP +--- http_config + init_by_lua_block { + foo = "hello, FOO" + } +--- config + location /lua { + content_by_lua_block { + ngx.say(foo) + } + } +--- request +GET /lua +--- response_body +hello, FOO +--- no_error_log +[error] + + + +=== TEST 2: error in init after HUP (master still alive, worker process still the same as before) +--- http_config + init_by_lua_block { + error("failed to init") + } +--- config + location /lua { + content_by_lua_block { + ngx.say(foo) + } + } +--- request +GET /lua +--- response_body +hello, FOO +--- error_log +failed to init +--- reload_fails + + + +=== TEST 3: no error in init again +--- http_config + init_by_lua_block { + foo = "hello, foo" + } +--- config + location /lua { + content_by_lua_block { + ngx.say(foo) + } + } +--- request +GET /lua +--- response_body +hello, foo +--- no_error_log +[error] + + + +=== TEST 4: no error in init before HUP, used ngx.shared.DICT +--- http_config + lua_shared_dict dogs 1m; + + init_by_lua_block { + local dogs = ngx.shared.dogs + dogs:set("foo", "hello, FOO") + } +--- config + location /lua { + content_by_lua_block { + local dogs = ngx.shared.dogs + local foo = dogs:get("foo") + ngx.say(foo) + } + } +--- request +GET /lua +--- response_body +hello, FOO +--- no_error_log +[error] + + + +=== TEST 5: error in init after HUP, not reloaded but foo have changed. +--- http_config + lua_shared_dict dogs 1m; + + init_by_lua_block { + local dogs = ngx.shared.dogs + dogs:set("foo", "foo have changed") + + error("failed to init") + } +--- config + location /lua { + content_by_lua_block { + ngx.say("HUP reload failed") + } + } +--- request +GET /lua +--- response_body +foo have changed +--- error_log +failed to init +--- reload_fails + + + +=== TEST 6: no error in init again, reload success and foo still have changed. +--- http_config + lua_shared_dict dogs 1m; + + init_by_lua_block { + -- do nothing + } +--- config + location /lua { + content_by_lua_block { + local dogs = ngx.shared.dogs + local foo = dogs:get("foo") + ngx.say(foo) + ngx.say("reload success") + } + } +--- request +GET /lua +--- response_body +foo have changed +reload success +--- no_error_log +[error] diff --git a/debian/modules/nginx-lua/t/152-timer-every.t b/debian/modules/nginx-lua/t/152-timer-every.t new file mode 100644 index 0000000..c8d62e7 --- /dev/null +++ b/debian/modules/nginx-lua/t/152-timer-every.t @@ -0,0 +1,385 @@ +# vim:set ft= ts=4 sw=4 et fdm=marker: +use Test::Nginx::Socket::Lua; + +#worker_connections(1014); +#master_on(); +#workers(2); +#log_level('warn'); + +repeat_each(2); + +plan tests => repeat_each() * (blocks() * 7 + 2); + +#no_diff(); +no_long_string(); + +our $HtmlDir = html_dir; + +$ENV{TEST_NGINX_MEMCACHED_PORT} ||= 11211; +$ENV{TEST_NGINX_HTML_DIR} = $HtmlDir; + +worker_connections(1024); +run_tests(); + +__DATA__ + +=== TEST 1: simple very +--- config + location /t { + content_by_lua_block { + local begin = ngx.now() + local function f(premature) + print("elapsed: ", ngx.now() - begin) + print("timer prematurely expired: ", premature) + end + + local ok, err = ngx.timer.every(0.05, f) + if not ok then + ngx.say("failed to set timer: ", err) + return + end + + ngx.say("registered timer") + } + } +--- request +GET /t +--- response_body +registered timer +--- wait: 0.11 +--- no_error_log +[error] +[alert] +[crit] +timer prematurely expired: true +--- error_log eval +[ +qr/\[lua\] content_by_lua\(nginx\.conf:\d+\):\d+: elapsed: 0\.0(?:4[4-9]|5[0-6])\d*, context: ngx\.timer, client: \d+\.\d+\.\d+\.\d+, server: 0\.0\.0\.0:\d+/, +qr/\[lua\] content_by_lua\(nginx\.conf:\d+\):\d+: elapsed: 0\.(?:09|10)\d*, context: ngx\.timer, client: \d+\.\d+\.\d+\.\d+, server: 0\.0\.0\.0:\d+/, +"lua ngx.timer expired", +"http lua close fake http connection", +"timer prematurely expired: false", +] + + + +=== TEST 2: separated global env +--- config + location /t { + content_by_lua_block { + local begin = ngx.now() + local function f() + foo = 3 + print("foo in timer: ", foo) + end + local ok, err = ngx.timer.every(0.05, f) + if not ok then + ngx.say("failed to set timer: ", err) + return + end + ngx.sleep(0.11) + ngx.say("foo = ", foo) + } + } +--- request +GET /t +--- response_body +foo = nil +--- wait: 0.12 +--- no_error_log +[error] +[alert] +[crit] +--- error_log eval +[ +qr/\[lua\] content_by_lua\(nginx\.conf:\d+\):\d+: foo in timer: 3/, +"lua ngx.timer expired", +"http lua close fake http connection" +] + + + +=== TEST 3: lua variable sharing via upvalue +--- config + location /t { + content_by_lua_block { + local begin = ngx.now() + local foo = 0 + local function f() + foo = foo + 3 + print("foo in timer: ", foo) + end + local ok, err = ngx.timer.every(0.05, f) + if not ok then + ngx.say("failed to set timer: ", err) + return + end + ngx.say("registered timer") + ngx.sleep(0.11) + ngx.say("foo = ", foo) + } + } +--- request +GET /t +--- response_body +registered timer +foo = 6 +--- wait: 0.12 +--- no_error_log +[error] +[alert] +[crit] +--- error_log eval +[ +qr/\[lua\] content_by_lua\(nginx\.conf:\d+\):\d+: foo in timer: 3/, +qr/\[lua\] content_by_lua\(nginx\.conf:\d+\):\d+: foo in timer: 6/, +"lua ngx.timer expired", +"http lua close fake http connection" +] + + + +=== TEST 4: create the next timer immediately when timer start running +--- config + location /t { + content_by_lua_block { + local begin = ngx.now() + local foo = 0 + local function f() + foo = foo + 3 + print("foo in timer: ", foo) + + ngx.sleep(0.1) + end + local ok, err = ngx.timer.every(0.05, f) + if not ok then + ngx.say("failed to set timer: ", err) + return + end + ngx.say("registered timer") + ngx.sleep(0.11) + ngx.say("foo = ", foo) + } + } +--- request +GET /t +--- response_body +registered timer +foo = 6 +--- wait: 0.12 +--- no_error_log +[error] +[alert] +[crit] +--- error_log eval +[ +qr/\[lua\] content_by_lua\(nginx\.conf:\d+\):\d+: foo in timer: 3/, +qr/\[lua\] content_by_lua\(nginx\.conf:\d+\):\d+: foo in timer: 6/, +"lua ngx.timer expired", +"http lua close fake http connection" +] + + + +=== TEST 5: callback args +--- config + location /t { + content_by_lua_block { + local n = 0 + + local function f(premature, a, b, c) + n = n + 1 + print("the ", n, " time, args: ", a, ", ", b, ", ", c) + + a, b, c = 0, 0, 0 + end + + local ok, err = ngx.timer.every(0.05, f, 1, 2) + if not ok then + ngx.say("failed to set timer: ", err) + return + end + + ngx.say("registered timer") + ngx.sleep(0.11) + } + } +--- request +GET /t +--- response_body +registered timer +--- wait: 0.12 +--- no_error_log +[error] +[alert] +[crit] +--- error_log eval +[ +"the 1 time, args: 1, 2, nil", +"the 2 time, args: 1, 2, nil", +"lua ngx.timer expired", +"http lua close fake http connection" +] + + + +=== TEST 6: memory leak check +--- config + location /t { + content_by_lua_block { + local function f() + local a = 1 + -- do nothing + end + + for i = 1, 100 do + local ok, err = ngx.timer.every(0.1, f) + if not ok then + ngx.say("failed to set timer: ", err) + return + end + end + + ngx.say("registered timer") + + collectgarbage("collect") + local start = collectgarbage("count") + + ngx.sleep(0.21) + + collectgarbage("collect") + local growth1 = collectgarbage("count") - start + + ngx.sleep(0.51) + + collectgarbage("collect") + local growth2 = collectgarbage("count") - start + + ngx.say("growth1 == growth2: ", growth1 == growth2) + } + } +--- request +GET /t +--- response_body +registered timer +growth1 == growth2: true +--- no_error_log +[error] +[alert] +[crit] +--- timeout: 8 + + + +=== TEST 7: respect lua_max_pending_timers +--- http_config + lua_max_pending_timers 10; +--- config + location /t { + content_by_lua_block { + local function f() + local a = 1 + -- do nothing + end + + for i = 1, 11 do + local ok, err = ngx.timer.every(0.1, f) + if not ok then + ngx.say("failed to set timer: ", err) + return + end + end + + ngx.say("registered 10 timers") + } + } +--- request +GET /t +--- response_body +failed to set timer: too many pending timers +--- no_error_log +[error] +[alert] +[crit] + + + +=== TEST 8: respect lua_max_running_timers +--- http_config + lua_max_pending_timers 100; + lua_max_running_timers 9; +--- config + location /t { + content_by_lua_block { + local function f() + local a = 1 + ngx.sleep(0.02) + -- do nothing + end + + for i = 1, 10 do + local ok, err = ngx.timer.every(0.01, f) + if not ok then + ngx.say("failed to set timer: ", err) + return + end + end + + ngx.say("registered 10 timers") + + ngx.sleep(0.03) + } + } +--- request +GET /t +--- response_body +registered 10 timers +--- no_error_log +[error] +[crit] +--- error_log +lua_max_running_timers are not enough + + + +=== TEST 9: lua_code_cache off +FIXME: it is know that this test case leaks memory. +so we skip it in the "check leak" testing mode. +--- http_config + lua_code_cache off; +--- config + location /t { + content_by_lua_block { + local function f() + local a = 1 + -- do nothing + end + + local ok, err = ngx.timer.every(0.01, f) + if not ok then + ngx.say("failed to set timer: ", err) + return + end + + collectgarbage("collect") + ngx.say("registered timer") + + ngx.sleep(0.03) + + collectgarbage("collect") + + ngx.sleep(0.03) + + collectgarbage("collect") + ngx.say("ok") + } + } +--- request +GET /t +--- response_body +registered timer +ok +--- no_error_log +[error] +[crit] +--- no_check_leak diff --git a/debian/modules/nginx-lua/t/153-semaphore-hup.t b/debian/modules/nginx-lua/t/153-semaphore-hup.t new file mode 100644 index 0000000..c85a21d --- /dev/null +++ b/debian/modules/nginx-lua/t/153-semaphore-hup.t @@ -0,0 +1,154 @@ +# vim:set ft= ts=4 sw=4 et fdm=marker: +use lib 'lib'; +use Test::Nginx::Socket::Lua; + +#worker_connections(10140); +#workers(1); +log_level('warn'); +master_process_enabled(1); +repeat_each(1); + +plan tests => repeat_each() * (blocks() * 3); + +no_long_string(); +#no_diff(); + +add_block_preprocessor(sub { + my $block = shift; + + my $http_config = $block->http_config || ''; + $http_config .= <<'_EOC_'; + lua_package_path "../lua-resty-core/lib/?.lua;../lua-resty-lrucache/lib/?.lua;;"; + lua_shared_dict shdict 4m; + + init_by_lua_block { + require "resty.core" + local process = require "ngx.process" + local ok, err = process.enable_privileged_agent() + if not ok then + ngx.log(ngx.ERR, "failed to enable_privileged_agent: ", err) + end + } + + init_worker_by_lua_block { + local function test(pre) + if pre then + return + end + + local semaphore = require "ngx.semaphore" + local sem = semaphore.new() + + ngx.log(ngx.ERR, "created semaphore object") + + local function sem_wait() + + local ok, err = sem:wait(100) + if not ok then + ngx.log(ngx.ERR, "err: ", err) + else + ngx.log(ngx.ERR, "wait success") + end + end + + while not ngx.worker.exiting() do + local co = ngx.thread.spawn(sem_wait) + ngx.thread.wait(co) + end + end + + local ok, err = ngx.timer.at(0, test) + if not ok then + ngx.log(ngx.ERR, "failed to create semaphore timer err: ", err) + end + + local function reload(pre) + if pre then + return + end + + shdict = ngx.shared.shdict + local success = shdict:add("reloaded", 1) + if not success then + return + end + + ngx.log(ngx.ERR, "try to reload nginx") + + local f, err = io.open(ngx.config.prefix() .. "/logs/nginx.pid", "r") + if not f then + ngx.say("failed to open nginx.pid: ", err) + return + end + + local pid = f:read() + + f:close() + os.execute("kill -HUP " .. pid) + end + + local typ = require "ngx.process".type + if typ() == "privileged agent" then + local ok, err = ngx.timer.at(0.1, reload) + if not ok then + ngx.log(ngx.ERR, "failed to create semaphore timer err: ", err) + end + end + } +_EOC_ + $block->set_value("http_config", $http_config); +}); + +run_tests(); + +__DATA__ + +=== TEST 1: timer + reload +--- config + location /test { + content_by_lua_block { + ngx.sleep(1) + ngx.say("hello") + } + } +--- request +GET /test +--- response_body +hello +--- grep_error_log eval: qr/created semaphore object|try to reload nginx|semaphore gc wait queue is not empty/ +--- grep_error_log_out +created semaphore object +created semaphore object +try to reload nginx +created semaphore object +created semaphore object +--- skip_nginx: 3: < 1.11.2 +--- no_check_leak +--- wait: 0.2 + + + +=== TEST 2: timer + reload (lua code cache off) +--- http_config + lua_code_cache off; +--- config + location /test { + content_by_lua_block { + ngx.sleep(1) + ngx.say("hello") + } + } +--- request +GET /test +--- response_body +hello +--- grep_error_log eval: qr/created semaphore object|try to reload nginx|semaphore gc wait queue is not empty/ +--- grep_error_log_out +created semaphore object +created semaphore object +try to reload nginx +created semaphore object +created semaphore object +--- skip_nginx: 3: < 1.11.2 +--- no_check_leak +--- wait: 0.2 diff --git a/debian/modules/nginx-lua/t/154-semaphore.t b/debian/modules/nginx-lua/t/154-semaphore.t new file mode 100644 index 0000000..3c1f004 --- /dev/null +++ b/debian/modules/nginx-lua/t/154-semaphore.t @@ -0,0 +1,118 @@ +# vim:set ft= ts=4 sw=4 et fdm=marker: +use lib 'lib'; +use Test::Nginx::Socket::Lua; + +#worker_connections(10140); +#workers(1); +#log_level('warn'); + +repeat_each(2); + +plan tests => repeat_each() * (blocks() * 3) + blocks(); + +no_long_string(); +#no_diff(); + +add_block_preprocessor(sub { + my $block = shift; + + my $http_config = $block->http_config || ''; + $http_config .= <<'_EOC_'; + lua_package_path "../lua-resty-core/lib/?.lua;../lua-resty-lrucache/lib/?.lua;;"; + + init_by_lua_block { + require "resty.core" + } +_EOC_ + $block->set_value("http_config", $http_config); +}); + +run_tests(); + +__DATA__ + +=== TEST 1: timer + shutdown error log +--- config + location /test { + content_by_lua_block { + local function test(pre) + + local semaphore = require "ngx.semaphore" + local sem = semaphore.new() + + local function sem_wait() + + local ok, err = sem:wait(10) + if not ok then + ngx.log(ngx.ERR, "err: ", err) + else + ngx.log(ngx.ERR, "wait success") + end + end + + while not ngx.worker.exiting() do + local co = ngx.thread.spawn(sem_wait) + ngx.thread.wait(co) + end + end + + local ok, err = ngx.timer.at(0, test) + ngx.log(ngx.ERR, "hello, world") + ngx.say("time: ", ok) + } + } +--- request +GET /test +--- response_body +time: 1 +--- grep_error_log eval: qr/hello, world|semaphore gc wait queue is not empty/ +--- grep_error_log_out +hello, world +--- shutdown_error_log +--- no_shutdown_error_log +semaphore gc wait queue is not empty + + + +=== TEST 2: timer + shutdown error log (lua code cache off) +--- http_config + lua_code_cache off; +--- config + location /test { + content_by_lua_block { + local function test(pre) + + local semaphore = require "ngx.semaphore" + local sem = semaphore.new() + + local function sem_wait() + + local ok, err = sem:wait(10) + if not ok then + ngx.log(ngx.ERR, "err: ", err) + else + ngx.log(ngx.ERR, "wait success") + end + end + + while not ngx.worker.exiting() do + local co = ngx.thread.spawn(sem_wait) + ngx.thread.wait(co) + end + end + + local ok, err = ngx.timer.at(0, test) + ngx.log(ngx.ERR, "hello, world") + ngx.say("time: ", ok) + } + } +--- request +GET /test +--- response_body +time: 1 +--- grep_error_log eval: qr/hello, world|semaphore gc wait queue is not empty/ +--- grep_error_log_out +hello, world +--- shutdown_error_log +--- no_shutdown_error_log +semaphore gc wait queue is not empty diff --git a/debian/modules/nginx-lua/t/cert/comodo-ca.crt b/debian/modules/nginx-lua/t/cert/comodo-ca.crt new file mode 100644 index 0000000..444461b --- /dev/null +++ b/debian/modules/nginx-lua/t/cert/comodo-ca.crt @@ -0,0 +1,29 @@ +-----BEGIN CERTIFICATE----- +MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCBhTELMAkGA1UE +BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG +A1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlv +biBBdXRob3JpdHkwHhcNMTAwMTE5MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMC +R0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UE +ChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCR6FSS0gpWsawNJN3Fz0Rn +dJkrN6N9I3AAcbxT38T6KhKPS38QVr2fcHK3YX/JSw8Xpz3jsARh7v8Rl8f0hj4K+j5c+ZPmNHrZ +FGvnnLOFoIJ6dq9xkNfs/Q36nGz637CC9BR++b7Epi9Pf5l/tfxnQ3K9DADWietrLNPtj5gcFKt+ +5eNu/Nio5JIk2kNrYrhV/erBvGy2i/MOjZrkm2xpmfh4SDBF1a3hDTxFYPwyllEnvGfDyi62a+pG +x8cgoLEfZd5ICLqkTqnyg0Y3hOvozIFIQ2dOciqbXL1MGyiKXCJ7tKuY2e7gUYPDCUZObT6Z+pUX +2nwzV0E8jVHtC7ZcryxjGt9XyD+86V3Em69FmeKjWiS0uqlWPc9vqv9JWL7wqP/0uK3pN/u6uPQL +OvnoQ0IeidiEyxPx2bvhiWC4jChWrBQdnArncevPDt09qZahSL0896+1DSJMwBGB7FY79tOi4lu3 +sgQiUpWAk2nojkxl8ZEDLXB0AuqLZxUpaVICu9ffUGpVRr+goyhhf3DQw6KqLCGqR84onAZFdr+C +GCe01a60y1Dma/RMhnEw6abfFobg2P9A3fvQQoh/ozM6LlweQRGBY84YcWsr7KaKtzFcOmpH4MN5 +WdYgGq/yapiqcrxXStJLnbsQ/LBMQeXtHT1eKJ2czL+zUdqnR+WEUwIDAQABo0IwQDAdBgNVHQ4E +FgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8w +DQYJKoZIhvcNAQEMBQADggIBAArx1UaEt65Ru2yyTUEUAJNMnMvlwFTPoCWOAvn9sKIN9SCYPBMt +rFaisNZ+EZLpLrqeLppysb0ZRGxhNaKatBYSaVqM4dc+pBroLwP0rmEdEBsqpIt6xf4FpuHA1sj+ +nq6PK7o9mfjYcwlYRm6mnPTXJ9OV2jeDchzTc+CiR5kDOF3VSXkAKRzH7JsgHAckaVd4sjn8OoSg +tZx8jb8uk2IntznaFxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwW +sRqZCuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiKboHGhfKp +pC3n9KUkEEeDys30jXlYsQab5xoq2Z0B15R97QNKyvDb6KkBPvVWmckejkk9u+UJueBPSZI9FoJA +zMxZxuY67RIuaTxslbH9qh17f4a+Hg4yRvv7E491f0yLS0Zj/gA0QHDBw7mh3aZw4gSzQbzpgJHq +ZJx64SIDqZxubw5lT2yHh17zbqD5daWbQOhTsiedSrnAdyGN/4fy3ryM7xfft0kL0fJuMAsaDk52 +7RH89elWsn2/x20Kk4yl0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7I +LaZRfyHBNVOFBkpdn627G190 +-----END CERTIFICATE----- diff --git a/debian/modules/nginx-lua/t/cert/startcom.crt b/debian/modules/nginx-lua/t/cert/startcom.crt deleted file mode 100644 index a5185ca..0000000 --- a/debian/modules/nginx-lua/t/cert/startcom.crt +++ /dev/null @@ -1,87 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIHhzCCBW+gAwIBAgIBLTANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQGEwJJTDEW -MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg -Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh -dGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0NjM3WhcNMzYwOTE3MTk0NjM2WjB9 -MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi -U2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3Rh -cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA -A4ICDwAwggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZk -pMyONvg45iPwbm2xPN1yo4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rf -OQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/C -Ji/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/deMotHweXMAEtcnn6RtYT -Kqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt2PZE4XNi -HzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMM -Av+Z6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w -+2OqqGwaVLRcJXrJosmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+ -Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3 -Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVcUjyJthkqcwEKDwOzEmDyei+B -26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT37uMdBNSSwID -AQABo4ICEDCCAgwwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD -VR0OBBYEFE4L7xqkQFulF2mHMMo0aEPQQa7yMB8GA1UdIwQYMBaAFE4L7xqkQFul -F2mHMMo0aEPQQa7yMIIBWgYDVR0gBIIBUTCCAU0wggFJBgsrBgEEAYG1NwEBATCC -ATgwLgYIKwYBBQUHAgEWImh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL3BvbGljeS5w -ZGYwNAYIKwYBBQUHAgEWKGh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL2ludGVybWVk -aWF0ZS5wZGYwgc8GCCsGAQUFBwICMIHCMCcWIFN0YXJ0IENvbW1lcmNpYWwgKFN0 -YXJ0Q29tKSBMdGQuMAMCAQEagZZMaW1pdGVkIExpYWJpbGl0eSwgcmVhZCB0aGUg -c2VjdGlvbiAqTGVnYWwgTGltaXRhdGlvbnMqIG9mIHRoZSBTdGFydENvbSBDZXJ0 -aWZpY2F0aW9uIEF1dGhvcml0eSBQb2xpY3kgYXZhaWxhYmxlIGF0IGh0dHA6Ly93 -d3cuc3RhcnRzc2wuY29tL3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgG -CWCGSAGG+EIBDQQrFilTdGFydENvbSBGcmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1 -dGhvcml0eTANBgkqhkiG9w0BAQsFAAOCAgEAjo/n3JR5fPGFf59Jb2vKXfuM/gTF -wWLRfUKKvFO3lANmMD+x5wqnUCBVJX92ehQN6wQOQOY+2IirByeDqXWmN3PH/UvS -Ta0XQMhGvjt/UfzDtgUx3M2FIk5xt/JxXrAaxrqTi3iSSoX4eA+D/i+tLPfkpLst -0OcNOrg+zvZ49q5HJMqjNTbOx8aHmNrs++myziebiMMEofYLWWivydsQD032ZGNc -pRJvkrKTlMeIFw6Ttn5ii5B/q06f/ON1FE8qMt9bDeD1e5MNq6HPh+GlBEXoPBKl -CcWw0bdT82AUuoVpaiF8H3VhFyAXe2w7QSlc4axa0c2Mm+tgHRns9+Ww2vl5GKVF -P0lDV9LdJNUso/2RjSe15esUBppMeyG7Oq0wBhjA2MFrLH9ZXF2RsXAiV+uKa0hK -1Q8p7MZAwC+ITGgBF3f0JBlPvfrhsiAhS90a2Cl9qrjeVOwhVYBsHvUwyKMQ5bLm -KhQxw4UtjJixhlpPiVktucf3HMiKf8CdBUrmQk9io20ppB+Fq9vlgcitKj1MXVuE -JnHEhV5xJMqlG2zYYdMa4FTbzrqpMrUi9nNBCV24F10OD5mQ1kfabwo6YigUZ4LZ -8dCAWZvLMdibD4x3TrVoivJs9iQOLWxwxXPR3hTQcY+203sC9uO41Alua551hDnm -fyWl8kgAwKQB2j8= ------END CERTIFICATE----- ------BEGIN CERTIFICATE----- -MIIHyTCCBbGgAwIBAgIBATANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEW -MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg -Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh -dGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0NjM2WhcNMzYwOTE3MTk0NjM2WjB9 -MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi -U2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3Rh -cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA -A4ICDwAwggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZk -pMyONvg45iPwbm2xPN1yo4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rf -OQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/C -Ji/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/deMotHweXMAEtcnn6RtYT -Kqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt2PZE4XNi -HzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMM -Av+Z6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w -+2OqqGwaVLRcJXrJosmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+ -Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3 -Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVcUjyJthkqcwEKDwOzEmDyei+B -26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT37uMdBNSSwID -AQABo4ICUjCCAk4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAa4wHQYDVR0OBBYE -FE4L7xqkQFulF2mHMMo0aEPQQa7yMGQGA1UdHwRdMFswLKAqoCiGJmh0dHA6Ly9j -ZXJ0LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMCugKaAnhiVodHRwOi8vY3Js -LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMIIBXQYDVR0gBIIBVDCCAVAwggFM -BgsrBgEEAYG1NwEBATCCATswLwYIKwYBBQUHAgEWI2h0dHA6Ly9jZXJ0LnN0YXJ0 -Y29tLm9yZy9wb2xpY3kucGRmMDUGCCsGAQUFBwIBFilodHRwOi8vY2VydC5zdGFy -dGNvbS5vcmcvaW50ZXJtZWRpYXRlLnBkZjCB0AYIKwYBBQUHAgIwgcMwJxYgU3Rh -cnQgQ29tbWVyY2lhbCAoU3RhcnRDb20pIEx0ZC4wAwIBARqBl0xpbWl0ZWQgTGlh -YmlsaXR5LCByZWFkIHRoZSBzZWN0aW9uICpMZWdhbCBMaW1pdGF0aW9ucyogb2Yg -dGhlIFN0YXJ0Q29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFBvbGljeSBhdmFp -bGFibGUgYXQgaHR0cDovL2NlcnQuc3RhcnRjb20ub3JnL3BvbGljeS5wZGYwEQYJ -YIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilTdGFydENvbSBGcmVlIFNT -TCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQUFAAOCAgEAFmyZ -9GYMNPXQhV59CuzaEE44HF7fpiUFS5Eyweg78T3dRAlbB0mKKctmArexmvclmAk8 -jhvh3TaHK0u7aNM5Zj2gJsfyOZEdUauCe37Vzlrk4gNXcGmXCPleWKYK34wGmkUW -FjgKXlf2Ysd6AgXmvB618p70qSmD+LIU424oh0TDkBreOKk8rENNZEXO3SipXPJz -ewT4F+irsfMuXGRuczE6Eri8sxHkfY+BUZo7jYn0TZNmezwD7dOaHZrzZVD1oNB1 -ny+v8OqCQ5j4aZyJecRDjkZy42Q2Eq/3JR44iZB3fsNrarnDy0RLrHiQi+fHLB5L -EUTINFInzQpdn4XBidUaePKVEFMy3YCEZnXZtWgo+2EuvoSoOMCZEoalHmdkrQYu -L6lwhceWD3yJZfWOQ1QOq92lgDmUYMA0yZZwLKMS9R9Ie70cfmu3nZD0Ijuu+Pwq -yvqCUqDvr0tVk+vBtfAii6w0TiYiBKGHLHVKt+V9E9e4DGTANtLJL4YSjCMJwRuC -O3NJo2pXh5Tl1njFmUNj403gdy3hZZlyaQQaRwnmDwFWJPsfvw55qVguucQJAX6V -um0ABj6y6koQOdjQK/W/7HW/lwLFCRsI3FU34oH7N4RDYiDK51ZLZer+bMEkkySh -NOsF/5oirpt9P/FlUQqmMGqz9IgcgA38corog14= ------END CERTIFICATE----- diff --git a/debian/modules/nginx-lua/t/data/fake-delayed-load-module/config b/debian/modules/nginx-lua/t/data/fake-delayed-load-module/config new file mode 100644 index 0000000..a5fa6fb --- /dev/null +++ b/debian/modules/nginx-lua/t/data/fake-delayed-load-module/config @@ -0,0 +1,3 @@ +ngx_addon_name="ngx_http_lua_fake_delayed_load_module" +HTTP_AUX_FILTER_MODULES="$HTTP_AUX_FILTER_MODULES ngx_http_lua_fake_delayed_load_module" +NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_lua_fake_delayed_load_module.c" diff --git a/debian/modules/nginx-lua/t/data/fake-delayed-load-module/ngx_http_lua_fake_delayed_load_module.c b/debian/modules/nginx-lua/t/data/fake-delayed-load-module/ngx_http_lua_fake_delayed_load_module.c new file mode 100644 index 0000000..2898255 --- /dev/null +++ b/debian/modules/nginx-lua/t/data/fake-delayed-load-module/ngx_http_lua_fake_delayed_load_module.c @@ -0,0 +1,77 @@ +/* + * This fake_delayed_load delayed load module was used to reproduce + * a bug in ngx_lua's function ngx_http_lua_add_package_preload. + */ + + +#include +#include +#include +#include + + +#include "ngx_http_lua_api.h" + + +static ngx_int_t ngx_http_lua_fake_delayed_load_init(ngx_conf_t *cf); +static int ngx_http_lua_fake_delayed_load_preload(lua_State *L); +static int ngx_http_lua_fake_delayed_load_function(lua_State * L); + + +static ngx_http_module_t ngx_http_lua_fake_delayed_load_module_ctx = { + NULL, /* preconfiguration */ + ngx_http_lua_fake_delayed_load_init, /* postconfiguration */ + + NULL, /* create main configuration */ + NULL, /* init main configuration */ + + NULL, /* create server configuration */ + NULL, /* merge server configuration */ + + NULL, /* create location configuration */ + NULL, /* merge location configuration */ +}; + +/* flow identify module struct */ +ngx_module_t ngx_http_lua_fake_delayed_load_module = { + NGX_MODULE_V1, + &ngx_http_lua_fake_delayed_load_module_ctx, /* module context */ + NULL, /* module directives */ + NGX_HTTP_MODULE, /* module type */ + NULL, /* init master */ + NULL, /* init module */ + NULL, /* init process */ + NULL, /* init thread */ + NULL, /* exit thread */ + NULL, /* exit process */ + NULL, /* exit master */ + NGX_MODULE_V1_PADDING +}; + + +static ngx_int_t +ngx_http_lua_fake_delayed_load_init(ngx_conf_t *cf) +{ + ngx_http_lua_add_package_preload(cf, "ngx.delayed_load", + ngx_http_lua_fake_delayed_load_preload); + return NGX_OK; +} + + +static int +ngx_http_lua_fake_delayed_load_preload(lua_State *L) +{ + lua_createtable(L, 0, 1); + + lua_pushcfunction(L, ngx_http_lua_fake_delayed_load_function); + lua_setfield(L, -2, "get_function"); + + return 1; +} + + +static int +ngx_http_lua_fake_delayed_load_function(lua_State * L) +{ + return 0; +} diff --git a/debian/modules/nginx-lua/t/data/fake-module/ngx_http_fake_module.c b/debian/modules/nginx-lua/t/data/fake-module/ngx_http_fake_module.c index 42cde55..650f4f7 100644 --- a/debian/modules/nginx-lua/t/data/fake-module/ngx_http_fake_module.c +++ b/debian/modules/nginx-lua/t/data/fake-module/ngx_http_fake_module.c @@ -1,5 +1,4 @@ -/* Copyright (C) ZHANG Heng (chiyouhen) - * +/* * This fake module was used to reproduce a bug in ngx_lua's * init_worker_by_lua implementation. */ diff --git a/debian/modules/nginx-lua/util/build.sh b/debian/modules/nginx-lua/util/build.sh index 7887fe9..e45c00a 100755 --- a/debian/modules/nginx-lua/util/build.sh +++ b/debian/modules/nginx-lua/util/build.sh @@ -52,6 +52,7 @@ time ngx-build $force $version \ --add-module=$root/../redis2-nginx-module \ --add-module=$root/t/data/fake-module \ --add-module=$root/t/data/fake-shm-module \ + --add-module=$root/t/data/fake-delayed-load-module \ --with-http_gunzip_module \ --with-http_dav_module \ --with-select_module \ diff --git a/debian/modules/nginx-lua/util/gdbinit b/debian/modules/nginx-lua/util/gdbinit deleted file mode 100644 index 1508c64..0000000 --- a/debian/modules/nginx-lua/util/gdbinit +++ /dev/null @@ -1,415 +0,0 @@ -# This gdb script provides several useful routines for debugging ngx_lua or -# standalone Lua/LuaJIT. -# -# You need gdb >= v7.3 to make this script working correctly. -# -# Installation: place it at $HOME/.gdbinit -# -# -- chaoslawful gmail com - -#### Lua type defines #### - -set $__LUA_TNONE = -1 -set $__LUA_TNIL = 0 -set $__LUA_TBOOLEAN = 1 -set $__LUA_TLIGHTUSERDATA = 2 -set $__LUA_TNUMBER = 3 -set $__LUA_TSTRING = 4 -set $__LUA_TTABLE = 5 -set $__LUA_TFUNCTION = 6 -set $__LUA_TUSERDATA = 7 -set $__LUA_TTHREAD = 8 - -#### Lua constants #### - -set $__LUA_GLOBALSINDEX = -10002 -set $__LUA_ENVIRONINDEX = -10001 -set $__LUA_REGISTRYINDEX = -10000 - -#### Auxiliary methods #### - -define __lua_debug_instance - if !$__lua_debug_instance - set $__lua_debug_instance = (lua_Debug*)malloc(sizeof(lua_Debug)) - end -end - -define __free_lua_debug_instance - if $__lua_debug_instance - set $rc = free($__lua_debug_instance) - set $__lua_debug_instance = 0 - end -end - -set $__BUCKET_SIZE = 16 -define __set_instance - if !$__set_instance - set $__set_instance = (void*(*(*))[2])malloc($__BUCKET_SIZE*sizeof(void*(*)[2])) - set $rc = memset($__set_instance, 0, $__BUCKET_SIZE*sizeof(void*(*)[2])) - end -end - -define __free_set_instance - if $__set_instance - __set_clean - set $rc = free($__set_instance) - set $__set_instance = 0 - end -end - -define __set_add - set $p = (void*)$arg0 - set $__bkt_idx = (int)$p%$__BUCKET_SIZE - - __set_instance - set $__elem = (void*(*)[2])$__set_instance[$__bkt_idx] - set $__found = 0 - while $__elem - if (*$__elem)[0] == $p - set $__found = 1 - loop_break - end - set $__elem = (void*(*)[2])(*$__elem)[1] - end - if $__found - set $existed_in_set = 1 - else - set $existed_in_set = 0 - - set $rc = (void*(*)[2])calloc(1, sizeof(void*)*2) - set (*$rc)[0] = $p - set (*$rc)[1] = $__set_instance[$__bkt_idx] - set $__set_instance[$__bkt_idx] = $rc - end -end - -define __set_is_exist - set $p = (void*)$arg0 - set $__bkt_idx = (int)$p%$__BUCKET_SIZE - - __set_instance - set $__elem = (void*(*)[2])$__set_instance[$__bkt_idx] - set $__found = 0 - while $__elem - if (*$__elem)[0] == $p - set $__found = 1 - loop_break - end - set $__elem = (void*(*)[2])(*$__elem)[1] - end - if $__found - set $existed_in_set = 1 - else - set $existed_in_set = 0 - end -end - -define __set_clean - __set_instance - - set $__bkt_idx = 0 - while $__bkt_idx < $__BUCKET_SIZE - set $__elem = (void*(*)[2])$__set_instance[$__bkt_idx] - while $__elem - set $__next = (void*(*)[2])(*$__elem)[1] - set $rc = free($__elem) - set $__elem = $__next - end - set $__set_instance[$__bkt_idx] = 0 - set $__bkt_idx = $__bkt_idx+1 - end -end - -define hook-quit - __free_lua_debug_instance - __free_set_instance -end - -define hook-detach - __free_lua_debug_instance - __free_set_instance -end - -define hook-disconnect - __free_lua_debug_instance - __free_set_instance -end - -define _lua_pop - set $l = (lua_State*)$arg0 - set $_n = (int)$arg1 - set $_rc = lua_settop($l, -$_n-1) -end - -define _lua_dump_locals - set $l = (lua_State*)$arg0 - set $dbg = (lua_Debug*)$arg1 - set $idx = 1 - - set $rc = lua_getlocal($l, $dbg, $idx) - if $rc - printf "\t----[[ Locals ]]----\n" - while $rc - printf "\t%d:\t'%s' = ", $idx, $rc - __lua_dump_stack $l -1 - printf "\n" - - _lua_pop $l 1 - set $idx = $idx + 1 - set $rc = lua_getlocal($l, $dbg, $idx) - end - else - printf "\tNo locals!\n" - end - printf "\n" -end - -define _lua_dump_upvalues - set $l = (lua_State*)$arg0 - set $dbg = (lua_Debug*)$arg1 - set $idx = 1 - - set $rc = lua_getinfo($l, "f", $dbg) - if $rc - set $rc = lua_getupvalue($l, -1, $idx) - if $rc - printf "\t----[[ Upvalues ]]----\n" - while $rc - printf "\t%d:\t'%s' = ", $idx, $rc - __lua_dump_stack $l -1 - printf "\n" - - _lua_pop $l 1 - set $idx = $idx + 1 - set $rc = lua_getupvalue($l, -1, $idx) - end - else - printf "\tNo upvalues!\n" - end - _lua_pop $l 1 - else - printf "\tFailed to get function closure!\n" - end - printf "\n" -end - -define __lua_dump_stack - __set_clean - __lua_dump_stack_aux $arg0 $arg1 0 -end - -define __lua_dump_stack_aux - set $l = (lua_State*)$arg0 - set $nidx_$arg2 = (int)$arg1 - set $cidx_$arg2 = (int)$arg2+1 - - # relative stack index to absolute index - if $nidx_$arg2 < 0 && $nidx_$arg2 > $__LUA_REGISTRYINDEX - set $nidx_$arg2 = $nidx_$arg2 + (int)lua_gettop($l) + 1 - end - - set $vt_$arg2 = (int)lua_type($l, $nidx_$arg2) - - if $vt_$arg2 == $__LUA_TNONE - echo - end - if $vt_$arg2 == $__LUA_TNIL - echo (nil) - end - if $vt_$arg2 == $__LUA_TBOOLEAN - printf "(bool) %d", lua_toboolean($l, $nidx_$arg2) - end - if $vt_$arg2 == $__LUA_TLIGHTUSERDATA - printf "(ludata) %p", lua_touserdata($l, $nidx_$arg2) - end - if $vt_$arg2 == $__LUA_TNUMBER - printf "%g", lua_tonumber($l, $nidx_$arg2) - end - if $vt_$arg2 == $__LUA_TSTRING - set $tmplen = (size_t*)malloc(sizeof(size_t)) - set $tmp = lua_pushvalue($l, $nidx_$arg2) - set $tmp = lua_tolstring($l, -1, $tmplen) -#printf "(string:%d) ", *$tmplen - eval "output/r *(const char (*)[%d])$tmp", *$tmplen - _lua_pop $l 1 - set $tmp = free($tmplen) - end - if $vt_$arg2 == $__LUA_TTABLE - set $rc = lua_topointer($l, $nidx_$arg2) -#printf "(table) %p { ", $rc - printf "{ " - __set_add $rc - if $existed_in_set - printf "... " - else - set $rc = lua_pushnil($l) - set $rc = lua_next($l, $nidx_$arg2) - while $rc != 0 - printf "[" - __lua_dump_stack_aux $l -2 $cidx_$arg2 - printf "]" - printf " = " - __lua_dump_stack_aux $l -1 $cidx_$arg2 - printf ", " - _lua_pop $l 1 - set $rc = lua_next($l, $nidx_$arg2) - end - end - printf "}" - end - if $vt_$arg2 == $__LUA_TFUNCTION - printf "(func) %p", lua_topointer($l, $nidx_$arg2) - end - if $vt_$arg2 == $__LUA_TUSERDATA - printf "(udata) %p", lua_topointer($l, $nidx_$arg2) - end - if $vt_$arg2 == $__LUA_TTHREAD - printf "(thread) %p", lua_topointer($l, $nidx_$arg2) - else - if $vt_$arg2 > $__LUA_TTHREAD || $vt_$arg2 < 0 - echo - end - end -end - -#### Command methods #### - -define lbt - if $argc < 1 - echo Please specify Lua state and/or dump flag!\n - else - set $l = (lua_State*)$arg0 - if $argc > 1 - set $dump_local = ($arg1&1)==1 - set $dump_upvalue = ($arg1&2)==2 - else - set $dump_local = 0 - set $dump_upvalue = 0 - end - - __lua_debug_instance - set $dbg = $__lua_debug_instance - - set $level = 0 - set $rc = lua_getstack($l, $level, $dbg) - while $rc > 0 - set $rc = lua_getinfo($l, "Sln", $dbg) - set $name = $dbg->name - if !$name - set $name = "???" - end - - printf "#%d\t%s\t[%s]\tat %s:%d\n", $level, $name, $dbg->what, $dbg->source, $dbg->currentline - - if $dump_local - _lua_dump_locals $l $dbg - end - if $dump_upvalue - _lua_dump_upvalues $l $dbg - end - - set $level = $level+1 - set $rc = lua_getstack($l, $level, $dbg) - end - end -end - -document lbt -lbt []: Dump the backtrace of the specified Lua state. is a mask value, whose bit 1/2 controls the dump of locals/upvalues at each stack frame correspondingly. So set to 1 dumps only locals; set to 2 dumps only upvalues; and set to 3 dumps both locals and upvalues. -end - -define ll - if $argc != 2 - echo Please specify Lua state and stack frame number (0-based)!\n - else - set $l = (lua_State*)$arg0 - set $level = (int)$arg1 - - __lua_debug_instance - set $dbg = $__lua_debug_instance - - set $rc = lua_getstack($l, $level, $dbg) - if $rc > 0 - _lua_dump_locals $l $dbg - else - echo Failed to get Lua stack frame!\n - end - end -end - -document ll -ll : Dump all local vars in the specified Lua stack frame (0-based). -end - -define lu - if $argc != 2 - echo Please specify Lua state and stack frame number (0-based)!\n - else - set $l = (lua_State*)$arg0 - set $level = (int)$arg1 - - __lua_debug_instance - set $dbg = $__lua_debug_instance - - set $rc = lua_getstack($l, $level, $dbg) - if $rc > 0 - _lua_dump_upvalues $l $dbg - else - echo Failed to get Lua stack frame!\n - end - end -end - -document lu -lu : Dump all upvalues in the specified Lua stack frame (0-based). -end - -define lg - if $argc != 1 - echo Please specify Lua state!\n - else - set $l = (lua_State*)$arg0 - __lua_dump_stack $l $__LUA_GLOBALSINDEX - printf "\n" - end -end - -document lg -lg : Dump all entries in Lua global table. -end - -define lr - if $argc != 1 - echo Please specify Lua state!\n - else - set $l = (lua_State*)$arg0 - __lua_dump_stack $l $__LUA_REGISTRYINDEX - printf "\n" - end -end - -document lr -lr : Dump all entries in Lua registry table. -end - -define ls - if $argc != 1 - echo Please specify Lua state!\n - else - set $l = (lua_State*)$arg0 - set $idx = lua_gettop($l) - while $idx >= 1 - printf "#%d ", $idx - __lua_dump_stack $l $idx - printf "\n" - set $idx = $idx - 1 - end - end -end - -document ls -ls : Dump all entries in call stack. -end - -# vi:ft=gdb ts=4 sw=4 - diff --git a/debian/modules/nginx-lua/util/reindex b/debian/modules/nginx-lua/util/reindex deleted file mode 100755 index bd54c9d..0000000 --- a/debian/modules/nginx-lua/util/reindex +++ /dev/null @@ -1,64 +0,0 @@ -#!/usr/bin/perl -#: reindex.pl -#: reindex .t files for Test::Base based test files -#: Copyright (c) 2006 Agent Zhang -#: 2006-04-27 2006-05-09 - -use strict; -use warnings; - -#use File::Copy; -use Getopt::Std; - -my %opts; -getopts('hb:', \%opts); -if ($opts{h} or ! @ARGV) { - die "Usage: reindex [-b 0] t/*.t\n"; -} - -my $init = $opts{b}; -$init = 1 if not defined $init; - -my @files = map glob, @ARGV; -for my $file (@files) { - next if -d $file or $file !~ /\.t_?$/; - reindex($file); -} - -sub reindex { - my $file = $_[0]; - open my $in, $file or - die "Can't open $file for reading: $!"; - my @lines; - my $counter = $init; - my $changed; - while (<$in>) { - s/\r$//; - my $num; - s/ ^ === \s+ TEST \s+ (\d+)/$num=$1; "=== TEST " . $counter++/xie; - next if !defined $num; - if ($num != $counter-1) { - $changed++; - } - } continue { - push @lines, $_; - } - close $in; - my $text = join '', @lines; - $text =~ s/(?x) \n+ === \s+ TEST/\n\n\n\n=== TEST/ixsg; - $text =~ s/__(DATA|END)__\n+=== TEST/__${1}__\n\n=== TEST/; - #$text =~ s/\n+$/\n\n/s; - if (! $changed and $text eq join '', @lines) { - warn "reindex: $file:\tskipped.\n"; - return; - } - #File::Copy::copy( $file, "$file.bak" ); - open my $out, "> $file" or - die "Can't open $file for writing: $!"; - binmode $out; - print $out $text; - close $out; - - warn "reindex: $file:\tdone.\n"; -} - diff --git a/debian/modules/nginx-lua/valgrind.suppress b/debian/modules/nginx-lua/valgrind.suppress index fe161e8..d0bcc56 100644 --- a/debian/modules/nginx-lua/valgrind.suppress +++ b/debian/modules/nginx-lua/valgrind.suppress @@ -149,3 +149,18 @@ fun:main fun:__libc_res_nquerydomain fun:__libc_res_nsearch } +{ + + Memcheck:Leak + match-leak-kinds: definite + fun:malloc + fun:ngx_alloc + fun:ngx_set_environment + fun:ngx_single_process_cycle + fun:main +} +{ + + Memcheck:Cond + obj:* +}