From bd7ab97a33627089f0a2d48d358228e02fde3c6c Mon Sep 17 00:00:00 2001 From: "Yichun Zhang (agentzh)" Date: Wed, 28 Sep 2016 20:03:12 -0700 Subject: [PATCH 01/74] checked in file dist.ini for OPM packaging. --- dist.ini | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 dist.ini diff --git a/dist.ini b/dist.ini new file mode 100644 index 000000000..6a704d155 --- /dev/null +++ b/dist.ini @@ -0,0 +1,10 @@ +name=lua-resty-core +abstract=New FFI-based Lua API for the ngx_lua module +author=Yichun "agentzh" Zhang (agentzh) +is_original=yes +license=2bsd +lib_dir=lib +doc_dir=lib +repo_link=https://github.com/openresty/lua-resty-core +main_module=lib/resty/core/base.lua +requires = luajit >= 2.1.0, nginx >= 1.11.2, ngx_http_lua = 0.10.6, openresty/lua-resty-lrucache From 730f7f1f12794b456d896c2290c89de3b6607258 Mon Sep 17 00:00:00 2001 From: Thibault Charbonnier Date: Mon, 24 Oct 2016 19:46:18 -0700 Subject: [PATCH 02/74] optimize: resty.core.shdict: removed one unused top-level Lua variable. Signed-off-by: Yichun Zhang (agentzh) --- lib/resty/core/shdict.lua | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/resty/core/shdict.lua b/lib/resty/core/shdict.lua index 20f40ae74..76e41b31f 100644 --- a/lib/resty/core/shdict.lua +++ b/lib/resty/core/shdict.lua @@ -19,9 +19,6 @@ local ngx_shared = ngx.shared local getmetatable = getmetatable -local MAX_ERR_MSG_LEN = 128 - - ffi.cdef[[ int ngx_http_lua_ffi_shdict_get(void *zone, const unsigned char *key, size_t key_len, int *value_type, unsigned char **str_value_buf, From 7ae24d341f0c393a75052d46bb0fddf46ac5dd7d Mon Sep 17 00:00:00 2001 From: "Yichun Zhang (agentzh)" Date: Sat, 29 Oct 2016 16:03:42 -0700 Subject: [PATCH 03/74] ssl.session: minor fixes and tweaks. --- lib/ngx/ssl/session.lua | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/ngx/ssl/session.lua b/lib/ngx/ssl/session.lua index cca593efe..6944cf169 100644 --- a/lib/ngx/ssl/session.lua +++ b/lib/ngx/ssl/session.lua @@ -1,4 +1,4 @@ -local _M = {} +-- Copyright (C) Yichun Zhang (agentzh) local ffi = require "ffi" @@ -32,6 +32,9 @@ int ngx_http_lua_ffi_ssl_get_session_id_size(ngx_http_request_t *r, ]] +local _M = { version = base.version } + + -- return session, err function _M.get_serialized_session() local r = getfenv(0).__ngx_req From b14b0da82eacfc9cf54dc585384ee2f77ad9fbb7 Mon Sep 17 00:00:00 2001 From: doujiang24 Date: Sun, 30 Oct 2016 10:36:15 +0800 Subject: [PATCH 04/74] tests: ssl_session_fetch/store_by_lua_* are now only allowed in http context. Signed-off-by: Yichun Zhang (agentzh) --- t/ssl-session-fetch.t | 110 +++++++++++++++++++++--------------------- t/ssl-session-store.t | 102 +++++++++++++++++++-------------------- 2 files changed, 106 insertions(+), 106 deletions(-) diff --git a/t/ssl-session-fetch.t b/t/ssl-session-fetch.t index 2fcb8aed5..a35a66ecd 100644 --- a/t/ssl-session-fetch.t +++ b/t/ssl-session-fetch.t @@ -31,15 +31,15 @@ __DATA__ === TEST 1: get resume session id serialized --- http_config lua_package_path "$TEST_NGINX_LUA_PACKAGE_PATH/?.lua;;"; + ssl_session_fetch_by_lua_block { + local ssl = require "ngx.ssl.session" + local sid = ssl.get_session_id() + print("session id: ", sid) + } server { listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl; server_name test.com; - ssl_session_fetch_by_lua_block { - local ssl = require "ngx.ssl.session" - local sid = ssl.get_session_id() - print("session id: ", sid) - } ssl_protocols SSLv3; ssl_certificate $TEST_NGINX_CERT_DIR/cert/test.crt; ssl_certificate_key $TEST_NGINX_CERT_DIR/cert/test.key; @@ -112,21 +112,21 @@ qr/ssl_session_fetch_by_lua_block:4: session id: [a-fA-f\d]+/s, === TEST 2: attempt to fetch new session in lua_ctx during resumption. --- http_config lua_package_path "$TEST_NGINX_LUA_PACKAGE_PATH/?.lua;;"; + ssl_session_fetch_by_lua_block { + local ssl = require "ngx.ssl.session" + local sess, err = ssl.get_serialized_session() + if sess then + print("session size: ", #sess) + end + + if err then + print("get session error: ", err) + end + } server { listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl; server_name test.com; - ssl_session_fetch_by_lua_block { - local ssl = require "ngx.ssl.session" - local sess, err = ssl.get_serialized_session() - if sess then - print("session size: ", #sess) - end - - if err then - print("get session error: ", err) - end - } ssl_protocols SSLv3; ssl_certificate $TEST_NGINX_CERT_DIR/cert/test.crt; ssl_certificate_key $TEST_NGINX_CERT_DIR/cert/test.key; @@ -203,32 +203,32 @@ Use a tmp file to store and resume session. This is for testing only. In practice, never store session in plaintext on persistent storage. --- http_config lua_package_path "$TEST_NGINX_LUA_PACKAGE_PATH/?.lua;;"; + ssl_session_store_by_lua_block { + local ssl = require "ngx.ssl.session" - server { - listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl; - server_name test.com; - ssl_session_store_by_lua_block { - local ssl = require "ngx.ssl.session" + local sid = ssl.get_session_id() + print("session id: ", sid) + local sess = ssl.get_serialized_session() + print("session size: ", #sess) - local sid = ssl.get_session_id() - print("session id: ", sid) - local sess = ssl.get_serialized_session() - print("session size: ", #sess) + local f = assert(io.open("t/servroot/html/session.tmp", "w")) + f:write(sess) + f:close() + } - local f = assert(io.open("t/servroot/html/session.tmp", "w")) - f:write(sess) - f:close() - } + ssl_session_fetch_by_lua_block { + local ssl = require "ngx.ssl.session" + local sid = ssl.get_session_id() + print("session id: ", sid) + local f = assert(io.open("t/servroot/html/session.tmp")) + local sess = f:read("*a") + f:close() + ssl.set_serialized_session(sess) + } - ssl_session_fetch_by_lua_block { - local ssl = require "ngx.ssl.session" - local sid = ssl.get_session_id() - print("session id: ", sid) - local f = assert(io.open("t/servroot/html/session.tmp")) - local sess = f:read("*a") - f:close() - ssl.set_serialized_session(sess) - } + server { + listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl; + server_name test.com; ssl_protocols SSLv3; ssl_certificate $TEST_NGINX_CERT_DIR/cert/test.crt; @@ -304,27 +304,27 @@ Session resumption should fail, but the handshake should be able to carry on and negotiate a new session. --- http_config lua_package_path "$TEST_NGINX_LUA_PACKAGE_PATH/?.lua;;"; + ssl_session_store_by_lua_block { + local ssl = require "ngx.ssl.session" + + local sid = ssl.get_session_id() + print("session id: ", sid) + } + + ssl_session_fetch_by_lua_block { + local ssl = require "ngx.ssl.session" + local sid = ssl.get_session_id() + print("session id: ", sid) + local sess = "==garbage data==" + local ok, err = ssl.set_serialized_session(sess) + if not ok or err then + print("failed to resume session: ", err) + end + } server { listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl; server_name test.com; - ssl_session_store_by_lua_block { - local ssl = require "ngx.ssl.session" - - local sid = ssl.get_session_id() - print("session id: ", sid) - } - - ssl_session_fetch_by_lua_block { - local ssl = require "ngx.ssl.session" - local sid = ssl.get_session_id() - print("session id: ", sid) - local sess = "==garbage data==" - local ok, err = ssl.set_serialized_session(sess) - if not ok or err then - print("failed to resume session: ", err) - end - } ssl_protocols SSLv3; ssl_certificate $TEST_NGINX_CERT_DIR/cert/test.crt; diff --git a/t/ssl-session-store.t b/t/ssl-session-store.t index 8542b08ef..d42e0598e 100644 --- a/t/ssl-session-store.t +++ b/t/ssl-session-store.t @@ -31,15 +31,15 @@ __DATA__ === TEST 1: get new session serialized --- http_config lua_package_path "$TEST_NGINX_LUA_PACKAGE_PATH/?.lua;;"; + ssl_session_store_by_lua_block { + local ssl = require "ngx.ssl.session" + local sess = ssl.get_serialized_session() + print("session size: ", #sess) + } server { listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl; server_name test.com; - ssl_session_store_by_lua_block { - local ssl = require "ngx.ssl.session" - local sess = ssl.get_serialized_session() - print("session size: ", #sess) - } ssl_protocols SSLv3; ssl_certificate $TEST_NGINX_CERT_DIR/cert/test.crt; ssl_certificate_key $TEST_NGINX_CERT_DIR/cert/test.key; @@ -103,15 +103,15 @@ qr/ssl_session_store_by_lua_block:4: session size: \d+/s === TEST 2: get new session id serialized --- http_config lua_package_path "$TEST_NGINX_LUA_PACKAGE_PATH/?.lua;;"; + ssl_session_store_by_lua_block { + local ssl = require "ngx.ssl.session" + local sid = ssl.get_session_id() + print("session id: ", sid) + } server { listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl; server_name test.com; - ssl_session_store_by_lua_block { - local ssl = require "ngx.ssl.session" - local sid = ssl.get_session_id() - print("session id: ", sid) - } ssl_protocols SSLv3; ssl_certificate $TEST_NGINX_CERT_DIR/cert/test.crt; ssl_certificate_key $TEST_NGINX_CERT_DIR/cert/test.key; @@ -175,51 +175,51 @@ qr/ssl_session_store_by_lua_block:4: session id: [a-fA-f\d]+/s === TEST 3: store the session via timer to memcached --- http_config lua_package_path "$TEST_NGINX_LUA_PACKAGE_PATH/?.lua;;"; + ssl_session_store_by_lua_block { + local ssl = require "ngx.ssl.session" + local function f(premature, key, value) + local sock = ngx.socket.tcp() + + sock:settimeout(5000) + + local ok, err = sock:connect("127.0.0.1", $TEST_NGINX_MEMCACHED_PORT) + if not ok then + ngx.log(ngx.ERR, "failed to connect to memc: ", err) + return + end + + local bytes, err = sock:send("set " .. key .. " 0 0 " + .. tostring(#value) .. " \r\n" + .. value .. "\r\n") + if not bytes then + ngx.log(ngx.ERR, "failed to send set command: ", err) + return + end + + local res, err = sock:receive() + if not res then + ngx.log(ngx.ERR, "failed to receive memc reply: ", err) + return + end + + print("received memc reply: ", res) + end + + local sid = ssl.get_session_id() + print("session id: ", sid) + local sess = ssl.get_serialized_session() + print("session size: ", #sess) + + local ok, err = ngx.timer.at(0, f, sid, sess) + if not ok then + ngx.log(ngx.ERR, "failed to create timer: ", err) + return + end + } server { listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl; server_name test.com; - ssl_session_store_by_lua_block { - local ssl = require "ngx.ssl.session" - local function f(premature, key, value) - local sock = ngx.socket.tcp() - - sock:settimeout(5000) - - local ok, err = sock:connect("127.0.0.1", $TEST_NGINX_MEMCACHED_PORT) - if not ok then - ngx.log(ngx.ERR, "failed to connect to memc: ", err) - return - end - - local bytes, err = sock:send("set " .. key .. " 0 0 " - .. tostring(#value) .. " \r\n" - .. value .. "\r\n") - if not bytes then - ngx.log(ngx.ERR, "failed to send set command: ", err) - return - end - - local res, err = sock:receive() - if not res then - ngx.log(ngx.ERR, "failed to receive memc reply: ", err) - return - end - - print("received memc reply: ", res) - end - - local sid = ssl.get_session_id() - print("session id: ", sid) - local sess = ssl.get_serialized_session() - print("session size: ", #sess) - - local ok, err = ngx.timer.at(0, f, sid, sess) - if not ok then - ngx.log(ngx.ERR, "failed to create timer: ", err) - return - end - } ssl_protocols SSLv3; ssl_certificate $TEST_NGINX_CERT_DIR/cert/test.crt; ssl_certificate_key $TEST_NGINX_CERT_DIR/cert/test.key; From 57128f5d4903bf4db5bf563864e946ff2219321d Mon Sep 17 00:00:00 2001 From: "Yichun Zhang (agentzh)" Date: Mon, 31 Oct 2016 15:31:46 -0700 Subject: [PATCH 05/74] now we require at least ngx_lua 0.10.7. --- README.markdown | 2 +- lib/resty/core/base.lua | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.markdown b/README.markdown index be7501461..8045ec68c 100644 --- a/README.markdown +++ b/README.markdown @@ -84,7 +84,7 @@ Prerequisites ============= * LuaJIT 2.1 (for now, it is the v2.1 git branch in the official luajit-2.0 git repository: http://luajit.org/download.html ) -* [ngx_lua](https://github.com/openresty/lua-nginx-module) v0.10.6 or later. +* [ngx_lua](https://github.com/openresty/lua-nginx-module) v0.10.7 or later. * [lua-resty-lrucache](https://github.com/openresty/lua-resty-lrucache) [Back to TOC](#table-of-contents) diff --git a/lib/resty/core/base.lua b/lib/resty/core/base.lua index 35e29beae..7dbc9828d 100644 --- a/lib/resty/core/base.lua +++ b/lib/resty/core/base.lua @@ -15,9 +15,9 @@ local FREE_LIST_REF = 0 if not ngx.config or not ngx.config.ngx_lua_version - or ngx.config.ngx_lua_version < 10006 + or ngx.config.ngx_lua_version < 10007 then - error("ngx_lua 0.10.6+ required") + error("ngx_lua 0.10.7+ required") end From 32a51dcbfa36d925f4583f503a3899a23d61de1e Mon Sep 17 00:00:00 2001 From: Thibault Charbonnier Date: Fri, 21 Oct 2016 21:05:17 -0700 Subject: [PATCH 06/74] feature: implemented the split() method in the ngx.re module. Implemented a new `ngx.re` module which implements the `split()` API described at https://github.com/openresty/lua-nginx-module/issues/217 Signed-off-by: Yichun Zhang (agentzh) --- README.markdown | 10 + lib/ngx/re.lua | 196 +++++++++++ lib/ngx/re.md | 199 +++++++++++ lib/resty/core/regex.lua | 6 + t/re-split.t | 707 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 1118 insertions(+) create mode 100644 lib/ngx/re.lua create mode 100644 lib/ngx/re.md create mode 100644 t/re-split.t diff --git a/README.markdown b/README.markdown index 8045ec68c..4c5265bd8 100644 --- a/README.markdown +++ b/README.markdown @@ -29,6 +29,7 @@ Table of Contents * [ngx.balancer](#ngxbalancer) * [ngx.ssl](#ngxssl) * [ngx.ssl.session](#ngxsslsession) + * [ngx.re](#ngxre) * [Caveat](#caveat) * [TODO](#todo) * [Author](#author) @@ -235,6 +236,15 @@ See the [documentation](./lib/ngx/ssl/session.md) for this Lua module for more d [Back to TOC](#table-of-contents) +## ngx.re + +This Lua module provides a Lua API which implements convenience utilities for +the `ngx.re` API. + +See the [documentation](./lib/ngx/re.md) for this Lua module for more details. + +[Back to TOC](#table-of-contents) + Caveat ====== diff --git a/lib/ngx/re.lua b/lib/ngx/re.lua new file mode 100644 index 000000000..85234700d --- /dev/null +++ b/lib/ngx/re.lua @@ -0,0 +1,196 @@ +-- I hereby assign copyright in this code to the lua-resty-core project, +-- to be licensed under the same terms as the rest of the code. + + +local ffi = require 'ffi' +local bit = require "bit" +local base = require "resty.core.base" +local core_regex = require "resty.core.regex" + + +local C = ffi.C +local sub = string.sub +local type = type +local band = bit.band +local new_tab = base.new_tab +local tostring = tostring +local math_max = math.max +local math_min = math.min +local re_match_compile = core_regex.re_match_compile +local destroy_compiled_regex = core_regex.destroy_compiled_regex + + +local FLAG_DFA = 0x02 +local PCRE_ERROR_NOMATCH = -1 +local DEFAULT_SPLIT_RES_SIZE = 4 + + +local split_ctx = new_tab(0, 1) + + +local _M = { version = base.version } + + +local function re_split_helper(subj, compiled, compile_once, flags, ctx) + local rc + do + local pos = math_max(ctx.pos - 1, 0) + + rc = C.ngx_http_lua_ffi_exec_regex(compiled, flags, subj, #subj, pos) + end + + if rc == PCRE_ERROR_NOMATCH then + if not compile_once then + destroy_compiled_regex(compiled) + end + return nil, nil, nil + end + + if rc < 0 then + if not compile_once then + destroy_compiled_regex(compiled) + end + return nil, nil, nil, "pcre_exec() failed: " .. rc + end + + if rc == 0 then + if band(flags, FLAG_DFA) == 0 then + return nil, nil, nil, "capture size too small" + end + + rc = 1 + end + + local caps = compiled.captures + local ncaps = compiled.ncaptures + + local from = caps[0] + 1 + local to = caps[1] + + if from < 0 or to < 0 then + return nil, nil, nil + end + + ctx.pos = to + 1 + + -- retrieve the first sub-match capture if any + + if ncaps > 0 and rc > 1 then + return from, to, sub(subj, caps[2] + 1, caps[3]) + end + + return from, to +end + + +function _M.split(subj, regex, opts, ctx, max, res) + -- we need to cast this to strings to avoid exceptions when they are + -- something else. + -- needed because of further calls to string.sub in this function. + subj = tostring(subj) + + if not ctx then + ctx = split_ctx + ctx.pos = 1 -- set or reset upvalue field + + elseif not ctx.pos then + -- ctx provided by user but missing pos field + ctx.pos = 1 + end + + max = max or 0 + + if not res then + -- limit the initial arr_n size of res to a reasonable value + -- 0 < narr <= DEFAULT_SPLIT_RES_SIZE + local narr = DEFAULT_SPLIT_RES_SIZE + if max > 0 then + -- the user specified a valid max limiter if max > 0 + narr = math_min(narr, max) + end + + res = new_tab(narr, 0) + + elseif type(res) ~= "table" then + return error("res is not a table", 2) + end + + -- compile regex + + local compiled, compile_once, flags = re_match_compile(regex, opts) + if compiled == nil then + -- compiled_once holds the error string + return nil, compile_once + end + + local sub_idx = ctx.pos + local res_idx = 0 + + -- splitting: with and without a max limiter + + if max > 0 then + local count = 1 + + while count < max do + local from, to, capture, err = re_split_helper(subj, compiled, + compile_once, flags, ctx) + if err then + return nil, err + end + + if not from then + break + end + + count = count + 1 + res_idx = res_idx + 1 + res[res_idx] = sub(subj, sub_idx, from - 1) + + if capture then + res_idx = res_idx + 1 + res[res_idx] = capture + end + + sub_idx = to + 1 + end + + if count == max then + if not compile_once then + destroy_compiled_regex(compiled) + end + end + + else + while true do + local from, to, capture, err = re_split_helper(subj, compiled, + compile_once, flags, ctx) + if err then + return nil, err + end + + if not from then + break + end + + res_idx = res_idx + 1 + res[res_idx] = sub(subj, sub_idx, from - 1) + + if capture then + res_idx = res_idx + 1 + res[res_idx] = capture + end + + sub_idx = to + 1 + end + end + + -- trailing nil for non-cleared res tables + + res[res_idx + 1] = sub(subj, sub_idx, #subj) + res[res_idx + 2] = nil + + return res +end + + +return _M diff --git a/lib/ngx/re.md b/lib/ngx/re.md new file mode 100644 index 000000000..a76080abe --- /dev/null +++ b/lib/ngx/re.md @@ -0,0 +1,199 @@ +Name +==== + +ngx.re - Lua API for convenience utilities for `ngx.re`. + +Table of Contents +================= + +* [Name](#name) +* [Status](#status) +* [Synopsis](#synopsis) +* [Description](#description) +* [Methods](#methods) + * [split](#split) +* [Community](#community) + * [English Mailing List](#english-mailing-list) + * [Chinese Mailing List](#chinese-mailing-list) +* [Bugs and Patches](#bugs-and-patches) +* [Author](#author) +* [Copyright and License](#copyright-and-license) +* [See Also](#see-also) + +Status +====== + +This Lua module is currently considered experimental. + +Synopsis +======== + +```lua +local ngx_re = require "ngx.re" + +-- split +local res, err = ngx_re.split("a,b,c,d", ",") +--> res is now {"a", "b", "c", "d"} +``` + +[Back to TOC](#table-of-contents) + +Description +=========== + +This Lua module provides a Lua API which implements convenience utilities for +the `ngx.re` API. + +[Back to TOC](#table-of-contents) + +Methods +======= + +All the methods of this module are static (or module-level). That is, you do +not need an object (or instance) to call these methods. + +[Back to TOC](#table-of-contents) + +split +----- +**syntax:** *res, err = ngx_re.split(subject, regex, options?, ctx?, max?, res?)* + +Splits the `subject` string using the Perl compatible regular expression +`regex` with the optional `options`. + +This function returns a Lua (array) table (with integer keys) containing the +splitted values. + +In case of error, `nil` will be returned as well as a string describing the +error. + +When `regex` contains a sub-match capturing group, and when such a match is +found, the first submatch capture will be inserted in between each splitted +value, like so: + +```lua +local ngx_re = require "ngx.re" + +local res, err = ngx_re.split("a,b,c,d", "(,)") +-- res is now {"a", ",", "b", ",", "c", ",", "d"} +``` + +The optional `ctx` table argument can be a Lua table holding an optional `pos` +field. When the `pos` field in the `ctx` table argument is specified, +`ngx_re.split` will start splitting the `subject` from that index: + +```lua +local ngx_re = require "ngx.re" + +local res, err = ngx_re.split("a,b,c,d", ",", nil, {pos = 5}) +-- res is now {"c", "d"} +``` + +The optional `max` argument is a number that when specified, will prevent +`ngx_re.split` from adding more than `max` matches to the `res` array: + +```lua +local ngx_re = require "ngx.re" + +local res, err = ngx_re.split("a,b,c,d", ",", nil, nil, 3) +-- res is now {"a", "b", "c,d"} +``` + +Specifying `max <= 0` disables this behavior, meaning that the number of +results won't be limited. + +The optional 6th argument `res` can be a table that `ngx_re.split` will re-use +to hold the results instead of creating a new one, which can improve +performance in hot code paths. It is used like so: + +```lua +local ngx_re = require "ngx.re" + +local my_table = {"hello world"} + +local res, err = ngx_re.split("a,b,c,d", ",", nil, nil, nil, my_table) +-- res/my_table is now {"a", "b", "c", "d"} +``` + +When provided with a `res` table, `ngx_re.split` won't clear the table +for performance reasons, but will rather insert a trailing `nil` value +when the split is completed: + +```lua +local ngx_re = require "ngx.re" + +local my_table = {"W", "X", "Y", "Z"} + +local res, err = ngx_re.split("a,b", ",", nil, nil, nil, my_table) +-- res/my_table is now {"a", "b", nil, "Z"} +``` + +When the trailing `nil` is not enough for your purpose, you should +clear the table yourself before feeding it into the `split` function. + +[Back to TOC](#table-of-contents) + +Community +========= + +[Back to TOC](#table-of-contents) + +English Mailing List +-------------------- + +The [openresty-en](https://groups.google.com/group/openresty-en) mailing list +is for English speakers. + +[Back to TOC](#table-of-contents) + +Chinese Mailing List +-------------------- + +The [openresty](https://groups.google.com/group/openresty) mailing list is for +Chinese speakers. + +[Back to TOC](#table-of-contents) + +Bugs and Patches +================ + +Please report bugs or submit patches by + +1. creating a ticket on the [GitHub Issue Tracker](https://github.com/openresty/lua-resty-core/issues), +1. or posting to the [OpenResty community](#community). + +[Back to TOC](#table-of-contents) + +Author +====== + +Thibault Charbonnier - ([@thibaultcha](https://github.com/thibaultcha)) + +[Back to TOC](#table-of-contents) + +Copyright and License +===================== + +This module is licensed under the BSD license. + +Copyright (C) 2016, by Yichun "agentzh" Zhang, CloudFlare Inc. + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +[Back to TOC](#table-of-contents) + +See Also +======== +* library [lua-resty-core](https://github.com/openresty/lua-resty-core) +* the ngx_lua module: https://github.com/openresty/lua-nginx-module +* OpenResty: http://openresty.org + +[Back to TOC](#table-of-contents) diff --git a/lib/resty/core/regex.lua b/lib/resty/core/regex.lua index 95db44e03..fad7ae856 100644 --- a/lib/resty/core/regex.lua +++ b/lib/resty/core/regex.lua @@ -286,6 +286,9 @@ local function destroy_compiled_regex(compiled) end +_M.destroy_compiled_regex = destroy_compiled_regex + + local function re_match_compile(regex, opts) local flags = 0 local pcre_opts = 0 @@ -343,6 +346,9 @@ local function re_match_compile(regex, opts) end +_M.re_match_compile = re_match_compile + + local function re_match_helper(subj, regex, opts, ctx, want_caps, res, nth) -- we need to cast this to strings to avoid exceptions when they are -- something else. diff --git a/t/re-split.t b/t/re-split.t new file mode 100644 index 000000000..e10108b71 --- /dev/null +++ b/t/re-split.t @@ -0,0 +1,707 @@ +# vim:set ft= ts=4 sw=4 et fdm=marker: +use lib 'lib'; +use Test::Nginx::Socket::Lua; +use Cwd qw(cwd); + +#worker_connections(1014); +#master_process_enabled(1); +#log_level('warn'); + +repeat_each(2); + +plan tests => repeat_each() * blocks() * 4 + (2 * repeat_each()); + +my $pwd = cwd(); + +our $HttpConfig = <<_EOC_; + lua_package_path "$pwd/lib/?.lua;../lua-resty-lrucache/lib/?.lua;;"; + init_by_lua_block { + -- local verbose = true + local verbose = false + local outfile = "$Test::Nginx::Util::ErrLogFile" + -- local outfile = "/tmp/v.log" + if verbose then + local dump = require "jit.dump" + dump.on(nil, outfile) + else + local v = require "jit.v" + v.on(outfile) + end + + require "resty.core" + -- jit.opt.start("hotloop=1") + -- jit.opt.start("loopunroll=1000000") + -- jit.off() + } +_EOC_ + +no_diff(); +no_long_string(); +check_accum_error_log(); +run_tests(); + +__DATA__ + +=== TEST 1: split matches, no submatch, no jit compile, no regex cache +--- http_config eval: $::HttpConfig +--- config + location = /re { + content_by_lua_block { + local ngx_re = require "ngx.re" + + local res, err = ngx_re.split("a,b,c,d", ",") + if err then + ngx.log(ngx.ERR, "failed: ", err) + return + end + + for i = 1, #res do + ngx.say(res[i]) + end + } + } +--- request +GET /re +--- response_body +a +b +c +d +--- error_log eval +qr/\[TRACE \d+/ +--- no_error_log +[error] + + + +=== TEST 2: split matches, no submatch, no jit compile, no regex cache +--- http_config eval: $::HttpConfig +--- config + location = /re { + content_by_lua_block { + local ngx_re = require "ngx.re" + + local res, err = ngx_re.split("a;,b;,c;,d;e", ";,") + if err then + ngx.log(ngx.ERR, "failed: ", err) + return + end + + for i = 1, #res do + ngx.say(res[i]) + end + } + } +--- request +GET /re +--- response_body +a +b +c +d;e +--- error_log eval +qr/\[TRACE \d+/ +--- no_error_log +[error] + + + +=== TEST 3: split matches, no submatch, jit compile, regex cache +--- http_config eval: $::HttpConfig +--- config + location = /re { + content_by_lua_block { + local ngx_re = require "ngx.re" + + local res, err = ngx_re.split("a,b,c,d", ",", "jo") + if err then + ngx.log(ngx.ERR, "failed: ", err) + return + end + + for i = 1, #res do + ngx.say(res[i]) + end + } + } +--- request +GET /re +--- response_body +a +b +c +d +--- error_log eval +qr/\[TRACE \d+/ +--- no_error_log +[error] + + + +=== TEST 4: split matches + submatch (matching) +--- http_config eval: $::HttpConfig +--- config + location = /re { + content_by_lua_block { + local ngx_re = require "ngx.re" + + local res, err = ngx_re.split("a;,b;,c;,d,e", "(;),") + if err then + ngx.log(ngx.ERR, "failed: ", err) + return + end + + for i = 1, #res do + ngx.say(res[i]) + end + } + } +--- request +GET /re +--- response_body +a +; +b +; +c +; +d,e +--- error_log eval +qr/\[TRACE \d+/ +--- no_error_log +[error] + + + +=== TEST 5: split matches + submatch (not matching) +--- http_config eval: $::HttpConfig +--- config + location = /re { + content_by_lua_block { + local ngx_re = require "ngx.re" + + local res, err = ngx_re.split("a,b,c,d,e", "(;)|,") + if err then + ngx.log(ngx.ERR, "failed: ", err) + return + end + + for i = 1, #res do + ngx.say(res[i]) + end + } + } +--- request +GET /re +--- response_body +a +b +c +d +e +--- error_log eval +qr/\[TRACE \d+/ +--- no_error_log +[error] + + + +=== TEST 6: split matches + max limiter +--- http_config eval: $::HttpConfig +--- config + location = /re { + content_by_lua_block { + local ngx_re = require "ngx.re" + + local res, err = ngx_re.split("a,b,c,d,e", ",", nil, nil, 3) + if err then + ngx.log(ngx.ERR, "failed: ", err) + return + end + + for i = 1, #res do + ngx.say(res[i]) + end + } + } +--- request +GET /re +--- response_body +a +b +c,d,e +--- error_log eval +qr/\[TRACE \d+/ +--- no_error_log +[error] + + + +=== TEST 7: split matches + submatch + max limiter +--- http_config eval: $::HttpConfig +--- config + location = /re { + content_by_lua_block { + local ngx_re = require "ngx.re" + + local res, err = ngx_re.split("a,b,c,d,e", "(,)", nil, nil, 3) + if err then + ngx.log(ngx.ERR, "failed: ", err) + return + end + + for i = 1, #res do + ngx.say(res[i]) + end + } + } +--- request +GET /re +--- response_body +a +, +b +, +c,d,e +--- error_log eval +qr/\[TRACE \d+/ +--- no_error_log +[error] + + + +=== TEST 8: split matches + max limiter set to 0 +--- http_config eval: $::HttpConfig +--- config + location = /re { + content_by_lua_block { + local ngx_re = require "ngx.re" + + local res, err = ngx_re.split("a,b,c,d,e", ",", nil, nil, 0) + if err then + ngx.log(ngx.ERR, "failed: ", err) + return + end + + for i = 1, #res do + ngx.say(res[i]) + end + } + } +--- request +GET /re +--- response_body +a +b +c +d +e +--- error_log eval +qr/\[TRACE \d+/ +--- no_error_log +[error] + + + +=== TEST 9: split matches + max limiter set to a negative value +--- http_config eval: $::HttpConfig +--- config + location = /re { + content_by_lua_block { + local ngx_re = require "ngx.re" + + local res, err = ngx_re.split("a,b,c,d,e", ",", nil, nil, -1) + if err then + ngx.log(ngx.ERR, "failed: ", err) + return + end + + for i = 1, #res do + ngx.say(res[i]) + end + } + } +--- request +GET /re +--- response_body +a +b +c +d +e +--- error_log eval +qr/\[TRACE \d+/ +--- no_error_log +[error] + + + +=== TEST 10: split matches + max limiter set to 1 +--- http_config eval: $::HttpConfig +--- config + location = /re { + content_by_lua_block { + local ngx_re = require "ngx.re" + + local res, err = ngx_re.split("a,b,c,d,e", ",", nil, nil, 1) + if err then + ngx.log(ngx.ERR, "failed: ", err) + return + end + + for i = 1, #res do + ngx.say(res[i]) + end + } + } +--- request +GET /re +--- response_body +a,b,c,d,e +--- error_log eval +qr/\[TRACE \d+/ +--- no_error_log +[error] + + + +=== TEST 11: split matches, provided res table +--- http_config eval: $::HttpConfig +--- config + location = /re { + content_by_lua_block { + local ngx_re = require "ngx.re" + + local my_table = {} + + local res, err = ngx_re.split("a,b,c,d,e", ",", nil, nil, nil, my_table) + if err then + ngx.log(ngx.ERR, "failed: ", err) + return + end + + for i = 1, #res do + ngx.say(res[i]) + end + } + } +--- request +GET /re +--- response_body +a +b +c +d +e +--- error_log eval +qr/\[TRACE \d+/ +--- no_error_log +[error] + + + +=== TEST 12: split matches, provided res table (non-cleared) +--- http_config eval: $::HttpConfig +--- config + location = /re { + content_by_lua_block { + local ngx_re = require "ngx.re" + + local my_table = {} + + for i = 1, 10 do + my_table[i] = i.." hello world" + end + + local res, err = ngx_re.split("a,b,c,d,e", ",", nil, nil, nil, my_table) + if err then + ngx.log(ngx.ERR, "failed: ", err) + return + end + + for i in ipairs(my_table) do + ngx.say(res[i]) + end + } + } +--- request +GET /re +--- response_body +a +b +c +d +e +--- error_log eval +qr/\[TRACE \d+/ +--- no_error_log +[error] + + + +=== TEST 13: split matches, provided res table + max limiter +--- http_config eval: $::HttpConfig +--- config + location = /re { + content_by_lua_block { + local ngx_re = require "ngx.re" + + local my_table = {"hello, world"} + + local res, err = ngx_re.split("a,b,c,d,e", ",", nil, nil, 3, my_table) + if err then + ngx.log(ngx.ERR, "failed: ", err) + return + end + + for i = 1, #my_table do + ngx.say(res[i]) + end + } + } +--- request +GET /re +--- response_body +a +b +c,d,e +--- error_log eval +qr/\[TRACE \d+/ +--- no_error_log +[error] + + + +=== TEST 14: split matches, provided res table (non-cleared) + max limiter +--- http_config eval: $::HttpConfig +--- config + location = /re { + content_by_lua_block { + local ngx_re = require "ngx.re" + + local my_table = {} + + for i = 1, 10 do + my_table[i] = i.." hello world" + end + + local res, err = ngx_re.split("a,b,c,d,e", ",", nil, nil, 3, my_table) + if err then + ngx.log(ngx.ERR, "failed: ", err) + return + end + + for i in ipairs(my_table) do + ngx.say(res[i]) + end + } + } +--- request +GET /re +--- response_body +a +b +c,d,e +--- error_log eval +qr/\[TRACE \d+/ +--- no_error_log +[error] + + + +=== TEST 15: split matches, provided res table + max limiter + sub-match capturing group +--- http_config eval: $::HttpConfig +--- config + location = /re { + content_by_lua_block { + local ngx_re = require "ngx.re" + + local my_table = {"hello, world"} + + local res, err = ngx_re.split("a,b,c,d,e", "(,)", nil, nil, 3, my_table) + if err then + ngx.log(ngx.ERR, "failed: ", err) + return + end + + for i = 1, #my_table do + ngx.say(res[i]) + end + } + } +--- request +GET /re +--- response_body +a +, +b +, +c,d,e +--- error_log eval +qr/\[TRACE \d+/ +--- no_error_log +[error] + + + +=== TEST 16: split matches, ctx arg +--- http_config eval: $::HttpConfig +--- config + location = /re { + content_by_lua_block { + local ngx_re = require "ngx.re" + + local res, err = ngx_re.split("a,b,c,d,e", ",", nil, { pos = 5 }) + if err then + ngx.log(ngx.ERR, "failed: ", err) + return + end + + for i = 1, #res do + ngx.say(res[i]) + end + } + } +--- request +GET /re +--- response_body +c +d +e +--- error_log eval +qr/\[TRACE \d+/ +--- no_error_log +[error] + + + +=== TEST 17: split matches, trailing subjects +--- http_config eval: $::HttpConfig +--- config + location /re { + content_by_lua_block { + local ngx_re = require "ngx.re" + + local res, err = ngx_re.split(",a,b,c,d,", ",") + if err then + ngx.log(ngx.ERR, "failed: ", err) + return + end + + for i = 1, #res do + if res[i] == "" then + ngx.say("_blank_") + else + ngx.say(res[i]) + end + end + } + } +--- request +GET /re +--- response_body +_blank_ +a +b +c +d +_blank_ +--- error_log eval +qr/\[TRACE \d+/ +--- no_error_log +[error] +attempt to get length of local 'regex' (a number value) + + + +=== TEST 18: split matches, real use-case +--- http_config eval: $::HttpConfig +--- config + location /re { + content_by_lua_block { + local ngx_re = require "ngx.re" + + local res, err = ngx_re.split("abcd,erfg,ghij;hello world;aaa", ",|;") + if err then + ngx.log(ngx.ERR, "failed: ", err) + return + end + + for i = 1, #res do + ngx.say(res[i]) + end + } + } +--- request +GET /re +--- response_body +abcd +erfg +ghij +hello world +aaa +--- error_log eval +qr/\[TRACE \d+/ +--- no_error_log +[error] + + + +=== TEST 19: split no matches +--- http_config eval: $::HttpConfig +--- config + location /re { + content_by_lua_block { + local ngx_re = require "ngx.re" + + local res, err = ngx_re.split("abcd", ",") + if err then + ngx.log(ngx.ERR, "failed: ", err) + return + end + + for i = 1, #res do + ngx.say(res[i]) + end + } + } +--- request +GET /re +--- response_body +abcd +--- error_log eval +qr/\[TRACE \d+/ +--- no_error_log +[error] + + + +=== TEST 20: subject is not a string type +--- http_config eval: $::HttpConfig +--- config + location /re { + content_by_lua_block { + local ngx_re = require "ngx.re" + + local res, err = ngx_re.split(1234512345, "23", "jo") + if err then + ngx.log(ngx.ERR, "failed: ", err) + return + end + + for i = 1, #res do + ngx.say(res[i]) + end + } + } +--- request +GET /re +--- response_body +1 +451 +45 +--- error_log eval +qr/\[TRACE \d+/ +--- no_error_log +[error] +attempt to get length of local 'subj' (a number value) From fccfa33ef88392bbe4a317aaf29865b8a388304b Mon Sep 17 00:00:00 2001 From: "Yichun Zhang (agentzh)" Date: Fri, 16 Dec 2016 11:31:13 -0800 Subject: [PATCH 07/74] dist.ini: updated the minimum ngx_lua version required. --- dist.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dist.ini b/dist.ini index 6a704d155..403bef01b 100644 --- a/dist.ini +++ b/dist.ini @@ -7,4 +7,4 @@ lib_dir=lib doc_dir=lib repo_link=https://github.com/openresty/lua-resty-core main_module=lib/resty/core/base.lua -requires = luajit >= 2.1.0, nginx >= 1.11.2, ngx_http_lua = 0.10.6, openresty/lua-resty-lrucache +requires = luajit >= 2.1.0, nginx >= 1.11.2, ngx_http_lua = 0.10.7, openresty/lua-resty-lrucache From 1ad0efda025e9f23c5374e7397a184234367bd41 Mon Sep 17 00:00:00 2001 From: Andreas Lubbe Date: Fri, 16 Dec 2016 18:41:38 +0100 Subject: [PATCH 08/74] travis-ci: added nginx 1.11.2 to the test matrix. Signed-off-by: Yichun Zhang (agentzh) --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index bbbfbb897..4bfe8e7dd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -30,7 +30,7 @@ env: - TEST_NGINX_SLEEP=0.006 matrix: - NGINX_VERSION=1.9.15 -# - NGINX_VERSION=1.10.0 + - NGINX_VERSION=1.11.2 install: - if [ ! -d download-cache ]; then mkdir download-cache; fi From 69703fe40582fff47fb5c949aa9986f1561c5d4a Mon Sep 17 00:00:00 2001 From: "Yichun Zhang (agentzh)" Date: Sun, 18 Dec 2016 14:44:11 -0800 Subject: [PATCH 09/74] doc: updated copyright notice. --- README.markdown | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.markdown b/README.markdown index 4c5265bd8..483eebb23 100644 --- a/README.markdown +++ b/README.markdown @@ -266,7 +266,7 @@ TODO Author ====== -Yichun "agentzh" Zhang (章亦春) , CloudFlare Inc. +Yichun "agentzh" Zhang (章亦春) , OpenResty Inc. [Back to TOC](#table-of-contents) @@ -275,7 +275,7 @@ Copyright and License This module is licensed under the BSD license. -Copyright (C) 2013-2016, by Yichun "agentzh" Zhang, CloudFlare Inc. +Copyright (C) 2013-2017, by Yichun "agentzh" Zhang, OpenResty Inc. All rights reserved. From 03d8a3210aa02373ab52d3a49936c0de5db1b6bf Mon Sep 17 00:00:00 2001 From: "Yichun Zhang (agentzh)" Date: Mon, 19 Dec 2016 11:26:51 -0800 Subject: [PATCH 10/74] updated copyright notices. --- lib/ngx/balancer.md | 4 ++-- lib/ngx/ocsp.md | 4 ++-- lib/ngx/re.md | 2 +- lib/ngx/semaphore.md | 2 +- lib/ngx/ssl.md | 4 ++-- lib/ngx/ssl/session.md | 4 ++-- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/lib/ngx/balancer.md b/lib/ngx/balancer.md index 51513bac2..e090e65c6 100644 --- a/lib/ngx/balancer.md +++ b/lib/ngx/balancer.md @@ -216,7 +216,7 @@ Please report bugs or submit patches by Author ====== -Yichun Zhang <agentzh@gmail.com> (agentzh), CloudFlare Inc. +Yichun Zhang <agentzh@gmail.com> (agentzh), OpenResty Inc. [Back to TOC](#table-of-contents) @@ -225,7 +225,7 @@ Copyright and License This module is licensed under the BSD license. -Copyright (C) 2015, by Yichun "agentzh" Zhang, CloudFlare Inc. +Copyright (C) 2015-2017, by Yichun "agentzh" Zhang, OpenResty Inc. All rights reserved. diff --git a/lib/ngx/ocsp.md b/lib/ngx/ocsp.md index 856ee8400..1db7501cb 100644 --- a/lib/ngx/ocsp.md +++ b/lib/ngx/ocsp.md @@ -264,7 +264,7 @@ Please report bugs or submit patches by Author ====== -Yichun Zhang <agentzh@gmail.com> (agentzh), CloudFlare Inc. +Yichun Zhang <agentzh@gmail.com> (agentzh), OpenResty Inc. [Back to TOC](#table-of-contents) @@ -273,7 +273,7 @@ Copyright and License This module is licensed under the BSD license. -Copyright (C) 2015, by Yichun "agentzh" Zhang, CloudFlare Inc. +Copyright (C) 2015-2017, by Yichun "agentzh" Zhang, OpenResty Inc. All rights reserved. diff --git a/lib/ngx/re.md b/lib/ngx/re.md index a76080abe..aff47ac19 100644 --- a/lib/ngx/re.md +++ b/lib/ngx/re.md @@ -176,7 +176,7 @@ Copyright and License This module is licensed under the BSD license. -Copyright (C) 2016, by Yichun "agentzh" Zhang, CloudFlare Inc. +Copyright (C) 2016-2017, by Yichun "agentzh" Zhang, OpenResty Inc. All rights reserved. diff --git a/lib/ngx/semaphore.md b/lib/ngx/semaphore.md index aad9576ba..8c9314fa6 100644 --- a/lib/ngx/semaphore.md +++ b/lib/ngx/semaphore.md @@ -332,7 +332,7 @@ Copyright and License This module is licensed under the BSD license. -Copyright (C) 2015, by Yichun "agentzh" Zhang, CloudFlare Inc. +Copyright (C) 2015-2017, by Yichun "agentzh" Zhang, OpenResty Inc. All rights reserved. diff --git a/lib/ngx/ssl.md b/lib/ngx/ssl.md index 8ca2b9871..fc7ecae5f 100644 --- a/lib/ngx/ssl.md +++ b/lib/ngx/ssl.md @@ -413,7 +413,7 @@ Please report bugs or submit patches by Author ====== -Yichun Zhang <agentzh@gmail.com> (agentzh), CloudFlare Inc. +Yichun Zhang <agentzh@gmail.com> (agentzh), OpenResty Inc. [Back to TOC](#table-of-contents) @@ -422,7 +422,7 @@ Copyright and License This module is licensed under the BSD license. -Copyright (C) 2015, by Yichun "agentzh" Zhang, CloudFlare Inc. +Copyright (C) 2015-2017, by Yichun "agentzh" Zhang, OpenResty Inc. All rights reserved. diff --git a/lib/ngx/ssl/session.md b/lib/ngx/ssl/session.md index 30708545f..fe8522702 100644 --- a/lib/ngx/ssl/session.md +++ b/lib/ngx/ssl/session.md @@ -243,7 +243,7 @@ Please report bugs or submit patches by Author ====== -Yichun Zhang <agentzh@gmail.com> (agentzh), CloudFlare Inc. +Yichun Zhang <agentzh@gmail.com> (agentzh), OpenResty Inc. [Back to TOC](#table-of-contents) @@ -252,7 +252,7 @@ Copyright and License This module is licensed under the BSD license. -Copyright (C) 2016, by Yichun "agentzh" Zhang, CloudFlare Inc. +Copyright (C) 2016-2017, by Yichun "agentzh" Zhang, OpenResty Inc. All rights reserved. From dd9f57f72fb1ca10efb6860493b1991eb3c662fd Mon Sep 17 00:00:00 2001 From: "Yichun Zhang (agentzh)" Date: Mon, 2 Jan 2017 15:47:41 -0800 Subject: [PATCH 11/74] feature: resty.core.regex: exported internal helper functions collect_captures, check_buf_size, and re_sub_compile. These functions are deliberately undocumented and thus subject to future changes. --- lib/resty/core/regex.lua | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/resty/core/regex.lua b/lib/resty/core/regex.lua index fad7ae856..6031faf2a 100644 --- a/lib/resty/core/regex.lua +++ b/lib/resty/core/regex.lua @@ -281,6 +281,9 @@ local function collect_captures(compiled, rc, subj, flags, res) end +_M.collect_captures = collect_captures + + local function destroy_compiled_regex(compiled) C.ngx_http_lua_ffi_destroy_regex(ffi_gc(compiled, nil)) end @@ -491,6 +494,9 @@ local function check_buf_size(buf, buf_size, pos, len, new_len, must_alloc) end +_M.check_buf_size = check_buf_size + + local function re_sub_compile(regex, opts, replace, func) local flags = 0 local pcre_opts = 0 @@ -593,6 +599,9 @@ local function re_sub_compile(regex, opts, replace, func) end +_M.re_sub_compile = re_sub_compile + + local function re_sub_func_helper(subj, regex, replace, opts, global) local compiled, compile_once, flags = re_sub_compile(regex, opts, nil, replace) From 8c0bf1c8a3253371d4a2c156305a8da7692475ba Mon Sep 17 00:00:00 2001 From: doujiang24 Date: Sat, 7 Jan 2017 15:34:27 +0800 Subject: [PATCH 12/74] bugfix: ngx.re: split() might enter infinite loops when the regex is an empty string. Signed-off-by: Yichun Zhang (agentzh) --- lib/ngx/re.lua | 28 ++++++++- lib/ngx/re.md | 10 ++++ t/re-split.t | 160 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 197 insertions(+), 1 deletion(-) diff --git a/lib/ngx/re.lua b/lib/ngx/re.lua index 85234700d..efe37ea37 100644 --- a/lib/ngx/re.lua +++ b/lib/ngx/re.lua @@ -115,6 +115,32 @@ function _M.split(subj, regex, opts, ctx, max, res) return error("res is not a table", 2) end + local len = #subj + if ctx.pos > len then + res[1] = nil + return res + end + + if regex == "" then + local pos = ctx.pos + local last = len + if max > 0 then + last = math_min(len, pos + max - 1) + end + + local res_idx = 1 + while pos < last do + res[res_idx] = sub(subj, pos, pos) + res_idx = res_idx + 1 + pos = pos + 1 + end + + res[res_idx] = sub(subj, pos) + res[res_idx + 1] = nil + + return res + end + -- compile regex local compiled, compile_once, flags = re_match_compile(regex, opts) @@ -186,7 +212,7 @@ function _M.split(subj, regex, opts, ctx, max, res) -- trailing nil for non-cleared res tables - res[res_idx + 1] = sub(subj, sub_idx, #subj) + res[res_idx + 1] = sub(subj, sub_idx) res[res_idx + 2] = nil return res diff --git a/lib/ngx/re.md b/lib/ngx/re.md index aff47ac19..7fbfd0c85 100644 --- a/lib/ngx/re.md +++ b/lib/ngx/re.md @@ -78,6 +78,16 @@ local res, err = ngx_re.split("a,b,c,d", "(,)") -- res is now {"a", ",", "b", ",", "c", ",", "d"} ``` +When `regex` is empty string `""`, the `subject` will be split into chars, +like so: + +```lua +local ngx_re = require "ngx.re" + +local res, err = ngx_re.split("abcd", "") +-- res is now {"a", "b", "c", "d"} +``` + The optional `ctx` table argument can be a Lua table holding an optional `pos` field. When the `pos` field in the `ctx` table argument is specified, `ngx_re.split` will start splitting the `subject` from that index: diff --git a/t/re-split.t b/t/re-split.t index e10108b71..bccee4c4c 100644 --- a/t/re-split.t +++ b/t/re-split.t @@ -705,3 +705,163 @@ qr/\[TRACE \d+/ --- no_error_log [error] attempt to get length of local 'subj' (a number value) + + + +=== TEST 21: split matches, pos is larger than subject length +--- http_config eval: $::HttpConfig +--- config + location = /re { + content_by_lua_block { + local ngx_re = require "ngx.re" + + local res, err = ngx_re.split("a,b,c,d,e", ",", nil, { pos = 10 }) + if err then + ngx.log(ngx.ERR, "failed: ", err) + return + end + + for i = 1, #res do + ngx.say(res[i]) + end + ngx.say("len: ", #res) + } + } +--- request +GET /re +--- response_body +len: 0 +--- no_error_log +[error] +[TRACE + + + +=== TEST 22: regex is "" +--- http_config eval: $::HttpConfig +--- config + location /re { + content_by_lua_block { + local ngx_re = require "ngx.re" + + local res, err = ngx_re.split("12345", "", "jo") + if err then + ngx.log(ngx.ERR, "failed: ", err) + return + end + + for i = 1, #res do + ngx.say(res[i]) + end + + ngx.say("len: ", #res) + } + } +--- request +GET /re +--- response_body +1 +2 +3 +4 +5 +len: 5 +--- no_error_log +[error] +[TRACE + + + +=== TEST 23: regex is "" with pos +--- http_config eval: $::HttpConfig +--- config + location /re { + content_by_lua_block { + local ngx_re = require "ngx.re" + + local res, err = ngx_re.split("12345", "", "jo", { pos = 2 }) + if err then + ngx.log(ngx.ERR, "failed: ", err) + return + end + + for i = 1, #res do + ngx.say(res[i]) + end + + ngx.say("len: ", #res) + } + } +--- request +GET /re +--- response_body +2 +3 +4 +5 +len: 4 +--- no_error_log +[error] +[TRACE + + + +=== TEST 24: regex is "" with pos larger than subject length +--- http_config eval: $::HttpConfig +--- config + location /re { + content_by_lua_block { + local ngx_re = require "ngx.re" + + local res, err = ngx_re.split("12345", "", "jo", { pos = 10 }) + if err then + ngx.log(ngx.ERR, "failed: ", err) + return + end + + for i = 1, #res do + ngx.say(res[i]) + end + + ngx.say("len: ", #res) + } + } +--- request +GET /re +--- response_body +len: 0 +--- no_error_log +[error] +[TRACE + + + +=== TEST 25: regex is "" with pos & max +--- http_config eval: $::HttpConfig +--- config + location /re { + content_by_lua_block { + local ngx_re = require "ngx.re" + + local res, err = ngx_re.split("12345", "", "jo", { pos = 2 }, 2) + if err then + ngx.log(ngx.ERR, "failed: ", err) + return + end + + for i = 1, #res do + ngx.say(res[i]) + end + + ngx.say("len: ", #res) + } + } +--- request +GET /re +--- response_body +2 +345 +len: 2 +--- no_error_log +[error] +[TRACE From a76cb9cc7bf74e9ed51504a239d1997859e10b88 Mon Sep 17 00:00:00 2001 From: "Yichun Zhang (agentzh)" Date: Mon, 9 Jan 2017 13:13:34 -0800 Subject: [PATCH 13/74] resty.core: made the warning louder by turning it to an alert when LuaJIT 2.0 is used. --- lib/resty/core/base.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/resty/core/base.lua b/lib/resty/core/base.lua index 7dbc9828d..384d7a237 100644 --- a/lib/resty/core/base.lua +++ b/lib/resty/core/base.lua @@ -22,7 +22,7 @@ end if string.find(jit.version, " 2.0") then - ngx.log(ngx.WARN, "use of lua-resty-core with LuaJIT 2.0 is " + ngx.log(ngx.ALERT, "use of lua-resty-core with LuaJIT 2.0 is " .. "not recommended; use LuaJIT 2.1+ instead") end From 4c53de363f34e0f26146797ff1108f5af6d3d7a5 Mon Sep 17 00:00:00 2001 From: "Yichun Zhang (agentzh)" Date: Mon, 9 Jan 2017 13:18:44 -0800 Subject: [PATCH 14/74] optimize: avoided string concat in the previous commit. thanks Thibault Charbonnier for the catch. --- lib/resty/core/base.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/resty/core/base.lua b/lib/resty/core/base.lua index 384d7a237..91b882e2a 100644 --- a/lib/resty/core/base.lua +++ b/lib/resty/core/base.lua @@ -22,8 +22,8 @@ end if string.find(jit.version, " 2.0") then - ngx.log(ngx.ALERT, "use of lua-resty-core with LuaJIT 2.0 is " - .. "not recommended; use LuaJIT 2.1+ instead") + ngx.log(ngx.ALERT, "use of lua-resty-core with LuaJIT 2.0 is ", + "not recommended; use LuaJIT 2.1+ instead") end From 8d1480a450d3b1221fd104f4dfae1227b64f5d54 Mon Sep 17 00:00:00 2001 From: Andreas Lubbe Date: Mon, 9 Jan 2017 16:48:57 +0100 Subject: [PATCH 15/74] travis-ci: updated openssl to 1.0.2j. Signed-off-by: Yichun Zhang (agentzh) --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4bfe8e7dd..e05d71b94 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,7 +25,7 @@ env: - OPENSSL_PREFIX=/opt/ssl - OPENSSL_LIB=$OPENSSL_PREFIX/lib - OPENSSL_INC=$OPENSSL_PREFIX/include - - OPENSSL_VER=1.0.2h + - OPENSSL_VER=1.0.2j - LD_LIBRARY_PATH=$LUAJIT_LIB:$LD_LIBRARY_PATH - TEST_NGINX_SLEEP=0.006 matrix: @@ -57,8 +57,8 @@ script: - cd lua-resty-lrucache && sudo make DESTDIR=$LUAJIT_PREFIX LUA_LIB_DIR=/share/lua/5.1 install && cd .. - tar zxf download-cache/openssl-$OPENSSL_VER.tar.gz - cd openssl-$OPENSSL_VER/ - - wget https://raw.githubusercontent.com/openresty/openresty/master/patches/openssl-$OPENSSL_VER-sess_set_get_cb_yield.patch - - patch -p1 < openssl-$OPENSSL_VER-sess_set_get_cb_yield.patch + - if [ ! -f openssl-1.0.2h-sess_set_get_cb_yield.patch ]; then wget -O openssl-1.0.2h-sess_set_get_cb_yield.patch https://raw.githubusercontent.com/openresty/openresty/master/patches/openssl-1.0.2h-sess_set_get_cb_yield.patch; fi + - patch -p1 < openssl-1.0.2h-sess_set_get_cb_yield.patch - ./config shared --prefix=$OPENSSL_PREFIX -DPURIFY > build.log 2>&1 || (cat build.log && exit 1) - make -j$JOBS > build.log 2>&1 || (cat build.log && exit 1) - sudo make PATH=$PATH install_sw > build.log 2>&1 || (cat build.log && exit 1) From ef197ad86d1e29228fa6eb7d20963fd9af705bcd Mon Sep 17 00:00:00 2001 From: "Yichun Zhang (agentzh)" Date: Thu, 12 Jan 2017 11:01:25 -0800 Subject: [PATCH 16/74] fixed or work-around warnings from luacheck. --- lib/ngx/semaphore.lua | 3 ++- lib/resty/core/base.lua | 3 ++- lib/resty/core/exit.lua | 2 +- lib/resty/core/regex.lua | 18 ++++++++++-------- lib/resty/core/shdict.lua | 20 ++++++++++---------- 5 files changed, 25 insertions(+), 21 deletions(-) diff --git a/lib/ngx/semaphore.lua b/lib/ngx/semaphore.lua index dc28c30ab..0d9234b87 100644 --- a/lib/ngx/semaphore.lua +++ b/lib/ngx/semaphore.lua @@ -114,7 +114,8 @@ function _M.wait(self, seconds) -- might need the current function call's activation -- record to hold the reference to our semaphore object -- to prevent it from getting GC'd prematurely. - local ok, err = co_yield() + local ok + ok, err = co_yield() return ok, err end diff --git a/lib/resty/core/base.lua b/lib/resty/core/base.lua index 91b882e2a..db441878b 100644 --- a/lib/resty/core/base.lua +++ b/lib/resty/core/base.lua @@ -33,7 +33,8 @@ if not ok then end -local ok, clear_tab = pcall(require, "table.clear") +local clear_tab +ok, clear_tab = pcall(require, "table.clear") if not ok then clear_tab = function (tab) for k, _ in pairs(tab) do diff --git a/lib/resty/core/exit.lua b/lib/resty/core/exit.lua index 2fad312aa..210069cdd 100644 --- a/lib/resty/core/exit.lua +++ b/lib/resty/core/exit.lua @@ -31,7 +31,7 @@ ngx.exit = function (rc) return error("no request found") end errlen[0] = ERR_BUF_SIZE - local rc = C.ngx_http_lua_ffi_exit(r, rc, err, errlen) + rc = C.ngx_http_lua_ffi_exit(r, rc, err, errlen) if rc == 0 then -- print("yielding...") return co_yield() diff --git a/lib/resty/core/regex.lua b/lib/resty/core/regex.lua index 6031faf2a..3cf8eca0c 100644 --- a/lib/resty/core/regex.lua +++ b/lib/resty/core/regex.lua @@ -656,10 +656,10 @@ local function re_sub_func_helper(subj, regex, replace, opts, global) local res = collect_captures(compiled, rc, subj, flags) - local bit = tostring(replace(res)) - local bit_len = #bit + local piece = tostring(replace(res)) + local piece_len = #piece - local new_dst_len = dst_len + prefix_len + bit_len + local new_dst_len = dst_len + prefix_len + piece_len dst_buf, dst_buf_size, dst_pos, dst_len = check_buf_size(dst_buf, dst_buf_size, dst_pos, dst_len, new_dst_len, true) @@ -670,9 +670,9 @@ local function re_sub_func_helper(subj, regex, replace, opts, global) dst_pos = dst_pos + prefix_len end - if bit_len > 0 then - ffi_copy(dst_pos, bit, bit_len) - dst_pos = dst_pos + bit_len + if piece_len > 0 then + ffi_copy(dst_pos, piece, piece_len) + dst_pos = dst_pos + piece_len end cp_pos = compiled.captures[1] @@ -698,7 +698,8 @@ local function re_sub_func_helper(subj, regex, replace, opts, global) local suffix_len = subj_len - cp_pos local new_dst_len = dst_len + suffix_len - dst_buf, dst_buf_size, dst_pos, dst_len = + local _ + dst_buf, _, dst_pos, dst_len = check_buf_size(dst_buf, dst_buf_size, dst_pos, dst_len, new_dst_len, true) @@ -827,7 +828,8 @@ local function re_sub_str_helper(subj, regex, replace, opts, global) local suffix_len = subj_len - cp_pos local new_dst_len = dst_len + suffix_len - dst_buf, dst_buf_size, dst_pos, dst_len = + local _ + dst_buf, _, dst_pos, dst_len = check_buf_size(dst_buf, dst_buf_size, dst_pos, dst_len, new_dst_len) diff --git a/lib/resty/core/shdict.lua b/lib/resty/core/shdict.lua index 76e41b31f..7ab55eda6 100644 --- a/lib/resty/core/shdict.lua +++ b/lib/resty/core/shdict.lua @@ -98,9 +98,9 @@ local function shdict_store(zone, op, key, value, exptime, flags) return nil, "key too long" end - local str_value_buf - local str_value_len = 0 - local num_value = 0 + local str_val_buf + local str_val_len = 0 + local num_val = 0 local valtyp = type(value) -- print("value type: ", valtyp) @@ -108,27 +108,27 @@ local function shdict_store(zone, op, key, value, exptime, flags) if valtyp == "string" then valtyp = 4 -- LUA_TSTRING - str_value_buf = value - str_value_len = #value + str_val_buf = value + str_val_len = #value elseif valtyp == "number" then valtyp = 3 -- LUA_TNUMBER - num_value = value + num_val = value elseif value == nil then valtyp = 0 -- LUA_TNIL elseif valtyp == "boolean" then valtyp = 1 -- LUA_TBOOLEAN - num_value = value and 1 or 0 + num_val = value and 1 or 0 else return nil, "bad value type" end local rc = C.ngx_http_lua_ffi_shdict_store(zone, op, key, key_len, - valtyp, str_value_buf, - str_value_len, num_value, + valtyp, str_val_buf, + str_val_len, num_val, exptime * 1000, flags, errmsg, forcible) @@ -388,7 +388,7 @@ end if ngx_shared then - local name, dict = next(ngx_shared, nil) + local _, dict = next(ngx_shared, nil) if dict then local mt = getmetatable(dict) if mt then From edef85621ad86bc13c2c8ab4ea927f8e12adb433 Mon Sep 17 00:00:00 2001 From: zhuyan Date: Thu, 12 Jan 2017 17:58:48 +0800 Subject: [PATCH 17/74] travis-ci: added luacheck testing. --- .luacheckrc | 2 ++ .travis.yml | 14 ++++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 .luacheckrc diff --git a/.luacheckrc b/.luacheckrc new file mode 100644 index 000000000..57560fa6c --- /dev/null +++ b/.luacheckrc @@ -0,0 +1,2 @@ +std = 'ngx_lua' +unused_args = false diff --git a/.travis.yml b/.travis.yml index e05d71b94..2e5fa2a9c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,6 +9,13 @@ compiler: - gcc - clang +addons: + apt: + packages: + - cpanminus + - axel + - luarocks + cache: directories: - download-cache @@ -32,11 +39,14 @@ env: - NGINX_VERSION=1.9.15 - NGINX_VERSION=1.11.2 +before_install: + - sudo luarocks install luacheck + - luacheck -q . + - sudo cpanm --notest Test::Nginx > build.log 2>&1 || (cat build.log && exit 1) + install: - if [ ! -d download-cache ]; then mkdir download-cache; fi - if [ ! -f download-cache/openssl-$OPENSSL_VER.tar.gz ]; then wget -O download-cache/openssl-$OPENSSL_VER.tar.gz https://www.openssl.org/source/openssl-$OPENSSL_VER.tar.gz; fi - - sudo apt-get install -qq -y cpanminus axel - - sudo cpanm --notest Test::Nginx > build.log 2>&1 || (cat build.log && exit 1) - wget http://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz - git clone https://github.com/openresty/openresty.git ../openresty - git clone https://github.com/openresty/nginx-devel-utils.git From bd85d8465366ba83be66aaa89b074baec1598165 Mon Sep 17 00:00:00 2001 From: "Yichun Zhang (agentzh)" Date: Thu, 12 Jan 2017 11:39:46 -0800 Subject: [PATCH 18/74] travis-ci: added checks for any uses of tabs and lines longer than 80 cols in Lua source files. --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 2e5fa2a9c..76ab84d00 100644 --- a/.travis.yml +++ b/.travis.yml @@ -42,6 +42,8 @@ env: before_install: - sudo luarocks install luacheck - luacheck -q . + - '! grep -n -P ''(?<=.{80}).+'' --color `find . -name ''*.lua''` || (echo "ERROR: Found Lua source lines exceeding 80 columns." > /dev/stderr; exit 1)' + - '! grep -n -P ''\t+'' --color `find . -name ''*.lua''` || (echo "ERROR: Cannot use tabs." > /dev/stderr; exit 1)' - sudo cpanm --notest Test::Nginx > build.log 2>&1 || (cat build.log && exit 1) install: From 729e1861282e1e4ae478825daa44950d7fecdae3 Mon Sep 17 00:00:00 2001 From: Robert Paprocki Date: Sun, 12 Feb 2017 20:48:57 -0800 Subject: [PATCH 19/74] tests: refactored tests to use _by_lua_block directives exclusively. Signed-off-by: Yichun Zhang (agentzh) --- t/count.t | 8 ++-- t/ctx.t | 12 ++--- t/decode-base64.t | 28 ++++++------ t/encode-base64.t | 36 +++++++-------- t/exit.t | 12 ++--- t/md5.t | 20 ++++---- t/md5_bin.t | 20 ++++---- t/misc.t | 16 +++---- t/re-find.t | 28 ++++++------ t/re-match.t | 70 ++++++++++++++-------------- t/re-sub.t | 48 +++++++++---------- t/request.t | 68 +++++++++++++-------------- t/response.t | 32 ++++++------- t/sha1_bin.t | 20 ++++---- t/shdict.t | 112 ++++++++++++++++++++++----------------------- t/status.t | 12 ++--- t/time.t | 12 ++--- t/uri.t | 44 +++++++++--------- t/var.t | 32 ++++++------- t/worker.t | 20 ++++---- t/worker_count_5.t | 8 ++-- 21 files changed, 329 insertions(+), 329 deletions(-) diff --git a/t/count.t b/t/count.t index 74e61bcea..3042651d1 100644 --- a/t/count.t +++ b/t/count.t @@ -15,7 +15,7 @@ my $pwd = cwd(); our $HttpConfig = <<_EOC_; lua_package_path "$pwd/lib/?.lua;../lua-resty-lrucache/lib/?.lua;;"; - init_by_lua ' + init_by_lua_block { -- local verbose = true local verbose = false local outfile = "$Test::Nginx::Util::ErrLogFile" @@ -32,7 +32,7 @@ our $HttpConfig = <<_EOC_; -- jit.opt.start("hotloop=1") -- jit.opt.start("loopunroll=1000000") -- jit.off() - '; + } _EOC_ #no_diff(); @@ -46,14 +46,14 @@ __DATA__ --- config location = /re { access_log off; - content_by_lua ' + content_by_lua_block { local base = require "resty.core.base" local n = 0 for _, _ in pairs(base) do n = n + 1 end ngx.say("base size: ", n) - '; + } } --- request GET /re diff --git a/t/ctx.t b/t/ctx.t index a848ea0c8..8520c975a 100644 --- a/t/ctx.t +++ b/t/ctx.t @@ -16,7 +16,7 @@ my $pwd = cwd(); our $HttpConfig = <<_EOC_; lua_package_path "$pwd/lib/?.lua;\$prefix/html/?.lua;../lua-resty-lrucache/lib/?.lua;;"; - init_by_lua ' + init_by_lua_block { local verbose = false if verbose then local dump = require "jit.dump" @@ -28,7 +28,7 @@ our $HttpConfig = <<_EOC_; require "resty.core" -- jit.off() - '; + } _EOC_ #no_diff(); @@ -42,12 +42,12 @@ __DATA__ --- http_config eval: $::HttpConfig --- config location = /t { - content_by_lua ' + content_by_lua_block { for i = 1, 100 do ngx.ctx.foo = i end ngx.say("ctx.foo = ", ngx.ctx.foo) - '; + } } --- request GET /t @@ -66,12 +66,12 @@ qr/\[TRACE\s+\d+\s+content_by_lua\(nginx\.conf:\d+\):2 loop\]/ --- http_config eval: $::HttpConfig --- config location = /t { - content_by_lua ' + content_by_lua_block { for i = 1, 100 do ngx.ctx = {foo = i} end ngx.say("ctx.foo = ", ngx.ctx.foo) - '; + } } --- request GET /t diff --git a/t/decode-base64.t b/t/decode-base64.t index 632d0808e..efc91f6ad 100644 --- a/t/decode-base64.t +++ b/t/decode-base64.t @@ -15,7 +15,7 @@ my $pwd = cwd(); our $HttpConfig = <<_EOC_; lua_package_path "$pwd/lib/?.lua;../lua-resty-lrucache/lib/?.lua;;"; - init_by_lua ' + init_by_lua_block { local verbose = false if verbose then local dump = require "jit.dump" @@ -27,7 +27,7 @@ our $HttpConfig = <<_EOC_; require "resty.core" -- jit.off() - '; + } _EOC_ #no_diff(); @@ -41,13 +41,13 @@ __DATA__ --- http_config eval: $::HttpConfig --- config location = /base64 { - content_by_lua ' + content_by_lua_block { local s for i = 1, 100 do s = ngx.decode_base64("aGVsbG8=") end ngx.say(s) - '; + } } --- request GET /base64 @@ -65,13 +65,13 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):3 loop\]/ --- http_config eval: $::HttpConfig --- config location = /base64 { - content_by_lua ' + content_by_lua_block { local s for i = 1, 100 do s = ngx.decode_base64("") end ngx.say(s) - '; + } } --- request GET /base64 @@ -88,13 +88,13 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):3 loop\]/ --- http_config eval: $::HttpConfig --- config location = /base64 { - content_by_lua ' + content_by_lua_block { local s for i = 1, 100 do s = ngx.decode_base64("My4xNA==") end ngx.say(s) - '; + } } --- request GET /base64 @@ -112,13 +112,13 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):3 loop\]/ --- http_config eval: $::HttpConfig --- config location = /base64 { - content_by_lua ' + content_by_lua_block { local s for i = 1, 100 do s = ngx.decode_base64("dHJ1ZQ==") end ngx.say(s) - '; + } } --- request GET /base64 @@ -136,7 +136,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):3 loop\]/ --- http_config eval: $::HttpConfig --- config location = /base64 { - content_by_lua ' + content_by_lua_block { local s for i = 1, 100 do s = ngx.decode_base64(string.rep("a", 5460)) @@ -146,7 +146,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):3 loop\]/ else ngx.say(string.len(s)) end - '; + } } --- request GET /base64 @@ -164,7 +164,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):3 loop\]/ --- http_config eval: $::HttpConfig --- config location = /base64 { - content_by_lua ' + content_by_lua_block { local s for i = 1, 100 do s = ngx.decode_base64(string.rep("a", 5462)) @@ -174,7 +174,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):3 loop\]/ else ngx.say(string.len(s)) end - '; + } } --- request GET /base64 diff --git a/t/encode-base64.t b/t/encode-base64.t index f6bda6978..d9ae34b70 100644 --- a/t/encode-base64.t +++ b/t/encode-base64.t @@ -15,7 +15,7 @@ my $pwd = cwd(); our $HttpConfig = <<_EOC_; lua_package_path "$pwd/lib/?.lua;../lua-resty-lrucache/lib/?.lua;;"; - init_by_lua ' + init_by_lua_block { local verbose = false if verbose then local dump = require "jit.dump" @@ -27,7 +27,7 @@ our $HttpConfig = <<_EOC_; require "resty.core" -- jit.off() - '; + } _EOC_ #no_diff(); @@ -41,13 +41,13 @@ __DATA__ --- http_config eval: $::HttpConfig --- config location = /base64 { - content_by_lua ' + content_by_lua_block { local s for i = 1, 100 do s = ngx.encode_base64("hello") end ngx.say(s) - '; + } } --- request GET /base64 @@ -65,13 +65,13 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):3 loop\]/ --- http_config eval: $::HttpConfig --- config location = /base64 { - content_by_lua ' + content_by_lua_block { local s for i = 1, 100 do s = ngx.encode_base64(nil) end ngx.say(s) - '; + } } --- request GET /base64 @@ -88,13 +88,13 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):3 loop\]/ --- http_config eval: $::HttpConfig --- config location = /base64 { - content_by_lua ' + content_by_lua_block { local s for i = 1, 100 do s = ngx.encode_base64(3.14) end ngx.say(s) - '; + } } --- request GET /base64 @@ -112,13 +112,13 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):3 loop\]/ --- http_config eval: $::HttpConfig --- config location = /base64 { - content_by_lua ' + content_by_lua_block { local s for i = 1, 100 do s = ngx.encode_base64(true) end ngx.say(s) - '; + } } --- request GET /base64 @@ -136,13 +136,13 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):3 loop\]/ --- http_config eval: $::HttpConfig --- config location = /base64 { - content_by_lua ' + content_by_lua_block { local s for i = 1, 100 do s = ngx.encode_base64(string.rep("a", 3073)) end ngx.say(string.len(s)) - '; + } } --- request GET /base64 @@ -160,13 +160,13 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):3 loop\]/ --- http_config eval: $::HttpConfig --- config location = /base64 { - content_by_lua ' + content_by_lua_block { local s for i = 1, 100 do s = ngx.encode_base64(string.rep("a", 3071)) end ngx.say(string.len(s)) - '; + } } --- request GET /base64 @@ -184,13 +184,13 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):3 loop\]/ --- http_config eval: $::HttpConfig --- config location = /base64 { - content_by_lua ' + content_by_lua_block { local s for i = 1, 200 do s = ngx.encode_base64(3.14, true) end ngx.say(s) - '; + } } --- request GET /base64 @@ -208,13 +208,13 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):3 loop\]/ --- http_config eval: $::HttpConfig --- config location = /base64 { - content_by_lua ' + content_by_lua_block { local s for i = 1, 200 do s = ngx.encode_base64(3.14, false) end ngx.say(s) - '; + } } --- request GET /base64 diff --git a/t/exit.t b/t/exit.t index 86cebb91d..89b997f6d 100644 --- a/t/exit.t +++ b/t/exit.t @@ -16,7 +16,7 @@ my $pwd = cwd(); our $HttpConfig = <<_EOC_; lua_package_path "$pwd/lib/?.lua;\$prefix/html/?.lua;../lua-resty-lrucache/lib/?.lua;;"; - init_by_lua ' + init_by_lua_block { local verbose = false if verbose then local dump = require "jit.dump" @@ -28,7 +28,7 @@ our $HttpConfig = <<_EOC_; require "resty.core" -- jit.off() - '; + } _EOC_ #no_diff(); @@ -41,9 +41,9 @@ __DATA__ --- http_config eval: $::HttpConfig --- config location = /t { - content_by_lua ' + content_by_lua_block { ngx.exit(403) - '; + } } --- request GET /t @@ -60,10 +60,10 @@ qr/ -- NYI: (?!FastFunc coroutine.yield)/, --- http_config eval: $::HttpConfig --- config location = /t { - content_by_lua ' + content_by_lua_block { local foo = require "foo" foo.go() - '; + } } --- user_files >>> foo.lua diff --git a/t/md5.t b/t/md5.t index 73a5f16a3..59830aceb 100644 --- a/t/md5.t +++ b/t/md5.t @@ -15,11 +15,11 @@ my $pwd = cwd(); our $HttpConfig = <<_EOC_; lua_package_path "$pwd/lib/?.lua;../lua-resty-lrucache/lib/?.lua;;"; - init_by_lua ' + init_by_lua_block { local v = require "jit.v" v.on("$Test::Nginx::Util::ErrLogFile") require "resty.core" - '; + } _EOC_ #no_diff(); @@ -33,13 +33,13 @@ __DATA__ --- http_config eval: $::HttpConfig --- config location = /md5 { - content_by_lua ' + content_by_lua_block { local s for i = 1, 100 do s = ngx.md5("hello") end ngx.say(s) - '; + } } --- request GET /md5 @@ -56,13 +56,13 @@ qr/\[TRACE 1 content_by_lua\(nginx\.conf:\d+\):3 loop\]/ --- http_config eval: $::HttpConfig --- config location = /md5 { - content_by_lua ' + content_by_lua_block { local s for i = 1, 100 do s = ngx.md5(nil) end ngx.say(s) - '; + } } --- request GET /md5 @@ -79,13 +79,13 @@ qr/\[TRACE 1 content_by_lua\(nginx\.conf:\d+\):3 loop\]/ --- http_config eval: $::HttpConfig --- config location /md5 { - content_by_lua ' + content_by_lua_block { local s for i = 1, 100 do s = ngx.md5("") end ngx.say(s) - '; + } } --- request GET /md5 @@ -102,13 +102,13 @@ qr/\[TRACE 1 content_by_lua\(nginx\.conf:\d+\):3 loop\]/ --- http_config eval: $::HttpConfig --- config location /md5 { - content_by_lua ' + content_by_lua_block { local s for i = 1, 100 do s = ngx.md5(3.14) end ngx.say(s) - '; + } } --- request GET /md5 diff --git a/t/md5_bin.t b/t/md5_bin.t index decc7e7dd..a95886402 100644 --- a/t/md5_bin.t +++ b/t/md5_bin.t @@ -15,7 +15,7 @@ my $pwd = cwd(); our $HttpConfig = <<_EOC_; lua_package_path "$pwd/lib/?.lua;../lua-resty-lrucache/lib/?.lua;;"; - init_by_lua ' + init_by_lua_block { local verbose = false if verbose then local dump = require "jit.dump" @@ -27,7 +27,7 @@ our $HttpConfig = <<_EOC_; require "resty.core" -- jit.off() - '; + } _EOC_ #no_diff(); @@ -41,13 +41,13 @@ __DATA__ --- http_config eval: $::HttpConfig --- config location = /md5_bin { - content_by_lua ' + content_by_lua_block { local s for i = 1, 100 do s = ngx.md5_bin("hello") end ngx.say(string.len(s)) - '; + } } --- request GET /md5_bin @@ -64,13 +64,13 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):3 loop\]/ --- http_config eval: $::HttpConfig --- config location = /md5_bin { - content_by_lua ' + content_by_lua_block { local s for i = 1, 100 do s = ngx.md5_bin(nil) end ngx.say(string.len(s)) - '; + } } --- request GET /md5_bin @@ -87,13 +87,13 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):3 loop\]/ --- http_config eval: $::HttpConfig --- config location = /md5_bin { - content_by_lua ' + content_by_lua_block { local s for i = 1, 100 do s = ngx.md5_bin(3.14) end ngx.say(string.len(s)) - '; + } } --- request GET /md5_bin @@ -110,13 +110,13 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):3 loop\]/ --- http_config eval: $::HttpConfig --- config location = /md5_bin { - content_by_lua ' + content_by_lua_block { local s for i = 1, 100 do s = ngx.md5_bin(true) end ngx.say(string.len(s)) - '; + } } --- request GET /md5_bin diff --git a/t/misc.t b/t/misc.t index 213731e01..2fb70df9f 100644 --- a/t/misc.t +++ b/t/misc.t @@ -16,7 +16,7 @@ my $pwd = cwd(); our $HttpConfig = <<_EOC_; lua_package_path "$pwd/lib/?.lua;\$prefix/html/?.lua;../lua-resty-lrucache/lib/?.lua;;"; - init_by_lua ' + init_by_lua_block { local verbose = false if verbose then local dump = require "jit.dump" @@ -28,7 +28,7 @@ our $HttpConfig = <<_EOC_; require "resty.core" -- jit.off() - '; + } _EOC_ #no_diff(); @@ -43,13 +43,13 @@ __DATA__ --- config location = /t { return 201; - header_filter_by_lua ' + header_filter_by_lua_block { local rc for i = 1, 100 do rc = ngx.is_subrequest end ngx.log(ngx.WARN, "is subrequest: ", rc) - '; + } } --- request GET /t @@ -70,13 +70,13 @@ qr/\[TRACE\s+\d+\s+header_filter_by_lua:3 loop\]/ --- http_config eval: $::HttpConfig --- config location = /t { - content_by_lua ' + content_by_lua_block { local rc for i = 1, 100 do rc = ngx.headers_sent end ngx.say("headers sent: ", rc) - '; + } } --- request GET /t @@ -95,14 +95,14 @@ qr/\[TRACE\s+\d+\s+content_by_lua\(nginx\.conf:\d+\):3 loop\]/ --- http_config eval: $::HttpConfig --- config location = /t { - content_by_lua ' + content_by_lua_block { ngx.send_headers() local rc for i = 1, 100 do rc = ngx.headers_sent end ngx.say("headers sent: ", rc) - '; + } } --- request GET /t diff --git a/t/re-find.t b/t/re-find.t index 3b2c889bb..b896949a2 100644 --- a/t/re-find.t +++ b/t/re-find.t @@ -15,7 +15,7 @@ my $pwd = cwd(); our $HttpConfig = <<_EOC_; lua_package_path "$pwd/lib/?.lua;../lua-resty-lrucache/lib/?.lua;;"; - init_by_lua ' + init_by_lua_block { -- local verbose = true local verbose = false local outfile = "$Test::Nginx::Util::ErrLogFile" @@ -32,7 +32,7 @@ our $HttpConfig = <<_EOC_; -- jit.opt.start("hotloop=1") -- jit.opt.start("loopunroll=1000000") -- jit.off() - '; + } _EOC_ #no_diff(); @@ -47,7 +47,7 @@ __DATA__ --- config location = /re { access_log off; - content_by_lua ' + content_by_lua_block { local from, to, err local find = ngx.re.find local s = "a" @@ -65,7 +65,7 @@ __DATA__ ngx.say("from: ", from) ngx.say("to: ", to) ngx.say("matched: ", string.sub(s, from, to)) - '; + } } --- request GET /re @@ -86,7 +86,7 @@ bad argument type --- config location = /re { access_log off; - content_by_lua ' + content_by_lua_block { local from, to, err local find = ngx.re.find local s = "a" @@ -104,7 +104,7 @@ bad argument type ngx.say("from: ", from) ngx.say("to: ", to) ngx.say("matched: ", string.sub(s, from, to)) - '; + } } --- request GET /re @@ -125,7 +125,7 @@ NYI --- config location = /re { access_log off; - content_by_lua ' + content_by_lua_block { local from, to, err local find = ngx.re.find local s = "b" @@ -143,7 +143,7 @@ NYI ngx.say("from: ", from) ngx.say("to: ", to) ngx.say("matched: ", string.sub(s, from, to)) - '; + } } --- request GET /re @@ -161,7 +161,7 @@ NYI --- http_config eval: $::HttpConfig --- config location /re { - content_by_lua ' + content_by_lua_block { local s = "hello, 1234" local from, to, err for i = 1, 100 do @@ -178,7 +178,7 @@ NYI end ngx.say("not matched!") end - '; + } } --- request GET /re @@ -196,7 +196,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):4 loop\]/ --- http_config eval: $::HttpConfig --- config location /re { - content_by_lua ' + content_by_lua_block { local s = "hello, 1234" local from, to, err for i = 1, 400 do @@ -213,7 +213,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):4 loop\]/ end ngx.say("not matched!") end - '; + } } --- request GET /re @@ -231,7 +231,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):4 loop\]/ --- http_config eval: $::HttpConfig --- config location /re { - content_by_lua ' + content_by_lua_block { local s = "hello, 1234" local from, to, err for i = 1, 100 do @@ -247,7 +247,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):4 loop\]/ end ngx.say("not matched!") end - '; + } } --- request GET /re diff --git a/t/re-match.t b/t/re-match.t index 02a856c80..53fa6abb8 100644 --- a/t/re-match.t +++ b/t/re-match.t @@ -15,7 +15,7 @@ my $pwd = cwd(); our $HttpConfig = <<_EOC_; lua_package_path "$pwd/lib/?.lua;../lua-resty-lrucache/lib/?.lua;;"; - init_by_lua ' + init_by_lua_block { -- local verbose = true local verbose = false local outfile = "$Test::Nginx::Util::ErrLogFile" @@ -32,7 +32,7 @@ our $HttpConfig = <<_EOC_; -- jit.opt.start("hotloop=1") -- jit.opt.start("loopunroll=1000000") -- jit.off() - '; + } _EOC_ #no_diff(); @@ -47,7 +47,7 @@ __DATA__ --- config location = /re { access_log off; - content_by_lua ' + content_by_lua_block { local m, err local match = ngx.re.match for i = 1, 400 do @@ -66,7 +66,7 @@ __DATA__ -- ngx.say("$2: ", m[2]) -- ngx.say("$3: ", m[3]) -- collectgarbage() - '; + } } --- request GET /re @@ -86,7 +86,7 @@ bad argument type --- config location = /re { access_log off; - content_by_lua ' + content_by_lua_block { local m, err local match = ngx.re.match for i = 1, 400 do @@ -103,7 +103,7 @@ bad argument type ngx.say("matched: ", m[0]) ngx.say("$1: ", m[1]) -- collectgarbage() - '; + } } --- request GET /re @@ -123,7 +123,7 @@ NYI --- config location = /re { access_log off; - content_by_lua ' + content_by_lua_block { local m, err local match = ngx.re.match for i = 1, 200 do @@ -140,7 +140,7 @@ NYI ngx.say("matched: ", m[0]) ngx.say("$1: ", m[1]) -- collectgarbage() - '; + } } --- request GET /re @@ -158,7 +158,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):4 loop\]/ --- config location = /re { access_log off; - content_by_lua ' + content_by_lua_block { local m, err local match = ngx.re.match for i = 1, 100 do @@ -175,7 +175,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):4 loop\]/ ngx.say("matched: ", m[0]) ngx.say("$1: ", m[1]) -- collectgarbage() - '; + } } --- request GET /re @@ -194,11 +194,11 @@ bad argument type --- config location = /re { access_log off; - content_by_lua ' + content_by_lua_block { local m, err local match = ngx.re.match for i = 1, 100 do - m, err = match("hello, 1234", [[(\\d)(\\d+)]]) + m, err = match("hello, 1234", [[(\d)(\d+)]]) end if err then ngx.log(ngx.ERR, "failed: ", err) @@ -213,7 +213,7 @@ bad argument type ngx.say("$2: ", m[2]) ngx.say("$3: ", m[3]) -- collectgarbage() - '; + } } --- request GET /re @@ -234,11 +234,11 @@ NYI --- config location = /re { access_log off; - content_by_lua ' + content_by_lua_block { local m, err local match = ngx.re.match for i = 1, 100 do - m, err = match("hello, 1234", [[(\\d)(\\d+)]], "jo") + m, err = match("hello, 1234", [[(\d)(\d+)]], "jo") end if err then ngx.log(ngx.ERR, "failed: ", err) @@ -254,7 +254,7 @@ NYI ngx.say("$3: ", m[3]) -- ngx.say(table.maxn(m)) -- collectgarbage() - '; + } } --- request GET /re @@ -276,7 +276,7 @@ NYI --- http_config eval: $::HttpConfig --- config location /re { - content_by_lua ' + content_by_lua_block { local m, err local match = ngx.re.match for i = 1, 100 do @@ -294,7 +294,7 @@ NYI end ngx.say("not matched!") end - '; + } } --- request GET /re @@ -317,7 +317,7 @@ NYI --- http_config eval: $::HttpConfig --- config location /re { - content_by_lua ' + content_by_lua_block { local m, err local match = ngx.re.match for i = 1, 200 do @@ -335,7 +335,7 @@ NYI end ngx.say("not matched!") end - '; + } } --- request GET /re @@ -355,7 +355,7 @@ NYI --- http_config eval: $::HttpConfig --- config location /re { - content_by_lua ' + content_by_lua_block { local m, err local match = ngx.re.match for i = 1, 100 do @@ -378,7 +378,7 @@ NYI end ngx.say("not matched!") end - '; + } } --- request GET /re @@ -402,7 +402,7 @@ NYI --- http_config eval: $::HttpConfig --- config location /re { - content_by_lua ' + content_by_lua_block { local new_tab = require "table.new" local clear_tab = require "table.clear" local m @@ -422,7 +422,7 @@ NYI else ngx.say("not matched!") end - '; + } } --- request GET /re @@ -445,7 +445,7 @@ qr/\[TRACE\s+\d+\s+/ --- http_config eval: $::HttpConfig --- config location /re { - content_by_lua ' + content_by_lua_block { local m = ngx.re.match("hello!", "(hello)(, .+)?(!)", "jo") if m then @@ -456,7 +456,7 @@ qr/\[TRACE\s+\d+\s+/ else ngx.say("not matched!") end - '; + } } --- request GET /re @@ -477,7 +477,7 @@ qr/\[TRACE\s+\d+\s+/ --- http_config eval: $::HttpConfig --- config location /re { - content_by_lua ' + content_by_lua_block { local m = ngx.re.match("hello", "(hello)(, .+)?(!)?", "jo") if m then @@ -488,7 +488,7 @@ qr/\[TRACE\s+\d+\s+/ else ngx.say("not matched!") end - '; + } } --- request GET /re @@ -509,7 +509,7 @@ qr/\[TRACE\s+\d+\s+/ --- http_config eval: $::HttpConfig --- config location /re { - content_by_lua ' + content_by_lua_block { local m = ngx.re.match("hello!", "(?hello)(?, .+)?(?!)", "jo") if m then @@ -523,7 +523,7 @@ qr/\[TRACE\s+\d+\s+/ else ngx.say("not matched!") end - '; + } } --- request GET /re @@ -547,8 +547,8 @@ qr/\[TRACE\s+\d+\s+/ --- http_config eval: $::HttpConfig --- config location /re { - content_by_lua ' - local m = ngx.re.match(12345, [=[(\\d+)]=], "jo") + content_by_lua_block { + local m = ngx.re.match(12345, [=[(\d+)]=], "jo") if m then ngx.say(m[0]) @@ -556,7 +556,7 @@ qr/\[TRACE\s+\d+\s+/ else ngx.say("not matched") end - '; + } } --- request GET /re @@ -573,7 +573,7 @@ attempt to get length of local 'subj' (a number value) --- http_config eval: $::HttpConfig --- config location /re { - content_by_lua ' + content_by_lua_block { local m = ngx.re.match(12345, "123", "jo") if m then @@ -581,7 +581,7 @@ attempt to get length of local 'subj' (a number value) else ngx.say("not matched") end - '; + } } --- request GET /re diff --git a/t/re-sub.t b/t/re-sub.t index f8af6918a..d0d32da3c 100644 --- a/t/re-sub.t +++ b/t/re-sub.t @@ -15,7 +15,7 @@ my $pwd = cwd(); our $HttpConfig = <<_EOC_; lua_package_path "$pwd/lib/?.lua;../lua-resty-lrucache/lib/?.lua;;"; - init_by_lua ' + init_by_lua_block { -- local verbose = true local verbose = false local outfile = "$Test::Nginx::Util::ErrLogFile" @@ -32,7 +32,7 @@ our $HttpConfig = <<_EOC_; -- jit.opt.start("hotloop=1") -- jit.opt.start("loopunroll=1000000") -- jit.off() - '; + } _EOC_ #no_diff(); @@ -47,7 +47,7 @@ __DATA__ --- config location = /re { access_log off; - content_by_lua ' + content_by_lua_block { local m, err local sub = ngx.re.sub for i = 1, 350 do @@ -59,7 +59,7 @@ __DATA__ end ngx.say("s: ", s) ngx.say("n: ", n) - '; + } } --- request GET /re @@ -80,7 +80,7 @@ NYI --- config location = /re { access_log off; - content_by_lua ' + content_by_lua_block { local m, err local sub = ngx.re.sub for i = 1, 400 do @@ -92,7 +92,7 @@ NYI end ngx.say("s: ", s) ngx.say("n: ", n) - '; + } } --- request GET /re @@ -112,7 +112,7 @@ bad argument type --- config location = /re { access_log off; - content_by_lua ' + content_by_lua_block { local m, err local function f(m) return "[" .. m[0] .. "(" .. m[1] .. ")]" @@ -127,7 +127,7 @@ bad argument type end ngx.say("s: ", s) ngx.say("n: ", n) - '; + } } --- request GET /re @@ -148,7 +148,7 @@ qr/NYI (?!bytecode 51 at)/, --- config location = /re { access_log off; - content_by_lua ' + content_by_lua_block { local m, err local sub = ngx.re.sub for i = 1, 350 do @@ -160,7 +160,7 @@ qr/NYI (?!bytecode 51 at)/, end ngx.say("s: ", s) ngx.say("n: ", n) - '; + } } --- request GET /re @@ -182,7 +182,7 @@ NYI --- config location = /re { access_log off; - content_by_lua ' + content_by_lua_block { local m, err local gsub = ngx.re.gsub local subj = string.rep("bcbd", 2048) @@ -195,7 +195,7 @@ NYI end ngx.say("s: ", s) ngx.say("n: ", n) - '; + } } --- request GET /re @@ -214,7 +214,7 @@ bad argument type --- config location = /t { - content_by_lua ' + content_by_lua_block { local data = [[ INNER INNER @@ -229,7 +229,7 @@ location = /t { end, "s") ngx.print(res) - '; + } } --- request @@ -250,7 +250,7 @@ NYI --- config location = /t { - content_by_lua ' + content_by_lua_block { local data = [[ INNER INNER @@ -265,7 +265,7 @@ location = /t { end, "s") ngx.print(res) - '; + } } --- request @@ -286,7 +286,7 @@ NYI --- config location = /t { - content_by_lua ' + content_by_lua_block { function test() local data = [[ OUTER {FIRST} @@ -314,7 +314,7 @@ location = /t { end test() - '; + } } --- request GET /t @@ -332,11 +332,11 @@ NYI --- http_config eval: $::HttpConfig --- config location /re { - content_by_lua ' + content_by_lua_block { local newstr, n, err = ngx.re.sub(1234, "([0-9])[0-9]", 5, "jo") ngx.say(newstr) - '; + } } --- request GET /re @@ -352,7 +352,7 @@ attempt to get length of local 'subj' (a number value) --- http_config eval: $::HttpConfig --- config location /re { - content_by_lua ' + content_by_lua_block { local lookup = function(m) -- note we are returning a number type here return 5 @@ -360,7 +360,7 @@ attempt to get length of local 'subj' (a number value) local newstr, n, err = ngx.re.sub("hello, 1234", "([0-9])[0-9]", lookup, "jo") ngx.say(newstr) - '; + } } --- request GET /re @@ -376,7 +376,7 @@ attempt to get length of local 'bit' (a number value) --- http_config eval: $::HttpConfig --- config location /re { - content_by_lua ' + content_by_lua_block { local lookup = function(m) -- note we are returning a number type here return 5 @@ -384,7 +384,7 @@ attempt to get length of local 'bit' (a number value) local newstr, n, err = ngx.re.gsub("hello, 1234", "([0-9])[0-9]", lookup, "jo") ngx.say(newstr) - '; + } } --- request GET /re diff --git a/t/request.t b/t/request.t index 3d13035c2..4d1b6209c 100644 --- a/t/request.t +++ b/t/request.t @@ -16,7 +16,7 @@ my $pwd = cwd(); our $HttpConfig = <<_EOC_; lua_shared_dict dogs 1m; lua_package_path "$pwd/lib/?.lua;../lua-resty-lrucache/lib/?.lua;;"; - init_by_lua ' + init_by_lua_block { local verbose = false if verbose then local dump = require "jit.dump" @@ -28,7 +28,7 @@ our $HttpConfig = <<_EOC_; require "resty.core" -- jit.off() - '; + } _EOC_ #no_diff(); @@ -43,7 +43,7 @@ __DATA__ --- config location = /t { set $foo hello; - content_by_lua ' + content_by_lua_block { local ffi = require "ffi" local headers for i = 1, 200 do @@ -57,7 +57,7 @@ __DATA__ for _, k in ipairs(keys) do ngx.say(k, ": ", headers[k]) end - '; + } } --- request GET /t @@ -86,7 +86,7 @@ qr/ -- NYI: (?!return to lower frame)/, --- config location = /t { set $foo hello; - content_by_lua ' + content_by_lua_block { local ffi = require "ffi" local headers for i = 1, 200 do @@ -100,7 +100,7 @@ qr/ -- NYI: (?!return to lower frame)/, for _, k in ipairs(keys) do ngx.say(k, ": ", headers[k]) end - '; + } } --- request GET /t @@ -127,7 +127,7 @@ qr/\[TRACE \d+ .*? -> 1\]/ --- config location = /t { set $foo hello; - content_by_lua ' + content_by_lua_block { local ffi = require "ffi" local headers for i = 1, 200 do @@ -141,7 +141,7 @@ qr/\[TRACE \d+ .*? -> 1\]/ for _, k in ipairs(keys) do ngx.say(k, ": ", headers[k]) end - '; + } } --- request GET /t @@ -165,7 +165,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):4 loop\]/ --- config location = /t { set $foo hello; - content_by_lua ' + content_by_lua_block { local ffi = require "ffi" local headers, header for i = 1, 100 do @@ -181,7 +181,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):4 loop\]/ for _, k in ipairs(keys) do ngx.say(k, ": ", headers[k]) end - '; + } } --- request GET /t @@ -208,7 +208,7 @@ qr/ -- NYI: (?!return to lower frame at)(?!C function 0x[0-9a-f]+ at content_by_ --- config location = /t { set $foo hello; - content_by_lua ' + content_by_lua_block { local ffi = require "ffi" local args for i = 1, 200 do @@ -231,7 +231,7 @@ qr/ -- NYI: (?!return to lower frame at)(?!C function 0x[0-9a-f]+ at content_by_ ngx.say(k, ": ", v) end end - '; + } } --- request GET /t?a=3%200&foo%20bar=&a=hello&blah @@ -253,7 +253,7 @@ qr/\[TRACE \d+ .*? -> \d+\]/ --- config location = /t { set $foo hello; - content_by_lua ' + content_by_lua_block { local ffi = require "ffi" local args for i = 1, 200 do @@ -276,7 +276,7 @@ qr/\[TRACE \d+ .*? -> \d+\]/ ngx.say(k, ": ", v) end end - '; + } } --- request GET /t? @@ -294,7 +294,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):4 loop\]/ --- config location = /t { access_log off; - content_by_lua ' + content_by_lua_block { local t for i = 1, 500 do t = ngx.req.start_time() @@ -305,7 +305,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):4 loop\]/ ngx.say(">= 0.099: ", elapsed >= 0.099) ngx.say("< 0.11: ", elapsed < 0.11) -- ngx.say(t, " ", elapsed) - '; + } } --- request GET /t @@ -328,13 +328,13 @@ stitch --- config location = /t { access_log off; - content_by_lua ' + content_by_lua_block { local t for i = 1, 500 do t = ngx.req.get_method() end ngx.say("method: ", t) - '; + } } --- request GET /t @@ -355,13 +355,13 @@ stitch --- config location = /t { access_log off; - content_by_lua ' + content_by_lua_block { local t for i = 1, 500 do t = ngx.req.get_method() end ngx.say("method: ", t) - '; + } } --- request OPTIONS /t @@ -382,14 +382,14 @@ stitch --- config location = /t { access_log off; - content_by_lua ' + content_by_lua_block { local t for i = 1, 500 do t = ngx.req.get_method() end ngx.say("method: ", t) ngx.req.discard_body() - '; + } } --- request POST /t @@ -411,14 +411,14 @@ stitch --- config location = /t { access_log off; - content_by_lua ' + content_by_lua_block { local t for i = 1, 500 do t = ngx.req.get_method() end ngx.say("method: ", t) ngx.req.discard_body() - '; + } } --- request BLAH /t @@ -440,14 +440,14 @@ stitch --- config location = /t { access_log off; - content_by_lua ' + content_by_lua_block { local t for i = 1, 500 do t = ngx.req.get_method() end ngx.say("method: ", t) ngx.req.discard_body() - '; + } } --- request CONNECT /t @@ -469,13 +469,13 @@ stitch --- config location = /t { access_log off; - content_by_lua ' + content_by_lua_block { local t for i = 1, 500 do ngx.req.set_method(ngx.HTTP_PUT) end ngx.say("method: ", ngx.req.get_method()) - '; + } } --- request GET /t @@ -496,13 +496,13 @@ stitch --- config location = /t { access_log off; - content_by_lua ' + content_by_lua_block { local t for i = 1, 500 do ngx.req.set_header("foo", i) end ngx.say("header foo: ", ngx.var.http_foo) - '; + } } --- request GET /t @@ -523,13 +523,13 @@ stitch --- config location = /t { access_log off; - content_by_lua ' + content_by_lua_block { local t for i = 1, 500 do ngx.req.set_header("foo", nil) end ngx.say("header foo: ", type(ngx.var.http_foo)) - '; + } } --- request GET /t @@ -550,14 +550,14 @@ stitch --- config location = /t { access_log off; - content_by_lua ' + content_by_lua_block { ngx.req.set_header("foo", "hello") local t for i = 1, 500 do t = ngx.req.clear_header("foo") end ngx.say("header foo: ", type(ngx.var.http_foo)) - '; + } } --- request GET /t diff --git a/t/response.t b/t/response.t index 885101887..b075f3886 100644 --- a/t/response.t +++ b/t/response.t @@ -16,7 +16,7 @@ my $pwd = cwd(); our $HttpConfig = <<_EOC_; lua_shared_dict dogs 1m; lua_package_path "$pwd/lib/?.lua;../lua-resty-lrucache/lib/?.lua;;"; - init_by_lua ' + init_by_lua_block { local verbose = false if verbose then local dump = require "jit.dump" @@ -28,7 +28,7 @@ our $HttpConfig = <<_EOC_; require "resty.core" -- jit.off() - '; + } _EOC_ #no_diff(); @@ -43,12 +43,12 @@ __DATA__ --- config location = /t { set $foo hello; - content_by_lua ' + content_by_lua_block { for i = 1, 100 do ngx.header["Foo"] = i end ngx.say("Foo: ", ngx.header["Foo"]) - '; + } } --- request GET /t @@ -68,13 +68,13 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):2 loop\]/ --- config location = /t { set $foo hello; - content_by_lua ' + content_by_lua_block { for i = 1, 200 do ngx.header["Foo"] = i ngx.header["Foo"] = nil end ngx.say("Foo: ", ngx.header["Foo"]) - '; + } } --- request GET /t @@ -95,7 +95,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):2 loop\]/ --- config location = /t { set $foo hello; - content_by_lua ' + content_by_lua_block { for i = 1, 200 do ngx.header["Foo"] = {i, i + 1} end @@ -105,7 +105,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):2 loop\]/ else ngx.say("Foo: ", v) end - '; + } } --- request GET /t @@ -125,14 +125,14 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):2 loop\]/ --- config location = /t { set $foo hello; - content_by_lua ' + content_by_lua_block { local v for i = 1, 100 do ngx.header["Foo"] = i v = ngx.header["Foo"] end ngx.say("Foo: ", v) - '; + } } --- request GET /t @@ -155,13 +155,13 @@ qr/ -- NYI: (?!return to lower frame)/, --- config location = /t { set $foo hello; - content_by_lua ' + content_by_lua_block { local v for i = 1, 100 do v = ngx.header["Foo"] end ngx.say("Foo: ", v) - '; + } } --- request GET /t @@ -182,14 +182,14 @@ stitch --- config location = /t { set $foo hello; - content_by_lua ' + content_by_lua_block { ngx.header["Foo"] = {"foo", "bar"} local v for i = 1, 100 do v = ngx.header["Foo"] end ngx.say("Foo: ", table.concat(v, ", ")) - '; + } } --- request GET /t @@ -209,7 +209,7 @@ stitch --- http_config eval: $::HttpConfig --- config location /lua { - content_by_lua ' + content_by_lua_block { ngx.header.cache_control = { "private", "no-store" } ngx.header.cache_control = { "no-cache", "blah", "foo" } local v @@ -217,7 +217,7 @@ stitch v = ngx.header.cache_control end ngx.say("Cache-Control: ", table.concat(v, ", ")) - '; + } } --- request GET /lua diff --git a/t/sha1_bin.t b/t/sha1_bin.t index 818794191..5551c143e 100644 --- a/t/sha1_bin.t +++ b/t/sha1_bin.t @@ -15,7 +15,7 @@ my $pwd = cwd(); our $HttpConfig = <<_EOC_; lua_package_path "$pwd/lib/?.lua;../lua-resty-lrucache/lib/?.lua;;"; - init_by_lua ' + init_by_lua_block { local verbose = false if verbose then local dump = require "jit.dump" @@ -27,7 +27,7 @@ our $HttpConfig = <<_EOC_; require "resty.core" -- jit.off() - '; + } _EOC_ #no_diff(); @@ -41,13 +41,13 @@ __DATA__ --- http_config eval: $::HttpConfig --- config location = /sha1_bin { - content_by_lua ' + content_by_lua_block { local s for i = 1, 100 do s = ngx.sha1_bin("hello") end ngx.say(string.len(s)) - '; + } } --- request GET /sha1_bin @@ -64,13 +64,13 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):3 loop\]/ --- http_config eval: $::HttpConfig --- config location = /sha1_bin { - content_by_lua ' + content_by_lua_block { local s for i = 1, 100 do s = ngx.sha1_bin(nil) end ngx.say(string.len(s)) - '; + } } --- request GET /sha1_bin @@ -87,13 +87,13 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):3 loop\]/ --- http_config eval: $::HttpConfig --- config location = /sha1_bin { - content_by_lua ' + content_by_lua_block { local s for i = 1, 100 do s = ngx.sha1_bin(3.14) end ngx.say(string.len(s)) - '; + } } --- request GET /sha1_bin @@ -110,13 +110,13 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):3 loop\]/ --- http_config eval: $::HttpConfig --- config location = /sha1_bin { - content_by_lua ' + content_by_lua_block { local s for i = 1, 100 do s = ngx.sha1_bin(true) end ngx.say(string.len(s)) - '; + } } --- request GET /sha1_bin diff --git a/t/shdict.t b/t/shdict.t index 5d1f415fe..f1dd547c4 100644 --- a/t/shdict.t +++ b/t/shdict.t @@ -16,7 +16,7 @@ my $pwd = cwd(); our $HttpConfig = <<_EOC_; lua_shared_dict dogs 1m; lua_package_path "$pwd/lib/?.lua;../lua-resty-lrucache/lib/?.lua;;"; - init_by_lua ' + init_by_lua_block { local verbose = false if verbose then local dump = require "jit.dump" @@ -28,7 +28,7 @@ our $HttpConfig = <<_EOC_; require "resty.core" -- jit.off() - '; + } _EOC_ #no_diff(); @@ -42,7 +42,7 @@ __DATA__ --- http_config eval: $::HttpConfig --- config location = /t { - content_by_lua ' + content_by_lua_block { local ffi = require "ffi" local val, flags local dogs = ngx.shared.dogs @@ -58,7 +58,7 @@ __DATA__ ngx.say("value type: ", type(val)) ngx.say("value: ", val) ngx.say("flags: ", flags) - '; + } } --- request GET /t @@ -78,7 +78,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):11 loop\]/ --- http_config eval: $::HttpConfig --- config location = /t { - content_by_lua ' + content_by_lua_block { local ffi = require "ffi" local val, flags local dogs = ngx.shared.dogs @@ -90,7 +90,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):11 loop\]/ ngx.say("value type: ", type(val)) ngx.say("value: ", val) ngx.say("flags: ", flags) - '; + } } --- request GET /t @@ -110,7 +110,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):7 loop\]/ --- http_config eval: $::HttpConfig --- config location = /t { - content_by_lua ' + content_by_lua_block { local ffi = require "ffi" local val, flags local dogs = ngx.shared.dogs @@ -122,7 +122,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):7 loop\]/ ngx.say("value type: ", type(val)) ngx.say("value: ", val) ngx.say("flags: ", flags) - '; + } } --- request GET /t @@ -142,7 +142,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):7 loop\]/ --- http_config eval: $::HttpConfig --- config location = /t { - content_by_lua ' + content_by_lua_block { local ffi = require "ffi" local val, flags local dogs = ngx.shared.dogs @@ -154,7 +154,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):7 loop\]/ ngx.say("value type: ", type(val)) ngx.say("value: ", val) ngx.say("flags: ", flags) - '; + } } --- request GET /t @@ -174,7 +174,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):7 loop\]/ --- http_config eval: $::HttpConfig --- config location = /t { - content_by_lua ' + content_by_lua_block { local ffi = require "ffi" local val, flags local dogs = ngx.shared.dogs @@ -186,7 +186,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):7 loop\]/ ngx.say("value type: ", type(val)) ngx.say("value: ", val) ngx.say("flags: ", flags) - '; + } } --- request GET /t @@ -206,7 +206,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):7 loop\]/ --- http_config eval: $::HttpConfig --- config location = /t { - content_by_lua ' + content_by_lua_block { local ffi = require "ffi" local val, flags local dogs = ngx.shared.dogs @@ -218,7 +218,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):7 loop\]/ ngx.say("value type: ", type(val)) ngx.say("value: ", val) ngx.say("flags: ", flags) - '; + } } --- request GET /t @@ -238,7 +238,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):7 loop\]/ --- http_config eval: $::HttpConfig --- config location = /t { - content_by_lua ' + content_by_lua_block { local ffi = require "ffi" local val, flags local dogs = ngx.shared.dogs @@ -250,7 +250,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):7 loop\]/ ngx.say("value type: ", type(val)) ngx.say("value: ", val) ngx.say("flags: ", flags) - '; + } } --- request GET /t @@ -271,7 +271,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):7 loop\]/ --- http_config eval: $::HttpConfig --- config location = /t { - content_by_lua ' + content_by_lua_block { local ffi = require "ffi" local val, flags, stale local dogs = ngx.shared.dogs @@ -284,7 +284,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):7 loop\]/ ngx.say("value: ", val) ngx.say("flags: ", flags) ngx.say("stale: ", stale) - '; + } } --- request GET /t @@ -305,7 +305,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):7 loop\]/ --- http_config eval: $::HttpConfig --- config location = /t { - content_by_lua ' + content_by_lua_block { local ffi = require "ffi" local val, flags, stale local dogs = ngx.shared.dogs @@ -323,7 +323,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):7 loop\]/ ngx.say("value: ", val) ngx.say("flags: ", flags) ngx.say("stale: ", stale) - '; + } } --- request GET /t @@ -344,7 +344,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):12 loop\]/ --- http_config eval: $::HttpConfig --- config location = /t { - content_by_lua ' + content_by_lua_block { local ffi = require "ffi" local val local dogs = ngx.shared.dogs @@ -359,7 +359,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):12 loop\]/ end ngx.say("value: ", val) ngx.say("err: ", err) - '; + } } --- request GET /t @@ -378,7 +378,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):11 loop\]/ --- http_config eval: $::HttpConfig --- config location = /t { - content_by_lua ' + content_by_lua_block { local ffi = require "ffi" local val local dogs = ngx.shared.dogs @@ -389,7 +389,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):11 loop\]/ end ngx.say("value: ", val) ngx.say("err: ", err) - '; + } } --- request GET /t @@ -408,7 +408,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):7 loop\]/ --- http_config eval: $::HttpConfig --- config location = /t { - content_by_lua ' + content_by_lua_block { local ffi = require "ffi" local val, flags local dogs = ngx.shared.dogs @@ -425,7 +425,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):7 loop\]/ ngx.say("value type: ", type(val)) ngx.say("value: ", val) ngx.say("flags: ", flags) - '; + } } --- request GET /t @@ -445,7 +445,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):7 loop\]/ --- http_config eval: $::HttpConfig --- config location = /t { - content_by_lua ' + content_by_lua_block { local ffi = require "ffi" local val, flags local dogs = ngx.shared.dogs @@ -462,7 +462,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):7 loop\]/ ngx.say("value type: ", type(val)) ngx.say("value: ", val) ngx.say("flags: ", flags) - '; + } } --- request GET /t @@ -482,7 +482,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):7 loop\]/ --- http_config eval: $::HttpConfig --- config location = /t { - content_by_lua ' + content_by_lua_block { local ffi = require "ffi" local val, flags local dogs = ngx.shared.dogs @@ -494,7 +494,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):7 loop\]/ ngx.say("value type: ", type(val)) ngx.say("value: ", val) ngx.say("flags: ", flags) - '; + } } --- request GET /t @@ -514,7 +514,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):6 loop\]/ --- http_config eval: $::HttpConfig --- config location = /t { - content_by_lua ' + content_by_lua_block { local ffi = require "ffi" local val, flags local dogs = ngx.shared.dogs @@ -526,7 +526,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):6 loop\]/ ngx.say("value type: ", type(val)) ngx.say("value: ", val) ngx.say("flags: ", flags) - '; + } } --- request GET /t @@ -546,7 +546,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):6 loop\]/ --- http_config eval: $::HttpConfig --- config location = /t { - content_by_lua ' + content_by_lua_block { local ffi = require "ffi" local val, flags local dogs = ngx.shared.dogs @@ -558,7 +558,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):6 loop\]/ ngx.say("value type: ", type(val)) ngx.say("value: ", val) ngx.say("flags: ", flags) - '; + } } --- request GET /t @@ -578,7 +578,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):6 loop\]/ --- http_config eval: $::HttpConfig --- config location = /t { - content_by_lua ' + content_by_lua_block { local ffi = require "ffi" local val, flags local dogs = ngx.shared.dogs @@ -591,7 +591,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):6 loop\]/ ngx.say("value type: ", type(val)) ngx.say("value: ", val) ngx.say("flags: ", flags) - '; + } } --- request GET /t @@ -611,7 +611,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):6 loop\]/ --- http_config eval: $::HttpConfig --- config location = /t { - content_by_lua ' + content_by_lua_block { local ffi = require "ffi" local val, flags local dogs = ngx.shared.dogs @@ -623,7 +623,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):6 loop\]/ ngx.say("value type: ", type(val)) ngx.say("value: ", val) ngx.say("flags: ", flags) - '; + } } --- request GET /t @@ -643,7 +643,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):6 loop\]/ --- http_config eval: $::HttpConfig --- config location = /t { - content_by_lua ' + content_by_lua_block { local ffi = require "ffi" local val, flags local dogs = ngx.shared.dogs @@ -661,7 +661,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):6 loop\]/ ngx.say("value type: ", type(val)) ngx.say("value: ", val) ngx.say("flags: ", flags) - '; + } } --- request GET /t @@ -681,7 +681,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):8 loop\]/ --- http_config eval: $::HttpConfig --- config location = /t { - content_by_lua ' + content_by_lua_block { local ffi = require "ffi" local val, flags local dogs = ngx.shared.dogs @@ -699,7 +699,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):8 loop\]/ ngx.say("value type: ", type(val)) ngx.say("value: ", val) ngx.say("flags: ", flags) - '; + } } --- request GET /t @@ -719,7 +719,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):8 loop\]/ --- http_config eval: $::HttpConfig --- config location = /t { - content_by_lua ' + content_by_lua_block { local ffi = require "ffi" local val, flags local dogs = ngx.shared.dogs @@ -737,7 +737,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):8 loop\]/ ngx.say("value type: ", type(val)) ngx.say("value: ", val) ngx.say("flags: ", flags) - '; + } } --- request GET /t @@ -757,7 +757,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):8 loop\]/ --- http_config eval: $::HttpConfig --- config location = /t { - content_by_lua ' + content_by_lua_block { local ffi = require "ffi" local val, flags local dogs = ngx.shared.dogs @@ -770,7 +770,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):8 loop\]/ ngx.say("value type: ", type(val)) ngx.say("value: ", val) ngx.say("flags: ", flags) - '; + } } --- request GET /t @@ -791,14 +791,14 @@ stitch --- http_config eval: $::HttpConfig --- config location = /t { - content_by_lua ' + content_by_lua_block { local val, flags local dogs = ngx.shared.dogs local ok, err = dogs:set(nil, "bar") if not ok then ngx.say("failed to set: ", err) end - '; + } } --- request GET /t @@ -815,14 +815,14 @@ failed to set: nil key --- http_config eval: $::HttpConfig --- config location = /t { - content_by_lua ' + content_by_lua_block { local val, flags local dogs = ngx.shared.dogs local value, err = dogs:get(nil, "bar") if not ok then ngx.say("failed to get: ", err) end - '; + } } --- request GET /t @@ -839,14 +839,14 @@ failed to get: nil key --- http_config eval: $::HttpConfig --- config location = /t { - content_by_lua ' + content_by_lua_block { local val, flags local dogs = ngx.shared.dogs local value, err = dogs:get_stale(nil, "bar") if not ok then ngx.say("failed to get stale: ", err) end - '; + } } --- request GET /t @@ -863,14 +863,14 @@ failed to get stale: nil key --- http_config eval: $::HttpConfig --- config location = /t { - content_by_lua ' + content_by_lua_block { local val, flags local dogs = ngx.shared.dogs local value, err = dogs:incr(nil, 32) if not value then ngx.say("failed to incr: ", err) end - '; + } } --- request GET /t @@ -887,7 +887,7 @@ failed to incr: nil key --- http_config eval: $::HttpConfig --- config location = /t { - content_by_lua ' + content_by_lua_block { local ffi = require "ffi" local val, flags local dogs = ngx.shared.dogs @@ -900,7 +900,7 @@ failed to incr: nil key ngx.say("value type: ", type(val)) ngx.say("value: ", val) ngx.say("flags: ", flags) - '; + } } --- request GET /t diff --git a/t/status.t b/t/status.t index e611b785c..1d10d8c90 100644 --- a/t/status.t +++ b/t/status.t @@ -16,7 +16,7 @@ my $pwd = cwd(); our $HttpConfig = <<_EOC_; lua_package_path "$pwd/lib/?.lua;\$prefix/html/?.lua;../lua-resty-lrucache/lib/?.lua;;"; - init_by_lua ' + init_by_lua_block { local verbose = false if verbose then local dump = require "jit.dump" @@ -28,7 +28,7 @@ our $HttpConfig = <<_EOC_; require "resty.core" -- jit.off() - '; + } _EOC_ #no_diff(); @@ -43,13 +43,13 @@ __DATA__ --- config location = /t { return 201; - header_filter_by_lua ' + header_filter_by_lua_block { local sum = 0 for i = 1, 100 do sum = sum + ngx.status end ngx.log(ngx.WARN, "sum: ", sum) - '; + } } --- request GET /t @@ -71,12 +71,12 @@ qr/\[TRACE\s+\d+\s+header_filter_by_lua:3 loop\]/ --- config location = /t { return 201; - header_filter_by_lua ' + header_filter_by_lua_block { for i = 100, 200 do ngx.status = i end ngx.log(ngx.WARN, "status: ", ngx.status) - '; + } } --- request GET /t diff --git a/t/time.t b/t/time.t index b9e1c7c40..4b4772a47 100644 --- a/t/time.t +++ b/t/time.t @@ -15,7 +15,7 @@ my $pwd = cwd(); our $HttpConfig = <<_EOC_; lua_package_path "$pwd/lib/?.lua;../lua-resty-lrucache/lib/?.lua;;"; - init_by_lua ' + init_by_lua_block { -- local verbose = true local verbose = false local outfile = "$Test::Nginx::Util::ErrLogFile" @@ -32,7 +32,7 @@ our $HttpConfig = <<_EOC_; -- jit.opt.start("hotloop=1") -- jit.opt.start("loopunroll=1000000") -- jit.off() - '; + } _EOC_ #no_diff(); @@ -47,7 +47,7 @@ __DATA__ --- config location = /t { access_log off; - content_by_lua ' + content_by_lua_block { local t for i = 1, 500 do t = ngx.now() @@ -58,7 +58,7 @@ __DATA__ ngx.say(">= 0.099: ", elapsed >= 0.099) ngx.say("< 0.11: ", elapsed < 0.11) -- ngx.say(t, " ", elapsed) - '; + } } --- request GET /t @@ -81,7 +81,7 @@ stitch --- config location = /t { access_log off; - content_by_lua ' + content_by_lua_block { local t for i = 1, 500 do t = ngx.time() @@ -89,7 +89,7 @@ stitch ngx.say(t > 1400960598) local diff = os.time() - t ngx.say(diff <= 1) - '; + } } --- request GET /t diff --git a/t/uri.t b/t/uri.t index cd531d458..8f852c7c1 100644 --- a/t/uri.t +++ b/t/uri.t @@ -15,7 +15,7 @@ my $pwd = cwd(); our $HttpConfig = <<_EOC_; lua_package_path "$pwd/lib/?.lua;../lua-resty-lrucache/lib/?.lua;;"; - init_by_lua ' + init_by_lua_block { local verbose = false if verbose then local dump = require "jit.dump" @@ -27,7 +27,7 @@ our $HttpConfig = <<_EOC_; require "resty.core" -- jit.off() - '; + } _EOC_ #no_diff(); @@ -41,13 +41,13 @@ __DATA__ --- http_config eval: $::HttpConfig --- config location = /uri { - content_by_lua ' + content_by_lua_block { local s for i = 1, 100 do s = ngx.unescape_uri("hello%20world") end ngx.say(s) - '; + } } --- request GET /uri @@ -64,13 +64,13 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):3 loop\]/ --- http_config eval: $::HttpConfig --- config location = /uri { - content_by_lua ' + content_by_lua_block { local s for i = 1, 100 do s = ngx.unescape_uri(nil) end ngx.say(s) - '; + } } --- request GET /uri @@ -86,13 +86,13 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):3 loop\]/ --- http_config eval: $::HttpConfig --- config location = /uri { - content_by_lua ' + content_by_lua_block { local s for i = 1, 100 do s = ngx.unescape_uri(3.14) end ngx.say(s) - '; + } } --- request GET /uri @@ -109,13 +109,13 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):3 loop\]/ --- http_config eval: $::HttpConfig --- config location = /uri { - content_by_lua ' + content_by_lua_block { local s for i = 1, 100 do s = ngx.escape_uri("hello world") end ngx.say(s) - '; + } } --- request GET /uri @@ -132,13 +132,13 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):3 loop\]/ --- http_config eval: $::HttpConfig --- config location = /uri { - content_by_lua ' + content_by_lua_block { local s for i = 1, 100 do s = ngx.escape_uri("helloworld") end ngx.say(s) - '; + } } --- request GET /uri @@ -155,13 +155,13 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):3 loop\]/ --- http_config eval: $::HttpConfig --- config location = /uri { - content_by_lua ' + content_by_lua_block { local s for i = 1, 100 do s = ngx.escape_uri(nil) end ngx.say(s) - '; + } } --- request GET /uri @@ -177,13 +177,13 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):3 loop\]/ --- http_config eval: $::HttpConfig --- config location = /uri { - content_by_lua ' + content_by_lua_block { local s for i = 1, 100 do s = ngx.escape_uri(3.14) end ngx.say(s) - '; + } } --- request GET /uri @@ -200,13 +200,13 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):3 loop\]/ --- http_config eval: $::HttpConfig --- config location = /uri { - content_by_lua ' + content_by_lua_block { local s for i = 1, 100 do s = ngx.escape_uri(string.rep("a", 4097)) end ngx.say(s) - '; + } } --- request GET /uri @@ -222,13 +222,13 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):3 loop\]/ --- http_config eval: $::HttpConfig --- config location = /uri { - content_by_lua ' + content_by_lua_block { local s for i = 1, 100 do s = ngx.escape_uri(string.rep(" ", 1365)) end ngx.say(s) - '; + } } --- request GET /uri @@ -244,13 +244,13 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):3 loop\]/ --- http_config eval: $::HttpConfig --- config location = /uri { - content_by_lua ' + content_by_lua_block { local s for i = 1, 100 do s = ngx.escape_uri(string.rep(" ", 1366)) end ngx.say(s) - '; + } } --- request GET /uri diff --git a/t/var.t b/t/var.t index a92464169..79a574f93 100644 --- a/t/var.t +++ b/t/var.t @@ -16,7 +16,7 @@ my $pwd = cwd(); our $HttpConfig = <<_EOC_; lua_shared_dict dogs 1m; lua_package_path "$pwd/lib/?.lua;../lua-resty-lrucache/lib/?.lua;;"; - init_by_lua ' + init_by_lua_block { local verbose = false if verbose then local dump = require "jit.dump" @@ -28,7 +28,7 @@ our $HttpConfig = <<_EOC_; require "resty.core" -- jit.off() - '; + } _EOC_ #no_diff(); @@ -43,14 +43,14 @@ __DATA__ --- config location = /t { set $foo hello; - content_by_lua ' + content_by_lua_block { local ffi = require "ffi" local val for i = 1, 100 do val = ngx.var.foo end ngx.say("value: ", val) - '; + } } --- request GET /t @@ -69,14 +69,14 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):4 loop\]/ --- config location = /t { set $foo hello; - content_by_lua ' + content_by_lua_block { local ffi = require "ffi" local val for i = 1, 100 do val = ngx.var.FOO end ngx.say("value: ", val) - '; + } } --- request GET /t @@ -95,14 +95,14 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):4 loop\]/ --- config location = /t { set $foo hello; - content_by_lua ' + content_by_lua_block { local ffi = require "ffi" local val for i = 1, 100 do val = ngx.var[0] end ngx.say("value: ", val) - '; + } } --- request GET /t @@ -121,14 +121,14 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):4 loop\]/ --- config location ~ '^(/t)' { set $foo hello; - content_by_lua ' + content_by_lua_block { local ffi = require "ffi" local val for i = 1, 100 do val = ngx.var[1] end ngx.say("value: ", val) - '; + } } --- request GET /t @@ -147,14 +147,14 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):4 loop\]/ --- config location = /t { set $foo hello; - content_by_lua ' + content_by_lua_block { local ffi = require "ffi" local val = "hello" for i = 1, 100 do ngx.var.foo = val end ngx.say("value: ", val) - '; + } } --- request GET /t @@ -173,13 +173,13 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):4 loop\]/ --- config location = /t { set $foo hello; - content_by_lua ' + content_by_lua_block { local ffi = require "ffi" for i = 1, 100 do ngx.var.foo = nil end ngx.say("value: ", ngx.var.foo) - '; + } } --- request GET /t @@ -198,13 +198,13 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):3 loop\]/ --- config location = /t { set $foo hello; - content_by_lua ' + content_by_lua_block { local ffi = require "ffi" for i = 1, 100 do ngx.var.foo = i end ngx.say("value: ", ngx.var.foo) - '; + } } --- request GET /t diff --git a/t/worker.t b/t/worker.t index 1083b1448..80ff4174b 100644 --- a/t/worker.t +++ b/t/worker.t @@ -16,7 +16,7 @@ my $pwd = cwd(); our $HttpConfig = <<_EOC_; lua_shared_dict dogs 1m; lua_package_path "$pwd/lib/?.lua;../lua-resty-lrucache/lib/?.lua;;"; - init_by_lua ' + init_by_lua_block { local verbose = false if verbose then local dump = require "jit.dump" @@ -28,7 +28,7 @@ our $HttpConfig = <<_EOC_; require "resty.core" -- jit.off() - '; + } _EOC_ #no_diff(); @@ -42,14 +42,14 @@ __DATA__ --- http_config eval: $::HttpConfig --- config location = /t { - content_by_lua ' + content_by_lua_block { local v local exiting = ngx.worker.exiting for i = 1, 400 do v = exiting() end ngx.say(v) - '; + } } --- request GET /t @@ -68,7 +68,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):4 loop\]/ --- http_config eval: $::HttpConfig --- config location = /t { - content_by_lua ' + content_by_lua_block { local v local pid = ngx.worker.pid for i = 1, 400 do @@ -76,7 +76,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):4 loop\]/ end ngx.say(v == tonumber(ngx.var.pid)) ngx.say(v) - '; + } } --- request GET /t @@ -96,14 +96,14 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):4 loop\]/ --- http_config eval: $::HttpConfig --- config location = /t { - content_by_lua ' + content_by_lua_block { local v local id = ngx.worker.id for i = 1, 400 do v = id() end ngx.say("worker id: ", v) - '; + } } --- request GET /t @@ -123,14 +123,14 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):4 loop\]/ --- http_config eval: $::HttpConfig --- config location = /t { - content_by_lua ' + content_by_lua_block { local v local count = ngx.worker.count for i = 1, 400 do v = count() end ngx.say("workers: ", v) - '; + } } --- request GET /t diff --git a/t/worker_count_5.t b/t/worker_count_5.t index c0d68282a..488ec521c 100644 --- a/t/worker_count_5.t +++ b/t/worker_count_5.t @@ -17,7 +17,7 @@ my $pwd = cwd(); our $HttpConfig = <<_EOC_; lua_shared_dict dogs 1m; lua_package_path "$pwd/lib/?.lua;../lua-resty-lrucache/lib/?.lua;;"; - init_by_lua ' + init_by_lua_block { local verbose = false if verbose then local dump = require "jit.dump" @@ -29,7 +29,7 @@ our $HttpConfig = <<_EOC_; require "resty.core" -- jit.off() - '; + } _EOC_ #no_diff(); @@ -43,14 +43,14 @@ __DATA__ --- http_config eval: $::HttpConfig --- config location = /t { - content_by_lua ' + content_by_lua_block { local v local count = ngx.worker.count for i = 1, 400 do v = count() end ngx.say("workers: ", v) - '; + } } --- request GET /t From b46a48f5e9bec49ec4eb65fbdadfb28d7b65eeb7 Mon Sep 17 00:00:00 2001 From: Thibault Charbonnier Date: Sat, 11 Mar 2017 14:49:31 -0800 Subject: [PATCH 20/74] luacheck: added 'coroutine._yield' to read-only globals. This fixes builds with Luacheck 0.19.0+. Signed-off-by: Yichun Zhang (agentzh) --- .luacheckrc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.luacheckrc b/.luacheckrc index 57560fa6c..8981e16a5 100644 --- a/.luacheckrc +++ b/.luacheckrc @@ -1,2 +1,5 @@ std = 'ngx_lua' unused_args = false +read_globals = { + "coroutine._yield" +} From 563063925c40d3319f432e62087d1d28c724936a Mon Sep 17 00:00:00 2001 From: "Yichun Zhang (agentzh)" Date: Sat, 25 Mar 2017 12:05:51 -0700 Subject: [PATCH 21/74] tests: make use of the $TEST_NGINX_SERVER_ROOT macro variable in the tests to allow the test suite runnable in parallel with `prove -jN`. --- t/ssl-session-fetch.t | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/t/ssl-session-fetch.t b/t/ssl-session-fetch.t index a35a66ecd..07dbfe3fd 100644 --- a/t/ssl-session-fetch.t +++ b/t/ssl-session-fetch.t @@ -1,4 +1,4 @@ -# vim:set ft=ts=4 sw=4 et fdm=marker: +# vim:set ft= ts=4 sw=4 et fdm=marker: use Test::Nginx::Socket::Lua; use Cwd qw(abs_path realpath cwd); @@ -211,7 +211,7 @@ In practice, never store session in plaintext on persistent storage. local sess = ssl.get_serialized_session() print("session size: ", #sess) - local f = assert(io.open("t/servroot/html/session.tmp", "w")) + local f = assert(io.open("$TEST_NGINX_SERVER_ROOT/html/session.tmp", "w")) f:write(sess) f:close() } @@ -220,7 +220,7 @@ In practice, never store session in plaintext on persistent storage. local ssl = require "ngx.ssl.session" local sid = ssl.get_session_id() print("session id: ", sid) - local f = assert(io.open("t/servroot/html/session.tmp")) + local f = assert(io.open("$TEST_NGINX_SERVER_ROOT/html/session.tmp")) local sess = f:read("*a") f:close() ssl.set_serialized_session(sess) From b3de52538767728ecf4cd1fb8fa48cfed5f2cc97 Mon Sep 17 00:00:00 2001 From: "Yichun Zhang (agentzh)" Date: Sat, 25 Mar 2017 12:08:40 -0700 Subject: [PATCH 22/74] travis-ci: run the test suite in parallel jobs. --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 76ab84d00..8898c7467 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,7 +22,7 @@ cache: env: global: - - JOBS=3 + - JOBS=2 - NGX_BUILD_JOBS=$JOBS - LUAJIT_PREFIX=/opt/luajit21 - LUAJIT_LIB=$LUAJIT_PREFIX/lib @@ -83,4 +83,4 @@ script: - ngx-build $NGINX_VERSION --with-ipv6 --with-http_realip_module --with-http_ssl_module --with-cc-opt="-I$OPENSSL_INC" --with-ld-opt="-L$OPENSSL_LIB -Wl,-rpath,$OPENSSL_LIB" --add-module=../ndk-nginx-module --add-module=../echo-nginx-module --add-module=../headers-more-nginx-module --add-module=../lua-nginx-module --with-debug > build.log 2>&1 || (cat build.log && exit 1) - nginx -V - ldd `which nginx`|grep -E 'luajit|ssl|pcre' - - prove -r t + - prove -j$(JOBS) -r t From 2cf8c4cc4d5d7f01a5dae34f36951648b7a10927 Mon Sep 17 00:00:00 2001 From: "Yichun Zhang (agentzh)" Date: Sat, 25 Mar 2017 12:13:56 -0700 Subject: [PATCH 23/74] travis-ci: uses the git repo of test-nginx. --- .travis.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8898c7467..834aaa84d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -34,7 +34,8 @@ env: - OPENSSL_INC=$OPENSSL_PREFIX/include - OPENSSL_VER=1.0.2j - LD_LIBRARY_PATH=$LUAJIT_LIB:$LD_LIBRARY_PATH - - TEST_NGINX_SLEEP=0.006 + - TEST_NGINX_SLEEP=0.005 + - TEST_NGINX_RANDOMIZE=1 matrix: - NGINX_VERSION=1.9.15 - NGINX_VERSION=1.11.2 @@ -60,6 +61,7 @@ install: - git clone https://github.com/openresty/headers-more-nginx-module.git ../headers-more-nginx-module - git clone -b v2.1-agentzh https://github.com/openresty/luajit2.git - git clone https://github.com/openresty/mockeagain.git + - git clone https://github.com/openresty/test-nginx.git script: - cd luajit2/ @@ -83,4 +85,4 @@ script: - ngx-build $NGINX_VERSION --with-ipv6 --with-http_realip_module --with-http_ssl_module --with-cc-opt="-I$OPENSSL_INC" --with-ld-opt="-L$OPENSSL_LIB -Wl,-rpath,$OPENSSL_LIB" --add-module=../ndk-nginx-module --add-module=../echo-nginx-module --add-module=../headers-more-nginx-module --add-module=../lua-nginx-module --with-debug > build.log 2>&1 || (cat build.log && exit 1) - nginx -V - ldd `which nginx`|grep -E 'luajit|ssl|pcre' - - prove -j$(JOBS) -r t + - prove -Itest-nginx/lib -j$JOBS -r t From 890000ebfa525e938274031fbf027fdbce970217 Mon Sep 17 00:00:00 2001 From: "Yichun Zhang (agentzh)" Date: Sat, 25 Mar 2017 15:05:36 -0700 Subject: [PATCH 24/74] tests: suppressed one conditional move/jump valgrind error which might be a false positive. --- valgrind.suppress | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/valgrind.suppress b/valgrind.suppress index 3a49ed39c..8ca53f5a9 100644 --- a/valgrind.suppress +++ b/valgrind.suppress @@ -58,3 +58,9 @@ fun:epoll_ctl fun:ngx_epoll_test_rdhup } +{ + + Memcheck:Cond + obj:* + obj:* +} From d96205d18e38e9910610b68811c6074548be9c35 Mon Sep 17 00:00:00 2001 From: xiaoxuanzi Date: Mon, 27 Mar 2017 10:56:22 +0800 Subject: [PATCH 25/74] doc: fixed a typo in balancer.md. Signed-off-by: Yichun Zhang (agentzh) --- lib/ngx/balancer.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ngx/balancer.md b/lib/ngx/balancer.md index e090e65c6..9b1e584f0 100644 --- a/lib/ngx/balancer.md +++ b/lib/ngx/balancer.md @@ -173,7 +173,7 @@ Zero and negative timeout values are not allowed. You can specify millisecond precision in the timeout values by using floating point numbers like 0.001 (which means 1ms). -Returns `true` when the operation is successul; returns `nil` and a string describing the error +Returns `true` when the operation is successful; returns `nil` and a string describing the error otherwise. This only affects the current downstream request. It is not a global change. From 4fff68d709360311089f8a4a9f1e2efb6da4f568 Mon Sep 17 00:00:00 2001 From: "Yichun Zhang (agentzh)" Date: Sun, 2 Apr 2017 22:29:57 -0700 Subject: [PATCH 26/74] tests: updated valgrind.suppress to suppress a known "Conditional jump or move depends on uninitialised value(s)" valgrind error in the JITted machine code from PCRE 8.40. --- valgrind.suppress | 1 - 1 file changed, 1 deletion(-) diff --git a/valgrind.suppress b/valgrind.suppress index 8ca53f5a9..472352e2c 100644 --- a/valgrind.suppress +++ b/valgrind.suppress @@ -62,5 +62,4 @@ Memcheck:Cond obj:* - obj:* } From 741bbf091a92699c140a261cac23b571459ff893 Mon Sep 17 00:00:00 2001 From: "Yichun Zhang (agentzh)" Date: Sat, 8 Apr 2017 14:13:44 -0700 Subject: [PATCH 27/74] change: now we require ngx_http_lua_module 0.10.8+. --- README.markdown | 2 +- lib/resty/core/base.lua | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.markdown b/README.markdown index 483eebb23..ad149bd33 100644 --- a/README.markdown +++ b/README.markdown @@ -85,7 +85,7 @@ Prerequisites ============= * LuaJIT 2.1 (for now, it is the v2.1 git branch in the official luajit-2.0 git repository: http://luajit.org/download.html ) -* [ngx_lua](https://github.com/openresty/lua-nginx-module) v0.10.7 or later. +* [ngx_lua](https://github.com/openresty/lua-nginx-module) v0.10.8 or later. * [lua-resty-lrucache](https://github.com/openresty/lua-resty-lrucache) [Back to TOC](#table-of-contents) diff --git a/lib/resty/core/base.lua b/lib/resty/core/base.lua index db441878b..af35373b6 100644 --- a/lib/resty/core/base.lua +++ b/lib/resty/core/base.lua @@ -15,9 +15,9 @@ local FREE_LIST_REF = 0 if not ngx.config or not ngx.config.ngx_lua_version - or ngx.config.ngx_lua_version < 10007 + or ngx.config.ngx_lua_version < 10008 then - error("ngx_lua 0.10.7+ required") + error("ngx_lua 0.10.8+ required") end From ae74c9a232045edb302325e3ca9bc6b3636cc97c Mon Sep 17 00:00:00 2001 From: "Yichun Zhang (agentzh)" Date: Sat, 8 Apr 2017 15:30:56 -0700 Subject: [PATCH 28/74] bumped version to 0.1.11. --- lib/resty/core/base.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/resty/core/base.lua b/lib/resty/core/base.lua index af35373b6..ed7a9a275 100644 --- a/lib/resty/core/base.lua +++ b/lib/resty/core/base.lua @@ -96,7 +96,7 @@ local c_buf_type = ffi.typeof("char[?]") local _M = new_tab(0, 16) -_M.version = "0.1.8" +_M.version = "0.1.11" _M.new_tab = new_tab _M.clear_tab = clear_tab From ddd544d73e51e40926681a07dab9d060706ddc1d Mon Sep 17 00:00:00 2001 From: "Yichun Zhang (agentzh)" Date: Tue, 11 Apr 2017 11:33:13 -0700 Subject: [PATCH 29/74] opm: fixed the deps in dist.ini. --- dist.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dist.ini b/dist.ini index 403bef01b..4534c1d46 100644 --- a/dist.ini +++ b/dist.ini @@ -7,4 +7,4 @@ lib_dir=lib doc_dir=lib repo_link=https://github.com/openresty/lua-resty-core main_module=lib/resty/core/base.lua -requires = luajit >= 2.1.0, nginx >= 1.11.2, ngx_http_lua = 0.10.7, openresty/lua-resty-lrucache +requires = luajit >= 2.1.0, nginx >= 1.11.2, ngx_http_lua = 0.10.8, openresty/lua-resty-lrucache >= 0.06 From be97dea3a1ee4161483160d368f18204c8006ad2 Mon Sep 17 00:00:00 2001 From: Andreas Lubbe Date: Tue, 11 Apr 2017 19:10:34 +0200 Subject: [PATCH 30/74] travis-ci: use pcre 8.40 and enable pcre jit. Extracted from https://github.com/openresty/lua-resty-core/pull/44 Currently, travis links against the system pcre, which has pcre jit disabled. This PR fixes that. Signed-off-by: Yichun Zhang (agentzh) --- .travis.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 834aaa84d..f99be4c13 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,6 +29,7 @@ env: - LUAJIT_INC=$LUAJIT_PREFIX/include/luajit-2.1 - LUA_INCLUDE_DIR=$LUAJIT_INC - LUA_CMODULE_DIR=/lib + - PCRE_VER=8.40 - OPENSSL_PREFIX=/opt/ssl - OPENSSL_LIB=$OPENSSL_PREFIX/lib - OPENSSL_INC=$OPENSSL_PREFIX/include @@ -50,6 +51,7 @@ before_install: install: - if [ ! -d download-cache ]; then mkdir download-cache; fi - if [ ! -f download-cache/openssl-$OPENSSL_VER.tar.gz ]; then wget -O download-cache/openssl-$OPENSSL_VER.tar.gz https://www.openssl.org/source/openssl-$OPENSSL_VER.tar.gz; fi + - if [ ! -f download-cache/pcre-$PCRE_VER.tar.gz ]; then wget -P download-cache http://ftp.cs.stanford.edu/pub/exim/pcre/pcre-$PCRE_VER.tar.gz; fi - wget http://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz - git clone https://github.com/openresty/openresty.git ../openresty - git clone https://github.com/openresty/nginx-devel-utils.git @@ -77,12 +79,13 @@ script: - make -j$JOBS > build.log 2>&1 || (cat build.log && exit 1) - sudo make PATH=$PATH install_sw > build.log 2>&1 || (cat build.log && exit 1) - cd ../mockeagain/ && make CC=$CC -j$JOBS && cd .. + - tar zxf download-cache/pcre-$PCRE_VER.tar.gz - export PATH=$PWD/work/nginx/sbin:$PWD/nginx-devel-utils:$PATH - export LD_PRELOAD=$PWD/mockeagain/mockeagain.so - export LD_LIBRARY_PATH=$PWD/mockeagain:$LD_LIBRARY_PATH - export TEST_NGINX_RESOLVER=8.8.4.4 - export NGX_BUILD_CC=$CC - - ngx-build $NGINX_VERSION --with-ipv6 --with-http_realip_module --with-http_ssl_module --with-cc-opt="-I$OPENSSL_INC" --with-ld-opt="-L$OPENSSL_LIB -Wl,-rpath,$OPENSSL_LIB" --add-module=../ndk-nginx-module --add-module=../echo-nginx-module --add-module=../headers-more-nginx-module --add-module=../lua-nginx-module --with-debug > build.log 2>&1 || (cat build.log && exit 1) + - ngx-build $NGINX_VERSION --with-ipv6 --with-http_realip_module --with-http_ssl_module --with-pcre=../../pcre-$PCRE_VER --with-pcre-jit --with-cc-opt="-I$OPENSSL_INC" --with-ld-opt="-L$OPENSSL_LIB -Wl,-rpath,$OPENSSL_LIB" --add-module=../ndk-nginx-module --add-module=../echo-nginx-module --add-module=../headers-more-nginx-module --add-module=../lua-nginx-module --with-debug > build.log 2>&1 || (cat build.log && exit 1) - nginx -V - ldd `which nginx`|grep -E 'luajit|ssl|pcre' - prove -Itest-nginx/lib -j$JOBS -r t From 9903f1aab2e60b6f7e3704f29e60e852299cff48 Mon Sep 17 00:00:00 2001 From: weihaitong <63264003.qq.com> Date: Wed, 12 Apr 2017 10:30:56 +0800 Subject: [PATCH 31/74] doc: a typo fixe in Synopsis. Signed-off-by: Yichun Zhang (agentzh) --- lib/ngx/ocsp.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ngx/ocsp.md b/lib/ngx/ocsp.md index 1db7501cb..a0d673994 100644 --- a/lib/ngx/ocsp.md +++ b/lib/ngx/ocsp.md @@ -115,7 +115,7 @@ server { end -- set the OCSP stapling - ok, err = ocsp.set_ocsp_status_resp(resp) + ok, err = ocsp.set_ocsp_status_resp(ocsp_resp) if not ok then ngx.log(ngx.ERR, "failed to set ocsp status resp: ", err) return ngx.exit(ngx.ERROR) From a548fbb8bc285be9720f55abf03996233dc86d6d Mon Sep 17 00:00:00 2001 From: Evgeny S Date: Wed, 19 Apr 2017 12:36:48 +0300 Subject: [PATCH 32/74] optimize: simplified the "BOOL and true or false" expressions. Signed-off-by: Yichun Zhang (agentzh) --- lib/resty/core/misc.lua | 2 +- lib/resty/core/worker.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/resty/core/misc.lua b/lib/resty/core/misc.lua index 5b7a690e0..2f30528d0 100644 --- a/lib/resty/core/misc.lua +++ b/lib/resty/core/misc.lua @@ -123,7 +123,7 @@ local function is_subreq() return error("API disabled in the current context") end - return rc == 1 and true or false + return rc == 1 end register_getter("is_subrequest", is_subreq) diff --git a/lib/resty/core/worker.lua b/lib/resty/core/worker.lua index 1e9b0963e..0da8086cc 100644 --- a/lib/resty/core/worker.lua +++ b/lib/resty/core/worker.lua @@ -17,7 +17,7 @@ int ngx_http_lua_ffi_worker_count(void); function ngx.worker.exiting() - return C.ngx_http_lua_ffi_worker_exiting() ~= 0 and true or false + return C.ngx_http_lua_ffi_worker_exiting() ~= 0 end From f23cce47172cbcdcb5c09c0bfaa3b8ced4165e03 Mon Sep 17 00:00:00 2001 From: Yuansheng Date: Thu, 20 Apr 2017 10:10:11 +0800 Subject: [PATCH 33/74] tests: removed extra file trailing newlines from the test files via the `reindex' tool. Signed-off-by: Yichun Zhang (agentzh) --- t/count.t | 1 - t/ctx.t | 1 - t/decode-base64.t | 1 - t/encode-base64.t | 1 - t/exit.t | 1 - t/md5.t | 1 - t/md5_bin.t | 1 - t/misc.t | 1 - t/re-find.t | 1 - t/re-match.t | 1 - t/request.t | 1 - t/response.t | 1 - t/sha1_bin.t | 1 - t/status.t | 1 - t/time.t | 1 - t/uri.t | 1 - t/var.t | 1 - 17 files changed, 17 deletions(-) diff --git a/t/count.t b/t/count.t index 3042651d1..0b61ba9ee 100644 --- a/t/count.t +++ b/t/count.t @@ -69,4 +69,3 @@ probe process("$LIBLUA_PATH").function("rehashtab") { base size: 16 --- no_error_log [error] - diff --git a/t/ctx.t b/t/ctx.t index 8520c975a..9cceb6f0d 100644 --- a/t/ctx.t +++ b/t/ctx.t @@ -83,4 +83,3 @@ ctx.foo = 100 bad argument --- error_log eval qr/\[TRACE\s+\d+\s+content_by_lua\(nginx\.conf:\d+\):2 loop\]/ - diff --git a/t/decode-base64.t b/t/decode-base64.t index efc91f6ad..140d822e8 100644 --- a/t/decode-base64.t +++ b/t/decode-base64.t @@ -185,4 +185,3 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):3 loop\]/ --- no_error_log [error] -- NYI: - diff --git a/t/encode-base64.t b/t/encode-base64.t index d9ae34b70..ed4a54c96 100644 --- a/t/encode-base64.t +++ b/t/encode-base64.t @@ -225,4 +225,3 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):3 loop\]/ --- no_error_log [error] -- NYI: - diff --git a/t/exit.t b/t/exit.t index 89b997f6d..c4ad4a778 100644 --- a/t/exit.t +++ b/t/exit.t @@ -83,4 +83,3 @@ GET /t ["[error]", qr/ -- NYI: (?!FastFunc coroutine.yield)/, " bad argument"] - diff --git a/t/md5.t b/t/md5.t index 59830aceb..3f88b14fc 100644 --- a/t/md5.t +++ b/t/md5.t @@ -118,4 +118,3 @@ GET /md5 qr/\[TRACE 1 content_by_lua\(nginx\.conf:\d+\):3 loop\]/ --- no_error_log [error] - diff --git a/t/md5_bin.t b/t/md5_bin.t index a95886402..cc29fd0e9 100644 --- a/t/md5_bin.t +++ b/t/md5_bin.t @@ -126,4 +126,3 @@ GET /md5_bin qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):3 loop\]/ --- no_error_log [error] - diff --git a/t/misc.t b/t/misc.t index 2fb70df9f..5f102ca55 100644 --- a/t/misc.t +++ b/t/misc.t @@ -114,4 +114,3 @@ headers sent: true bad argument --- error_log eval qr/\[TRACE\s+\d+\s+content_by_lua\(nginx\.conf:\d+\):4 loop\]/ - diff --git a/t/re-find.t b/t/re-find.t index b896949a2..772ec3b6d 100644 --- a/t/re-find.t +++ b/t/re-find.t @@ -260,4 +260,3 @@ matched: 234 NYI --- error_log eval qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):4 loop\]/ - diff --git a/t/re-match.t b/t/re-match.t index 53fa6abb8..84e7e0def 100644 --- a/t/re-match.t +++ b/t/re-match.t @@ -590,4 +590,3 @@ attempt to get length of local 'subj' (a number value) --- no_error_log [error] attempt to get length of local 'regex' (a number value) - diff --git a/t/request.t b/t/request.t index 4d1b6209c..f6be77bf0 100644 --- a/t/request.t +++ b/t/request.t @@ -570,4 +570,3 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):4 loop\]/ [error] bad argument type stitch - diff --git a/t/response.t b/t/response.t index b075f3886..47451236f 100644 --- a/t/response.t +++ b/t/response.t @@ -231,4 +231,3 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):5 (?:loop|-> \d+)\]/ [error] -- NYI: stitch - diff --git a/t/sha1_bin.t b/t/sha1_bin.t index 5551c143e..05fe51081 100644 --- a/t/sha1_bin.t +++ b/t/sha1_bin.t @@ -126,4 +126,3 @@ GET /sha1_bin qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):3 loop\]/ --- no_error_log [error] - diff --git a/t/status.t b/t/status.t index 1d10d8c90..c45c5c016 100644 --- a/t/status.t +++ b/t/status.t @@ -89,4 +89,3 @@ GET /t ["status: 200,", qr/\[TRACE\s+\d+\s+header_filter_by_lua:2 loop\]/ ] - diff --git a/t/time.t b/t/time.t index 4b4772a47..c5338364f 100644 --- a/t/time.t +++ b/t/time.t @@ -103,4 +103,3 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):3 loop\]/ [error] bad argument type stitch - diff --git a/t/uri.t b/t/uri.t index 8f852c7c1..277090b50 100644 --- a/t/uri.t +++ b/t/uri.t @@ -259,4 +259,3 @@ GET /uri qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):3 loop\]/ --- no_error_log [error] - diff --git a/t/var.t b/t/var.t index 79a574f93..bdb0e592b 100644 --- a/t/var.t +++ b/t/var.t @@ -215,4 +215,3 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):3 loop\]/ --- no_error_log [error] -- NYI: - From 42f3b41e5d78c9144e43d780c34fb240c1deedb5 Mon Sep 17 00:00:00 2001 From: Yuansheng Date: Mon, 1 May 2017 20:53:12 +0800 Subject: [PATCH 34/74] doc: ngx.ssl: a typo fix. Signed-off-by: Yichun Zhang (agentzh) --- lib/ngx/ssl.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ngx/ssl.md b/lib/ngx/ssl.md index fc7ecae5f..71c82a9a9 100644 --- a/lib/ngx/ssl.md +++ b/lib/ngx/ssl.md @@ -199,7 +199,7 @@ This function can be called in whatever contexts. set_der_priv_key ---------------- -**syntax:** *ok, err = ssl.set_der_priv_key(der_cert_chain)* +**syntax:** *ok, err = ssl.set_der_priv_key(der_priv_key)* **context:** *ssl_certificate_by_lua** From a79387c457939c7bb52e0611963cefe843ce1388 Mon Sep 17 00:00:00 2001 From: Andreas Lubbe Date: Fri, 3 Jun 2016 14:45:32 +0200 Subject: [PATCH 35/74] feature: added opt() function to the ngx.re Lua module that accepts the "jit_stack_size" option to tune the JIT stack size of PCRE. Signed-off-by: Yichun Zhang (agentzh) --- lib/ngx/re.lua | 37 ++++++++ lib/ngx/re.md | 37 ++++++++ lib/resty/core/regex.lua | 17 +++- t/re-opt.t | 179 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 269 insertions(+), 1 deletion(-) create mode 100644 t/re-opt.t diff --git a/lib/ngx/re.lua b/lib/ngx/re.lua index efe37ea37..28e9ed040 100644 --- a/lib/ngx/re.lua +++ b/lib/ngx/re.lua @@ -9,17 +9,24 @@ local core_regex = require "resty.core.regex" local C = ffi.C +local ffi_str = ffi.string local sub = string.sub +local error = error local type = type local band = bit.band local new_tab = base.new_tab local tostring = tostring local math_max = math.max local math_min = math.min +local is_regex_cache_empty = core_regex.is_regex_cache_empty local re_match_compile = core_regex.re_match_compile local destroy_compiled_regex = core_regex.destroy_compiled_regex +local get_string_buf = base.get_string_buf +local get_size_ptr = base.get_size_ptr +local FFI_OK = base.FFI_OK +local MAX_ERR_MSG_LEN = 128 local FLAG_DFA = 0x02 local PCRE_ERROR_NOMATCH = -1 local DEFAULT_SPLIT_RES_SIZE = 4 @@ -28,6 +35,12 @@ local DEFAULT_SPLIT_RES_SIZE = 4 local split_ctx = new_tab(0, 1) +ffi.cdef[[ +int ngx_http_lua_ffi_set_jit_stack_size(int size, unsigned char *errstr, + size_t *errstr_size); +]] + + local _M = { version = base.version } @@ -219,4 +232,28 @@ function _M.split(subj, regex, opts, ctx, max, res) end +function _M.opt(option, value) + if option == "jit_stack_size" then + if not is_regex_cache_empty() then + error("changing jit stack size is not allowed when some " .. + "regexs have already been compiled and cached") + end + + local errbuf = get_string_buf(MAX_ERR_MSG_LEN) + local sizep = get_size_ptr() + sizep[0] = MAX_ERR_MSG_LEN + + local rc = C.ngx_http_lua_ffi_set_jit_stack_size(value, errbuf, sizep) + + if rc == FFI_OK then + return + end + + error(ffi_str(errbuf, sizep[0])) + end + + error("unrecognized option name") +end + + return _M diff --git a/lib/ngx/re.md b/lib/ngx/re.md index 7fbfd0c85..c1df8ed92 100644 --- a/lib/ngx/re.md +++ b/lib/ngx/re.md @@ -34,6 +34,10 @@ local ngx_re = require "ngx.re" -- split local res, err = ngx_re.split("a,b,c,d", ",") --> res is now {"a", "b", "c", "d"} + +-- opt +ngx_re.opt("jit_stack_size", 128 * 1024) +--> the PCRE jit stack can now handle more complex regular expressions ``` [Back to TOC](#table-of-contents) @@ -141,6 +145,39 @@ local res, err = ngx_re.split("a,b", ",", nil, nil, nil, my_table) When the trailing `nil` is not enough for your purpose, you should clear the table yourself before feeding it into the `split` function. +opt +----- +**syntax:** *ngx_re.opt(option, value)* + +Allows changing of regex settings. Currently, it can only change the +`jit_stack_size` of the PCRE engine, like so: + +```nginx + + init_by_lua_block { ngx.re.opt("jit_stack_size", 128 * 1024) } + + server { + location /re { + content_by_lua_block { + -- full regex and string are taken from https://github.com/JuliaLang/julia/issues/8278 + local very_long_string = [[71.163.72.113 - - [30/Jul/2014:16:40:55 -0700] ...]] + local very_complicated_regex = [[([\d\.]+) ([\w.-]+) ([\w.-]+) (\[.+\]) ...]] + local from, to, err = ngx.re.find(very_long_string, very_complicated_regex, "jo") + + -- with the regular jit_stack_size, we would get the error 'pcre_exec() failed: -27' + -- instead, we get a match + ngx.print(from .. "-" .. to) -- prints '1-1563' + } + } + } +``` + +The `jit_stack_size` cannot be set to a value lower than PCRE's default of 32K. + +This method requires the PCRE library enabled in Nginx. + +This feature was first introduced in the `v0.1.12` release. + [Back to TOC](#table-of-contents) Community diff --git a/lib/resty/core/regex.lua b/lib/resty/core/regex.lua index 3cf8eca0c..071e6ad29 100644 --- a/lib/resty/core/regex.lua +++ b/lib/resty/core/regex.lua @@ -140,6 +140,7 @@ local _M = { local buf_grow_ratio = 2 + function _M.set_buf_grow_ratio(ratio) buf_grow_ratio = ratio end @@ -154,6 +155,20 @@ local function get_max_regex_cache_size() end +local regex_cache_is_empty = true + + +function _M.is_regex_cache_empty() + return regex_cache_is_empty +end + + +local function lrucache_set_wrapper(...) + regex_cache_is_empty = false + lrucache_set(...) +end + + local function parse_regex_opts(opts) local t = cached_re_opts[opts] if t then @@ -341,7 +356,7 @@ local function re_match_compile(regex, opts) if compile_once then -- print("inserting compiled regex into cache") - lrucache_set(regex_match_cache, key, compiled) + lrucache_set_wrapper(regex_match_cache, key, compiled) end end diff --git a/t/re-opt.t b/t/re-opt.t new file mode 100644 index 000000000..18f66a307 --- /dev/null +++ b/t/re-opt.t @@ -0,0 +1,179 @@ +# vim:set ft= ts=4 sw=4 et fdm=marker: +use lib 'lib'; +use Test::Nginx::Socket::Lua; +use Cwd qw(cwd); + +#worker_connections(1014); +#master_process_enabled(1); +#log_level('warn'); + +repeat_each(2); + +plan tests => repeat_each() * blocks() * 3; + +our $pwd = cwd(); + +our $HttpConfig = <<_EOC_; + lua_package_path "$pwd/lib/?.lua;../lua-resty-lrucache/lib/?.lua;;"; + init_by_lua_block { + -- local verbose = true + local verbose = false + local outfile = "$Test::Nginx::Util::ErrLogFile" + -- local outfile = "/tmp/v.log" + if verbose then + local dump = require "jit.dump" + dump.on(nil, outfile) + else + local v = require "jit.v" + v.on(outfile) + end + + require "resty.core" + -- jit.opt.start("hotloop=1") + -- jit.opt.start("loopunroll=1000000") + -- jit.off() + } +_EOC_ + +no_diff(); +no_long_string(); +check_accum_error_log(); +run_tests(); + +__DATA__ + +=== TEST 1: default jit_stack_size too small +--- http_config eval: $::HttpConfig +--- config + location /re { + content_by_lua_block { + -- regex is taken from https://github.com/JuliaLang/julia/issues/8278 + local very_long_string = [[71.163.72.113 - - [30/Jul/2014:16:40:55 -0700] "GET emptymind.org/thevacantwall/wp-content/uploads/2013/02/DSC_006421.jpg HTTP/1.1" 200 492513 "http://images.search.yahoo.com/images/view;_ylt=AwrB8py9gdlTGEwADcSjzbkF;_ylu=X3oDMTI2cGZrZTA5BHNlYwNmcC1leHAEc2xrA2V4cARvaWQDNTA3NTRiMzYzY2E5OTEwNjBiMjc2YWJhMjkxMTEzY2MEZ3BvcwM0BGl0A2Jpbmc-?back=http%3A%2F%2Fus.yhs4.search.yahoo.com%2Fyhs%2Fsearch%3Fei%3DUTF-8%26p%3Dapartheid%2Bwall%2Bin%2Bpalestine%26type%3Dgrvydef%26param1%3D1%26param2%3Dsid%253Db01676f9c26355f014f8a9db87545d61%2526b%253DChrome%2526ip%253D71.163.72.113%2526p%253Dgroovorio%2526x%253DAC811262A746D3CD%2526dt%253DS940%2526f%253D7%2526a%253Dgrv_tuto1_14_30%26hsimp%3Dyhs-fullyhosted_003%26hspart%3Dironsource&w=588&h=387&imgurl=occupiedpalestine.files.wordpress.com%2F2012%2F08%2F5-peeking-through-the-wall.jpg%3Fw%3D588%26h%3D387&rurl=http%3A%2F%2Fwww.stopdebezetting.com%2Fwereldpers%2Fcompare-the-berlin-wall-vs-israel-s-apartheid-wall-in-palestine.html&size=49.0KB&name=...+%3Cb%3EApartheid+wall+in+Palestine%3C%2Fb%3E...+%7C+Or+you+go+peeking+through+the+%3Cb%3Ewall%3C%2Fb%3E&p=apartheid+wall+in+palestine&oid=50754b363ca991060b276aba291113cc&fr2=&fr=&tt=...+%3Cb%3EApartheid+wall+in+Palestine%3C%2Fb%3E...+%7C+Or+you+go+peeking+through+the+%3Cb%3Ewall%3C%2Fb%3E&b=0&ni=21&no=4&ts=&tab=organic&sigr=13evdtqdq&sigb=19k7nsjvb&sigi=12o2la1db&sigt=12lia2m0j&sign=12lia2m0j&.crumb=.yUtKgFI6DE&hsimp=yhs-fullyhosted_003&hspart=ironsource" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36]] + local very_complicated_regex = [[([\d\.]+) ([\w.-]+) ([\w.-]+) (\[.+\]) "([^"\r\n]*|[^"\r\n\[]*\[.+\][^"]+|[^"\r\n]+.[^"]+)" (\d{3}) (\d+|-) ("(?:[^"]|\")+)"? ("(?:[^"]|\")+)"?]] + local from, to, err = ngx.re.find(very_long_string, very_complicated_regex, "jo") + if from or to then + ngx.say("from: ", from) + ngx.say("to: ", to) + else + if err then + ngx.say("error: ", err) + return + end + ngx.say("not matched!") + end + } + } +--- request + GET /re +--- response_body +error: pcre_exec() failed: -27 +--- no_error_log +[error] +--- timeout: 10 + + + +=== TEST 2: increase jit_stack_size +--- http_config eval +qq{ + lua_package_path "$::pwd/lib/?.lua;../lua-resty-lrucache/lib/?.lua;;"; + init_by_lua_block { + -- local verbose = true + local verbose = false + local outfile = "$Test::Nginx::Util::ErrLogFile" + -- local outfile = "/tmp/v.log" + if verbose then + local dump = require "jit.dump" + dump.on(nil, outfile) + else + local v = require "jit.v" + v.on(outfile) + end + + require "resty.core" + -- jit.opt.start("hotloop=1") + -- jit.opt.start("loopunroll=1000000") + -- jit.off() + + local ngx_re = require "ngx.re" + ngx_re.opt("jit_stack_size", 128 * 1024) + } +} +--- config + location /re { + content_by_lua_block { + -- regex is taken from https://github.com/JuliaLang/julia/issues/8278 + local very_long_string = [[71.163.72.113 - - [30/Jul/2014:16:40:55 -0700] "GET emptymind.org/thevacantwall/wp-content/uploads/2013/02/DSC_006421.jpg HTTP/1.1" 200 492513 "http://images.search.yahoo.com/images/view;_ylt=AwrB8py9gdlTGEwADcSjzbkF;_ylu=X3oDMTI2cGZrZTA5BHNlYwNmcC1leHAEc2xrA2V4cARvaWQDNTA3NTRiMzYzY2E5OTEwNjBiMjc2YWJhMjkxMTEzY2MEZ3BvcwM0BGl0A2Jpbmc-?back=http%3A%2F%2Fus.yhs4.search.yahoo.com%2Fyhs%2Fsearch%3Fei%3DUTF-8%26p%3Dapartheid%2Bwall%2Bin%2Bpalestine%26type%3Dgrvydef%26param1%3D1%26param2%3Dsid%253Db01676f9c26355f014f8a9db87545d61%2526b%253DChrome%2526ip%253D71.163.72.113%2526p%253Dgroovorio%2526x%253DAC811262A746D3CD%2526dt%253DS940%2526f%253D7%2526a%253Dgrv_tuto1_14_30%26hsimp%3Dyhs-fullyhosted_003%26hspart%3Dironsource&w=588&h=387&imgurl=occupiedpalestine.files.wordpress.com%2F2012%2F08%2F5-peeking-through-the-wall.jpg%3Fw%3D588%26h%3D387&rurl=http%3A%2F%2Fwww.stopdebezetting.com%2Fwereldpers%2Fcompare-the-berlin-wall-vs-israel-s-apartheid-wall-in-palestine.html&size=49.0KB&name=...+%3Cb%3EApartheid+wall+in+Palestine%3C%2Fb%3E...+%7C+Or+you+go+peeking+through+the+%3Cb%3Ewall%3C%2Fb%3E&p=apartheid+wall+in+palestine&oid=50754b363ca991060b276aba291113cc&fr2=&fr=&tt=...+%3Cb%3EApartheid+wall+in+Palestine%3C%2Fb%3E...+%7C+Or+you+go+peeking+through+the+%3Cb%3Ewall%3C%2Fb%3E&b=0&ni=21&no=4&ts=&tab=organic&sigr=13evdtqdq&sigb=19k7nsjvb&sigi=12o2la1db&sigt=12lia2m0j&sign=12lia2m0j&.crumb=.yUtKgFI6DE&hsimp=yhs-fullyhosted_003&hspart=ironsource" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/36.0.1985.125 Safari/537.36]] + local very_complicated_regex = [[([\d\.]+) ([\w.-]+) ([\w.-]+) (\[.+\]) "([^"\r\n]*|[^"\r\n\[]*\[.+\][^"]+|[^"\r\n]+.[^"]+)" (\d{3}) (\d+|-) ("(?:[^"]|\")+)"? ("(?:[^"]|\")+)"?]] + local from, to, err = ngx.re.find(very_long_string, very_complicated_regex, "jo") + if from or to then + ngx.say("from: ", from) + ngx.say("to: ", to) + else + if err then + ngx.say("error: ", err) + return + end + ngx.say("not matched!") + end + } + } +--- request + GET /re +--- response_body +from: 1 +to: 1563 +--- no_error_log +[error] +--- timeout: 10 + + + +=== TEST 3: jit_stack_size change disallowed once regex cache is populated +--- http_config eval: $::HttpConfig +--- config + location /re { + content_by_lua_block { + local ngx_re = require "ngx.re" + + local status, err = pcall(ngx_re.opt, "jit_stack_size", 128 * 1024) + if err then ngx.log(ngx.ERR, err) end + local s = "hello, 1234" + local from, to = ngx.re.find(s, "(hello world)|([0-9])", "jo") + ngx.say("from: ", from) + ngx.say("to: ", to) + } + } +--- request + GET /re +--- response_body +from: 8 +to: 8 + +--- grep_error_log eval +qr/changing jit stack size is not allowed when some regexs have already been compiled and cached/ + +--- grep_error_log_out eval +["", "changing jit stack size is not allowed when some regexs have already been compiled and cached\n"] +--- timeout: 10 + + + +=== TEST 4: passing unknown options to ngx_re.opt throws an error +--- http_config eval: $::HttpConfig +--- config + location /re { + content_by_lua_block { + local ngx_re = require "ngx.re" + + local status, err = pcall(ngx_re.opt, "foo", 123) + ngx.say(err) + } + } +--- request + GET /re +--- response_body_like chomp +unrecognized option name$ +--- no_error_log +[error] +--- timeout: 10 From 392976cc0240dfde431b6e5702fe140a0da3093d Mon Sep 17 00:00:00 2001 From: "Yichun Zhang (agentzh)" Date: Fri, 5 May 2017 23:07:28 -0700 Subject: [PATCH 36/74] travis-ci: enable -msse4.2 when building luajit2. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index f99be4c13..db33f568e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -67,7 +67,7 @@ install: script: - cd luajit2/ - - make -j$JOBS CCDEBUG=-g Q= PREFIX=$LUAJIT_PREFIX CC=$CC XCFLAGS='-DLUA_USE_APICHECK -DLUA_USE_ASSERT' > build.log 2>&1 || (cat build.log && exit 1) + - make -j$JOBS CCDEBUG=-g Q= PREFIX=$LUAJIT_PREFIX CC=$CC XCFLAGS='-DLUA_USE_APICHECK -DLUA_USE_ASSERT -msse4.2' > build.log 2>&1 || (cat build.log && exit 1) - sudo make install PREFIX=$LUAJIT_PREFIX > build.log 2>&1 || (cat build.log && exit 1) - cd .. - cd lua-resty-lrucache && sudo make DESTDIR=$LUAJIT_PREFIX LUA_LIB_DIR=/share/lua/5.1 install && cd .. From ae79bf71594407cf81508d923c02868d6d35b1ae Mon Sep 17 00:00:00 2001 From: Yuansheng Date: Sun, 16 Apr 2017 21:44:14 +0800 Subject: [PATCH 37/74] feature: added new Lua module ngx.process which has functions type() and enable_privileged_agent(). Signed-off-by: Yichun Zhang (agentzh) --- .travis.yml | 4 +- README.markdown | 12 ++ lib/ngx/process.lua | 54 +++++++++ lib/ngx/process.md | 188 ++++++++++++++++++++++++++++++ t/process-type-cache.t | 96 +++++++++++++++ t/process-type-hup.t | 96 +++++++++++++++ t/process-type-master.t | 85 ++++++++++++++ t/process-type-privileged-agent.t | 140 ++++++++++++++++++++++ 8 files changed, 673 insertions(+), 2 deletions(-) create mode 100644 lib/ngx/process.lua create mode 100644 lib/ngx/process.md create mode 100644 t/process-type-cache.t create mode 100644 t/process-type-hup.t create mode 100644 t/process-type-master.t create mode 100644 t/process-type-privileged-agent.t diff --git a/.travis.yml b/.travis.yml index db33f568e..3f5cf76bf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -54,7 +54,7 @@ install: - if [ ! -f download-cache/pcre-$PCRE_VER.tar.gz ]; then wget -P download-cache http://ftp.cs.stanford.edu/pub/exim/pcre/pcre-$PCRE_VER.tar.gz; fi - wget http://nginx.org/download/nginx-${NGINX_VERSION}.tar.gz - git clone https://github.com/openresty/openresty.git ../openresty - - git clone https://github.com/openresty/nginx-devel-utils.git + - git clone https://github.com/openresty/openresty-devel-utils.git - git clone https://github.com/simpl/ngx_devel_kit.git ../ndk-nginx-module - git clone https://github.com/openresty/lua-nginx-module.git ../lua-nginx-module - git clone https://github.com/openresty/no-pool-nginx.git ../no-pool-nginx @@ -80,7 +80,7 @@ script: - sudo make PATH=$PATH install_sw > build.log 2>&1 || (cat build.log && exit 1) - cd ../mockeagain/ && make CC=$CC -j$JOBS && cd .. - tar zxf download-cache/pcre-$PCRE_VER.tar.gz - - export PATH=$PWD/work/nginx/sbin:$PWD/nginx-devel-utils:$PATH + - export PATH=$PWD/work/nginx/sbin:$PWD/openresty-devel-utils:$PATH - export LD_PRELOAD=$PWD/mockeagain/mockeagain.so - export LD_LIBRARY_PATH=$PWD/mockeagain:$LD_LIBRARY_PATH - export TEST_NGINX_RESOLVER=8.8.4.4 diff --git a/README.markdown b/README.markdown index ad149bd33..56edfead3 100644 --- a/README.markdown +++ b/README.markdown @@ -30,6 +30,8 @@ Table of Contents * [ngx.ssl](#ngxssl) * [ngx.ssl.session](#ngxsslsession) * [ngx.re](#ngxre) + * [ngx.process](ngxprocess) + * [Caveat](#caveat) * [TODO](#todo) * [Author](#author) @@ -245,6 +247,16 @@ See the [documentation](./lib/ngx/re.md) for this Lua module for more details. [Back to TOC](#table-of-contents) +## ngx.process + +This Lua module is used to manage the nginx process in Lua. + +See the [documentation](./lib/ngx/process.md) for this Lua module for more details. + +This module was first introduced in lua-resty-core v0.1.12. + +[Back to TOC](#table-of-contents) + Caveat ====== diff --git a/lib/ngx/process.lua b/lib/ngx/process.lua new file mode 100644 index 000000000..5c7c0289e --- /dev/null +++ b/lib/ngx/process.lua @@ -0,0 +1,54 @@ +-- Copyright (C) Yichun Zhang (agentzh) + + +local ffi = require 'ffi' +local base = require "resty.core.base" +local errmsg = base.get_errmsg_ptr() +local FFI_ERROR = base.FFI_ERROR +local ffi_str = ffi.string +local ngx_phase = ngx.get_phase +local tonumber = tonumber + + +local process_type_names = { + [0 ] = "single", + [1 ] = "master", + [2 ] = "signaller", + [3 ] = "worker", + [4 ] = "helper", + [99] = "privileged agent", +} + + +local C = ffi.C +local _M = { version = base.version } + + +ffi.cdef[[ +int ngx_http_lua_ffi_enable_privileged_agent(char **err); +int ngx_http_lua_ffi_get_process_type(void); +]] + + +function _M.type() + local typ = C.ngx_http_lua_ffi_get_process_type() + return process_type_names[tonumber(typ)] +end + + +function _M.enable_privileged_agent() + if ngx_phase() ~= "init" then + return nil, "API disabled in the current context" + end + + local rc = C.ngx_http_lua_ffi_enable_privileged_agent(errmsg) + + if rc == FFI_ERROR then + return nil, ffi_str(errmsg[0]) + end + + return true +end + + +return _M diff --git a/lib/ngx/process.md b/lib/ngx/process.md new file mode 100644 index 000000000..b32b4b16a --- /dev/null +++ b/lib/ngx/process.md @@ -0,0 +1,188 @@ +Name +==== + +`ngx.process` - manage the nginx processes for OpenResty/ngx_lua. + +Table of Contents +================= + +* [Name](#name) +* [Status](#status) +* [Synopsis](#synopsis) + * [Enables privileged agent process and get process type](#enables-privileged-agent-process-and-get-process-type) +* [Methods](#methods) + * [type](#type) + * [enable_privileged_agent](#enable_privileged_agent) +* [Community](#community) + * [English Mailing List](#english-mailing-list) + * [Chinese Mailing List](#chinese-mailing-list) +* [Bugs and Patches](#bugs-and-patches) +* [Author](#author) +* [Copyright and License](#copyright-and-license) +* [See Also](#see-also) + +Status +====== + +This Lua module is currently considered experimental. +The API is still in flux and may change in the future without notice. + +Synopsis +======== + +Enables privileged agent process and get process type +----------------------------------------- + +```nginx +# http config +init_by_lua_block { + local process = require "ngx.process" + + -- enables privileged agent process + local ok, err = process.enable_privileged_agent() + if not ok then + ngx.log(ngx.ERR, "enables privileged agent failed error:", err) + end + + -- output process type + ngx.log(ngx.INFO, "process type: ", process.type()) +} + +init_worker_by_lua_block { + local process = require "ngx.process" + ngx.log(ngx.INFO, "process type: ", process.type()) +} + +server { + # ... + location = /t { + content_by_lua_block { + local process = require "ngx.process" + ngx.say("process type: ", process.type()) + } + } +} + +``` + +The example config above produces an output to `error.log` when +server starts: + +``` +[lua] init_by_lua:11: process type: master +[lua] init_worker_by_lua:3: process type: privileged agent +[lua] init_worker_by_lua:3: process type: worker +``` + +The example location above produces the following response body: + +``` +process type: worker +``` + +[Back to TOC](#table-of-contents) + +Methods +======= + +type +---- +**syntax:** *type_name = process_module.type()* + +**context:** *any* + +Returns the current process's type name. Here are all of the names: + +``` +single +master +signaller +worker +helper +privileged agent +``` + +For example, + +```lua + local process = require "ngx.process" + ngx.say("process type:", process.type()) -- worker +``` + +[Back to TOC](#table-of-contents) + +enable_privileged_agent +----------------------- +**syntax:** *ok, err = process_module.enable_privileged_agent()* + +**context:** *init_by_lua** + +Enables the privileged agent process in Nginx. + +In case of failures, returns `nil` and a string describing the error. + +[Back to TOC](#table-of-contents) + +Community +========= + +[Back to TOC](#table-of-contents) + +English Mailing List +-------------------- + +The [openresty-en](https://groups.google.com/group/openresty-en) mailing list is for English speakers. + +[Back to TOC](#table-of-contents) + +Chinese Mailing List +-------------------- + +The [openresty](https://groups.google.com/group/openresty) mailing list is for Chinese speakers. + +[Back to TOC](#table-of-contents) + +Bugs and Patches +================ + +Please report bugs or submit patches by + +1. creating a ticket on the [GitHub Issue Tracker](https://github.com/openresty/lua-resty-core/issues), +1. or posting to the [OpenResty community](#community). + +[Back to TOC](#table-of-contents) + +Author +====== + +Yuansheng Wang <membphis@gmail.com> (membphis), OpenResty Inc. + +[Back to TOC](#table-of-contents) + +Copyright and License +===================== + +This module is licensed under the BSD license. + +Copyright (C) 2017, by Yichun "agentzh" Zhang, OpenResty Inc. + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +[Back to TOC](#table-of-contents) + +See Also +======== +* library [lua-resty-core](https://github.com/openresty/lua-resty-core) +* the ngx_lua module: https://github.com/openresty/lua-nginx-module +* OpenResty: http://openresty.org + +[Back to TOC](#table-of-contents) + diff --git a/t/process-type-cache.t b/t/process-type-cache.t new file mode 100644 index 000000000..8165f214f --- /dev/null +++ b/t/process-type-cache.t @@ -0,0 +1,96 @@ +# vim:set ft= ts=4 sw=4 et fdm=marker: +use lib 'lib'; +use Test::Nginx::Socket::Lua; +use Cwd qw(cwd); + +#worker_connections(1014); +master_process_enabled(1); +#log_level('info'); + +repeat_each(2); + +plan tests => repeat_each() * (blocks() * 5); + +my $pwd = cwd(); + +our $HttpConfig = <<_EOC_; + proxy_cache_path /tmp/proxy_cache_dir keys_zone=cache_one:200m; + + lua_shared_dict dogs 1m; + lua_package_path "$pwd/lib/?.lua;../lua-resty-lrucache/lib/?.lua;;"; + init_by_lua_block { + local verbose = false + if verbose then + local dump = require "jit.dump" + dump.on("b", "$Test::Nginx::Util::ErrLogFile") + else + local v = require "jit.v" + v.on("$Test::Nginx::Util::ErrLogFile") + end + + require "resty.core" + -- jit.off() + } + + init_worker_by_lua_block { + local base = require "resty.core.base" + local v + local typ = (require "ngx.process").type + for i = 1, 400 do + v = typ() + end + + if v == "helper" then + ngx.log(ngx.WARN, "process type: ", v) + end + } +_EOC_ + +#no_diff(); +#no_long_string(); +check_accum_error_log(); +run_tests(); + +__DATA__ + +=== TEST 1: sanity +--- http_config eval: $::HttpConfig +--- config + location = /t { + content_by_lua_block { + ngx.sleep(0.1) + local v + local typ = (require "ngx.process").type + for i = 1, 400 do + v = typ() + end + ngx.say("type: ", v) + } + } +--- request +GET /t +--- response_body +type: worker +--- grep_error_log eval +qr/\[TRACE \d+ init_worker_by_lua:\d loop\]|\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):\d loop\]|process type: \w+/ +--- grep_error_log_out eval +[ +qr/\[TRACE \d init_worker_by_lua:5 loop\] +\[TRACE \d init_worker_by_lua:5 loop\] +\[TRACE \d init_worker_by_lua:5 loop\] +\[TRACE \d content_by_lua\(nginx.conf:78\):5 loop\] +process type: helper +process type: helper +/, +qr/\[TRACE \d init_worker_by_lua:5 loop\] +\[TRACE \d init_worker_by_lua:5 loop\] +\[TRACE \d init_worker_by_lua:5 loop\] +\[TRACE \d content_by_lua\(nginx.conf:78\):5 loop\] +process type: helper +process type: helper +/ +] +--- no_error_log +[error] + -- NYI: +--- skip_nginx: 5: < 1.11.2 diff --git a/t/process-type-hup.t b/t/process-type-hup.t new file mode 100644 index 000000000..ad35fc760 --- /dev/null +++ b/t/process-type-hup.t @@ -0,0 +1,96 @@ +# 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 $SkipReason ? (skip_all => $SkipReason) : (); +use Cwd qw(cwd); + +#worker_connections(1014); +master_process_enabled(1); +log_level('warn'); + +repeat_each(2); + +plan tests => repeat_each() * (blocks() * 4); + +my $pwd = cwd(); + +our $HttpConfig = <<_EOC_; + + lua_package_path "$pwd/lib/?.lua;../lua-resty-lrucache/lib/?.lua;;"; + 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, "enable_privileged_agent failed: ", err) + end + } + + init_worker_by_lua_block { + local base = require "resty.core.base" + local typ = require "ngx.process".type + + if typ() == "privileged agent" then + ngx.log(ngx.WARN, "process type: ", typ()) + end + } +_EOC_ + +#no_diff(); +#no_long_string(); +check_accum_error_log(); +run_tests(); + +__DATA__ + +=== TEST 1: sanity +--- http_config eval: $::HttpConfig +--- config + location = /t { + content_by_lua_block { + local typ = require "ngx.process".type + + 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() + -- ngx.say("master pid: [", pid, "]") + + f:close() + + ngx.say("type: ", typ(true)) + os.execute("kill -HUP " .. pid) + } + } +--- request +GET /t +--- response_body +type: worker +--- grep_error_log eval +qr/init_worker_by_lua:\d+: process type: \w+/ +--- grep_error_log_out eval +[ +"init_worker_by_lua:6: process type: privileged +init_worker_by_lua:6: process type: privileged +", +"init_worker_by_lua:6: process type: privileged +init_worker_by_lua:6: process type: privileged +" +] +--- no_error_log +[error] +--- skip_nginx: 4: < 1.11.2 diff --git a/t/process-type-master.t b/t/process-type-master.t new file mode 100644 index 000000000..9b5207102 --- /dev/null +++ b/t/process-type-master.t @@ -0,0 +1,85 @@ +# vim:set ft= ts=4 sw=4 et fdm=marker: +use lib 'lib'; +use Test::Nginx::Socket::Lua; +use Cwd qw(cwd); + +#worker_connections(1014); +master_process_enabled(1); +#log_level('error'); + +repeat_each(2); + +plan tests => repeat_each() * (blocks() * 5); + +my $pwd = cwd(); + +our $HttpConfig = <<_EOC_; + lua_shared_dict dogs 1m; + lua_package_path "$pwd/lib/?.lua;../lua-resty-lrucache/lib/?.lua;;"; + init_by_lua_block { + local verbose = false + if verbose then + local dump = require "jit.dump" + dump.on("b", "$Test::Nginx::Util::ErrLogFile") + else + local v = require "jit.v" + v.on("$Test::Nginx::Util::ErrLogFile") + end + + require "resty.core" + -- jit.off() + } + + init_worker_by_lua_block { + local v + local typ = (require "ngx.process").type + for i = 1, 400 do + v = typ() + end + + ngx.log(ngx.WARN, "process type: ", v) + } +_EOC_ + +#no_diff(); +#no_long_string(); +check_accum_error_log(); +run_tests(); + +__DATA__ + +=== TEST 1: sanity +--- http_config eval: $::HttpConfig +--- config + location = /t { + content_by_lua_block { + local v + local typ = (require "ngx.process").type + for i = 1, 400 do + v = typ() + end + + ngx.say("process type: ", v) + } + } +--- request +GET /t +--- response_body +process type: worker +--- grep_error_log eval +qr/\[TRACE \d+ init_worker_by_lua:4 loop\]|\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):4 loop\]|init_worker_by_lua:\d: process type: \w+/ +--- grep_error_log_out eval +[ +qr/\[TRACE 1 init_worker_by_lua:4 loop\] +\[TRACE 2 content_by_lua\(nginx.conf:73\):4 loop\] +init_worker_by_lua:8: process type: worker +/, +qr/\[TRACE 1 init_worker_by_lua:4 loop\] +\[TRACE 2 content_by_lua\(nginx.conf:73\):4 loop\] +init_worker_by_lua:8: process type: worker +/ +] +--- no_error_log +[error] + -- NYI: +--- skip_nginx: 5: < 1.11.2 diff --git a/t/process-type-privileged-agent.t b/t/process-type-privileged-agent.t new file mode 100644 index 000000000..f7128b03f --- /dev/null +++ b/t/process-type-privileged-agent.t @@ -0,0 +1,140 @@ +# vim:set ft= ts=4 sw=4 et fdm=marker: +use lib 'lib'; +use Test::Nginx::Socket::Lua; +use Cwd qw(cwd); + +#worker_connections(1014); +master_process_enabled(1); +#log_level('error'); + +repeat_each(2); + +plan tests => repeat_each() * (blocks() * 5 - 3); + +my $pwd = cwd(); + +our $HttpConfig = <<_EOC_; + + lua_package_path "$pwd/lib/?.lua;../lua-resty-lrucache/lib/?.lua;;"; + init_by_lua_block { + local verbose = false + if verbose then + local dump = require "jit.dump" + dump.on("b", "$Test::Nginx::Util::ErrLogFile") + else + local v = require "jit.v" + v.on("$Test::Nginx::Util::ErrLogFile") + end + + require "resty.core" + local process = require "ngx.process" + local ok, err = process.enable_privileged_agent() + if not ok then + ngx.log(ngx.ERR, "enable_privileged_agent failed: ", err) + end + } + + init_worker_by_lua_block { + local base = require "resty.core.base" + local v + local typ = (require "ngx.process").type + for i = 1, 400 do + v = typ() + end + + if v == "privileged agent" then + ngx.log(ngx.WARN, "process type: ", v) + end + } +_EOC_ + +#no_diff(); +#no_long_string(); +check_accum_error_log(); +run_tests(); + +__DATA__ + +=== TEST 1: sanity +--- http_config eval: $::HttpConfig +--- config + location = /t { + content_by_lua_block { + ngx.sleep(0.1) + local v + local typ = require "ngx.process".type + for i = 1, 400 do + v = typ() + end + + ngx.say("type: ", v) + } + } +--- request +GET /t +--- response_body +type: worker +--- grep_error_log eval +qr/\[TRACE \d+ init_worker_by_lua:\d+ loop\]|\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):\d+ loop\]|init_worker_by_lua:\d+: process type: \w+/ +--- grep_error_log_out eval +[ +qr/\[TRACE \d init_worker_by_lua:5 loop\] +\[TRACE \d init_worker_by_lua:5 loop\] +\[TRACE \d content_by_lua\(nginx.conf:81\):5 loop\] +init_worker_by_lua:10: process type: privileged +/, +qr/\[TRACE \d init_worker_by_lua:5 loop\] +\[TRACE \d init_worker_by_lua:5 loop\] +\[TRACE \d content_by_lua\(nginx.conf:81\):5 loop\] +init_worker_by_lua:10: process type: privileged +/ +] +--- no_error_log +[error] + -- NYI: +--- skip_nginx: 5: < 1.11.2 + + + +=== TEST 2: `enable_privileged_agent` disabled +--- http_config eval: $::HttpConfig +--- config + location = /t { + content_by_lua_block { + local process = require "ngx.process" + local ok, err = process.enable_privileged_agent() + if not ok then + error(err) + end + } + } +--- request +GET /t +--- response_body_like: 500 Internal Server Error +--- error_code: 500 +--- error_log eval +qr/\[error\] .*? API disabled in the current context/ +--- skip_nginx: 3: < 1.11.2 + + + +=== TEST 3: `enable_privileged_agent` not patched +--- http_config eval: $::HttpConfig +--- config + location = /t { + content_by_lua_block { + local process = require "ngx.process" + local ok, err = process.enable_privileged_agent() + if not ok then + error(err) + end + } + } +--- request +GET /t +--- response_body_like: 500 Internal Server Error +--- error_code: 500 +--- error_log +missing privileged agent process patch in the nginx core +API disabled in the current context +--- skip_nginx: 4: >= 1.11.2 From f9ae2d3684a639f8dc5bf4c353fe7fc00e743c0e Mon Sep 17 00:00:00 2001 From: "Yichun Zhang (agentzh)" Date: Sat, 6 May 2017 18:27:21 -0700 Subject: [PATCH 38/74] now we require at least ngx_lua 0.10.9. --- README.markdown | 6 +++++- lib/resty/core/base.lua | 4 ++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/README.markdown b/README.markdown index 56edfead3..8de1b0f47 100644 --- a/README.markdown +++ b/README.markdown @@ -86,8 +86,12 @@ and requirements. Prerequisites ============= +**WARNING** This library is included with every OpenResty release. You should use the bundled version +of this library in the particular OpenResty release you are using. Otherwise you may run +into serious comaptibility issues. + * LuaJIT 2.1 (for now, it is the v2.1 git branch in the official luajit-2.0 git repository: http://luajit.org/download.html ) -* [ngx_lua](https://github.com/openresty/lua-nginx-module) v0.10.8 or later. +* [ngx_lua](https://github.com/openresty/lua-nginx-module) v0.10.9 or later. * [lua-resty-lrucache](https://github.com/openresty/lua-resty-lrucache) [Back to TOC](#table-of-contents) diff --git a/lib/resty/core/base.lua b/lib/resty/core/base.lua index ed7a9a275..e29bfcd44 100644 --- a/lib/resty/core/base.lua +++ b/lib/resty/core/base.lua @@ -15,9 +15,9 @@ local FREE_LIST_REF = 0 if not ngx.config or not ngx.config.ngx_lua_version - or ngx.config.ngx_lua_version < 10008 + or ngx.config.ngx_lua_version < 10009 then - error("ngx_lua 0.10.8+ required") + error("ngx_lua 0.10.9+ required") end From de9e1ce1d7288dee0d0970ff08630301336876e0 Mon Sep 17 00:00:00 2001 From: "Yichun Zhang (agentzh)" Date: Sun, 7 May 2017 21:14:59 -0700 Subject: [PATCH 39/74] bumped version number to 0.1.12. --- lib/resty/core/base.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/resty/core/base.lua b/lib/resty/core/base.lua index e29bfcd44..c0abb6123 100644 --- a/lib/resty/core/base.lua +++ b/lib/resty/core/base.lua @@ -96,7 +96,7 @@ local c_buf_type = ffi.typeof("char[?]") local _M = new_tab(0, 16) -_M.version = "0.1.11" +_M.version = "0.1.12" _M.new_tab = new_tab _M.clear_tab = clear_tab From e14696cbd8af2b5755a2e0215237227791d3ddf0 Mon Sep 17 00:00:00 2001 From: spacewander Date: Mon, 8 May 2017 22:31:19 +0800 Subject: [PATCH 40/74] doc: updated the TOC section in lib/ngx/re.md file with markdown-toc.pl. Signed-off-by: Yichun Zhang (agentzh) --- lib/ngx/re.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/ngx/re.md b/lib/ngx/re.md index c1df8ed92..5f9b7335c 100644 --- a/lib/ngx/re.md +++ b/lib/ngx/re.md @@ -12,6 +12,7 @@ Table of Contents * [Description](#description) * [Methods](#methods) * [split](#split) + * [opt](#opt) * [Community](#community) * [English Mailing List](#english-mailing-list) * [Chinese Mailing List](#chinese-mailing-list) @@ -145,6 +146,8 @@ local res, err = ngx_re.split("a,b", ",", nil, nil, nil, my_table) When the trailing `nil` is not enough for your purpose, you should clear the table yourself before feeding it into the `split` function. +[Back to TOC](#table-of-contents) + opt ----- **syntax:** *ngx_re.opt(option, value)* From 92e60532ed5e1a614036f4fc29508bace8cafb11 Mon Sep 17 00:00:00 2001 From: "Yichun Zhang (agentzh)" Date: Tue, 9 May 2017 19:59:10 -0700 Subject: [PATCH 41/74] doc: ngx.process: more details on the privileged agent process. --- lib/ngx/process.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/ngx/process.md b/lib/ngx/process.md index b32b4b16a..c00306b89 100644 --- a/lib/ngx/process.md +++ b/lib/ngx/process.md @@ -119,6 +119,14 @@ enable_privileged_agent Enables the privileged agent process in Nginx. +The priviledged agent process does not listen on any virtual server ports like those worker processes. +And it uses the same system account as the nginx master process, which is usually a privileged account +like `root`. + +The `init_worker_by_lua*` directive handler still runs in the privileged agent process. And one can +use the [type](#type) function provided by this module to check if the current process is a privileged +agent. + In case of failures, returns `nil` and a string describing the error. [Back to TOC](#table-of-contents) From b806b49abb1cc9baa6e95fa47173a20e93de8cab Mon Sep 17 00:00:00 2001 From: Yuansheng Date: Thu, 11 May 2017 11:10:53 +0800 Subject: [PATCH 42/74] tests & docs: minor tweaks. Signed-off-by: Yichun Zhang (agentzh) --- lib/ngx/process.md | 2 +- t/process-type-hup.t | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/ngx/process.md b/lib/ngx/process.md index c00306b89..436779e66 100644 --- a/lib/ngx/process.md +++ b/lib/ngx/process.md @@ -106,7 +106,7 @@ For example, ```lua local process = require "ngx.process" - ngx.say("process type:", process.type()) -- worker + ngx.say("process type:", process.type()) -- RESPONSE: worker ``` [Back to TOC](#table-of-contents) diff --git a/t/process-type-hup.t b/t/process-type-hup.t index ad35fc760..d24b6609a 100644 --- a/t/process-type-hup.t +++ b/t/process-type-hup.t @@ -72,7 +72,7 @@ __DATA__ f:close() - ngx.say("type: ", typ(true)) + ngx.say("type: ", typ()) os.execute("kill -HUP " .. pid) } } From 4d3d773ba22eb48006eacce3ce11d0bcb9e580c8 Mon Sep 17 00:00:00 2001 From: Yuansheng Date: Fri, 12 May 2017 10:51:02 +0800 Subject: [PATCH 43/74] doc: fixed the code example since directives `ssl_session_*_by_lua*` are no longer allowed in `server {}`. Signed-off-by: Yichun Zhang (agentzh) --- lib/ngx/ssl/session.md | 158 ++++++++++++++++++++--------------------- 1 file changed, 79 insertions(+), 79 deletions(-) diff --git a/lib/ngx/ssl/session.md b/lib/ngx/ssl/session.md index fe8522702..5e6243781 100644 --- a/lib/ngx/ssl/session.md +++ b/lib/ngx/ssl/session.md @@ -37,99 +37,99 @@ Synopsis # OpenResty 1.11.2.1+. lua_package_path "/path/to/lua-resty-core/lib/?.lua;;"; -server { - listen 443 ssl; - server_name test.com; +ssl_session_fetch_by_lua_block { + local ssl_sess = require "ngx.ssl.session" + + local sess_id, err = ssl_sess.get_session_id() + if not sess_id then + ngx.log(ngx.ERR, "failed to get session ID: ", err) + -- considered a cache miss, and just return... + return + end + + -- the user is supposed to implement the my_lookup_ssl_session_by_id + -- Lua function used below. She can look up an external memcached + -- or redis cluster, for example. And she can also introduce a local + -- cache layer at the same time... + local sess, err = my_lookup_ssl_session_by_id(sess_id) + if not sess then + if err then + ngx.log(ngx.ERR, "failed to look up the session by ID ", + sess_id, ": ", err) + return + end - # well, we could configure ssl_certificate_by_lua* here as well... - ssl_certificate /path/to/server-cert.pem; - ssl_certificate_key /path/to/server-priv-key.pem; + -- cache miss...just return + return + end - ssl_session_fetch_by_lua_block { - local ssl_sess = require "ngx.ssl.session" + local ok, err = ssl_sess.set_serialized_session(sess) + if not ok then + ngx.log(ngx.ERR, "failed to set SSL session for ID ", sess_id, + ": ", err) + -- consider it as a cache miss... + return + end - local sess_id, err = ssl_sess.get_session_id() - if not sess_id then - ngx.log(ngx.ERR, "failed to get session ID: ", err) - -- considered a cache miss, and just return... - return - end + -- done here, SSL session successfully set and should resume accordingly... +} - -- the user is supposed to implement the my_lookup_ssl_session_by_id - -- Lua function used below. She can look up an external memcached - -- or redis cluster, for example. And she can also introduce a local - -- cache layer at the same time... - local sess, err = my_lookup_ssl_session_by_id(sess_id) +ssl_session_store_by_lua_block { + local ssl_sess = require "ngx.ssl.session" + + local sess_id, err = ssl_sess.get_session_id() + if not sess_id then + ngx.log(ngx.ERR, "failed to get session ID: ", err) + -- just give up + return + end + + local sess, err = ssl_sess.get_serialized_session() + if not sess then + ngx.log(ngx.ERR, "failed to get SSL session from the ", + "current connection: ", err) + -- just give up + return + end + + -- for the best performance, we should avoid creating a closure + -- dynamically here on the hot code path. Instead, we should + -- put this function in one of our own Lua module files. this + -- example is just for demonstration purposes... + local function save_it(premature, sess_id, sess) + -- the user is supposed to implement the + -- my_save_ssl_session_by_id Lua function used below. + -- She can save to an external memcached + -- or redis cluster, for example. And she can also introduce + -- a local cache layer at the same time... + local sess, err = my_save_ssl_session_by_id(sess_id, sess) if not sess then if err then - ngx.log(ngx.ERR, "failed to look up the session by ID ", + ngx.log(ngx.ERR, "failed to save the session by ID ", sess_id, ": ", err) - return + return ngx.exit(ngx.ERROR) end -- cache miss...just return return end + end + + -- create a 0-delay timer here... + local ok, err = ngx.timer.at(0, save_it) + if not ok then + ngx.log(ngx.ERR, "failed to create a 0-delay timer: ", err) + return + end +} - local ok, err = ssl_sess.set_serialized_session(sess) - if not ok then - ngx.log(ngx.ERR, "failed to set SSL session for ID ", sess_id, - ": ", err) - -- consider it as a cache miss... - return - end - - -- done here, SSL session successfully set and should resume accordingly... - } - - ssl_session_store_by_lua_block { - local ssl_sess = require "ngx.ssl.session" - - local sess_id, err = ssl_sess.get_session_id() - if not sess_id then - ngx.log(ngx.ERR, "failed to get session ID: ", err) - -- just give up - return - end - - local sess, err = ssl_sess.get_serialized_session() - if not sess then - ngx.log(ngx.ERR, "failed to get SSL session from the ", - "current connection: ", err) - -- just give up - return - end - - -- for the best performance, we should avoid creating a closure - -- dynamically here on the hot code path. Instead, we should - -- put this function in one of our own Lua module files. this - -- example is just for demonstration purposes... - local function save_it(premature, sess_id, sess) - -- the user is supposed to implement the - -- my_save_ssl_session_by_id Lua function used below. - -- She can save to an external memcached - -- or redis cluster, for example. And she can also introduce - -- a local cache layer at the same time... - local sess, err = my_save_ssl_session_by_id(sess_id, sess) - if not sess then - if err then - ngx.log(ngx.ERR, "failed to save the session by ID ", - sess_id, ": ", err) - return ngx.exit(ngx.ERROR) - end - - -- cache miss...just return - return - end - end +server { + listen 443 ssl; + server_name test.com; - -- create a 0-delay timer here... - local ok, err = ngx.timer.at(0, save_it) - if not ok then - ngx.log(ngx.ERR, "failed to create a 0-delay timer: ", err) - return - end - } + # well, we could configure ssl_certificate_by_lua* here as well... + ssl_certificate /path/to/server-cert.pem; + ssl_certificate_key /path/to/server-priv-key.pem; } ``` From 1d7cfc0533edfd29cceb4079dcf5e2f22d13ced0 Mon Sep 17 00:00:00 2001 From: Yuansheng Date: Fri, 14 Apr 2017 01:44:52 +0800 Subject: [PATCH 44/74] feature: added new Lua module ngx.errlog which provides Lua API to capture nginx error log data on Lua land. Signed-off-by: Yichun Zhang (agentzh) --- README.markdown | 14 +- lib/ngx/errlog.lua | 85 +++++ lib/ngx/errlog.md | 268 ++++++++++++++ t/errlog.t | 884 +++++++++++++++++++++++++++++++++++++++++++++ t/shdict.t | 4 +- 5 files changed, 1251 insertions(+), 4 deletions(-) create mode 100644 lib/ngx/errlog.lua create mode 100644 lib/ngx/errlog.md create mode 100644 t/errlog.t diff --git a/README.markdown b/README.markdown index 8de1b0f47..da28057e9 100644 --- a/README.markdown +++ b/README.markdown @@ -30,8 +30,8 @@ Table of Contents * [ngx.ssl](#ngxssl) * [ngx.ssl.session](#ngxsslsession) * [ngx.re](#ngxre) - * [ngx.process](ngxprocess) - + * [ngx.process](#ngxprocess) + * [ngx.errlog](#ngxerrlog) * [Caveat](#caveat) * [TODO](#todo) * [Author](#author) @@ -261,6 +261,16 @@ This module was first introduced in lua-resty-core v0.1.12. [Back to TOC](#table-of-contents) +## ngx.errlog + +This Lua module provides Lua API to capture and manage nginx error log messages. + +See the [documentation](./lib/ngx/errlog.md) for this Lua module for more details. + +This module was first introduced in lua-resty-core v0.1.12. + +[Back to TOC](#table-of-contents) + Caveat ====== diff --git a/lib/ngx/errlog.lua b/lib/ngx/errlog.lua new file mode 100644 index 000000000..c18569991 --- /dev/null +++ b/lib/ngx/errlog.lua @@ -0,0 +1,85 @@ +-- Copyright (C) Yichun Zhang (agentzh) + + +local ffi = require 'ffi' +local base = require "resty.core.base" +local ffi_string = ffi.string +local get_string_buf = base.get_string_buf +local get_size_ptr = base.get_size_ptr +local C = ffi.C +local new_tab = base.new_tab +local ffi_new = ffi.new +local charpp = ffi_new("char *[1]") +local intp = ffi.new("int[1]") + + +local _M = { version = base.version } + + +ffi.cdef[[ +int ngx_http_lua_ffi_set_errlog_filter(int level, unsigned char *err, + size_t *errlen); +int ngx_http_lua_ffi_get_errlog_data(char **log, int *loglevel, + unsigned char *err, size_t *errlen); +]] + + +local ERR_BUF_SIZE = 128 +local FFI_ERROR = base.FFI_ERROR + + +function _M.set_errlog_filter(level) + if not level then + return nil, [[missing "level" argument]] + end + + local err = get_string_buf(ERR_BUF_SIZE) + local errlen = get_size_ptr() + errlen[0] = ERR_BUF_SIZE + local rc = C.ngx_http_lua_ffi_set_errlog_filter(level, err, errlen) + + if rc == FFI_ERROR then + return nil, ffi_string(err, errlen[0]) + end + + return true +end + + +function _M.get_error_logs(max, logs) + local err = get_string_buf(ERR_BUF_SIZE) + local errlen = get_size_ptr() + errlen[0] = ERR_BUF_SIZE + + local log = charpp + local loglevel = intp + + max = max or 10 + + if not logs then + logs = new_tab(max * 2 + 1, 0) + end + + for i = 1, max do + local loglen = C.ngx_http_lua_ffi_get_errlog_data(log, + loglevel, err, errlen) + if loglen == FFI_ERROR then + return nil, ffi_string(err, errlen[0]) + end + + if loglen > 0 then + logs[i * 2 - 1] = loglevel[0] + logs[i * 2] = ffi_string(log[0], loglen) + end + + if loglen < 0 or i == max then -- last one + logs[i * 2 + 1] = nil + break + end + end + + return logs +end + + +return _M diff --git a/lib/ngx/errlog.md b/lib/ngx/errlog.md new file mode 100644 index 000000000..e2bd510ca --- /dev/null +++ b/lib/ngx/errlog.md @@ -0,0 +1,268 @@ +Name +==== + +`ngx.errlog` - manage nginx error log data in Lua for OpenResty/ngx_lua. + +Table of Contents +================= + +* [Name](#name) +* [Status](#status) +* [Synopsis](#synopsis) + * [Intercept nginx error logs with specified log level](#intercept-nginx-error-logs-with-specified-log-level) +* [Methods](#methods) + * [set_errlog_filter](#set_errlog_filter) + * [get_error_logs](#get_error_logs) +* [Community](#community) + * [English Mailing List](#english-mailing-list) + * [Chinese Mailing List](#chinese-mailing-list) +* [Bugs and Patches](#bugs-and-patches) +* [Author](#author) +* [Copyright and License](#copyright-and-license) +* [See Also](#see-also) + +Status +====== + +This Lua module is currently considered experimental. + +The API is still in flux and may change in the future without notice. + +Synopsis +======== + +Intercept nginx error logs with specified log level +--------------------------------------------------- + +```nginx +error logs/error.log info; + +http { + # enable intercept error log + lua_intercept_error_log 32m; + + init_by_lua_block { + local errlog = require "ngx.errlog" + local status, err = errlog.set_errlog_filter(ngx.WARN) + if not status then + ngx.log(ngx.ERR, err) + return + end + ngx.log(ngx.WARN, "set error filter level: WARN") + } + + server { + # ... + location = /t { + content_by_lua_block { + local errlog = require "ngx.errlog" + ngx.log(ngx.INFO, "test1") + ngx.log(ngx.WARN, "test2") + ngx.log(ngx.ERR, "test3") + + local logs, err = errlog.get_error_logs() + if not logs then + ngx.say("FAILED ", err) + return + end + + for _, log in ipairs(logs) do + ngx.say("level: ", log[1], " data: ", log[2]) + end + } + } + } +} + +``` + +The example location above produces a response like this: + +``` +level: 5 data: 2017/04/19 22:20:03 [warn] 63176#0: + [lua] init_by_lua:7: set error filter level: WARN +level: 5 data: 2017/04/19 22:20:05 [warn] 63176#0: *1 + [lua] content_by_lua(nginx.conf:59):4: test2 +level: 4 data: 2017/04/19 22:20:05 [error] 63176#0: *1 + [lua] content_by_lua(nginx.conf:59):5: test3 +``` + +[Back to TOC](#table-of-contents) + +Methods +======= + +set_errlog_filter +----------------- +**syntax:** *status, err = log_module.set_errlog_filter(log_level)* + +**context:** *init_by_lua** + +Specifies the filter log level, only to intercept the error log we need. +If we don't call this API, all of the error logs will be intercepted by default. + +In case of error, `nil` will be returned as well as a string describing the +error. + +This API should always work with directive [lua_intercept_error_log](https://github.com/openresty/lua-nginx-module#lua_intercept_error_log). + +See [Nginx log level constants](https://github.com/openresty/lua-nginx-module#nginx-log-level-constants) for all nginx log levels. + +For example, + +```lua + init_by_lua_block { + local errlog = require "ngx.errlog" + errlog.set_errlog_filter(ngx.WARN) + } +``` + +*NOTE:* The debugging logs since when OpenResty or NGINX is not built with `--with-debug`, all the debug level logs are suppressed regardless. + +[Back to TOC](#table-of-contents) + +get_error_logs +-------------- +**syntax:** *res, err = log_module.get_error_logs(max, res?)* + +**context:** *any* + +Returns the intercepted nginx error logs if successful. + +In case of error, `nil` will be returned as well as a string describing the +error. + +The optional `max` argument is a number that when specified, will prevent +`errlog.get_error_logs` from adding more than `max` messages to the `res` array. + +```lua +for i = 1, 20 do + ngx.log(ngx.ERR, "test") +end + +local errlog = require "ngx.errlog" +local res = errlog.get_error_logs(10) +-- the number of messages in the `res` table is 10 and the `res` table +-- has 20 elements. +``` + +The resulting table has the following structure: + +```lua +{ level1, msg1, level2, msg2, ... } +``` + +So to traverse this array, the user can use a loop like this: + +```lua +for i = 1, #res, 2 do + local level = res[i] + if not level then + break + end + local msg = res[i + 1] + -- handle the current message with log level in `level` and + -- log message body in `msg`. +end +``` + +Specifying `max <= 0` disables this behavior, meaning that the number of +results won't be limited. + +The optional 2th argument `res` can be a user-supplied Lua table +to hold the result instead of creating a brand new table. This can avoid +unnecessary table dynamic allocations on hot Lua code paths. It is used like this: + +```lua +local errlog = require "ngx.errlog" +local new_tab = require "table.new" + +local buffer = new_tab(100 * 2, 0) -- for 100 messages + +local errlog = require "ngx.errlog" +local res, err = errlog.get_error_logs(0, buffer) +if res then + -- res is the same table as `buffer` + for i = 1, #res, 2 do + local level = res[i] + if not level then + break + end + local msg = res[i + 1] + ... + end +end +``` + +When provided with a `res` table, `errlog.get_error_logs` won't clear the table +for performance reasons, but will rather insert a trailing `nil` value +after the last table element. + +When the trailing `nil` is not enough for your purpose, you should +clear the table yourself before feeding it into the `errlog.get_error_logs` function. + +[Back to TOC](#table-of-contents) + +Community +========= + +[Back to TOC](#table-of-contents) + +English Mailing List +-------------------- + +The [openresty-en](https://groups.google.com/group/openresty-en) mailing list is for English speakers. + +[Back to TOC](#table-of-contents) + +Chinese Mailing List +-------------------- + +The [openresty](https://groups.google.com/group/openresty) mailing list is for Chinese speakers. + +[Back to TOC](#table-of-contents) + +Bugs and Patches +================ + +Please report bugs or submit patches by + +1. creating a ticket on the [GitHub Issue Tracker](https://github.com/openresty/lua-resty-core/issues), +1. or posting to the [OpenResty community](#community). + +[Back to TOC](#table-of-contents) + +Author +====== + +Yuansheng Wang <membphis@gmail.com> (membphis), OpenResty Inc. + +[Back to TOC](#table-of-contents) + +Copyright and License +===================== + +This module is licensed under the BSD license. + +Copyright (C) 2017, by Yichun "agentzh" Zhang, OpenResty Inc. + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +[Back to TOC](#table-of-contents) + +See Also +======== +* library [lua-resty-core](https://github.com/openresty/lua-resty-core) +* the ngx_lua module: https://github.com/openresty/lua-nginx-module +* OpenResty: http://openresty.org + +[Back to TOC](#table-of-contents) + diff --git a/t/errlog.t b/t/errlog.t new file mode 100644 index 000000000..c026ed0fa --- /dev/null +++ b/t/errlog.t @@ -0,0 +1,884 @@ +# vim:set ft= ts=4 sw=4 et fdm=marker: + +use Test::Nginx::Socket::Lua; +use Cwd qw(cwd); + +#worker_connections(1014); +#master_process_enabled(1); +log_level('error'); + +repeat_each(2); + +plan tests => repeat_each() * (blocks() * 2 + 11); + +my $pwd = cwd(); + +add_block_preprocessor(sub { + my $block = shift; + + my $http_config = $block->http_config || ''; + $http_config .= <<_EOC_; + + lua_package_path "$pwd/lib/?.lua;../lua-resty-lrucache/lib/?.lua;;"; + init_by_lua_block { + require "resty.core" + } +_EOC_ + $block->set_value("http_config", $http_config); +}); + +#no_diff(); +no_long_string(); +#check_accum_error_log(); +run_tests(); + +__DATA__ + +=== TEST 1: sanity +--- http_config + lua_intercept_error_log 4m; +--- config + location /t { + access_by_lua_block { + ngx.log(ngx.ERR, "enter 1") + ngx.log(ngx.ERR, "enter 11") + + local errlog = require "ngx.errlog" + local res, err = errlog.get_error_logs() + if not res then + error("FAILED " .. err) + end + ngx.say("log lines:", #res / 2) + } + } +--- request +GET /t +--- response_body +log lines:2 +--- grep_error_log eval +qr/enter \d+/ +--- grep_error_log_out eval +[ +"enter 1 +enter 11 +", +"enter 1 +enter 11 +" +] +--- skip_nginx: 3: <1.11.2 + + + +=== TEST 2: overflow intercepted error logs +--- http_config + lua_intercept_error_log 4k; +--- config + location /t { + access_by_lua_block { + ngx.log(ngx.ERR, "enter 1") + ngx.log(ngx.ERR, "enter 22" .. string.rep("a", 4096)) + + local errlog = require "ngx.errlog" + local res, err = errlog.get_error_logs() + if not res then + error("FAILED " .. err) + end + ngx.say("log lines:", #res / 2) + } + } +--- request +GET /t +--- response_body +log lines:1 +--- grep_error_log eval +qr/enter \d+/ +--- grep_error_log_out eval +[ +"enter 1 +enter 22 +", +"enter 1 +enter 22 +" +] +--- skip_nginx: 3: <1.11.2 + + + +=== TEST 3: 404 error(not found) +--- http_config + lua_intercept_error_log 4m; +--- config + log_by_lua_block { + local errlog = require "ngx.errlog" + local res, err = errlog.get_error_logs() + if not res then + error("FAILED " .. err) + end + ngx.log(ngx.ERR, "intercept log line:", #res / 2) + } +--- request +GET /t +--- error_code: 404 +--- grep_error_log eval +qr/intercept log line:\d+|No such file or directory/ +--- grep_error_log_out eval +[ +qr/^No such file or directory +intercept log line:1 +$/, +qr/^No such file or directory +intercept log line:2 +$/ +] +--- skip_nginx: 2: <1.11.2 + + + +=== TEST 4: 500 error +--- http_config + lua_intercept_error_log 4m; +--- config + location /t { + content_by_lua_block { + local t = {}/4 + } + } + log_by_lua_block { + local errlog = require "ngx.errlog" + local res, err = errlog.get_error_logs() + if not res then + error("FAILED " .. err) + end + ngx.log(ngx.ERR, "intercept log line:", #res / 2) + } +--- request +GET /t +--- error_code: 500 +--- grep_error_log eval +qr/intercept log line:\d+|attempt to perform arithmetic on a table value/ +--- grep_error_log_out eval +[ +qr/^attempt to perform arithmetic on a table value +intercept log line:1 +$/, +qr/^attempt to perform arithmetic on a table value +intercept log line:2 +$/ +] +--- skip_nginx: 2: <1.11.2 + + + +=== TEST 5: no error log +--- http_config + lua_intercept_error_log 4m; +--- config + location /t { + echo "hello"; + } + log_by_lua_block { + local errlog = require "ngx.errlog" + local res, err = errlog.get_error_logs() + if not res then + error("FAILED " .. err) + end + ngx.log(ngx.ERR, "intercept log line:", #res / 2) + } +--- request +GET /t +--- response_body +hello +--- grep_error_log eval +qr/intercept log line:\d+/ +--- grep_error_log_out eval +[ +qr/^intercept log line:0 +$/, +qr/^intercept log line:1 +$/ +] +--- skip_nginx: 3: <1.11.2 + + + +=== TEST 6: customize the log path +--- http_config + lua_intercept_error_log 4m; + error_log logs/error_http.log error; +--- config + location /t { + error_log logs/error.log error; + access_by_lua_block { + ngx.log(ngx.ERR, "enter access /t") + } + echo "hello"; + } + log_by_lua_block { + local errlog = require "ngx.errlog" + local res, err = errlog.get_error_logs() + if not res then + error("FAILED " .. err) + end + ngx.log(ngx.ERR, "intercept log line:", #res / 2) + + } +--- request +GET /t +--- response_body +hello +--- grep_error_log eval +qr/intercept log line:\d+|enter access/ +--- grep_error_log_out eval +[ +qr/^enter access +intercept log line:1 +$/, +qr/^enter access +intercept log line:2 +$/ +] +--- skip_nginx: 3: <1.11.2 + + + +=== TEST 7: invalid size (< 4k) +--- http_config + lua_intercept_error_log 3k; +--- config + location /t { + echo "hello"; + } +--- must_die +--- error_log +invalid intercept error log size "3k", minimum size is 4096 +--- skip_nginx: 2: <1.11.2 + + + +=== TEST 8: invalid size (no argu) +--- http_config + lua_intercept_error_log; +--- config + location /t { + echo "hello"; + } +--- must_die +--- error_log +invalid number of arguments in "lua_intercept_error_log" directive +--- skip_nginx: 2: <1.11.2 + + + +=== TEST 9: without directive + ngx.errlog +--- config + location /t { + access_by_lua_block { + ngx.log(ngx.ERR, "enter 1") + + local errlog = require "ngx.errlog" + local res, err = errlog.get_error_logs() + if not res then + error("FAILED " .. err) + end + ngx.say("log lines:", #res / 2) + } + } +--- request +GET /t +--- response_body_like: 500 Internal Server Error +--- error_code: 500 +--- error_log +API "get_errlog_data" depends on directive "lua_intercept_error_log" +--- skip_nginx: 3: <1.11.2 + + + +=== TEST 10: without directive + ngx.set_errlog_filter +--- config + location /t { + access_by_lua_block { + local errlog = require "ngx.errlog" + local status, err = errlog.set_errlog_filter(ngx.ERR) + if not status then + error(err) + end + } + } +--- request +GET /t +--- response_body_like: 500 Internal Server Error +--- error_code: 500 +--- error_log +API "set_errlog_filter" depends on directive "lua_intercept_error_log" +--- skip_nginx: 3: <1.11.2 + + + +=== TEST 11: filter log by level(ngx.INFO) +--- http_config + lua_intercept_error_log 4m; +--- config + location /t { + access_by_lua_block { + local errlog = require "ngx.errlog" + local status, err = errlog.set_errlog_filter(ngx.INFO) + if not status then + error(err) + end + + ngx.log(ngx.INFO, "-->1") + ngx.log(ngx.WARN, "-->2") + ngx.log(ngx.ERR, "-->3") + } + content_by_lua_block { + local errlog = require "ngx.errlog" + local res = errlog.get_error_logs() + ngx.say("log lines:", #res / 2) + } + } +--- log_level: info +--- request +GET /t +--- response_body +log lines:3 +--- grep_error_log eval +qr/-->\d+/ +--- grep_error_log_out eval +[ +"-->1 +-->2 +-->3 +", +"-->1 +-->2 +-->3 +" +] +--- skip_nginx: 3: <1.11.2 + + + +=== TEST 12: filter log by level(ngx.WARN) +--- http_config + lua_intercept_error_log 4m; +--- config + location /t { + access_by_lua_block { + local errlog = require "ngx.errlog" + local status, err = errlog.set_errlog_filter(ngx.WARN) + if not status then + error(err) + end + + ngx.log(ngx.INFO, "-->1") + ngx.log(ngx.WARN, "-->2") + ngx.log(ngx.ERR, "-->3") + } + content_by_lua_block { + local errlog = require "ngx.errlog" + local res = errlog.get_error_logs() + ngx.say("log lines:", #res / 2) + } + } +--- log_level: info +--- request +GET /t +--- response_body +log lines:2 +--- grep_error_log eval +qr/-->\d+/ +--- grep_error_log_out eval +[ +"-->1 +-->2 +-->3 +", +"-->1 +-->2 +-->3 +" +] +--- skip_nginx: 3: <1.11.2 + + + +=== TEST 13: filter log by level(ngx.CRIT) +--- http_config + lua_intercept_error_log 4m; +--- log_level: info +--- config + location /t { + access_by_lua_block { + local errlog = require "ngx.errlog" + local status, err = errlog.set_errlog_filter(ngx.CRIT) + if not status then + error(err) + end + + ngx.log(ngx.INFO, "-->1") + ngx.log(ngx.WARN, "-->2") + ngx.log(ngx.ERR, "-->3") + } + content_by_lua_block { + local errlog = require "ngx.errlog" + local res = errlog.get_error_logs() + ngx.say("log lines:", #res / 2) + } + } +--- request +GET /t +--- response_body +log lines:0 +--- grep_error_log eval +qr/-->\d+/ +--- grep_error_log_out eval +[ +"-->1 +-->2 +-->3 +", +"-->1 +-->2 +-->3 +" +] +--- skip_nginx: 3: <1.11.2 + + + +=== TEST 14: set max count and reuse table +--- http_config + lua_intercept_error_log 4m; +--- config + location /t { + access_by_lua_block { + tab_clear = require "table.clear" + ngx.log(ngx.ERR, "enter 1") + ngx.log(ngx.ERR, "enter 22") + ngx.log(ngx.ERR, "enter 333") + + local errlog = require "ngx.errlog" + local res = {} + local err + res, err = errlog.get_error_logs(2, res) + if not res then + error("FAILED " .. err) + end + ngx.say("log lines:", #res / 2) + + tab_clear(res) + res, err = errlog.get_error_logs(2, res) + if not res then + error("FAILED " .. err) + end + ngx.say("log lines:", #res / 2) + } + } +--- request +GET /t +--- response_body +log lines:2 +log lines:1 +--- skip_nginx: 2: <1.11.2 + + + +=== TEST 15: wrong argument +--- http_config + lua_intercept_error_log 4m; +--- config + location /t { + access_by_lua_block { + local errlog = require "ngx.errlog" + local status, err = errlog.set_errlog_filter() + if not status then + error(err) + end + } + } +--- request +GET /t +--- error_code: 500 +--- response_body_like: 500 +--- grep_error_log eval +qr/missing \"level\" argument/ +--- grep_error_log_out eval +[ +"missing \"level\" argument +", +"missing \"level\" argument +", +] +--- skip_nginx: 3: <1.11.2 + + + +=== TEST 16: check the intercepted error log body +--- http_config + lua_intercept_error_log 4m; +--- config + location /t { + access_by_lua_block { + local errlog = require "ngx.errlog" + local status, err = errlog.set_errlog_filter(ngx.WARN) + if not status then + error(err) + end + + ngx.log(ngx.INFO, "-->1") + ngx.log(ngx.WARN, "-->2") + ngx.log(ngx.ERR, "-->3") + } + + content_by_lua_block { + local errlog = require "ngx.errlog" + local res = errlog.get_error_logs() + for i = 1, #res, 2 do + ngx.say("log level:", res[i]) + ngx.say("log body:", res[i + 1]) + end + } + } +--- log_level: info +--- request +GET /t +--- response_body_like +log level:5 +log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[warn\] (\d+).*access_by_lua\(nginx.conf:\d+\):\d+: -->2, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" +log level:4 +log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*access_by_lua\(nginx.conf:\d+\):\d+: -->3, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" +--- grep_error_log eval +qr/-->\d+/ +--- grep_error_log_out eval +[ +"-->1 +-->2 +-->3 +", +"-->1 +-->2 +-->3 +" +] +--- skip_nginx: 3: <1.11.2 + + + +=== TEST 17: flood the capturing buffer (4k) +--- http_config + lua_intercept_error_log 4k; +--- config + location /t { + access_by_lua_block { + local errlog = require "ngx.errlog" + local status, err = errlog.set_errlog_filter(ngx.WARN) + if not status then + error(err) + end + + for i = 1, 100 do + ngx.log(ngx.INFO, "--> ", i) + ngx.log(ngx.WARN, "--> ", i) + ngx.log(ngx.ERR, "--> ", i) + end + } + + content_by_lua_block { + local errlog = require "ngx.errlog" + local res = errlog.get_error_logs(1000) + ngx.say("log lines: #", #res / 2) + + -- first 3 logs + for i = 1, 2 * 3, 2 do + ngx.say("log level:", res[i]) + ngx.say("log body:", res[i + 1]) + end + + -- last 3 logs + for i = #res - 5, #res, 2 do + ngx.say("log level:", res[i]) + ngx.say("log body:", res[i + 1]) + end + } + } +--- log_level: info +--- request +GET /t +--- response_body_like chomp +\Alog lines: #22 +log level:5 +log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[warn\] (\d+).*access_by_lua\(nginx.conf:\d+\):\d+: --> 90, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" +log level:4 +log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*access_by_lua\(nginx.conf:\d+\):\d+: --> 90, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" +log level:5 +log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[warn\] (\d+).*access_by_lua\(nginx.conf:\d+\):\d+: --> 91, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" +log level:4 +log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*access_by_lua\(nginx.conf:\d+\):\d+: --> 99, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" +log level:5 +log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[warn\] (\d+).*access_by_lua\(nginx.conf:\d+\):\d+: --> 100, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" +log level:4 +log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*access_by_lua\(nginx.conf:\d+\):\d+: --> 100, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" +\z +--- skip_nginx: 2: <1.11.2 + + + +=== TEST 18: flood the capturing buffer (5k) +--- http_config + lua_intercept_error_log 5k; +--- config + location /t { + access_by_lua_block { + local errlog = require "ngx.errlog" + local status, err = errlog.set_errlog_filter(ngx.WARN) + if not status then + error(err) + end + + for i = 1, 100 do + ngx.log(ngx.INFO, "--> ", i) + ngx.log(ngx.WARN, "--> ", i) + ngx.log(ngx.ERR, "--> ", i) + end + } + + content_by_lua_block { + local errlog = require "ngx.errlog" + local res = errlog.get_error_logs(1000) + ngx.say("log lines: #", #res / 2) + + -- first 3 logs + for i = 1, 2 * 3, 2 do + ngx.say("log level:", res[i]) + ngx.say("log body:", res[i + 1]) + end + + -- last 3 logs + for i = #res - 5, #res, 2 do + ngx.say("log level:", res[i]) + ngx.say("log body:", res[i + 1]) + end + } + } +--- log_level: info +--- request +GET /t +--- response_body_like chomp +\Alog lines: #28 +log level:5 +log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[warn\] (\d+).*access_by_lua\(nginx.conf:\d+\):\d+: --> 87, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" +log level:4 +log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*access_by_lua\(nginx.conf:\d+\):\d+: --> 87, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" +log level:5 +log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[warn\] (\d+).*access_by_lua\(nginx.conf:\d+\):\d+: --> 88, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" +log level:4 +log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*access_by_lua\(nginx.conf:\d+\):\d+: --> 99, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" +log level:5 +log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[warn\] (\d+).*access_by_lua\(nginx.conf:\d+\):\d+: --> 100, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" +log level:4 +log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*access_by_lua\(nginx.conf:\d+\):\d+: --> 100, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" +\z +--- skip_nginx: 2: <1.11.2 + + + +=== TEST 19: fetch a few and generate a few, then fetch again (overflown again) +--- http_config + lua_intercept_error_log 5k; +--- config + location /t { + access_by_lua_block { + local errlog = require "ngx.errlog" + local status, err = errlog.set_errlog_filter(ngx.WARN) + if not status then + error(err) + end + + for i = 1, 100 do + ngx.log(ngx.INFO, "--> ", i) + ngx.log(ngx.WARN, "--> ", i) + ngx.log(ngx.ERR, "--> ", i) + end + } + + content_by_lua_block { + local errlog = require "ngx.errlog" + + local res = errlog.get_error_logs(3) + ngx.say("msg count: ", #res / 2) + + -- first 3 logs + for i = 1, #res, 2 do + ngx.say("log level:", res[i]) + ngx.say("log body:", res[i + 1]) + end + + ngx.log(ngx.ERR, "--> 101") + ngx.log(ngx.ERR, "--> 102") + ngx.log(ngx.ERR, "--> 103") + ngx.log(ngx.ERR, "--> 104") + + local res = errlog.get_error_logs(3) + ngx.say("msg count: ", #res / 2) + + -- first 3 logs + for i = 1, #res, 2 do + ngx.say("log level:", res[i]) + ngx.say("log body:", res[i + 1]) + end + + local res = errlog.get_error_logs(1000) + -- last 3 logs + for i = #res - 5, #res, 2 do + ngx.say("log level:", res[i]) + ngx.say("log body:", res[i + 1]) + end + } + } +--- log_level: info +--- request +GET /t +--- response_body_like chomp +\Amsg count: 3 +log level:5 +log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[warn\] (\d+).*?access_by_lua\(nginx.conf:\d+\):\d+: --> 87, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" +log level:4 +log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*?access_by_lua\(nginx.conf:\d+\):\d+: --> 87, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" +log level:5 +log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[warn\] (\d+).*?access_by_lua\(nginx.conf:\d+\):\d+: --> 88, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" +msg count: 3 +log level:5 +log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[warn\] (\d+).*?access_by_lua\(nginx.conf:\d+\):\d+: --> 89, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" +log level:4 +log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*?access_by_lua\(nginx.conf:\d+\):\d+: --> 89, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" +log level:5 +log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[warn\] (\d+).*?access_by_lua\(nginx.conf:\d+\):\d+: --> 90, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" +log level:4 +log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*?content_by_lua\(nginx.conf:\d+\):\d+: --> 102, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" +log level:4 +log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*?content_by_lua\(nginx.conf:\d+\):\d+: --> 103, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" +log level:4 +log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*?content_by_lua\(nginx.conf:\d+\):\d+: --> 104, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" +\z +--- skip_nginx: 2: <1.11.2 + + + +=== TEST 20: fetch a few and generate a few, then fetch again (not overflown again) +--- http_config + lua_intercept_error_log 5k; +--- config + location /t { + access_by_lua_block { + local errlog = require "ngx.errlog" + local status, err = errlog.set_errlog_filter(ngx.WARN) + if not status then + error(err) + end + + for i = 1, 100 do + ngx.log(ngx.INFO, "--> ", i) + ngx.log(ngx.WARN, "--> ", i) + ngx.log(ngx.ERR, "--> ", i) + end + } + + content_by_lua_block { + local errlog = require "ngx.errlog" + + local res = errlog.get_error_logs(3) + ngx.say("msg count: ", #res / 2) + + -- first 3 logs + for i = 1, #res, 2 do + ngx.say("log level:", res[i]) + ngx.say("log body:", res[i + 1]) + end + + ngx.log(ngx.ERR, "howdy, something new!") + ngx.log(ngx.ERR, "howdy, something even newer!") + + local res = errlog.get_error_logs(3) + ngx.say("msg count: ", #res / 2) + + -- first 3 logs + for i = 1, #res, 2 do + ngx.say("log level:", res[i]) + ngx.say("log body:", res[i + 1]) + end + + local res = errlog.get_error_logs(1000) + -- last 3 logs + for i = #res - 5, #res, 2 do + ngx.say("log level:", res[i]) + ngx.say("log body:", res[i + 1]) + end + } + } +--- log_level: info +--- request +GET /t +--- response_body_like chomp +\Amsg count: 3 +log level:5 +log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[warn\] (\d+).*?access_by_lua\(nginx.conf:\d+\):\d+: --> 87, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" +log level:4 +log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*?access_by_lua\(nginx.conf:\d+\):\d+: --> 87, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" +log level:5 +log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[warn\] (\d+).*?access_by_lua\(nginx.conf:\d+\):\d+: --> 88, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" +msg count: 3 +log level:4 +log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*?access_by_lua\(nginx.conf:\d+\):\d+: --> 88, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" +log level:5 +log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[warn\] (\d+).*?access_by_lua\(nginx.conf:\d+\):\d+: --> 89, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" +log level:4 +log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*?access_by_lua\(nginx.conf:\d+\):\d+: --> 89, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" +log level:4 +log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*?access_by_lua\(nginx.conf:\d+\):\d+: --> 100, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" +log level:4 +log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*?content_by_lua\(nginx.conf:\d+\):\d+: howdy, something new!, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" +log level:4 +log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*?content_by_lua\(nginx.conf:\d+\):\d+: howdy, something even newer!, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" +\z +--- skip_nginx: 2: <1.11.2 + + + +=== TEST 21: multi-line error log +--- http_config + lua_intercept_error_log 4k; +--- config + location /t { + access_by_lua_block { + local errlog = require "ngx.errlog" + local status, err = errlog.set_errlog_filter(ngx.WARN) + if not status then + error(err) + end + + ngx.log(ngx.ERR, "-->\n", "new line") + } + + content_by_lua_block { + local errlog = require "ngx.errlog" + local res = errlog.get_error_logs() + ngx.say("log lines: #", #res / 2) + + for i = 1, #res, 2 do + ngx.say("log level:", res[i]) + ngx.say("log body:", res[i + 1]) + end + } + } +--- log_level: info +--- request +GET /t +--- response_body_like chomp +\Alog lines: #1 +log level:4 +log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*access_by_lua\(nginx.conf:\d+\):\d+: --> +new line, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" +\z +--- skip_nginx: 2: <1.11.2 diff --git a/t/shdict.t b/t/shdict.t index f1dd547c4..b5f94eb77 100644 --- a/t/shdict.t +++ b/t/shdict.t @@ -384,7 +384,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):11 loop\]/ local dogs = ngx.shared.dogs -- local cd = ffi.cast("void *", dogs) dogs:set("foo", 56) - for i = 1, 100 do + for i = 1, 150 do val, err = dogs:incr("foo", 2.1) end ngx.say("value: ", val) @@ -394,7 +394,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):11 loop\]/ --- request GET /t --- response_body -value: 266 +value: 371 err: nil --- error_log eval qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):7 loop\]/ From 577dfeeac36a6a7801b71ca1b1c1e65c0d8d3d1f Mon Sep 17 00:00:00 2001 From: "Yichun Zhang (agentzh)" Date: Fri, 12 May 2017 18:05:00 -0700 Subject: [PATCH 45/74] doc: ngx.errlog: added more docs. --- lib/ngx/errlog.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/ngx/errlog.md b/lib/ngx/errlog.md index e2bd510ca..3d039035e 100644 --- a/lib/ngx/errlog.md +++ b/lib/ngx/errlog.md @@ -98,13 +98,14 @@ set_errlog_filter **context:** *init_by_lua** -Specifies the filter log level, only to intercept the error log we need. +Specifies the filter log level, only to intercept, capture, and buffer the error log we need. If we don't call this API, all of the error logs will be intercepted by default. In case of error, `nil` will be returned as well as a string describing the error. -This API should always work with directive [lua_intercept_error_log](https://github.com/openresty/lua-nginx-module#lua_intercept_error_log). +This API should always work with directive +[lua_intercept_error_log](https://github.com/openresty/lua-nginx-module#lua_intercept_error_log). See [Nginx log level constants](https://github.com/openresty/lua-nginx-module#nginx-log-level-constants) for all nginx log levels. @@ -127,7 +128,11 @@ get_error_logs **context:** *any* -Returns the intercepted nginx error logs if successful. +Fetches the captured nginx error log messages if any in the global data buffer +specified by `ngx_lua`'s +[lua_intercept_error_log](https://github.com/openresty/lua-nginx-module#lua_intercept_error_log) +directive. Upon return, this Lua function also *removes* those messages from +that global capturing buffer to make room for future new error log data. In case of error, `nil` will be returned as well as a string describing the error. From 5e21d0e2675cc1bc1d28b439c86ecca06a4a90f6 Mon Sep 17 00:00:00 2001 From: "Yichun Zhang (agentzh)" Date: Fri, 12 May 2017 18:24:04 -0700 Subject: [PATCH 46/74] change: updatd to reflect the recent renaming of the lua_intercept_error_log to lua_capture_error_log. --- lib/ngx/errlog.md | 20 ++++++------ t/errlog.t | 82 +++++++++++++++++++++++------------------------ 2 files changed, 52 insertions(+), 50 deletions(-) diff --git a/lib/ngx/errlog.md b/lib/ngx/errlog.md index 3d039035e..fdf13a065 100644 --- a/lib/ngx/errlog.md +++ b/lib/ngx/errlog.md @@ -9,7 +9,7 @@ Table of Contents * [Name](#name) * [Status](#status) * [Synopsis](#synopsis) - * [Intercept nginx error logs with specified log level](#intercept-nginx-error-logs-with-specified-log-level) + * [Capturing nginx error logs with specified log filtering level](#capturing-nginx-error-logs-with-specified-log-filtering-level) * [Methods](#methods) * [set_errlog_filter](#set_errlog_filter) * [get_error_logs](#get_error_logs) @@ -31,15 +31,15 @@ The API is still in flux and may change in the future without notice. Synopsis ======== -Intercept nginx error logs with specified log level ---------------------------------------------------- +Capturing nginx error logs with specified log filtering level +------------------------------------------------------------- ```nginx error logs/error.log info; http { - # enable intercept error log - lua_intercept_error_log 32m; + # enable capturing error logs + lua_capture_error_log 32m; init_by_lua_block { local errlog = require "ngx.errlog" @@ -98,14 +98,16 @@ set_errlog_filter **context:** *init_by_lua** -Specifies the filter log level, only to intercept, capture, and buffer the error log we need. -If we don't call this API, all of the error logs will be intercepted by default. +Specifies the filter log level, only to capture and buffer the error logs with a log level +no lower than the specified level. + +If we don't call this API, all of the error logs will be captured by default. In case of error, `nil` will be returned as well as a string describing the error. This API should always work with directive -[lua_intercept_error_log](https://github.com/openresty/lua-nginx-module#lua_intercept_error_log). +[lua_capture_error_log](https://github.com/openresty/lua-nginx-module#lua_capture_error_log). See [Nginx log level constants](https://github.com/openresty/lua-nginx-module#nginx-log-level-constants) for all nginx log levels. @@ -130,7 +132,7 @@ get_error_logs Fetches the captured nginx error log messages if any in the global data buffer specified by `ngx_lua`'s -[lua_intercept_error_log](https://github.com/openresty/lua-nginx-module#lua_intercept_error_log) +[lua_capture_error_log](https://github.com/openresty/lua-nginx-module#lua_capture_error_log) directive. Upon return, this Lua function also *removes* those messages from that global capturing buffer to make room for future new error log data. diff --git a/t/errlog.t b/t/errlog.t index c026ed0fa..96383b551 100644 --- a/t/errlog.t +++ b/t/errlog.t @@ -36,7 +36,7 @@ __DATA__ === TEST 1: sanity --- http_config - lua_intercept_error_log 4m; + lua_capture_error_log 4m; --- config location /t { access_by_lua_block { @@ -70,9 +70,9 @@ enter 11 -=== TEST 2: overflow intercepted error logs +=== TEST 2: overflow captured error logs --- http_config - lua_intercept_error_log 4k; + lua_capture_error_log 4k; --- config location /t { access_by_lua_block { @@ -108,7 +108,7 @@ enter 22 === TEST 3: 404 error(not found) --- http_config - lua_intercept_error_log 4m; + lua_capture_error_log 4m; --- config log_by_lua_block { local errlog = require "ngx.errlog" @@ -116,20 +116,20 @@ enter 22 if not res then error("FAILED " .. err) end - ngx.log(ngx.ERR, "intercept log line:", #res / 2) + ngx.log(ngx.ERR, "capture log line:", #res / 2) } --- request GET /t --- error_code: 404 --- grep_error_log eval -qr/intercept log line:\d+|No such file or directory/ +qr/capture log line:\d+|No such file or directory/ --- grep_error_log_out eval [ qr/^No such file or directory -intercept log line:1 +capture log line:1 $/, qr/^No such file or directory -intercept log line:2 +capture log line:2 $/ ] --- skip_nginx: 2: <1.11.2 @@ -138,7 +138,7 @@ $/ === TEST 4: 500 error --- http_config - lua_intercept_error_log 4m; + lua_capture_error_log 4m; --- config location /t { content_by_lua_block { @@ -151,20 +151,20 @@ $/ if not res then error("FAILED " .. err) end - ngx.log(ngx.ERR, "intercept log line:", #res / 2) + ngx.log(ngx.ERR, "capture log line:", #res / 2) } --- request GET /t --- error_code: 500 --- grep_error_log eval -qr/intercept log line:\d+|attempt to perform arithmetic on a table value/ +qr/capture log line:\d+|attempt to perform arithmetic on a table value/ --- grep_error_log_out eval [ qr/^attempt to perform arithmetic on a table value -intercept log line:1 +capture log line:1 $/, qr/^attempt to perform arithmetic on a table value -intercept log line:2 +capture log line:2 $/ ] --- skip_nginx: 2: <1.11.2 @@ -173,7 +173,7 @@ $/ === TEST 5: no error log --- http_config - lua_intercept_error_log 4m; + lua_capture_error_log 4m; --- config location /t { echo "hello"; @@ -184,19 +184,19 @@ $/ if not res then error("FAILED " .. err) end - ngx.log(ngx.ERR, "intercept log line:", #res / 2) + ngx.log(ngx.ERR, "capture log line:", #res / 2) } --- request GET /t --- response_body hello --- grep_error_log eval -qr/intercept log line:\d+/ +qr/capture log line:\d+/ --- grep_error_log_out eval [ -qr/^intercept log line:0 +qr/^capture log line:0 $/, -qr/^intercept log line:1 +qr/^capture log line:1 $/ ] --- skip_nginx: 3: <1.11.2 @@ -205,7 +205,7 @@ $/ === TEST 6: customize the log path --- http_config - lua_intercept_error_log 4m; + lua_capture_error_log 4m; error_log logs/error_http.log error; --- config location /t { @@ -221,7 +221,7 @@ $/ if not res then error("FAILED " .. err) end - ngx.log(ngx.ERR, "intercept log line:", #res / 2) + ngx.log(ngx.ERR, "capture log line:", #res / 2) } --- request @@ -229,14 +229,14 @@ GET /t --- response_body hello --- grep_error_log eval -qr/intercept log line:\d+|enter access/ +qr/capture log line:\d+|enter access/ --- grep_error_log_out eval [ qr/^enter access -intercept log line:1 +capture log line:1 $/, qr/^enter access -intercept log line:2 +capture log line:2 $/ ] --- skip_nginx: 3: <1.11.2 @@ -245,28 +245,28 @@ $/ === TEST 7: invalid size (< 4k) --- http_config - lua_intercept_error_log 3k; + lua_capture_error_log 3k; --- config location /t { echo "hello"; } --- must_die --- error_log -invalid intercept error log size "3k", minimum size is 4096 +invalid capture error log size "3k", minimum size is 4096 --- skip_nginx: 2: <1.11.2 === TEST 8: invalid size (no argu) --- http_config - lua_intercept_error_log; + lua_capture_error_log; --- config location /t { echo "hello"; } --- must_die --- error_log -invalid number of arguments in "lua_intercept_error_log" directive +invalid number of arguments in "lua_capture_error_log" directive --- skip_nginx: 2: <1.11.2 @@ -290,7 +290,7 @@ GET /t --- response_body_like: 500 Internal Server Error --- error_code: 500 --- error_log -API "get_errlog_data" depends on directive "lua_intercept_error_log" +API "get_errlog_data" depends on directive "lua_capture_error_log" --- skip_nginx: 3: <1.11.2 @@ -311,14 +311,14 @@ GET /t --- response_body_like: 500 Internal Server Error --- error_code: 500 --- error_log -API "set_errlog_filter" depends on directive "lua_intercept_error_log" +API "set_errlog_filter" depends on directive "lua_capture_error_log" --- skip_nginx: 3: <1.11.2 === TEST 11: filter log by level(ngx.INFO) --- http_config - lua_intercept_error_log 4m; + lua_capture_error_log 4m; --- config location /t { access_by_lua_block { @@ -362,7 +362,7 @@ qr/-->\d+/ === TEST 12: filter log by level(ngx.WARN) --- http_config - lua_intercept_error_log 4m; + lua_capture_error_log 4m; --- config location /t { access_by_lua_block { @@ -406,7 +406,7 @@ qr/-->\d+/ === TEST 13: filter log by level(ngx.CRIT) --- http_config - lua_intercept_error_log 4m; + lua_capture_error_log 4m; --- log_level: info --- config location /t { @@ -450,7 +450,7 @@ qr/-->\d+/ === TEST 14: set max count and reuse table --- http_config - lua_intercept_error_log 4m; + lua_capture_error_log 4m; --- config location /t { access_by_lua_block { @@ -487,7 +487,7 @@ log lines:1 === TEST 15: wrong argument --- http_config - lua_intercept_error_log 4m; + lua_capture_error_log 4m; --- config location /t { access_by_lua_block { @@ -515,9 +515,9 @@ qr/missing \"level\" argument/ -=== TEST 16: check the intercepted error log body +=== TEST 16: check the captured error log body --- http_config - lua_intercept_error_log 4m; + lua_capture_error_log 4m; --- config location /t { access_by_lua_block { @@ -568,7 +568,7 @@ qr/-->\d+/ === TEST 17: flood the capturing buffer (4k) --- http_config - lua_intercept_error_log 4k; + lua_capture_error_log 4k; --- config location /t { access_by_lua_block { @@ -627,7 +627,7 @@ log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*access_by_lua\(ngi === TEST 18: flood the capturing buffer (5k) --- http_config - lua_intercept_error_log 5k; + lua_capture_error_log 5k; --- config location /t { access_by_lua_block { @@ -686,7 +686,7 @@ log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*access_by_lua\(ngi === TEST 19: fetch a few and generate a few, then fetch again (overflown again) --- http_config - lua_intercept_error_log 5k; + lua_capture_error_log 5k; --- config location /t { access_by_lua_block { @@ -768,7 +768,7 @@ log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*?content_by_lua\(n === TEST 20: fetch a few and generate a few, then fetch again (not overflown again) --- http_config - lua_intercept_error_log 5k; + lua_capture_error_log 5k; --- config location /t { access_by_lua_block { @@ -848,7 +848,7 @@ log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*?content_by_lua\(n === TEST 21: multi-line error log --- http_config - lua_intercept_error_log 4k; + lua_capture_error_log 4k; --- config location /t { access_by_lua_block { From 8dfe4564a08bb9afee594d3039e0a31136d7c75e Mon Sep 17 00:00:00 2001 From: "Yichun Zhang (agentzh)" Date: Sat, 13 May 2017 19:31:10 -0700 Subject: [PATCH 47/74] change: ngx.errlog: renamed set_errlog_filter() to set_filter_level(); also renamed get_error_logs() to get_logs(). --- lib/ngx/errlog.lua | 14 ++++----- lib/ngx/errlog.md | 30 +++++++++---------- t/errlog.t | 72 +++++++++++++++++++++++----------------------- 3 files changed, 58 insertions(+), 58 deletions(-) diff --git a/lib/ngx/errlog.lua b/lib/ngx/errlog.lua index c18569991..eaccbe1eb 100644 --- a/lib/ngx/errlog.lua +++ b/lib/ngx/errlog.lua @@ -17,9 +17,9 @@ local _M = { version = base.version } ffi.cdef[[ -int ngx_http_lua_ffi_set_errlog_filter(int level, unsigned char *err, +int ngx_http_lua_ffi_errlog_set_filter_level(int level, unsigned char *err, size_t *errlen); -int ngx_http_lua_ffi_get_errlog_data(char **log, int *loglevel, +int ngx_http_lua_ffi_errlog_get_msg(char **log, int *loglevel, unsigned char *err, size_t *errlen); ]] @@ -28,7 +28,7 @@ local ERR_BUF_SIZE = 128 local FFI_ERROR = base.FFI_ERROR -function _M.set_errlog_filter(level) +function _M.set_filter_level(level) if not level then return nil, [[missing "level" argument]] end @@ -36,7 +36,7 @@ function _M.set_errlog_filter(level) local err = get_string_buf(ERR_BUF_SIZE) local errlen = get_size_ptr() errlen[0] = ERR_BUF_SIZE - local rc = C.ngx_http_lua_ffi_set_errlog_filter(level, err, errlen) + local rc = C.ngx_http_lua_ffi_errlog_set_filter_level(level, err, errlen) if rc == FFI_ERROR then return nil, ffi_string(err, errlen[0]) @@ -46,7 +46,7 @@ function _M.set_errlog_filter(level) end -function _M.get_error_logs(max, logs) +function _M.get_logs(max, logs) local err = get_string_buf(ERR_BUF_SIZE) local errlen = get_size_ptr() errlen[0] = ERR_BUF_SIZE @@ -61,8 +61,8 @@ function _M.get_error_logs(max, logs) end for i = 1, max do - local loglen = C.ngx_http_lua_ffi_get_errlog_data(log, - loglevel, err, errlen) + local loglen = C.ngx_http_lua_ffi_errlog_get_msg(log, + loglevel, err, errlen) if loglen == FFI_ERROR then return nil, ffi_string(err, errlen[0]) end diff --git a/lib/ngx/errlog.md b/lib/ngx/errlog.md index fdf13a065..5550f49b5 100644 --- a/lib/ngx/errlog.md +++ b/lib/ngx/errlog.md @@ -11,8 +11,8 @@ Table of Contents * [Synopsis](#synopsis) * [Capturing nginx error logs with specified log filtering level](#capturing-nginx-error-logs-with-specified-log-filtering-level) * [Methods](#methods) - * [set_errlog_filter](#set_errlog_filter) - * [get_error_logs](#get_error_logs) + * [set_filter_level](#set_filter_level) + * [get_logs](#get_logs) * [Community](#community) * [English Mailing List](#english-mailing-list) * [Chinese Mailing List](#chinese-mailing-list) @@ -43,7 +43,7 @@ http { init_by_lua_block { local errlog = require "ngx.errlog" - local status, err = errlog.set_errlog_filter(ngx.WARN) + local status, err = errlog.set_filter_level(ngx.WARN) if not status then ngx.log(ngx.ERR, err) return @@ -60,7 +60,7 @@ http { ngx.log(ngx.WARN, "test2") ngx.log(ngx.ERR, "test3") - local logs, err = errlog.get_error_logs() + local logs, err = errlog.get_logs(10) if not logs then ngx.say("FAILED ", err) return @@ -92,9 +92,9 @@ level: 4 data: 2017/04/19 22:20:05 [error] 63176#0: *1 Methods ======= -set_errlog_filter +set_filter_level ----------------- -**syntax:** *status, err = log_module.set_errlog_filter(log_level)* +**syntax:** *status, err = log_module.set_filter_level(log_level)* **context:** *init_by_lua** @@ -116,7 +116,7 @@ For example, ```lua init_by_lua_block { local errlog = require "ngx.errlog" - errlog.set_errlog_filter(ngx.WARN) + errlog.set_filter_level(ngx.WARN) } ``` @@ -124,9 +124,9 @@ For example, [Back to TOC](#table-of-contents) -get_error_logs --------------- -**syntax:** *res, err = log_module.get_error_logs(max, res?)* +get_logs +-------- +**syntax:** *res, err = log_module.get_logs(max?, res?)* **context:** *any* @@ -140,7 +140,7 @@ In case of error, `nil` will be returned as well as a string describing the error. The optional `max` argument is a number that when specified, will prevent -`errlog.get_error_logs` from adding more than `max` messages to the `res` array. +`errlog.get_logs` from adding more than `max` messages to the `res` array. ```lua for i = 1, 20 do @@ -148,7 +148,7 @@ for i = 1, 20 do end local errlog = require "ngx.errlog" -local res = errlog.get_error_logs(10) +local res = errlog.get_logs(10) -- the number of messages in the `res` table is 10 and the `res` table -- has 20 elements. ``` @@ -187,7 +187,7 @@ local new_tab = require "table.new" local buffer = new_tab(100 * 2, 0) -- for 100 messages local errlog = require "ngx.errlog" -local res, err = errlog.get_error_logs(0, buffer) +local res, err = errlog.get_logs(0, buffer) if res then -- res is the same table as `buffer` for i = 1, #res, 2 do @@ -201,12 +201,12 @@ if res then end ``` -When provided with a `res` table, `errlog.get_error_logs` won't clear the table +When provided with a `res` table, `errlog.get_logs` won't clear the table for performance reasons, but will rather insert a trailing `nil` value after the last table element. When the trailing `nil` is not enough for your purpose, you should -clear the table yourself before feeding it into the `errlog.get_error_logs` function. +clear the table yourself before feeding it into the `errlog.get_logs` function. [Back to TOC](#table-of-contents) diff --git a/t/errlog.t b/t/errlog.t index 96383b551..d4070db0c 100644 --- a/t/errlog.t +++ b/t/errlog.t @@ -44,7 +44,7 @@ __DATA__ ngx.log(ngx.ERR, "enter 11") local errlog = require "ngx.errlog" - local res, err = errlog.get_error_logs() + local res, err = errlog.get_logs() if not res then error("FAILED " .. err) end @@ -80,7 +80,7 @@ enter 11 ngx.log(ngx.ERR, "enter 22" .. string.rep("a", 4096)) local errlog = require "ngx.errlog" - local res, err = errlog.get_error_logs() + local res, err = errlog.get_logs() if not res then error("FAILED " .. err) end @@ -112,7 +112,7 @@ enter 22 --- config log_by_lua_block { local errlog = require "ngx.errlog" - local res, err = errlog.get_error_logs() + local res, err = errlog.get_logs() if not res then error("FAILED " .. err) end @@ -147,7 +147,7 @@ $/ } log_by_lua_block { local errlog = require "ngx.errlog" - local res, err = errlog.get_error_logs() + local res, err = errlog.get_logs() if not res then error("FAILED " .. err) end @@ -180,7 +180,7 @@ $/ } log_by_lua_block { local errlog = require "ngx.errlog" - local res, err = errlog.get_error_logs() + local res, err = errlog.get_logs() if not res then error("FAILED " .. err) end @@ -217,7 +217,7 @@ $/ } log_by_lua_block { local errlog = require "ngx.errlog" - local res, err = errlog.get_error_logs() + local res, err = errlog.get_logs() if not res then error("FAILED " .. err) end @@ -278,7 +278,7 @@ invalid number of arguments in "lua_capture_error_log" directive ngx.log(ngx.ERR, "enter 1") local errlog = require "ngx.errlog" - local res, err = errlog.get_error_logs() + local res, err = errlog.get_logs() if not res then error("FAILED " .. err) end @@ -290,17 +290,17 @@ GET /t --- response_body_like: 500 Internal Server Error --- error_code: 500 --- error_log -API "get_errlog_data" depends on directive "lua_capture_error_log" +directive "lua_capture_error_log" is not set --- skip_nginx: 3: <1.11.2 -=== TEST 10: without directive + ngx.set_errlog_filter +=== TEST 10: without directive + ngx.set_filter_level --- config location /t { access_by_lua_block { local errlog = require "ngx.errlog" - local status, err = errlog.set_errlog_filter(ngx.ERR) + local status, err = errlog.set_filter_level(ngx.ERR) if not status then error(err) end @@ -311,7 +311,7 @@ GET /t --- response_body_like: 500 Internal Server Error --- error_code: 500 --- error_log -API "set_errlog_filter" depends on directive "lua_capture_error_log" +directive "lua_capture_error_log" is not set --- skip_nginx: 3: <1.11.2 @@ -323,7 +323,7 @@ API "set_errlog_filter" depends on directive "lua_capture_error_log" location /t { access_by_lua_block { local errlog = require "ngx.errlog" - local status, err = errlog.set_errlog_filter(ngx.INFO) + local status, err = errlog.set_filter_level(ngx.INFO) if not status then error(err) end @@ -334,7 +334,7 @@ API "set_errlog_filter" depends on directive "lua_capture_error_log" } content_by_lua_block { local errlog = require "ngx.errlog" - local res = errlog.get_error_logs() + local res = errlog.get_logs() ngx.say("log lines:", #res / 2) } } @@ -367,7 +367,7 @@ qr/-->\d+/ location /t { access_by_lua_block { local errlog = require "ngx.errlog" - local status, err = errlog.set_errlog_filter(ngx.WARN) + local status, err = errlog.set_filter_level(ngx.WARN) if not status then error(err) end @@ -378,7 +378,7 @@ qr/-->\d+/ } content_by_lua_block { local errlog = require "ngx.errlog" - local res = errlog.get_error_logs() + local res = errlog.get_logs() ngx.say("log lines:", #res / 2) } } @@ -412,7 +412,7 @@ qr/-->\d+/ location /t { access_by_lua_block { local errlog = require "ngx.errlog" - local status, err = errlog.set_errlog_filter(ngx.CRIT) + local status, err = errlog.set_filter_level(ngx.CRIT) if not status then error(err) end @@ -423,7 +423,7 @@ qr/-->\d+/ } content_by_lua_block { local errlog = require "ngx.errlog" - local res = errlog.get_error_logs() + local res = errlog.get_logs() ngx.say("log lines:", #res / 2) } } @@ -462,14 +462,14 @@ qr/-->\d+/ local errlog = require "ngx.errlog" local res = {} local err - res, err = errlog.get_error_logs(2, res) + res, err = errlog.get_logs(2, res) if not res then error("FAILED " .. err) end ngx.say("log lines:", #res / 2) tab_clear(res) - res, err = errlog.get_error_logs(2, res) + res, err = errlog.get_logs(2, res) if not res then error("FAILED " .. err) end @@ -492,7 +492,7 @@ log lines:1 location /t { access_by_lua_block { local errlog = require "ngx.errlog" - local status, err = errlog.set_errlog_filter() + local status, err = errlog.set_filter_level() if not status then error(err) end @@ -522,7 +522,7 @@ qr/missing \"level\" argument/ location /t { access_by_lua_block { local errlog = require "ngx.errlog" - local status, err = errlog.set_errlog_filter(ngx.WARN) + local status, err = errlog.set_filter_level(ngx.WARN) if not status then error(err) end @@ -534,7 +534,7 @@ qr/missing \"level\" argument/ content_by_lua_block { local errlog = require "ngx.errlog" - local res = errlog.get_error_logs() + local res = errlog.get_logs() for i = 1, #res, 2 do ngx.say("log level:", res[i]) ngx.say("log body:", res[i + 1]) @@ -573,7 +573,7 @@ qr/-->\d+/ location /t { access_by_lua_block { local errlog = require "ngx.errlog" - local status, err = errlog.set_errlog_filter(ngx.WARN) + local status, err = errlog.set_filter_level(ngx.WARN) if not status then error(err) end @@ -587,7 +587,7 @@ qr/-->\d+/ content_by_lua_block { local errlog = require "ngx.errlog" - local res = errlog.get_error_logs(1000) + local res = errlog.get_logs(1000) ngx.say("log lines: #", #res / 2) -- first 3 logs @@ -632,7 +632,7 @@ log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*access_by_lua\(ngi location /t { access_by_lua_block { local errlog = require "ngx.errlog" - local status, err = errlog.set_errlog_filter(ngx.WARN) + local status, err = errlog.set_filter_level(ngx.WARN) if not status then error(err) end @@ -646,7 +646,7 @@ log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*access_by_lua\(ngi content_by_lua_block { local errlog = require "ngx.errlog" - local res = errlog.get_error_logs(1000) + local res = errlog.get_logs(1000) ngx.say("log lines: #", #res / 2) -- first 3 logs @@ -691,7 +691,7 @@ log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*access_by_lua\(ngi location /t { access_by_lua_block { local errlog = require "ngx.errlog" - local status, err = errlog.set_errlog_filter(ngx.WARN) + local status, err = errlog.set_filter_level(ngx.WARN) if not status then error(err) end @@ -706,7 +706,7 @@ log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*access_by_lua\(ngi content_by_lua_block { local errlog = require "ngx.errlog" - local res = errlog.get_error_logs(3) + local res = errlog.get_logs(3) ngx.say("msg count: ", #res / 2) -- first 3 logs @@ -720,7 +720,7 @@ log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*access_by_lua\(ngi ngx.log(ngx.ERR, "--> 103") ngx.log(ngx.ERR, "--> 104") - local res = errlog.get_error_logs(3) + local res = errlog.get_logs(3) ngx.say("msg count: ", #res / 2) -- first 3 logs @@ -729,7 +729,7 @@ log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*access_by_lua\(ngi ngx.say("log body:", res[i + 1]) end - local res = errlog.get_error_logs(1000) + local res = errlog.get_logs(1000) -- last 3 logs for i = #res - 5, #res, 2 do ngx.say("log level:", res[i]) @@ -773,7 +773,7 @@ log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*?content_by_lua\(n location /t { access_by_lua_block { local errlog = require "ngx.errlog" - local status, err = errlog.set_errlog_filter(ngx.WARN) + local status, err = errlog.set_filter_level(ngx.WARN) if not status then error(err) end @@ -788,7 +788,7 @@ log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*?content_by_lua\(n content_by_lua_block { local errlog = require "ngx.errlog" - local res = errlog.get_error_logs(3) + local res = errlog.get_logs(3) ngx.say("msg count: ", #res / 2) -- first 3 logs @@ -800,7 +800,7 @@ log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*?content_by_lua\(n ngx.log(ngx.ERR, "howdy, something new!") ngx.log(ngx.ERR, "howdy, something even newer!") - local res = errlog.get_error_logs(3) + local res = errlog.get_logs(3) ngx.say("msg count: ", #res / 2) -- first 3 logs @@ -809,7 +809,7 @@ log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*?content_by_lua\(n ngx.say("log body:", res[i + 1]) end - local res = errlog.get_error_logs(1000) + local res = errlog.get_logs(1000) -- last 3 logs for i = #res - 5, #res, 2 do ngx.say("log level:", res[i]) @@ -853,7 +853,7 @@ log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*?content_by_lua\(n location /t { access_by_lua_block { local errlog = require "ngx.errlog" - local status, err = errlog.set_errlog_filter(ngx.WARN) + local status, err = errlog.set_filter_level(ngx.WARN) if not status then error(err) end @@ -863,7 +863,7 @@ log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*?content_by_lua\(n content_by_lua_block { local errlog = require "ngx.errlog" - local res = errlog.get_error_logs() + local res = errlog.get_logs() ngx.say("log lines: #", #res / 2) for i = 1, #res, 2 do From c600057e3f1f2c102bc198ee9d2c62327d80bf41 Mon Sep 17 00:00:00 2001 From: "Yichun Zhang (agentzh)" Date: Sat, 13 May 2017 21:31:53 -0700 Subject: [PATCH 48/74] doc: ngx.re: opt(): fixed the obsolete code example. --- lib/ngx/re.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ngx/re.md b/lib/ngx/re.md index 5f9b7335c..1c97ff668 100644 --- a/lib/ngx/re.md +++ b/lib/ngx/re.md @@ -157,7 +157,7 @@ Allows changing of regex settings. Currently, it can only change the ```nginx - init_by_lua_block { ngx.re.opt("jit_stack_size", 128 * 1024) } + init_by_lua_block { require "ngx.re".opt("jit_stack_size", 200 * 1024) } server { location /re { From f81a55690e4edef5723f614f7925a0f4f6adf047 Mon Sep 17 00:00:00 2001 From: "Yichun Zhang (agentzh)" Date: Sun, 14 May 2017 11:26:34 -0700 Subject: [PATCH 49/74] feature: added the new signal_graceful_exit() function to the ngx.process Lua module. --- lib/ngx/process.lua | 6 ++++++ lib/ngx/process.md | 25 ++++++++++++++++++++++--- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/lib/ngx/process.lua b/lib/ngx/process.lua index 5c7c0289e..b797c0b2e 100644 --- a/lib/ngx/process.lua +++ b/lib/ngx/process.lua @@ -27,6 +27,7 @@ local _M = { version = base.version } ffi.cdef[[ int ngx_http_lua_ffi_enable_privileged_agent(char **err); int ngx_http_lua_ffi_get_process_type(void); +void ngx_http_lua_ffi_process_signal_graceful_exit(void); ]] @@ -51,4 +52,9 @@ function _M.enable_privileged_agent() end +function _M.signal_graceful_exit() + C.ngx_http_lua_ffi_process_signal_graceful_exit() +end + + return _M diff --git a/lib/ngx/process.md b/lib/ngx/process.md index 436779e66..cbf4303a6 100644 --- a/lib/ngx/process.md +++ b/lib/ngx/process.md @@ -10,9 +10,10 @@ Table of Contents * [Status](#status) * [Synopsis](#synopsis) * [Enables privileged agent process and get process type](#enables-privileged-agent-process-and-get-process-type) -* [Methods](#methods) +* [Functions](#functions) * [type](#type) * [enable_privileged_agent](#enable_privileged_agent) + * [signal_graceful_exit](#signal_graceful_exit) * [Community](#community) * [English Mailing List](#english-mailing-list) * [Chinese Mailing List](#chinese-mailing-list) @@ -82,8 +83,8 @@ process type: worker [Back to TOC](#table-of-contents) -Methods -======= +Functions +========= type ---- @@ -131,6 +132,24 @@ In case of failures, returns `nil` and a string describing the error. [Back to TOC](#table-of-contents) +signal_graceful_exit +-------------------- +**syntax:** *process_module.signal_graceful_exit()* + +**context:** *any* + +Signals the current nginx process to quit gracefully, i.e., after all the timers have expired (in time or expired prematurely). + +Note that this API function simply sets the nginx global C variable `ngx_quit` to signal the nginx event +loop directly. No UNIX signals or IPC are involved here. + +WARNING: the official NGINX core does not perform the graceful exiting procedure when the [master_process](http://nginx.org/r/master_process) +directive is turned `off`. The OpenResty's NGINX core has a +[custom patch](https://github.com/openresty/openresty/blob/master/patches/nginx-1.11.2-single_process_graceful_exit.patch) +applied, which fixes this issue. + +[Back to TOC](#table-of-contents) + Community ========= From d42aa9a9b8aab62224d7fc164050d63ecbf2e8e9 Mon Sep 17 00:00:00 2001 From: "Yichun Zhang (agentzh)" Date: Mon, 15 May 2017 09:52:53 -0700 Subject: [PATCH 50/74] doc: ngx.process: made the docs for signal_graceful_exit() clearer. --- lib/ngx/process.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ngx/process.md b/lib/ngx/process.md index cbf4303a6..080b91370 100644 --- a/lib/ngx/process.md +++ b/lib/ngx/process.md @@ -138,7 +138,7 @@ signal_graceful_exit **context:** *any* -Signals the current nginx process to quit gracefully, i.e., after all the timers have expired (in time or expired prematurely). +Signals the *current* nginx (worker) process to quit gracefully, i.e., after all the timers have expired (in time or expired prematurely). Note that this API function simply sets the nginx global C variable `ngx_quit` to signal the nginx event loop directly. No UNIX signals or IPC are involved here. From 4a7d1dc09f1d0ad1a506b8a6216d7fafe56e2106 Mon Sep 17 00:00:00 2001 From: soul11201 Date: Thu, 18 May 2017 10:22:14 +0800 Subject: [PATCH 51/74] doc: ngx.ssl.session: fixed the missing arguments in the code example. Signed-off-by: Yichun Zhang (agentzh) --- lib/ngx/ssl/session.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ngx/ssl/session.md b/lib/ngx/ssl/session.md index 5e6243781..b6671b37a 100644 --- a/lib/ngx/ssl/session.md +++ b/lib/ngx/ssl/session.md @@ -116,7 +116,7 @@ ssl_session_store_by_lua_block { end -- create a 0-delay timer here... - local ok, err = ngx.timer.at(0, save_it) + local ok, err = ngx.timer.at(0, save_it, sess_id, sess) if not ok then ngx.log(ngx.ERR, "failed to create a 0-delay timer: ", err) return From 16a48311c94fad8b8bcb74e5b31656bb81e93a9c Mon Sep 17 00:00:00 2001 From: soul11201 Date: Thu, 18 May 2017 10:08:48 +0800 Subject: [PATCH 52/74] doc: code example: private keys are usually stored in PEM, so we use the func priv_key_pem_to_der in the example to do the conversion. Signed-off-by: Yichun Zhang (agentzh) --- lib/ngx/ssl.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/ngx/ssl.md b/lib/ngx/ssl.md index 71c82a9a9..c775a6d77 100644 --- a/lib/ngx/ssl.md +++ b/lib/ngx/ssl.md @@ -84,7 +84,14 @@ server { -- assuming the user already defines the my_load_private_key() -- function herself. - local der_pkey = assert(my_load_private_key()) + local pem_pkey = assert(my_load_private_key()) + + local der_pkey, err = ssl.priv_key_pem_to_der(pem_pkey) + if not der_pkey then + ngx.log(ngx.ERR, "failed to convert private key ", + "from PEM to DER: ", err) + return ngx.exit(ngx.ERROR) + end local ok, err = ssl.set_der_priv_key(der_pkey) if not ok then From 3031e5f63fe732852d86240f1b04d998cf56fd98 Mon Sep 17 00:00:00 2001 From: Yuansheng Date: Thu, 18 May 2017 10:04:29 +0800 Subject: [PATCH 53/74] bugfix: ngx.errlog: get_logs(): we did not set `nil` at the current table index when exhausting the existing error log data before reaching the `max` limit. Signed-off-by: Yichun Zhang (agentzh) --- lib/ngx/errlog.lua | 7 ++++++- t/errlog.t | 52 +++++++++++++++++++++++++++++++++++++++++++++- t/semaphore.t | 6 +++--- 3 files changed, 60 insertions(+), 5 deletions(-) diff --git a/lib/ngx/errlog.lua b/lib/ngx/errlog.lua index eaccbe1eb..a1b5afdaf 100644 --- a/lib/ngx/errlog.lua +++ b/lib/ngx/errlog.lua @@ -72,7 +72,12 @@ function _M.get_logs(max, logs) logs[i * 2] = ffi_string(log[0], loglen) end - if loglen < 0 or i == max then -- last one + if loglen < 0 then -- no error log + logs[i * 2 - 1] = nil + break + end + + if i == max then -- last one logs[i * 2 + 1] = nil break end diff --git a/t/errlog.t b/t/errlog.t index d4070db0c..5429db936 100644 --- a/t/errlog.t +++ b/t/errlog.t @@ -106,7 +106,7 @@ enter 22 -=== TEST 3: 404 error(not found) +=== TEST 3: 404 error (not found) --- http_config lua_capture_error_log 4m; --- config @@ -882,3 +882,53 @@ log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*access_by_lua\(ngi new line, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" \z --- skip_nginx: 2: <1.11.2 + + + +=== TEST 22: user-supplied Lua table to hold the result (get one log + no log) +--- http_config + lua_capture_error_log 4k; +--- config + location /t { + access_by_lua_block { + local errlog = require "ngx.errlog" + local status, err = errlog.set_filter_level(ngx.WARN) + if not status then + error(err) + end + + ngx.log(ngx.ERR, "-->\n", "new line") + } + + content_by_lua_block { + local errlog = require "ngx.errlog" + local t = {} + + for i = 1, 2 do + local res = errlog.get_logs(10, t) + ngx.say("maybe log lines: #", #res / 2) + for j = 1, #res, 2 do + local level, msg = res[j], res[j + 1] + if not level then + break + end + ngx.say("log level:", level) + ngx.say("log body:", msg) + end + ngx.say("end") + end + } + } +--- log_level: info +--- request +GET /t +--- response_body_like chomp +\Amaybe log lines: #1 +log level:4 +log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*access_by_lua\(nginx.conf:\d+\):\d+: --> +new line, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" +end +maybe log lines: #1 +end +\z +--- skip_nginx: 2: <1.11.2 diff --git a/t/semaphore.t b/t/semaphore.t index 18c838985..509e317cc 100644 --- a/t/semaphore.t +++ b/t/semaphore.t @@ -1304,7 +1304,7 @@ count in A: 0 -=== TEST 26: kill a light thread that is waiting on a semaphore(no resource) +=== TEST 26: kill a light thread that is waiting on a semaphore (no resource) --- http_config eval: $::HttpConfig --- config location /test { @@ -1337,7 +1337,7 @@ ok -=== TEST 27: kill a light thread that is waiting on a semaphore(after post) +=== TEST 27: kill a light thread that is waiting on a semaphore (after post) --- http_config eval: $::HttpConfig --- config location /test { @@ -1774,7 +1774,7 @@ GET /test -=== TEST 39: basic semaphore count(negative number) +=== TEST 39: basic semaphore count (negative number) --- http_config eval: $::HttpConfig --- config location /test { From 7cd1a033f7e204a7e2be34ff1351a11840fc88f9 Mon Sep 17 00:00:00 2001 From: spacewander Date: Mon, 22 May 2017 17:35:18 +0800 Subject: [PATCH 54/74] feature: ngx.errlog: added the get_sys_filter_level() API function to get the "system" error log filtering level defined in nginx.conf's error_log directive. Signed-off-by: Yichun Zhang (agentzh) --- lib/ngx/errlog.lua | 10 +++++ lib/ngx/errlog.md | 28 +++++++++++++ t/errlog.t | 97 +++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 133 insertions(+), 2 deletions(-) diff --git a/lib/ngx/errlog.lua b/lib/ngx/errlog.lua index a1b5afdaf..1b4c7254f 100644 --- a/lib/ngx/errlog.lua +++ b/lib/ngx/errlog.lua @@ -11,6 +11,8 @@ local new_tab = base.new_tab local ffi_new = ffi.new local charpp = ffi_new("char *[1]") local intp = ffi.new("int[1]") +local getfenv = getfenv +local tonumber = tonumber local _M = { version = base.version } @@ -21,6 +23,8 @@ int ngx_http_lua_ffi_errlog_set_filter_level(int level, unsigned char *err, size_t *errlen); int ngx_http_lua_ffi_errlog_get_msg(char **log, int *loglevel, unsigned char *err, size_t *errlen); + +int ngx_http_lua_ffi_errlog_get_sys_filter_level(ngx_http_request_t *r); ]] @@ -87,4 +91,10 @@ function _M.get_logs(max, logs) end +function _M.get_sys_filter_level() + local r = getfenv(0).__ngx_req + return tonumber(C.ngx_http_lua_ffi_errlog_get_sys_filter_level(r)) +end + + return _M diff --git a/lib/ngx/errlog.md b/lib/ngx/errlog.md index 5550f49b5..192de6656 100644 --- a/lib/ngx/errlog.md +++ b/lib/ngx/errlog.md @@ -13,6 +13,7 @@ Table of Contents * [Methods](#methods) * [set_filter_level](#set_filter_level) * [get_logs](#get_logs) + * [get_sys_filter_level](#get_sys_filter_level) * [Community](#community) * [English Mailing List](#english-mailing-list) * [Chinese Mailing List](#chinese-mailing-list) @@ -210,6 +211,33 @@ clear the table yourself before feeding it into the `errlog.get_logs` function. [Back to TOC](#table-of-contents) +get_sys_filter_level +-------------------- +**syntax:** *log_level = log_module.get_sys_filter_level()* + +**context:** *any* + +Return the nginx core's error log filter level (defined via the [error_log](http://nginx.org/r/error_log) +configuration directive in `nginx.conf`) as an integer value matching the nginx error log level +constants documented below: + +https://github.com/openresty/lua-nginx-module/#nginx-log-level-constants + +For example: + +```lua +local errlog = require "ngx.errlog" +local log_level = errlog.get_sys_filter_level() +-- Now the filter level is always one level higher than system default log level on priority +local status, err = errlog.set_filter_level(log_level - 1) +if not status then + ngx.log(ngx.ERR, err) + return +end +``` + +[Back to TOC](#table-of-contents) + Community ========= diff --git a/t/errlog.t b/t/errlog.t index 5429db936..04b197e74 100644 --- a/t/errlog.t +++ b/t/errlog.t @@ -9,7 +9,7 @@ log_level('error'); repeat_each(2); -plan tests => repeat_each() * (blocks() * 2 + 11); +plan tests => repeat_each() * (blocks() * 2 + 13); my $pwd = cwd(); @@ -17,13 +17,16 @@ add_block_preprocessor(sub { my $block = shift; my $http_config = $block->http_config || ''; + my $init_by_lua_block = $block->init_by_lua_block || 'require "resty.core"'; + $http_config .= <<_EOC_; lua_package_path "$pwd/lib/?.lua;../lua-resty-lrucache/lib/?.lua;;"; init_by_lua_block { - require "resty.core" + $init_by_lua_block } _EOC_ + $block->set_value("http_config", $http_config); }); @@ -932,3 +935,93 @@ maybe log lines: #1 end \z --- skip_nginx: 2: <1.11.2 + + + +=== TEST 23: the system default filter level is "debug" +--- config + location /t { + content_by_lua_block { + local errlog = require "ngx.errlog" + ngx.print('Is "debug" the system default filter level? ', + errlog.get_sys_filter_level() == ngx.DEBUG) + } + } +--- log_level: debug +--- request +GET /t +--- response_body chomp +Is "debug" the system default filter level? true + + + +=== TEST 24: the system default filter level is "emerg" +--- config + location /t { + content_by_lua_block { + local errlog = require "ngx.errlog" + ngx.print('Is "emerg" the system default filter level? ', + errlog.get_sys_filter_level() == ngx.EMERG) + } + } +--- log_level: emerg +--- request +GET /t +--- response_body chomp +Is "emerg" the system default filter level? true + + + +=== TEST 25: get system default filter level during Nginx starts (init) +--- init_by_lua_block + require "resty.core" + local errlog = require "ngx.errlog" + package.loaded.log_level = errlog.get_sys_filter_level() + +--- config + location /t { + content_by_lua_block { + local log_level = package.loaded.log_level + + if log_level >= ngx.WARN then + ngx.log(ngx.WARN, "log a warning event") + else + ngx.log(ngx.WARN, "do not log another warning event") + end + } + } +--- log_level: warn +--- request +GET /t +--- error_log +log a warning event +--- no_error_log +do not log another warning event + + + +=== TEST 26: get system default filter level during Nginx worker starts (init worker) +--- http_config + init_worker_by_lua_block { + local errlog = require "ngx.errlog" + package.loaded.log_level = errlog.get_sys_filter_level() + } +--- config + location /t { + content_by_lua_block { + local log_level = package.loaded.log_level + + if log_level >= ngx.WARN then + ngx.log(ngx.WARN, "log a warning event") + else + ngx.log(ngx.WARN, "do not log another warning event") + end + } + } +--- log_level: warn +--- request +GET /t +--- error_log +log a warning event +--- no_error_log +do not log another warning event From 1928892e5857f797a353ac045e1638f8e924d39a Mon Sep 17 00:00:00 2001 From: detailyang Date: Thu, 8 Jun 2017 13:48:38 +0800 Subject: [PATCH 55/74] doc: ngx.balancer: fixed some typos in balancer.md. Signed-off-by: Yichun Zhang (agentzh) --- lib/ngx/balancer.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/ngx/balancer.md b/lib/ngx/balancer.md index 9b1e584f0..5884ca526 100644 --- a/lib/ngx/balancer.md +++ b/lib/ngx/balancer.md @@ -80,8 +80,8 @@ Description =========== This Lua module provides API functions to allow defining highly dynamic NGINX load balancers for -any existing nginx upstream modules like [http://nginx.org/en/docs/http/ngx_http_proxy_module.html ngx_proxy] and -[http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html ngx_fastcgi]. +any existing nginx upstream modules like [ngx_proxy](http://nginx.org/en/docs/http/ngx_http_proxy_module.html) and +[ngx_fastcgi](http://nginx.org/en/docs/http/ngx_http_fastcgi_module.html). It allows you to dynamically select a backend peer to connect to (or retry) on a per-request basis from a list of backend peers which may also be dynamic. From 238c150dcdd09b825c106711d33ee6f569c0eaed Mon Sep 17 00:00:00 2001 From: Thibault Charbonnier Date: Mon, 15 May 2017 19:53:01 -0700 Subject: [PATCH 56/74] bugfix: ngx.re: split() might enter infinite loops when the regex yields matches with empty captures. Signed-off-by: Yichun Zhang (agentzh) --- lib/ngx/re.lua | 82 ++++++++----- t/re-split.t | 328 ++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 370 insertions(+), 40 deletions(-) diff --git a/lib/ngx/re.lua b/lib/ngx/re.lua index 28e9ed040..2ca40164e 100644 --- a/lib/ngx/re.lua +++ b/lib/ngx/re.lua @@ -77,13 +77,17 @@ local function re_split_helper(subj, compiled, compile_once, flags, ctx) local caps = compiled.captures local ncaps = compiled.ncaptures - local from = caps[0] + 1 + local from = caps[0] local to = caps[1] if from < 0 or to < 0 then return nil, nil, nil end + -- convert to Lua string indexes + + from = from + 1 + to = to + 1 ctx.pos = to + 1 -- retrieve the first sub-match capture if any @@ -134,26 +138,6 @@ function _M.split(subj, regex, opts, ctx, max, res) return res end - if regex == "" then - local pos = ctx.pos - local last = len - if max > 0 then - last = math_min(len, pos + max - 1) - end - - local res_idx = 1 - while pos < last do - res[res_idx] = sub(subj, pos, pos) - res_idx = res_idx + 1 - pos = pos + 1 - end - - res[res_idx] = sub(subj, pos) - res[res_idx + 1] = nil - - return res - end - -- compile regex local compiled, compile_once, flags = re_match_compile(regex, opts) @@ -164,6 +148,7 @@ function _M.split(subj, regex, opts, ctx, max, res) local sub_idx = ctx.pos local res_idx = 0 + local last_empty_match -- splitting: with and without a max limiter @@ -181,16 +166,30 @@ function _M.split(subj, regex, opts, ctx, max, res) break end - count = count + 1 - res_idx = res_idx + 1 - res[res_idx] = sub(subj, sub_idx, from - 1) + if last_empty_match then + sub_idx = last_empty_match + end - if capture then - res_idx = res_idx + 1 - res[res_idx] = capture + if from == to then + last_empty_match = from end - sub_idx = to + 1 + if from > sub_idx or not last_empty_match then + count = count + 1 + res_idx = res_idx + 1 + res[res_idx] = sub(subj, sub_idx, from - 1) + + if capture then + res_idx = res_idx + 1 + res[res_idx] = capture + end + + sub_idx = to + + if sub_idx >= len then + break + end + end end if count == max then @@ -211,16 +210,31 @@ function _M.split(subj, regex, opts, ctx, max, res) break end - res_idx = res_idx + 1 - res[res_idx] = sub(subj, sub_idx, from - 1) + if last_empty_match then + sub_idx = last_empty_match + end - if capture then - res_idx = res_idx + 1 - res[res_idx] = capture + if from == to then + last_empty_match = from end - sub_idx = to + 1 + if from > sub_idx or not last_empty_match then + res_idx = res_idx + 1 + res[res_idx] = sub(subj, sub_idx, from - 1) + + if capture then + res_idx = res_idx + 1 + res[res_idx] = capture + end + + sub_idx = to + + if sub_idx >= len then + break + end + end end + end -- trailing nil for non-cleared res tables diff --git a/t/re-split.t b/t/re-split.t index bccee4c4c..0a9cd444c 100644 --- a/t/re-split.t +++ b/t/re-split.t @@ -766,13 +766,48 @@ GET /re 4 5 len: 5 +--- error_log eval +qr/\[TRACE \d+/ +--- no_error_log +[error] + + + +=== TEST 23: regex is "" with max +--- http_config eval: $::HttpConfig +--- config + location /re { + content_by_lua_block { + local ngx_re = require "ngx.re" + + local res, err = ngx_re.split("12345", "", "jo", nil, 3) + if err then + ngx.log(ngx.ERR, "failed: ", err) + return + end + + for i = 1, #res do + ngx.say(res[i]) + end + + ngx.say("len: ", #res) + } + } +--- request +GET /re +--- response_body +1 +2 +345 +len: 3 +--- error_log eval +qr/\[TRACE \d+/ --- no_error_log [error] -[TRACE -=== TEST 23: regex is "" with pos +=== TEST 24: regex is "" with pos --- http_config eval: $::HttpConfig --- config location /re { @@ -800,13 +835,14 @@ GET /re 4 5 len: 4 +--- error_log eval +qr/\[TRACE \d+/ --- no_error_log [error] -[TRACE -=== TEST 24: regex is "" with pos larger than subject length +=== TEST 25: regex is "" with pos larger than subject length --- http_config eval: $::HttpConfig --- config location /re { @@ -836,7 +872,7 @@ len: 0 -=== TEST 25: regex is "" with pos & max +=== TEST 26: regex is "" with pos & max --- http_config eval: $::HttpConfig --- config location /re { @@ -862,6 +898,286 @@ GET /re 2 345 len: 2 +--- error_log eval +qr/\[TRACE \d+/ +--- no_error_log +[error] + + + +=== TEST 27: no match separator (github issue #104) +--- http_config eval: $::HttpConfig +--- config + location /re { + content_by_lua_block { + local ngx_re = require "ngx.re" + + local res, err = ngx_re.split("abcd", "|") + if err then + ngx.log(ngx.ERR, "failed: ", err) + return + end + + ngx.say(table.concat(res, ":")) + ngx.say("len: ", #res) + } + } +--- request +GET /re +--- response_body +a:b:c:d +len: 4 +--- error_log eval +qr/\[TRACE \d+/ +--- no_error_log +[error] + + + +=== TEST 28: no match separator (github issue #104) & max +--- http_config eval: $::HttpConfig +--- config + location /re { + content_by_lua_block { + local ngx_re = require "ngx.re" + + local res, err = ngx_re.split("abcd", "|", nil, nil, 2) + if err then + ngx.log(ngx.ERR, "failed: ", err) + return + end + + ngx.say(table.concat(res, ":")) + ngx.say("len: ", #res) + } + } +--- request +GET /re +--- response_body +a:bcd +len: 2 +--- error_log eval +qr/\[TRACE \d+/ +--- no_error_log +[error] + + + +=== TEST 29: no match separator bis (github issue #104) +--- http_config eval: $::HttpConfig +--- config + location /re { + content_by_lua_block { + local ngx_re = require "ngx.re" + + local res, err = ngx_re.split("abcd", "()") + if err then + ngx.log(ngx.ERR, "failed: ", err) + return + end + + ngx.say(table.concat(res, ":")) + ngx.say("len: ", #res) + } + } +--- request +GET /re +--- response_body +a::b::c::d +len: 7 +--- error_log eval +qr/\[TRACE \d+/ +--- no_error_log +[error] + + + +=== TEST 30: behavior with /^/ differs from Perl's split +--- http_config eval: $::HttpConfig +--- config + location /re { + content_by_lua_block { + local ngx_re = require "ngx.re" + + local res, err = ngx_re.split("ab\ncd\nef", "^") + if err then + ngx.log(ngx.ERR, "failed: ", err) + return + end + + ngx.say(table.concat(res, ":")) + + ngx.say("len: ", #res) + } + } +--- request +GET /re +--- response_body +ab +cd +ef +len: 1 +--- error_log eval +qr/\[TRACE \d+/ +--- no_error_log +[error] + + + +=== TEST 31: behavior with /^/m +--- http_config eval: $::HttpConfig +--- config + location /re { + content_by_lua_block { + local ngx_re = require "ngx.re" + + local res, err = ngx_re.split("ab\ncd\nef", "^", "m") + if err then + ngx.log(ngx.ERR, "failed: ", err) + return + end + + ngx.say(table.concat(res, ":")) + + ngx.say("len: ", #res) + } + } +--- request +GET /re +--- response_body +ab +:cd +:ef +len: 3 +--- error_log eval +qr/\[TRACE \d+/ +--- no_error_log +[error] + + + +=== TEST 32: behavior with /^()/m (capture) +--- http_config eval: $::HttpConfig +--- config + location /re { + content_by_lua_block { + local ngx_re = require "ngx.re" + + local res, err = ngx_re.split("ab\ncd\nef", "^()", "m") + if err then + ngx.log(ngx.ERR, "failed: ", err) + return + end + + ngx.say(table.concat(res, ":")) + + ngx.say("len: ", #res) + } + } +--- request +GET /re +--- response_body +ab +::cd +::ef +len: 5 +--- error_log eval +qr/\[TRACE \d+/ +--- no_error_log +[error] + + + +=== TEST 33: behavior with /^/m & max +--- http_config eval: $::HttpConfig +--- config + location /re { + content_by_lua_block { + local ngx_re = require "ngx.re" + + local res, err = ngx_re.split("ab\ncd\nef", "^", "m", nil, 2) + if err then + ngx.log(ngx.ERR, "failed: ", err) + return + end + + ngx.say(table.concat(res, ":")) + + ngx.say("len: ", #res) + } + } +--- request +GET /re +--- response_body +ab +:cd +ef +len: 2 +--- error_log eval +qr/\[TRACE \d+/ +--- no_error_log +[error] + + + +=== TEST 34: behavior with /^\d/m +--- http_config eval: $::HttpConfig +--- config + location /re { + content_by_lua_block { + local ngx_re = require "ngx.re" + + local res, err = ngx_re.split("ab\n1cdefg\n2hij", "^\\d", "m") + if err then + ngx.log(ngx.ERR, "failed: ", err) + return + end + + ngx.say(table.concat(res, ":")) + + ngx.say("len: ", #res) + } + } +--- request +GET /re +--- response_body +ab +:cdefg +:hij +len: 3 +--- error_log eval +qr/\[TRACE \d+/ +--- no_error_log +[error] + + + +=== TEST 35: behavior with /^(\d)/m (capture) +--- http_config eval: $::HttpConfig +--- config + location /re { + content_by_lua_block { + local ngx_re = require "ngx.re" + + local res, err = ngx_re.split("ab\n1cdefg\n2hij", "^(\\d)", "m") + if err then + ngx.log(ngx.ERR, "failed: ", err) + return + end + + ngx.say(table.concat(res, ":")) + + ngx.say("len: ", #res) + } + } +--- request +GET /re +--- response_body +ab +:1:cdefg +:2:hij +len: 5 +--- error_log eval +qr/\[TRACE \d+/ --- no_error_log [error] -[TRACE From 285c155a3acffc4ac2c141f5506bc00116b12815 Mon Sep 17 00:00:00 2001 From: spacewander Date: Wed, 14 Jun 2017 14:18:36 +0800 Subject: [PATCH 57/74] doc: fixed some typos detected by misspell. Signed-off-by: Yichun Zhang (agentzh) --- lib/ngx/ocsp.md | 2 +- t/encode-base64.t | 2 +- t/ssl.t | 28 ++++++++++++++-------------- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/lib/ngx/ocsp.md b/lib/ngx/ocsp.md index a0d673994..62c230810 100644 --- a/lib/ngx/ocsp.md +++ b/lib/ngx/ocsp.md @@ -72,7 +72,7 @@ server { -- use cosocket-based HTTP client libraries like lua-resty-http-simple -- to send the request (url + ocsp_req as POST params or URL args) to -- CA's OCSP server. assuming the server returns the OCSP response - -- in the Lua varaible, resp. + -- in the Lua variable, resp. local schema, host, port, ocsp_uri, err = parse_url(ocsp_url) diff --git a/t/encode-base64.t b/t/encode-base64.t index ed4a54c96..b022b3ab2 100644 --- a/t/encode-base64.t +++ b/t/encode-base64.t @@ -204,7 +204,7 @@ qr/\[TRACE \d+ content_by_lua\(nginx\.conf:\d+\):3 loop\]/ -=== TEST 8: set base64 (number) with padding (explictly specified) +=== TEST 8: set base64 (number) with padding (explicitly specified) --- http_config eval: $::HttpConfig --- config location = /base64 { diff --git a/t/ssl.t b/t/ssl.t index a1c5e2f49..55aca4c5f 100644 --- a/t/ssl.t +++ b/t/ssl.t @@ -83,7 +83,7 @@ __DATA__ 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 @@ -194,7 +194,7 @@ sslv3 alert handshake failure 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 @@ -293,7 +293,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 @@ -393,7 +393,7 @@ read SNI name from Lua: 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 @@ -509,7 +509,7 @@ read SNI name from Lua: nil, type: nil 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 @@ -629,7 +629,7 @@ qr/Using unix socket file .*?nginx\.sock/ 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 @@ -747,7 +747,7 @@ Using IPv4 address: 127.0.0.1 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 @@ -869,7 +869,7 @@ Using IPv6 address: 0.0.0.1 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 @@ -996,7 +996,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 @@ -1521,7 +1521,7 @@ ssl cert by lua done 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 @@ -1654,7 +1654,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 @@ -1787,7 +1787,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 @@ -1911,7 +1911,7 @@ qr/\[error\] .*? failed to parse pem cert: PEM_read_bio_X509_AUX\(\) 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 @@ -2035,7 +2035,7 @@ qr/\[error\] .*? failed to parse pem cert: PEM_read_bio_X509\(\) 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 From 3d6c823704bff94b4438054525df9e56b8fbc258 Mon Sep 17 00:00:00 2001 From: Yuansheng Date: Tue, 27 Jun 2017 06:29:36 +0800 Subject: [PATCH 58/74] feature: ngx.errlog: get_logs(): now we return the UNIX timestamps with msec precision for each captured error log entry. Signed-off-by: Yichun Zhang (agentzh) --- lib/ngx/errlog.lua | 23 +++-- lib/ngx/errlog.md | 47 ++++++---- t/errlog.t | 218 +++++++++++++++++++++++++++++++-------------- 3 files changed, 198 insertions(+), 90 deletions(-) diff --git a/lib/ngx/errlog.lua b/lib/ngx/errlog.lua index 1b4c7254f..2f8c2882e 100644 --- a/lib/ngx/errlog.lua +++ b/lib/ngx/errlog.lua @@ -11,6 +11,7 @@ local new_tab = base.new_tab local ffi_new = ffi.new local charpp = ffi_new("char *[1]") local intp = ffi.new("int[1]") +local num_value = ffi_new("double[1]") local getfenv = getfenv local tonumber = tonumber @@ -22,7 +23,7 @@ ffi.cdef[[ int ngx_http_lua_ffi_errlog_set_filter_level(int level, unsigned char *err, size_t *errlen); int ngx_http_lua_ffi_errlog_get_msg(char **log, int *loglevel, - unsigned char *err, size_t *errlen); + unsigned char *err, size_t *errlen, double *log_time); int ngx_http_lua_ffi_errlog_get_sys_filter_level(ngx_http_request_t *r); ]] @@ -57,32 +58,38 @@ function _M.get_logs(max, logs) local log = charpp local loglevel = intp + local log_time = num_value max = max or 10 if not logs then - logs = new_tab(max * 2 + 1, 0) + logs = new_tab(max * 3 + 1, 0) end + local count = 0 + for i = 1, max do - local loglen = C.ngx_http_lua_ffi_errlog_get_msg(log, - loglevel, err, errlen) + local loglen = C.ngx_http_lua_ffi_errlog_get_msg(log, loglevel, err, + errlen, log_time) if loglen == FFI_ERROR then return nil, ffi_string(err, errlen[0]) end if loglen > 0 then - logs[i * 2 - 1] = loglevel[0] - logs[i * 2] = ffi_string(log[0], loglen) + logs[count + 1] = loglevel[0] + logs[count + 2] = log_time[0] + logs[count + 3] = ffi_string(log[0], loglen) + + count = count + 3 end if loglen < 0 then -- no error log - logs[i * 2 - 1] = nil + logs[count + 1] = nil break end if i == max then -- last one - logs[i * 2 + 1] = nil + logs[count + 1] = nil break end end diff --git a/lib/ngx/errlog.md b/lib/ngx/errlog.md index 192de6656..452ed1ca5 100644 --- a/lib/ngx/errlog.md +++ b/lib/ngx/errlog.md @@ -67,8 +67,9 @@ http { return end - for _, log in ipairs(logs) do - ngx.say("level: ", log[1], " data: ", log[2]) + for i = 1, #logs, 3 do + ngx.say("level: ", logs[i], " time: ", logs[i + 1], + " data: ", logs[i + 2]) end } } @@ -80,12 +81,12 @@ http { The example location above produces a response like this: ``` -level: 5 data: 2017/04/19 22:20:03 [warn] 63176#0: - [lua] init_by_lua:7: set error filter level: WARN -level: 5 data: 2017/04/19 22:20:05 [warn] 63176#0: *1 - [lua] content_by_lua(nginx.conf:59):4: test2 -level: 4 data: 2017/04/19 22:20:05 [error] 63176#0: *1 - [lua] content_by_lua(nginx.conf:59):5: test3 +level: 5 time: 1498546995.304 data: 2017/06/27 15:03:15 [warn] 46877#0: + [lua] init_by_lua:8: set error filter level: WARN +level: 5 time: 1498546999.178 data: 2017/06/27 15:03:19 [warn] 46879#0: *1 + [lua] test.lua:5: test2, client: 127.0.0.1, server: localhost, ...... +level: 4 time: 1498546999.178 data: 2017/06/27 15:03:19 [error] 46879#0: *1 + [lua] test.lua:6: test3, client: 127.0.0.1, server: localhost, ...... ``` [Back to TOC](#table-of-contents) @@ -157,20 +158,33 @@ local res = errlog.get_logs(10) The resulting table has the following structure: ```lua -{ level1, msg1, level2, msg2, ... } +{ level1, time1, msg1, level2, time2, msg2, ... } ``` +The `levelX` values are constants defined below: + +https://github.com/openresty/lua-nginx-module/#nginx-log-level-constants + +The `timeX` values are UNIX timestamps in seconds with millisecond precision. The sub-second part is presented as the decimal part. +The time format is exactly the same as the value returned by [ngx.now](https://github.com/openresty/lua-nginx-module/#ngxnow). It is +also subject to NGINX core's time caching. + +The `msgX` values are the error log message texts. + So to traverse this array, the user can use a loop like this: ```lua -for i = 1, #res, 2 do +for i = 1, #res, 3 do local level = res[i] if not level then break end - local msg = res[i + 1] - -- handle the current message with log level in `level` and - -- log message body in `msg`. + + local time = res[i + 1] + local msg = res[i + 2] + + -- handle the current message with log level in `level`, + -- log time in `time`, and log message body in `msg`. end ``` @@ -185,18 +199,19 @@ unnecessary table dynamic allocations on hot Lua code paths. It is used like thi local errlog = require "ngx.errlog" local new_tab = require "table.new" -local buffer = new_tab(100 * 2, 0) -- for 100 messages +local buffer = new_tab(100 * 3, 0) -- for 100 messages local errlog = require "ngx.errlog" local res, err = errlog.get_logs(0, buffer) if res then -- res is the same table as `buffer` - for i = 1, #res, 2 do + for i = 1, #res, 3 do local level = res[i] if not level then break end - local msg = res[i + 1] + local time = res[i + 1] + local msg = res[i + 2] ... end end diff --git a/t/errlog.t b/t/errlog.t index 04b197e74..6038a7599 100644 --- a/t/errlog.t +++ b/t/errlog.t @@ -9,7 +9,7 @@ log_level('error'); repeat_each(2); -plan tests => repeat_each() * (blocks() * 2 + 13); +plan tests => repeat_each() * (blocks() * 2 + 15); my $pwd = cwd(); @@ -51,7 +51,7 @@ __DATA__ if not res then error("FAILED " .. err) end - ngx.say("log lines:", #res / 2) + ngx.say("log lines:", #res / 3) } } --- request @@ -87,7 +87,7 @@ enter 11 if not res then error("FAILED " .. err) end - ngx.say("log lines:", #res / 2) + ngx.say("log lines:", #res / 3) } } --- request @@ -119,7 +119,7 @@ enter 22 if not res then error("FAILED " .. err) end - ngx.log(ngx.ERR, "capture log line:", #res / 2) + ngx.log(ngx.ERR, "capture log line:", #res / 3) } --- request GET /t @@ -154,7 +154,7 @@ $/ if not res then error("FAILED " .. err) end - ngx.log(ngx.ERR, "capture log line:", #res / 2) + ngx.log(ngx.ERR, "capture log line:", #res / 3) } --- request GET /t @@ -187,7 +187,7 @@ $/ if not res then error("FAILED " .. err) end - ngx.log(ngx.ERR, "capture log line:", #res / 2) + ngx.log(ngx.ERR, "capture log line:", #res / 3) } --- request GET /t @@ -224,7 +224,7 @@ $/ if not res then error("FAILED " .. err) end - ngx.log(ngx.ERR, "capture log line:", #res / 2) + ngx.log(ngx.ERR, "capture log line:", #res / 3) } --- request @@ -285,7 +285,7 @@ invalid number of arguments in "lua_capture_error_log" directive if not res then error("FAILED " .. err) end - ngx.say("log lines:", #res / 2) + ngx.say("log lines:", #res / 3) } } --- request @@ -338,7 +338,7 @@ directive "lua_capture_error_log" is not set content_by_lua_block { local errlog = require "ngx.errlog" local res = errlog.get_logs() - ngx.say("log lines:", #res / 2) + ngx.say("log lines:", #res / 3) } } --- log_level: info @@ -382,7 +382,7 @@ qr/-->\d+/ content_by_lua_block { local errlog = require "ngx.errlog" local res = errlog.get_logs() - ngx.say("log lines:", #res / 2) + ngx.say("log lines:", #res / 3) } } --- log_level: info @@ -427,7 +427,7 @@ qr/-->\d+/ content_by_lua_block { local errlog = require "ngx.errlog" local res = errlog.get_logs() - ngx.say("log lines:", #res / 2) + ngx.say("log lines:", #res / 3) } } --- request @@ -469,14 +469,14 @@ qr/-->\d+/ if not res then error("FAILED " .. err) end - ngx.say("log lines:", #res / 2) + ngx.say("log lines:", #res / 3) tab_clear(res) res, err = errlog.get_logs(2, res) if not res then error("FAILED " .. err) end - ngx.say("log lines:", #res / 2) + ngx.say("log lines:", #res / 3) } } --- request @@ -538,9 +538,9 @@ qr/missing \"level\" argument/ content_by_lua_block { local errlog = require "ngx.errlog" local res = errlog.get_logs() - for i = 1, #res, 2 do + for i = 1, #res, 3 do ngx.say("log level:", res[i]) - ngx.say("log body:", res[i + 1]) + ngx.say("log body:", res[i + 2]) end } } @@ -591,18 +591,18 @@ qr/-->\d+/ content_by_lua_block { local errlog = require "ngx.errlog" local res = errlog.get_logs(1000) - ngx.say("log lines: #", #res / 2) + ngx.say("log lines: #", #res / 3) -- first 3 logs - for i = 1, 2 * 3, 2 do + for i = 1, 3 * 3, 3 do ngx.say("log level:", res[i]) - ngx.say("log body:", res[i + 1]) + ngx.say("log body:", res[i + 2]) end -- last 3 logs - for i = #res - 5, #res, 2 do + for i = #res - 8, #res, 3 do ngx.say("log level:", res[i]) - ngx.say("log body:", res[i + 1]) + ngx.say("log body:", res[i + 2]) end } } @@ -610,9 +610,7 @@ qr/-->\d+/ --- request GET /t --- response_body_like chomp -\Alog lines: #22 -log level:5 -log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[warn\] (\d+).*access_by_lua\(nginx.conf:\d+\):\d+: --> 90, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" +\Alog lines: #21 log level:4 log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*access_by_lua\(nginx.conf:\d+\):\d+: --> 90, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" log level:5 @@ -650,18 +648,18 @@ log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*access_by_lua\(ngi content_by_lua_block { local errlog = require "ngx.errlog" local res = errlog.get_logs(1000) - ngx.say("log lines: #", #res / 2) + ngx.say("log lines: #", #res / 3) -- first 3 logs - for i = 1, 2 * 3, 2 do + for i = 1, 3 * 3, 3 do ngx.say("log level:", res[i]) - ngx.say("log body:", res[i + 1]) + ngx.say("log body:", res[i + 2]) end -- last 3 logs - for i = #res - 5, #res, 2 do + for i = #res - 8, #res, 3 do ngx.say("log level:", res[i]) - ngx.say("log body:", res[i + 1]) + ngx.say("log body:", res[i + 2]) end } } @@ -669,13 +667,13 @@ log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*access_by_lua\(ngi --- request GET /t --- response_body_like chomp -\Alog lines: #28 +\Alog lines: #26 log level:5 -log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[warn\] (\d+).*access_by_lua\(nginx.conf:\d+\):\d+: --> 87, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" +log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[warn\] (\d+).*access_by_lua\(nginx.conf:\d+\):\d+: --> 88, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" log level:4 -log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*access_by_lua\(nginx.conf:\d+\):\d+: --> 87, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" +log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*access_by_lua\(nginx.conf:\d+\):\d+: --> 88, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" log level:5 -log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[warn\] (\d+).*access_by_lua\(nginx.conf:\d+\):\d+: --> 88, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" +log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[warn\] (\d+).*access_by_lua\(nginx.conf:\d+\):\d+: --> 89, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" log level:4 log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*access_by_lua\(nginx.conf:\d+\):\d+: --> 99, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" log level:5 @@ -710,12 +708,12 @@ log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*access_by_lua\(ngi local errlog = require "ngx.errlog" local res = errlog.get_logs(3) - ngx.say("msg count: ", #res / 2) + ngx.say("msg count: ", #res / 3) -- first 3 logs - for i = 1, #res, 2 do + for i = 1, #res, 3 do ngx.say("log level:", res[i]) - ngx.say("log body:", res[i + 1]) + ngx.say("log body:", res[i + 2]) end ngx.log(ngx.ERR, "--> 101") @@ -724,19 +722,19 @@ log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*access_by_lua\(ngi ngx.log(ngx.ERR, "--> 104") local res = errlog.get_logs(3) - ngx.say("msg count: ", #res / 2) + ngx.say("msg count: ", #res / 3) -- first 3 logs - for i = 1, #res, 2 do + for i = 1, #res, 3 do ngx.say("log level:", res[i]) - ngx.say("log body:", res[i + 1]) + ngx.say("log body:", res[i + 2]) end local res = errlog.get_logs(1000) -- last 3 logs - for i = #res - 5, #res, 2 do + for i = #res - 8, #res, 3 do ngx.say("log level:", res[i]) - ngx.say("log body:", res[i + 1]) + ngx.say("log body:", res[i + 2]) end } } @@ -746,18 +744,18 @@ GET /t --- response_body_like chomp \Amsg count: 3 log level:5 -log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[warn\] (\d+).*?access_by_lua\(nginx.conf:\d+\):\d+: --> 87, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" +log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[warn\] (\d+).*?access_by_lua\(nginx.conf:\d+\):\d+: --> 88, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" log level:4 -log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*?access_by_lua\(nginx.conf:\d+\):\d+: --> 87, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" +log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*?access_by_lua\(nginx.conf:\d+\):\d+: --> 88, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" log level:5 -log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[warn\] (\d+).*?access_by_lua\(nginx.conf:\d+\):\d+: --> 88, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" +log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[warn\] (\d+).*?access_by_lua\(nginx.conf:\d+\):\d+: --> 89, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" msg count: 3 log level:5 -log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[warn\] (\d+).*?access_by_lua\(nginx.conf:\d+\):\d+: --> 89, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" +log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[warn\] (\d+).*?access_by_lua\(nginx.conf:\d+\):\d+: --> 90, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" log level:4 -log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*?access_by_lua\(nginx.conf:\d+\):\d+: --> 89, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" +log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*?access_by_lua\(nginx.conf:\d+\):\d+: --> 90, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" log level:5 -log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[warn\] (\d+).*?access_by_lua\(nginx.conf:\d+\):\d+: --> 90, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" +log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[warn\] (\d+).*?access_by_lua\(nginx.conf:\d+\):\d+: --> 91, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" log level:4 log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*?content_by_lua\(nginx.conf:\d+\):\d+: --> 102, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" log level:4 @@ -792,31 +790,31 @@ log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*?content_by_lua\(n local errlog = require "ngx.errlog" local res = errlog.get_logs(3) - ngx.say("msg count: ", #res / 2) + ngx.say("msg count: ", #res / 3) -- first 3 logs - for i = 1, #res, 2 do + for i = 1, #res, 3 do ngx.say("log level:", res[i]) - ngx.say("log body:", res[i + 1]) + ngx.say("log body:", res[i + 2]) end ngx.log(ngx.ERR, "howdy, something new!") ngx.log(ngx.ERR, "howdy, something even newer!") local res = errlog.get_logs(3) - ngx.say("msg count: ", #res / 2) + ngx.say("msg count: ", #res / 3) -- first 3 logs - for i = 1, #res, 2 do + for i = 1, #res, 3 do ngx.say("log level:", res[i]) - ngx.say("log body:", res[i + 1]) + ngx.say("log body:", res[i + 2]) end local res = errlog.get_logs(1000) -- last 3 logs - for i = #res - 5, #res, 2 do + for i = #res - 8, #res, 3 do ngx.say("log level:", res[i]) - ngx.say("log body:", res[i + 1]) + ngx.say("log body:", res[i + 2]) end } } @@ -826,18 +824,18 @@ GET /t --- response_body_like chomp \Amsg count: 3 log level:5 -log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[warn\] (\d+).*?access_by_lua\(nginx.conf:\d+\):\d+: --> 87, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" -log level:4 -log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*?access_by_lua\(nginx.conf:\d+\):\d+: --> 87, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" -log level:5 log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[warn\] (\d+).*?access_by_lua\(nginx.conf:\d+\):\d+: --> 88, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" -msg count: 3 log level:4 log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*?access_by_lua\(nginx.conf:\d+\):\d+: --> 88, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" log level:5 log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[warn\] (\d+).*?access_by_lua\(nginx.conf:\d+\):\d+: --> 89, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" +msg count: 3 log level:4 log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*?access_by_lua\(nginx.conf:\d+\):\d+: --> 89, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" +log level:5 +log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[warn\] (\d+).*?access_by_lua\(nginx.conf:\d+\):\d+: --> 90, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" +log level:4 +log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*?access_by_lua\(nginx.conf:\d+\):\d+: --> 90, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" log level:4 log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*?access_by_lua\(nginx.conf:\d+\):\d+: --> 100, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" log level:4 @@ -867,11 +865,11 @@ log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*?content_by_lua\(n content_by_lua_block { local errlog = require "ngx.errlog" local res = errlog.get_logs() - ngx.say("log lines: #", #res / 2) + ngx.say("log lines: #", #res / 3) - for i = 1, #res, 2 do + for i = 1, #res, 3 do ngx.say("log level:", res[i]) - ngx.say("log body:", res[i + 1]) + ngx.say("log body:", res[i + 2]) end } } @@ -909,14 +907,14 @@ new line, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host for i = 1, 2 do local res = errlog.get_logs(10, t) - ngx.say("maybe log lines: #", #res / 2) - for j = 1, #res, 2 do - local level, msg = res[j], res[j + 1] + ngx.say("maybe log lines: #", #res / 3) + for j = 1, #res, 3 do + local level, msg = res[j], res[j + 2] if not level then break end ngx.say("log level:", level) - ngx.say("log body:", msg) + ngx.say("log body:", msg) end ngx.say("end") end @@ -1025,3 +1023,91 @@ GET /t log a warning event --- no_error_log do not log another warning event + + + +=== TEST 27: sanity (with log time) +--- http_config + lua_capture_error_log 4m; +--- config + location /t { + access_by_lua_block { + ngx.log(ngx.ERR, "enter 1") + ngx.log(ngx.ERR, "enter 11") + + local errlog = require "ngx.errlog" + local res, err = errlog.get_logs(nil, nil, {fetch_time = true}) + if not res then + error("FAILED " .. err) + end + ngx.say("log lines:", #res / 3) + } + } +--- request +GET /t +--- response_body +log lines:2 +--- grep_error_log eval +qr/enter \d+/ +--- grep_error_log_out eval +[ +"enter 1 +enter 11 +", +"enter 1 +enter 11 +" +] +--- skip_nginx: 3: <1.11.2 + + + +=== TEST 28: log time eq ngx.now +--- http_config + lua_capture_error_log 4m; +--- config + location /t { + access_by_lua_block { + local now = ngx.now() + ngx.log(ngx.CRIT, "enter 1") + ngx.log(ngx.ERR, "enter 11") + + local errlog = require "ngx.errlog" + local res, err = errlog.get_logs(nil, nil, {fetch_time = true}) + if not res then + error("FAILED " .. err) + end + ngx.say("log lines: ", #res / 3) + + for i = 1, #res, 3 do + ngx.say("log level: ", res[i]) + ngx.say("log time: ", res[i + 1]) + ngx.say("log body: ", res[i + 2]) + ngx.say("same with now: ", res[i + 1] == now) + end + } + } +--- request +GET /t +--- response_body_like chomp +\Alog lines: 2 +log level: 3 +log time: \d+\.\d+ +log body: \d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[crit\] (\d+).*?access_by_lua\(nginx.conf:\d+\):\d+: enter 1, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" +same with now: true +log level: 4 +log time: \d{10}\.\d+ +log body: \d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*?access_by_lua\(nginx.conf:\d+\):\d+: enter 11, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" +same with now: true +--- grep_error_log eval +qr/enter \d+/ +--- grep_error_log_out eval +[ +"enter 1 +enter 11 +", +"enter 1 +enter 11 +" +] +--- skip_nginx: 3: <1.11.2 From 8d262d91572d15bf27d49498c2e0717e5b214ac7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=99=8F=E6=97=AD=E7=91=9E?= <617080352@qq.com> Date: Mon, 3 Jul 2017 10:29:29 +0800 Subject: [PATCH 59/74] doc: ngx.errlog: get_logs(): fixed a typo. Signed-off-by: Yichun Zhang (agentzh) --- lib/ngx/errlog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ngx/errlog.md b/lib/ngx/errlog.md index 452ed1ca5..031ad3125 100644 --- a/lib/ngx/errlog.md +++ b/lib/ngx/errlog.md @@ -152,7 +152,7 @@ end local errlog = require "ngx.errlog" local res = errlog.get_logs(10) -- the number of messages in the `res` table is 10 and the `res` table --- has 20 elements. +-- has 30 elements. ``` The resulting table has the following structure: From 6cd0c0ed3d32a269b2be660edea2b8bfe7eaf0a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Pracha=C5=99?= Date: Tue, 27 Jun 2017 19:36:00 +0200 Subject: [PATCH 60/74] tests: added test cases for error log ringbuf bugs. thanks Yuansheng Wang for the followup tweaks. Signed-off-by: Yichun Zhang (agentzh) --- .travis.yml | 2 +- t/errlog.t | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 129 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 3f5cf76bf..c54d8b674 100644 --- a/.travis.yml +++ b/.travis.yml @@ -56,7 +56,7 @@ install: - git clone https://github.com/openresty/openresty.git ../openresty - git clone https://github.com/openresty/openresty-devel-utils.git - git clone https://github.com/simpl/ngx_devel_kit.git ../ndk-nginx-module - - git clone https://github.com/openresty/lua-nginx-module.git ../lua-nginx-module + - git clone -b pracj3am/log-ringbuf-bugs https://github.com/pracj3am/lua-nginx-module.git ../lua-nginx-module - git clone https://github.com/openresty/no-pool-nginx.git ../no-pool-nginx - git clone https://github.com/openresty/echo-nginx-module.git ../echo-nginx-module - git clone https://github.com/openresty/lua-resty-lrucache.git diff --git a/t/errlog.t b/t/errlog.t index 6038a7599..392869ece 100644 --- a/t/errlog.t +++ b/t/errlog.t @@ -1111,3 +1111,131 @@ enter 11 " ] --- skip_nginx: 3: <1.11.2 + + + +=== TEST 29: ringbuf overflow bug +--- http_config + lua_capture_error_log 4k; +--- config + location /t { + access_by_lua_block { + local errlog = require "ngx.errlog" + local msg = string.rep("*", 10) + + for i = 1, 2 do + ngx.log(ngx.ERR, msg .. i) + end + } + + content_by_lua_block { + local errlog = require "ngx.errlog" + local msg = string.rep("*", 10) + + for i = 1, 40 do + local res = errlog.get_logs(1) + if res and #res then + ngx.log(ngx.ERR, msg .. i) + end + end + + local res = errlog.get_logs() + for i = 1, #res, 3 do + ngx.say("log level: ", res[i]) + ngx.say("log time: ", res[i + 1]) + ngx.say("log body: ", res[i + 2]) + end + } + } +--- log_level: info +--- request +GET /t +--- response_body_like chomp +log level: 4 +log time: \d+\.\d+ +log body: \d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*?content_by_lua\(nginx.conf:\d+\):\d+: \*\*\*\*\*\*\*\*\*\*39, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" +log level: 4 +log time: \d{10}\.\d+ +log body: \d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*?content_by_lua\(nginx.conf:\d+\):\d+: \*\*\*\*\*\*\*\*\*\*40, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" +--- skip_nginx: 2: <1.11.2 + + + +=== TEST 30: ringbuf sentinel bug1 +--- http_config + lua_capture_error_log 4k; +--- config + location /t { + access_by_lua_block { + local errlog = require "ngx.errlog" + local msg = string.rep("a", 20) + local bigmsg = string.rep("A", 3000) + + for i = 1, 10 do + ngx.log(ngx.ERR, msg) + end + ngx.log(ngx.ERR, bigmsg) + ngx.log(ngx.ERR, msg) + } + + content_by_lua_block { + local errlog = require "ngx.errlog" + + local res = errlog.get_logs(2) + ngx.say("log lines: #", #res / 3) + + for i = 1, #res, 3 do + ngx.say(string.gsub(res[i + 2], "^.*([Aa][Aa][Aa]).*$", "%1"), "") + end + } + } +--- log_level: info +--- request +GET /t +--- response_body +log lines: #2 +AAA +aaa +--- skip_nginx: 2: <1.11.2 + + + +=== TEST 31: ringbuf sentinel bug2 +--- http_config + lua_capture_error_log 4k; +--- config + location /t { + access_by_lua_block { + local errlog = require "ngx.errlog" + local msg = string.rep("a", 20) + + for i = 1, 20 do + ngx.log(ngx.ERR, msg) + end + } + + content_by_lua_block { + local errlog = require "ngx.errlog" + local msg = string.rep("a", 20) + + local res = errlog.get_logs(18) + ngx.say("log lines: #", #res / 3) + + for i = 1, 18 do + ngx.log(ngx.ERR, msg) + end + + local bigmsg = string.rep("A", 2000) + ngx.log(ngx.ERR, bigmsg) + + local res = errlog.get_logs() + ngx.say("log lines: #", #res / 3) + } + } +--- log_level: info +--- request +GET /t +--- response_body +log lines: #18 +log lines: #8 +--- skip_nginx: 2: <1.11.2 From 64256870189297eea8b44eb888fa8b7887258761 Mon Sep 17 00:00:00 2001 From: "Yichun Zhang (agentzh)" Date: Wed, 5 Jul 2017 11:21:46 -0700 Subject: [PATCH 61/74] tests: skipped several short-connection tests in the check leak testing mode to avoid exhaust local ports. --- t/ssl.t | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/t/ssl.t b/t/ssl.t index 55aca4c5f..4ba67e63f 100644 --- a/t/ssl.t +++ b/t/ssl.t @@ -1,4 +1,4 @@ -# vim:set ft=ts=4 sw=4 et fdm=marker: +# vim:set ft= ts=4 sw=4 et fdm=marker: use Test::Nginx::Socket::Lua; use Cwd qw(cwd); @@ -547,6 +547,7 @@ qr/Using unix socket file .*?nginx\.sock/ --- no_error_log [error] [alert] +--- no_check_leak @@ -665,6 +666,7 @@ Using IPv4 address: 127.0.0.1 --- no_error_log [error] [alert] +--- no_check_leak @@ -784,6 +786,7 @@ Using IPv6 address: 0.0.0.1 [error] [alert] --- skip_eval: 6: system("ping6 -c 1 ::1 >/dev/null 2>&1") ne 0 +--- no_check_leak From 7216bf93c335e32ab9f2e694e5434486cdb74d11 Mon Sep 17 00:00:00 2001 From: "Yichun Zhang (agentzh)" Date: Wed, 5 Jul 2017 11:33:07 -0700 Subject: [PATCH 62/74] tests: fixed failures when TEST_NGINX_USE_STAP env is set. --- t/process-type-cache.t | 7 ++++++- t/process-type-master.t | 5 +++++ t/process-type-privileged-agent.t | 5 +++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/t/process-type-cache.t b/t/process-type-cache.t index 8165f214f..e121a1b50 100644 --- a/t/process-type-cache.t +++ b/t/process-type-cache.t @@ -1,10 +1,15 @@ # vim:set ft= ts=4 sw=4 et fdm=marker: + +BEGIN { + undef $ENV{TEST_NGINX_USE_STAP}; +} + use lib 'lib'; use Test::Nginx::Socket::Lua; use Cwd qw(cwd); #worker_connections(1014); -master_process_enabled(1); +master_on(); #log_level('info'); repeat_each(2); diff --git a/t/process-type-master.t b/t/process-type-master.t index 9b5207102..8ae6070fe 100644 --- a/t/process-type-master.t +++ b/t/process-type-master.t @@ -1,4 +1,9 @@ # vim:set ft= ts=4 sw=4 et fdm=marker: + +BEGIN { + undef $ENV{TEST_NGINX_USE_STAP}; +} + use lib 'lib'; use Test::Nginx::Socket::Lua; use Cwd qw(cwd); diff --git a/t/process-type-privileged-agent.t b/t/process-type-privileged-agent.t index f7128b03f..61b671af0 100644 --- a/t/process-type-privileged-agent.t +++ b/t/process-type-privileged-agent.t @@ -1,4 +1,9 @@ # vim:set ft= ts=4 sw=4 et fdm=marker: + +BEGIN { + undef $ENV{TEST_NGINX_USE_STAP}; +} + use lib 'lib'; use Test::Nginx::Socket::Lua; use Cwd qw(cwd); From ed8c20e0da12581479d931ca03320adf41b2aa8a Mon Sep 17 00:00:00 2001 From: "Yichun Zhang (agentzh)" Date: Wed, 5 Jul 2017 18:39:21 -0700 Subject: [PATCH 63/74] tests: fixed test failures on i386. --- t/process-type-cache.t | 3 ++- t/process-type-privileged-agent.t | 11 ++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/t/process-type-cache.t b/t/process-type-cache.t index e121a1b50..b49c3944c 100644 --- a/t/process-type-cache.t +++ b/t/process-type-cache.t @@ -66,7 +66,7 @@ __DATA__ ngx.sleep(0.1) local v local typ = (require "ngx.process").type - for i = 1, 400 do + for i = 1, 200 do v = typ() end ngx.say("type: ", v) @@ -99,3 +99,4 @@ process type: helper [error] -- NYI: --- skip_nginx: 5: < 1.11.2 +--- wait: 0.2 diff --git a/t/process-type-privileged-agent.t b/t/process-type-privileged-agent.t index 61b671af0..0be6b62c7 100644 --- a/t/process-type-privileged-agent.t +++ b/t/process-type-privileged-agent.t @@ -68,7 +68,7 @@ __DATA__ ngx.sleep(0.1) local v local typ = require "ngx.process".type - for i = 1, 400 do + for i = 1, 200 do v = typ() end @@ -84,13 +84,13 @@ qr/\[TRACE \d+ init_worker_by_lua:\d+ loop\]|\[TRACE \d+ content_by_lua\(ngi --- grep_error_log_out eval [ qr/\[TRACE \d init_worker_by_lua:5 loop\] -\[TRACE \d init_worker_by_lua:5 loop\] -\[TRACE \d content_by_lua\(nginx.conf:81\):5 loop\] +(?:\[TRACE \d init_worker_by_lua:5 loop\] +)?\[TRACE \d content_by_lua\(nginx.conf:81\):5 loop\] init_worker_by_lua:10: process type: privileged /, qr/\[TRACE \d init_worker_by_lua:5 loop\] -\[TRACE \d init_worker_by_lua:5 loop\] -\[TRACE \d content_by_lua\(nginx.conf:81\):5 loop\] +(?:\[TRACE \d init_worker_by_lua:5 loop\] +)?\[TRACE \d content_by_lua\(nginx.conf:81\):5 loop\] init_worker_by_lua:10: process type: privileged / ] @@ -98,6 +98,7 @@ init_worker_by_lua:10: process type: privileged [error] -- NYI: --- skip_nginx: 5: < 1.11.2 +--- wait: 0.2 From 9c3a1b806666934caa000bbf5092b364cabcceff Mon Sep 17 00:00:00 2001 From: "Yichun Zhang (agentzh)" Date: Wed, 5 Jul 2017 19:02:47 -0700 Subject: [PATCH 64/74] tests: proces-type-hup.t: disabled long string output in case of test failures. --- t/process-type-hup.t | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/t/process-type-hup.t b/t/process-type-hup.t index d24b6609a..8b08313dc 100644 --- a/t/process-type-hup.t +++ b/t/process-type-hup.t @@ -48,7 +48,7 @@ our $HttpConfig = <<_EOC_; _EOC_ #no_diff(); -#no_long_string(); +no_long_string(); check_accum_error_log(); run_tests(); @@ -94,3 +94,4 @@ init_worker_by_lua:6: process type: privileged --- no_error_log [error] --- skip_nginx: 4: < 1.11.2 +--- wait: 0.1 From 4c7f596d632e7b2072b61f21a5e814dd3cde32f0 Mon Sep 17 00:00:00 2001 From: "Yichun Zhang (agentzh)" Date: Wed, 5 Jul 2017 19:22:04 -0700 Subject: [PATCH 65/74] tests: simplified a test case. --- t/process-type-hup.t | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/t/process-type-hup.t b/t/process-type-hup.t index 8b08313dc..f023b6c8a 100644 --- a/t/process-type-hup.t +++ b/t/process-type-hup.t @@ -80,17 +80,8 @@ __DATA__ GET /t --- response_body type: worker ---- grep_error_log eval -qr/init_worker_by_lua:\d+: process type: \w+/ ---- grep_error_log_out eval -[ -"init_worker_by_lua:6: process type: privileged +--- error_log init_worker_by_lua:6: process type: privileged -", -"init_worker_by_lua:6: process type: privileged -init_worker_by_lua:6: process type: privileged -" -] --- no_error_log [error] --- skip_nginx: 4: < 1.11.2 From 6a11c6e3fa1f0ed96e3e70107c17fcb78de44bb1 Mon Sep 17 00:00:00 2001 From: "Yichun Zhang (agentzh)" Date: Thu, 6 Jul 2017 10:46:32 -0700 Subject: [PATCH 66/74] =?UTF-8?q?travis-ci:=20avoided=20using=20the=20cont?= =?UTF-8?q?ributor's=20branch=20of=20ngx=5Flua.=20thanks=20Jan=20Pracha?= =?UTF-8?q?=C5=99=20for=20the=20report.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index c54d8b674..3f5cf76bf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -56,7 +56,7 @@ install: - git clone https://github.com/openresty/openresty.git ../openresty - git clone https://github.com/openresty/openresty-devel-utils.git - git clone https://github.com/simpl/ngx_devel_kit.git ../ndk-nginx-module - - git clone -b pracj3am/log-ringbuf-bugs https://github.com/pracj3am/lua-nginx-module.git ../lua-nginx-module + - git clone https://github.com/openresty/lua-nginx-module.git ../lua-nginx-module - git clone https://github.com/openresty/no-pool-nginx.git ../no-pool-nginx - git clone https://github.com/openresty/echo-nginx-module.git ../echo-nginx-module - git clone https://github.com/openresty/lua-resty-lrucache.git From bb8b7f67ac7c2db2e6c2d383b54cceefcd3655ab Mon Sep 17 00:00:00 2001 From: "Yichun Zhang (agentzh)" Date: Sun, 9 Jul 2017 14:30:51 -0700 Subject: [PATCH 67/74] tests: consolidated a test case in the mockeagain writing test mode. --- t/errlog.t | 2 ++ 1 file changed, 2 insertions(+) diff --git a/t/errlog.t b/t/errlog.t index 392869ece..7ca770e04 100644 --- a/t/errlog.t +++ b/t/errlog.t @@ -1220,6 +1220,7 @@ aaa local res = errlog.get_logs(18) ngx.say("log lines: #", #res / 3) + ngx.flush(true) for i = 1, 18 do ngx.log(ngx.ERR, msg) @@ -1230,6 +1231,7 @@ aaa local res = errlog.get_logs() ngx.say("log lines: #", #res / 3) + ngx.flush(true) } } --- log_level: info From 931d3f41cf8a01cc0c0f7b63d1fdb83a4911cdda Mon Sep 17 00:00:00 2001 From: "Yichun Zhang (agentzh)" Date: Sun, 9 Jul 2017 14:35:05 -0700 Subject: [PATCH 68/74] a followup fix for the previous commit. --- t/errlog.t | 1 + 1 file changed, 1 insertion(+) diff --git a/t/errlog.t b/t/errlog.t index 7ca770e04..87fdd8f40 100644 --- a/t/errlog.t +++ b/t/errlog.t @@ -623,6 +623,7 @@ log level:4 log body:\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*access_by_lua\(nginx.conf:\d+\):\d+: --> 100, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" \z --- skip_nginx: 2: <1.11.2 +--- wait: 0.1 From 5e959d53ce3dc74dd795d3ca8656f6b42c7f3076 Mon Sep 17 00:00:00 2001 From: "Yichun Zhang (agentzh)" Date: Sun, 9 Jul 2017 15:21:44 -0700 Subject: [PATCH 69/74] tests: skipped a test case in check leak mode. --- t/balancer.t | 1 + 1 file changed, 1 insertion(+) diff --git a/t/balancer.t b/t/balancer.t index 511b0da4b..2399305bc 100644 --- a/t/balancer.t +++ b/t/balancer.t @@ -748,6 +748,7 @@ ok --- grep_error_log eval: qr{hello from balancer by lua!} --- grep_error_log_out hello from balancer by lua! +--- no_check_leak From add6d39282901c4ed5a5cb08e86fcfc6f65b8c5e Mon Sep 17 00:00:00 2001 From: spacewander Date: Sun, 9 Jul 2017 13:49:21 +0800 Subject: [PATCH 70/74] test: mark fractional part as optional to avoid unexpected failure. If the fractional part of a number is zero only, ngx.say will eliminate it. For example, the output of ngx.say(1499575361.0) is 1499575361. Signed-off-by: Yichun Zhang (agentzh) --- t/errlog.t | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/t/errlog.t b/t/errlog.t index 87fdd8f40..a2857dd13 100644 --- a/t/errlog.t +++ b/t/errlog.t @@ -1093,11 +1093,11 @@ GET /t --- response_body_like chomp \Alog lines: 2 log level: 3 -log time: \d+\.\d+ +log time: \d+(?:\.\d+)? log body: \d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[crit\] (\d+).*?access_by_lua\(nginx.conf:\d+\):\d+: enter 1, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" same with now: true log level: 4 -log time: \d{10}\.\d+ +log time: \d{10}(?:\.\d+)? log body: \d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*?access_by_lua\(nginx.conf:\d+\):\d+: enter 11, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" same with now: true --- grep_error_log eval @@ -1153,10 +1153,10 @@ enter 11 GET /t --- response_body_like chomp log level: 4 -log time: \d+\.\d+ +log time: \d+(?:\.\d+)? log body: \d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*?content_by_lua\(nginx.conf:\d+\):\d+: \*\*\*\*\*\*\*\*\*\*39, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" log level: 4 -log time: \d{10}\.\d+ +log time: \d{10}(?:\.\d+)? log body: \d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} \[error\] (\d+).*?content_by_lua\(nginx.conf:\d+\):\d+: \*\*\*\*\*\*\*\*\*\*40, client: 127.0.0.1, server: localhost, request: "GET /t HTTP/1.1", host: "localhost" --- skip_nginx: 2: <1.11.2 From 10c4d7db9056566de7ca4230638e5d13a82fd4c7 Mon Sep 17 00:00:00 2001 From: spacewander Date: Wed, 26 Jul 2017 12:17:03 +0800 Subject: [PATCH 71/74] misc: added templates for issue and pull request. Signed-off-by: Yichun Zhang (agentzh) --- .github/ISSUE_TEMPLATE.md | 27 +++++++++++++++++++++++++++ .github/PULL_REQUEST_TEMPLATE.md | 2 ++ 2 files changed, 29 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE.md create mode 100644 .github/PULL_REQUEST_TEMPLATE.md diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 000000000..22fd00e70 --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,27 @@ +This place is for bug reports and development discussions only. For general questions and +discussions, please join the openresty-en mailing list instead: https://groups.google.com/group/openresty-en. +If you want to use Chinese, please join the openresty (Chinese) mailing list instead: https://groups.google.com/group/openresty. +Do not use Chinese in this place. + +Before you open a new issue, please search the internet and make sure it is not duplicate. + +Ensure you have provided the following details while reporting a problem: + +- [ ] The exact version of the related software, including but not limited to the OpenResty version +(if any), the NGINX core version, the `ngx_lua` module version(via `openresty -V` or `nginx -V`), +and the `lua-resty-core` version(via `resty -e 'print(require("resty.core").version)'`), +and your operating system version(via `uname -a`). +- [ ] **A minimal and standalone test case** that others can easily run on their side and +reproduce the issue you are seeing. +- [ ] Do not simply say "something is broken" or "something does not work". Always provide +as much details as possible. Always describe **the symptoms and your expected results**. + +You can (temporarily) enable the nginx debugging logs to see the internal workings +of NGINX in your nginx''s `error.log` file. See http://nginx.org/en/docs/debugging_log.html +The same instructions apply equally well to OpenResty. + +If you are seeing crashes, please provide the full backtrace for the crash. See +https://www.nginx.com/resources/wiki/start/topics/tutorials/debugging/#core-dump +for more details. + +Thanks for your cooperation. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 000000000..9d3889429 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,2 @@ +I hereby granted the copyright of the changes in this pull request +to the authors of this lua-resty-core project. From 06c81cd7bb04031646575295c7fe1139b34240f7 Mon Sep 17 00:00:00 2001 From: Filip Slavik Date: Tue, 1 Aug 2017 20:32:03 +0300 Subject: [PATCH 72/74] doc: ngx.ssl: added performace notes for set_priv_key() and set_cert(). Signed-off-by: Yichun Zhang (agentzh) --- lib/ngx/ssl.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/ngx/ssl.md b/lib/ngx/ssl.md index c775a6d77..fc63c24e9 100644 --- a/lib/ngx/ssl.md +++ b/lib/ngx/ssl.md @@ -369,6 +369,10 @@ Sets the SSL certificate chain opaque pointer returned by the Returns `true` on success, or a `nil` value and a string describing the error otherwise. +Note that this `set_cert` function will run slightly faster, in terms of CPU cycles wasted, than the +[set_der_cert](#set_der_cert) variant, since the first function uses opaque cdata pointers +which do not require any additional conversion needed to be performed by the SSL library during the SSL handshake. + This function was first added in version `0.1.7`. [Back to TOC](#table-of-contents) @@ -384,6 +388,10 @@ Sets the SSL private key opaque pointer returned by the Returns `true` on success, or a `nil` value and a string describing the error otherwise. +Note that this `set_priv_key` function will run slightly faster, in terms of CPU cycles wasted, than the +[set_der_priv_key](#set_der_priv_key) variant, since the first function uses opaque cdata pointers +which do not require any additional conversion needed to be performed by the SSL library during the SSL handshake. + This function was first added in version `0.1.7`. [Back to TOC](#table-of-contents) From 3d1f097b5af5834e47373499c57641e3a516bb92 Mon Sep 17 00:00:00 2001 From: "Yichun Zhang (agentzh)" Date: Sat, 5 Aug 2017 17:23:12 -0700 Subject: [PATCH 73/74] tests: fixed a skip test count. --- t/balancer.t | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/t/balancer.t b/t/balancer.t index 2399305bc..4cde517c5 100644 --- a/t/balancer.t +++ b/t/balancer.t @@ -707,7 +707,7 @@ qr/\[error] .*? upstream prematurely closed connection while reading response he === TEST 16: https (keepalive) ---- skip_nginx: 4: < 1.7.5 +--- skip_nginx: 5: < 1.7.5 --- http_config lua_package_path "$TEST_NGINX_CWD/lib/?.lua;;"; From 47c22c0a3f0869f2e4ab1bb91dfb39b695aee9b6 Mon Sep 17 00:00:00 2001 From: "Yichun Zhang (agentzh)" Date: Tue, 8 Aug 2017 15:09:27 -0700 Subject: [PATCH 74/74] dist.ini: now we require ngx_lua >= 0.10.9. --- dist.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dist.ini b/dist.ini index 4534c1d46..5e8fe79f3 100644 --- a/dist.ini +++ b/dist.ini @@ -7,4 +7,4 @@ lib_dir=lib doc_dir=lib repo_link=https://github.com/openresty/lua-resty-core main_module=lib/resty/core/base.lua -requires = luajit >= 2.1.0, nginx >= 1.11.2, ngx_http_lua = 0.10.8, openresty/lua-resty-lrucache >= 0.06 +requires = luajit >= 2.1.0, nginx >= 1.11.2, ngx_http_lua = 0.10.9, openresty/lua-resty-lrucache >= 0.06