nginx: add patches to lua modules for experimental PCRE2 support
authorChristian Marangi <[email protected]>
Fri, 22 Sep 2023 12:44:44 +0000 (14:44 +0200)
committerChristian Marangi <[email protected]>
Fri, 22 Sep 2023 12:55:02 +0000 (14:55 +0200)
Add patches to lua modules for experimental PCRE2 support.

Signed-off-by: Christian Marangi <[email protected]>
net/nginx/patches/nginx-mod-lua-resty-core/001-feature_support_pcre2.patch [new file with mode: 0644]
net/nginx/patches/nginx-mod-lua/001-feature_support_pcre2.patch [new file with mode: 0644]
net/nginx/patches/nginx-mod-lua/100-no_by_lua_block.patch

diff --git a/net/nginx/patches/nginx-mod-lua-resty-core/001-feature_support_pcre2.patch b/net/nginx/patches/nginx-mod-lua-resty-core/001-feature_support_pcre2.patch
new file mode 100644 (file)
index 0000000..a6b1c58
--- /dev/null
@@ -0,0 +1,389 @@
+From f72675beb5835b4ac31d7476de1580be767209d8 Mon Sep 17 00:00:00 2001
+From: swananan <[email protected]>
+Date: Thu, 31 Aug 2023 00:12:07 +0800
+Subject: [PATCH] feature: support pcre2
+
+---
+ .travis.yml              | 26 +++++++++++++-----------
+ lib/resty/core/regex.lua | 43 ++++++++++++++++++++++++++++++----------
+ t/re-base.t              | 25 +++++++++++++++++------
+ t/re-gmatch.t            | 10 +++++++---
+ t/re-match.t             |  7 +++++--
+ t/re-opt.t               |  9 +++++++--
+ t/stream/re-base.t       | 27 +++++++++++++++++++------
+ t/stream/re-gmatch.t     | 10 +++++++---
+ t/stream/re-match.t      |  7 +++++--
+ t/stream/re-opt.t        |  9 +++++++--
+ 10 files changed, 125 insertions(+), 48 deletions(-)
+
+--- a/nginx-mod-lua-resty-core/.travis.yml
++++ b/nginx-mod-lua-resty-core/.travis.yml
+@@ -34,9 +34,13 @@ env:
+     - LUA_INCLUDE_DIR=$LUAJIT_INC
+     - LUA_CMODULE_DIR=/lib
+     - PCRE_VER=8.45
++    - PCRE2_VER=10.37
+     - PCRE_PREFIX=/opt/pcre
++    - PCRE2_PREFIX=/opt/pcre2
+     - PCRE_LIB=$PCRE_PREFIX/lib
++    - PCRE2_LIB=$PCRE2_PREFIX/lib
+     - PCRE_INC=$PCRE_PREFIX/include
++    - PCRE2_INC=$PCRE2_PREFIX/include
+     - OPENSSL_PREFIX=/opt/ssl
+     - OPENSSL_LIB=$OPENSSL_PREFIX/lib
+     - OPENSSL_INC=$OPENSSL_PREFIX/include
+@@ -45,7 +49,7 @@ env:
+     - TEST_NGINX_RANDOMIZE=1
+     - LUACHECK_VER=0.21.1
+   matrix:
+-    - NGINX_VERSION=1.25.1 OPENSSL_VER=1.1.1u OPENSSL_PATCH_VER=1.1.1f
++    - NGINX_VERSION=1.25.1 OPENSSL_VER=1.1.1u OPENSSL_PATCH_VER=1.1.1f USE_PCRE2=Y
+     - NGINX_VERSION=1.21.4 OPENSSL_VER=1.1.1u OPENSSL_PATCH_VER=1.1.1f
+ services:
+@@ -61,11 +65,12 @@ before_install:
+ install:
+   - if [ ! -d download-cache ]; then mkdir download-cache; fi
+   - if [ ! -f download-cache/openssl-$OPENSSL_VER.tar.gz ]; then wget -P download-cache https://www.openssl.org/source/openssl-$OPENSSL_VER.tar.gz || wget -P download-cache https://www.openssl.org/source/old/${OPENSSL_VER//[a-z]/}/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
++  - if [ "$USE_PCRE2" != "Y" ] && [ ! -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
++  - if [ "$USE_PCRE2" = "Y" ] && [ ! -f download-cache/pcre2-$PCRE2_VER.tar.gz ]; then wget -P download-cache https://downloads.sourceforge.net/project/pcre/pcre2/${PCRE2_VER}/pcre2-${PCRE2_VER}.tar.gz; fi
+   - 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 https://github.com/swananan/lua-nginx-module.git -b support_pcre2 ../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
+@@ -73,8 +78,8 @@ install:
+   - git clone -b v2.1-agentzh https://github.com/openresty/luajit2.git luajit2
+   - git clone https://github.com/openresty/set-misc-nginx-module.git ../set-misc-nginx-module
+   - git clone https://github.com/openresty/mockeagain.git
+-  - git clone https://github.com/openresty/test-nginx.git
+-  - git clone https://github.com/openresty/stream-lua-nginx-module.git ../stream-lua-nginx-module
++  - git clone https://github.com/swananan/test-nginx.git -b support_pcre2
++  - git clone https://github.com/swananan/stream-lua-nginx-module.git -b support_pcre2 ../stream-lua-nginx-module
+ script:
+   - cd luajit2/
+@@ -89,12 +94,8 @@ 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
+-  - cd pcre-$PCRE_VER/
+-  - ./configure --prefix=$PCRE_PREFIX --enable-jit --enable-utf --enable-unicode-properties > build.log 2>&1 || (cat build.log && exit 1)
+-  - make -j$JOBS > build.log 2>&1 || (cat build.log && exit 1)
+-  - sudo PATH=$PATH make install > build.log 2>&1 || (cat build.log && exit 1)
+-  - cd ..
++  - if [ "$USE_PCRE2" != "Y" ]; then tar zxf download-cache/pcre-$PCRE_VER.tar.gz; cd pcre-$PCRE_VER/; ./configure --prefix=$PCRE_PREFIX --enable-jit --enable-utf --enable-unicode-properties > build.log 2>&1 || (cat build.log && exit 1); make -j$JOBS > build.log 2>&1 || (cat build.log && exit 1); sudo PATH=$PATH make install > build.log 2>&1 || (cat build.log && exit 1); cd ..; fi
++  - if [ "$USE_PCRE2" = "Y" ]; then tar zxf download-cache/pcre2-$PCRE2_VER.tar.gz; cd pcre2-$PCRE2_VER/; ./configure --prefix=$PCRE2_PREFIX --enable-jit --enable-utf > build.log 2>&1 || (cat build.log && exit 1); make -j$JOBS > build.log 2>&1 || (cat build.log && exit 1); sudo PATH=$PATH make install > build.log 2>&1 || (cat build.log && exit 1); cd ..; fi
+   - 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
+@@ -104,7 +105,8 @@ script:
+   - export disable_pcre2=--without-pcre2
+   - answer=`util/ver-ge "$NGINX_VERSION" 1.25.1`
+   - if [ "$OPENSSL_VER" = "1.1.0l" ] || [ "$answer" = "N" ]; then add_http3_module=""; fi
+-  - if [ "$answer" = "N" ]; then disable_pcre2=""; fi
++  - if [ "$answer" = "N" ] || [ "$USE_PCRE2" = "Y" ]; then disable_pcre2=""; fi
++  - if [ "$USE_PCRE2" = "Y" ]; then PCRE_INC=$PCRE2_INC; PCRE_LIB=$PCRE2_LIB; fi
+   - ngx-build $NGINX_VERSION --with-ipv6 $disable_pcre2 $add_http3_module --with-http_realip_module --with-http_ssl_module --with-pcre-jit --with-cc-opt="-I$OPENSSL_INC -I$PCRE_INC" --with-ld-opt="-L$OPENSSL_LIB -Wl,-rpath,$OPENSSL_LIB -L$PCRE_LIB -Wl,-rpath,$PCRE_LIB" --add-module=../ndk-nginx-module --add-module=../echo-nginx-module --add-module=../set-misc-nginx-module --add-module=../headers-more-nginx-module --add-module=../lua-nginx-module --with-debug --with-stream_ssl_module --with-stream --with-ipv6 --add-module=../stream-lua-nginx-module > build.log 2>&1 || (cat build.log && exit 1)
+   - nginx -V
+   - ldd `which nginx`|grep -E 'luajit|ssl|pcre'
+--- a/nginx-mod-lua-resty-core/lib/resty/core/regex.lua
++++ b/nginx-mod-lua-resty-core/lib/resty/core/regex.lua
+@@ -82,7 +82,7 @@ if not pcall(function() pcre_ver = ffi_s
+ end
+-local MAX_ERR_MSG_LEN = 128
++local MAX_ERR_MSG_LEN = 256
+ local FLAG_COMPILE_ONCE  = 0x01
+@@ -102,6 +102,7 @@ local PCRE_DUPNAMES          = 0x0080000
+ local PCRE_JAVASCRIPT_COMPAT = 0x2000000
++-- PCRE2_ERROR_NOMATCH uses the same value
+ local PCRE_ERROR_NOMATCH = -1
+@@ -135,22 +136,44 @@ local ngx_lua_ffi_script_eval_data
+ -- TODO: improve this workaround when PCRE allows for unspecifying the MAP_JIT
+ -- option.
+ local no_jit_in_init
++local pcre_ver_num
+-if jit.os == "OSX" then
+-    local maj, min = string.match(pcre_ver, "^(%d+)%.(%d+)")
+-    if maj and min then
+-        local pcre_ver_num = tonumber(maj .. min)
+-
+-        if pcre_ver_num >= 843 then
+-            no_jit_in_init = true
+-        end
++local maj, min = string.match(pcre_ver, "^(%d+)%.(%d+)")
++if maj and min then
++    pcre_ver_num = tonumber(maj .. min)
++end
+-    else
++if jit.os == "OSX" then
++    if pcre_ver_num == nil then
+         -- assume this version is faulty as well
+         no_jit_in_init = true
++
++    -- PCRE2 is also subject to this issue on macOS
++    elseif pcre_ver_num >= 843 then
++        no_jit_in_init = true
+     end
+ end
++-- pcre2
++if pcre_ver_num > 845 then
++    -- option
++    PCRE_CASELESS          = 0x00000008
++    PCRE_MULTILINE         = 0x00000400
++    PCRE_DOTALL            = 0x00000020
++    PCRE_EXTENDED          = 0x00000080
++    PCRE_ANCHORED          = 0x80000000
++    PCRE_UTF8              = 0x00080000
++    PCRE_DUPNAMES          = 0x00000040
++    -- In the pcre2, The PCRE_JAVASCRIPT_COMPAT option has been split into
++    -- independent functional options PCRE2_ALT_BSUX, PCRE2_ALLOW_EMPTY_CLASS,
++    -- and PCRE2_MATCH_UNSET_BACKREF.
++    local PCRE2_ALT_BSUX            = 0x00000002
++    local PCRE2_ALLOW_EMPTY_CLASS   = 0x00000001
++    local PCRE2_MATCH_UNSET_BACKREF = 0x00000200
++    PCRE_JAVASCRIPT_COMPAT = bor(PCRE2_ALT_BSUX, PCRE2_ALLOW_EMPTY_CLASS)
++    PCRE_JAVASCRIPT_COMPAT = bor(PCRE2_MATCH_UNSET_BACKREF,
++                                 PCRE_JAVASCRIPT_COMPAT)
++end
+ if subsystem == 'http' then
+     ffi.cdef[[
+--- a/nginx-mod-lua-resty-core/t/re-base.t
++++ b/nginx-mod-lua-resty-core/t/re-base.t
+@@ -26,8 +26,11 @@ __DATA__
+     }
+ --- request
+     GET /re
+---- response_body
+-error: pcre_compile() failed: missing ) in "(abc"
++--- response_body eval
++$Test::Nginx::Util::PcreVersion == 2 ?
++"error: pcre2_compile() failed: missing closing parenthesis in \"(abc\"\n"
++:
++"error: pcre_compile() failed: missing ) in \"(abc\"\n"
+ --- no_error_log
+ [error]
+@@ -63,8 +66,11 @@ error: pcre_compile() failed: missing )
+     }
+ --- request
+ GET /t
+---- response_body_like chop
+-error: pcre_exec\(\) failed: -10
++--- response_body eval
++$Test::Nginx::Util::PcreVersion == 2 ?
++"error: pcre_exec\(\) failed: -4\n"
++:
++"error: pcre_exec\(\) failed: -10\n"
+ --- no_error_log
+ [error]
+@@ -128,6 +134,7 @@ probe process("$LIBPCRE_PATH").function(
+     printf("exec opts: %x\n", $options)
+ }
++# TODO: PCRE2 use different option values from PCRE
+ --- stap_out
+ compile opts: 800
+ exec opts: 0
+@@ -172,8 +179,14 @@ end
+ --- request
+     GET /re
+---- response_body
+-error: pcre_exec() failed: -8
++--- response_body eval
++# lua_regex_match_limit uses pcre_extra->match_limit in the PCRE,
++# but PCRE2 replaces this with pcre2_set_match_limit interface,
++# which has different effects.
++$Test::Nginx::Util::PcreVersion == 2 ?
++"failed to match\n"
++:
++"error: pcre_exec() failed: -8\n"
+--- a/nginx-mod-lua-resty-core/t/re-gmatch.t
++++ b/nginx-mod-lua-resty-core/t/re-gmatch.t
+@@ -446,9 +446,13 @@ matched: nil
+     }
+ --- request
+ GET /re
+---- response_body
+-error: pcre_exec() failed: -10
+-not matched
++--- response_body eval
++# PCRE2_ERROR_UTF8_ERR2 (-4)
++# PCRE_ERROR_BADUTF8 (-10)
++$Test::Nginx::Util::PcreVersion == 2 ?
++"error: pcre_exec\(\) failed: -4\nnot matched\n"
++:
++"error: pcre_exec\(\) failed: -10\nnot matched\n"
+ --- no_error_log
+ [error]
+--- a/nginx-mod-lua-resty-core/t/re-match.t
++++ b/nginx-mod-lua-resty-core/t/re-match.t
+@@ -306,8 +306,11 @@ NYI
+     }
+ --- request
+     GET /re
+---- response_body_like chop
+-error: pcre_compile\(\) failed: two named subpatterns have the same name
++--- response_body eval
++$Test::Nginx::Util::PcreVersion == 2 ?
++"error: pcre2_compile\(\) failed: two named subpatterns have the same name \(PCRE2_DUPNAMES not set\) in \"\(\?<first>[a-z])\(\?<first>[a-z]+\), [0-9]+\" at \"[a-z]+\), [0-9]+\"\n"
++:
++"error: pcre_compile\(\) failed: two named subpatterns have the same name in \"\(\?<first>[a-z])\(\?<first>[a-z]+\), [0-9]+\" at \">[a-z]+\), [0-9]+\"\n"
+ --- error_log eval
+ qr/\[TRACE\s+\d+/
+--- a/nginx-mod-lua-resty-core/t/re-opt.t
++++ b/nginx-mod-lua-resty-core/t/re-opt.t
+@@ -39,8 +39,13 @@ __DATA__
+     }
+ --- request
+     GET /re
+---- response_body
+-error: pcre_exec() failed: -27
++--- response_body eval
++# PCRE2_ERROR_JIT_STACKLIMIT (-46)
++# PCRE_ERROR_JIT_STACKLIMIT  (-27)
++$Test::Nginx::Util::PcreVersion == 2 ?
++"error: pcre_exec\(\) failed: -46\n"
++:
++"error: pcre_exec\(\) failed: -27\n"
+ --- no_error_log
+ [error]
+ --- timeout: 10
+--- a/nginx-mod-lua-resty-core/t/stream/re-base.t
++++ b/nginx-mod-lua-resty-core/t/stream/re-base.t
+@@ -22,8 +22,11 @@ __DATA__
+             ngx.say("error: ", err)
+         end
+     }
+---- stream_response
+-error: pcre_compile() failed: missing ) in "(abc"
++--- stream_response eval
++$Test::Nginx::Util::PcreVersion == 2 ?
++"error: pcre2_compile() failed: missing closing parenthesis in \"(abc\"\n"
++:
++"error: pcre_compile() failed: missing ) in \"(abc\"\n"
+ --- no_error_log
+ [error]
+@@ -55,12 +58,17 @@ error: pcre_compile() failed: missing )
+             ngx.say("not matched")
+         end
+     }
+---- stream_response_like chop
+-error: pcre_exec\(\) failed: -10
++--- stream_response eval
++$Test::Nginx::Util::PcreVersion == 2 ?
++"error: pcre_exec\(\) failed: -4\n"
++:
++"error: pcre_exec\(\) failed: -10\n"
+ --- no_error_log
+ [error]
++--- ONLY
++
+ === TEST 3: UTF-8 mode without UTF-8 sequence checks
+@@ -114,6 +122,7 @@ probe process("$LIBPCRE_PATH").function(
+     printf("exec opts: %x\n", $options)
+ }
++# TODO: PCRE2 use different option values from PCRE
+ --- stap_out
+ compile opts: 800
+ exec opts: 0
+@@ -152,8 +161,14 @@ if not res then
+     return
+ end
+---- stream_response
+-error: pcre_exec() failed: -8
++--- stream_response eval
++# lua_regex_match_limit uses pcre_extra->match_limit in the PCRE,
++# but PCRE2 replaces this with pcre2_set_match_limit interface,
++# which has different effects.
++$Test::Nginx::Util::PcreVersion == 2 ?
++"failed to match\n"
++:
++"error: pcre_exec() failed: -8\n"
+--- a/nginx-mod-lua-resty-core/t/stream/re-gmatch.t
++++ b/nginx-mod-lua-resty-core/t/stream/re-gmatch.t
+@@ -394,9 +394,13 @@ matched: nil
+             ngx.say("not matched")
+         end
+     }
+---- stream_response
+-error: pcre_exec() failed: -10
+-not matched
++--- stream_response eval
++# PCRE2_ERROR_UTF8_ERR2 (-4)
++# PCRE_ERROR_BADUTF8 (-10)
++$Test::Nginx::Util::PcreVersion == 2 ?
++"error: pcre_exec\(\) failed: -4\nnot matched\n"
++:
++"error: pcre_exec\(\) failed: -10\nnot matched\n"
+ --- no_error_log
+ [error]
+--- a/nginx-mod-lua-resty-core/t/stream/re-match.t
++++ b/nginx-mod-lua-resty-core/t/stream/re-match.t
+@@ -268,8 +268,11 @@ NYI
+             ngx.say("not matched!")
+         end
+     }
+---- stream_response_like chop
+-error: pcre_compile\(\) failed: two named subpatterns have the same name
++--- stream_response eval
++$Test::Nginx::Util::PcreVersion == 2 ?
++"error: pcre2_compile\(\) failed: two named subpatterns have the same name \(PCRE2_DUPNAMES not set\) in \"\(\?<first>[a-z])\(\?<first>[a-z]+\), [0-9]+\" at \"[a-z]+\), [0-9]+\"\n"
++:
++"error: pcre_compile\(\) failed: two named subpatterns have the same name in \"\(\?<first>[a-z])\(\?<first>[a-z]+\), [0-9]+\" at \">[a-z]+\), [0-9]+\"\n"
+ --- error_log eval
+ qr/\[TRACE\s+\d+/
+--- a/nginx-mod-lua-resty-core/t/stream/re-opt.t
++++ b/nginx-mod-lua-resty-core/t/stream/re-opt.t
+@@ -36,8 +36,13 @@ __DATA__
+             ngx.say("not matched!")
+         end
+     }
+---- stream_response
+-error: pcre_exec() failed: -27
++--- stream_response eval
++# PCRE2_ERROR_JIT_STACKLIMIT (-46)
++# PCRE_ERROR_JIT_STACKLIMIT  (-27)
++$Test::Nginx::Util::PcreVersion == 2 ?
++"error: pcre_exec\(\) failed: -46\n"
++:
++"error: pcre_exec\(\) failed: -27\n"
+ --- no_error_log
+ [error]
+ --- timeout: 10
diff --git a/net/nginx/patches/nginx-mod-lua/001-feature_support_pcre2.patch b/net/nginx/patches/nginx-mod-lua/001-feature_support_pcre2.patch
new file mode 100644 (file)
index 0000000..b789984
--- /dev/null
@@ -0,0 +1,2009 @@
+From 26b48c5a9d1b35990064ddcd686f587c663b6048 Mon Sep 17 00:00:00 2001
+From: swananan <[email protected]>
+Date: Tue, 5 Sep 2023 18:42:20 +0800
+Subject: [PATCH 1/4] feature: support pcre2
+
+---
+ .travis.yml                |  23 +-
+ src/ngx_http_lua_common.h  |  10 +-
+ src/ngx_http_lua_module.c  |  14 +
+ src/ngx_http_lua_pcrefix.c |  89 +++++-
+ src/ngx_http_lua_pcrefix.h |   9 +-
+ src/ngx_http_lua_regex.c   | 538 +++++++++++++++++++++++++++++++------
+ t/028-req-header.t         |   1 -
+ t/034-match.t              |  32 ++-
+ t/035-gmatch.t             |  24 +-
+ t/036-sub.t                |  24 +-
+ t/037-gsub.t               |  17 +-
+ t/038-match-o.t            |   7 +-
+ t/047-match-jit.t          |  18 +-
+ t/049-gmatch-jit.t         |   7 +-
+ t/050-gmatch-dfa.t         |   7 +-
+ t/051-sub-jit.t            |  14 +-
+ t/052-sub-dfa.t            |  14 +-
+ t/053-gsub-jit.t           |  14 +-
+ t/054-gsub-dfa.t           |  14 +-
+ t/120-re-find.t            |  25 +-
+ util/build-with-dd.sh      |   6 +-
+ util/build-without-ssl.sh  |   6 +-
+ util/build.sh              |   6 +-
+ 23 files changed, 764 insertions(+), 155 deletions(-)
+
+--- a/nginx-mod-lua/.travis.yml
++++ b/nginx-mod-lua/.travis.yml
+@@ -38,9 +38,13 @@ env:
+     - LUAJIT_INC=$LUAJIT_PREFIX/include/luajit-2.1
+     - LUA_INCLUDE_DIR=$LUAJIT_INC
+     - PCRE_VER=8.45
++    - PCRE2_VER=10.37
+     - PCRE_PREFIX=/opt/pcre
++    - PCRE2_PREFIX=/opt/pcre2
+     - PCRE_LIB=$PCRE_PREFIX/lib
++    - PCRE2_LIB=$PCRE2_PREFIX/lib
+     - PCRE_INC=$PCRE_PREFIX/include
++    - PCRE2_INC=$PCRE2_PREFIX/include
+     - OPENSSL_PREFIX=/opt/ssl
+     - OPENSSL_LIB=$OPENSSL_PREFIX/lib
+     - OPENSSL_INC=$OPENSSL_PREFIX/include
+@@ -55,7 +59,7 @@ env:
+     - NGINX_VERSION=1.21.4 OPENSSL_VER=1.1.0l OPENSSL_PATCH_VER=1.1.0d
+     - NGINX_VERSION=1.21.4 OPENSSL_VER=1.1.1s OPENSSL_PATCH_VER=1.1.1f
+     - NGINX_VERSION=1.25.1 OPENSSL_VER=1.1.0l OPENSSL_PATCH_VER=1.1.0d
+-    - NGINX_VERSION=1.25.1 OPENSSL_VER=1.1.1s OPENSSL_PATCH_VER=1.1.1f
++    - NGINX_VERSION=1.25.1 OPENSSL_VER=1.1.1s OPENSSL_PATCH_VER=1.1.1f USE_PCRE2=Y
+ services:
+   - memcached
+@@ -71,9 +75,10 @@ before_install:
+   - pyenv global 2.7
+ install:
+   - if [ ! -f download-cache/drizzle7-$DRIZZLE_VER.tar.gz ]; then wget -P download-cache http://openresty.org/download/drizzle7-$DRIZZLE_VER.tar.gz; fi
+-  - if [ ! -f download-cache/pcre-$PCRE_VER.tar.gz ]; then wget -P download-cache https://downloads.sourceforge.net/project/pcre/pcre/${PCRE_VER}/pcre-${PCRE_VER}.tar.gz; fi
++  - if [ "$USE_PCRE2" != "Y" ] && [ ! -f download-cache/pcre-$PCRE_VER.tar.gz ]; then wget -P download-cache https://downloads.sourceforge.net/project/pcre/pcre/${PCRE_VER}/pcre-${PCRE_VER}.tar.gz; fi
++  - if [ "$USE_PCRE2" = "Y" ] && [ ! -f download-cache/pcre2-$PCRE2_VER.tar.gz ]; then wget -P download-cache https://downloads.sourceforge.net/project/pcre/pcre2/${PCRE2_VER}/pcre2-${PCRE2_VER}.tar.gz; fi
+   - if [ ! -f download-cache/openssl-$OPENSSL_VER.tar.gz ]; then wget -P download-cache https://www.openssl.org/source/openssl-$OPENSSL_VER.tar.gz || wget -P download-cache https://www.openssl.org/source/old/${OPENSSL_VER//[a-z]/}/openssl-$OPENSSL_VER.tar.gz; fi
+-  - git clone https://github.com/openresty/test-nginx.git
++  - git clone https://github.com/swananan/test-nginx.git -b support_pcre2
+   - git clone https://github.com/openresty/openresty.git ../openresty
+   - git clone https://github.com/openresty/no-pool-nginx.git ../no-pool-nginx
+   - git clone https://github.com/openresty/openresty-devel-utils.git
+@@ -91,12 +96,12 @@ install:
+   - git clone https://github.com/openresty/rds-json-nginx-module.git ../rds-json-nginx-module
+   - git clone https://github.com/openresty/srcache-nginx-module.git ../srcache-nginx-module
+   - git clone https://github.com/openresty/redis2-nginx-module.git ../redis2-nginx-module
+-  - git clone https://github.com/openresty/lua-resty-core.git ../lua-resty-core
++  - git clone https://github.com/swananan/lua-resty-core.git -b support_pcre2 ../lua-resty-core
+   - git clone https://github.com/openresty/lua-resty-lrucache.git ../lua-resty-lrucache
+   - git clone https://github.com/openresty/lua-resty-mysql.git ../lua-resty-mysql
+   - git clone https://github.com/spacewander/lua-resty-rsa.git ../lua-resty-rsa
+   - git clone https://github.com/openresty/lua-resty-string.git ../lua-resty-string
+-  - git clone https://github.com/openresty/stream-lua-nginx-module.git ../stream-lua-nginx-module
++  - git clone https://github.com/swananan/stream-lua-nginx-module.git -b support_pcre2 ../stream-lua-nginx-module
+   - git clone -b v2.1-agentzh https://github.com/openresty/luajit2.git luajit2
+ before_script:
+@@ -121,12 +126,8 @@ script:
+   - sudo make install-libdrizzle-1.0 > build.log 2>&1 || (cat build.log && exit 1)
+   - cd ../mockeagain/ && make CC=$CC -j$JOBS && cd ..
+   - cd lua-cjson/ && make -j$JOBS && sudo make install && cd ..
+-  - tar zxf download-cache/pcre-$PCRE_VER.tar.gz
+-  - cd pcre-$PCRE_VER/
+-  - ./configure --prefix=$PCRE_PREFIX --enable-jit --enable-utf --enable-unicode-properties > build.log 2>&1 || (cat build.log && exit 1)
+-  - make -j$JOBS > build.log 2>&1 || (cat build.log && exit 1)
+-  - sudo PATH=$PATH make install > build.log 2>&1 || (cat build.log && exit 1)
+-  - cd ..
++  - if [ "$USE_PCRE2" != "Y" ]; then tar zxf download-cache/pcre-$PCRE_VER.tar.gz; cd pcre-$PCRE_VER/; ./configure --prefix=$PCRE_PREFIX --enable-jit --enable-utf --enable-unicode-properties > build.log 2>&1 || (cat build.log && exit 1); make -j$JOBS > build.log 2>&1 || (cat build.log && exit 1); sudo PATH=$PATH make install > build.log 2>&1 || (cat build.log && exit 1); cd ..; fi
++  - if [ "$USE_PCRE2" = "Y" ]; then tar zxf download-cache/pcre2-$PCRE2_VER.tar.gz; cd pcre2-$PCRE2_VER/; ./configure --prefix=$PCRE2_PREFIX --enable-jit --enable-utf > build.log 2>&1 || (cat build.log && exit 1); make -j$JOBS > build.log 2>&1 || (cat build.log && exit 1); sudo PATH=$PATH make install > build.log 2>&1 || (cat build.log && exit 1); cd ..; fi
+   - tar zxf download-cache/openssl-$OPENSSL_VER.tar.gz
+   - cd openssl-$OPENSSL_VER/
+   - patch -p1 < ../../openresty/patches/openssl-$OPENSSL_PATCH_VER-sess_set_get_cb_yield.patch
+--- a/nginx-mod-lua/src/ngx_http_lua_common.h
++++ b/nginx-mod-lua/src/ngx_http_lua_common.h
+@@ -63,6 +63,10 @@ typedef struct {
+ #   endif
+ #endif
++#if (NGX_PCRE2)
++#   define LUA_HAVE_PCRE_JIT 1
++#endif
++
+ #if (nginx_version < 1006000)
+ #   error at least nginx 1.6.0 is required but found an older version
+@@ -217,11 +221,13 @@ struct ngx_http_lua_main_conf_s {
+     ngx_hash_t           builtin_headers_out;
+-#if (NGX_PCRE)
++#if (NGX_PCRE || NGX_PCRE2)
+     ngx_int_t            regex_cache_entries;
+     ngx_int_t            regex_cache_max_entries;
+     ngx_int_t            regex_match_limit;
+-#   if (LUA_HAVE_PCRE_JIT)
++#if (NGX_PCRE2)
++    pcre2_jit_stack     *jit_stack;
++#elif (LUA_HAVE_PCRE_JIT)
+     pcre_jit_stack      *jit_stack;
+ #   endif
+ #endif
+--- a/nginx-mod-lua/src/ngx_http_lua_module.c
++++ b/nginx-mod-lua/src/ngx_http_lua_module.c
+@@ -59,6 +59,9 @@ static char *ngx_http_lua_ssl_conf_comma
+ #endif
+ static char *ngx_http_lua_malloc_trim(ngx_conf_t *cf, ngx_command_t *cmd,
+     void *conf);
++#if (NGX_PCRE2)
++extern void ngx_http_lua_regex_cleanup(void *data);
++#endif
+ static ngx_conf_post_t  ngx_http_lua_lowat_post =
+@@ -855,6 +858,17 @@ ngx_http_lua_init(ngx_conf_t *cf)
+     cln->data = lmcf;
+     cln->handler = ngx_http_lua_sema_mm_cleanup;
++#if (NGX_PCRE2)
++    /* add the cleanup of pcre2 regex */
++    cln = ngx_pool_cleanup_add(cf->pool, 0);
++    if (cln == NULL) {
++        return NGX_ERROR;
++    }
++
++    cln->data = lmcf;
++    cln->handler = ngx_http_lua_regex_cleanup;
++#endif
++
+ #ifdef HAVE_NGX_LUA_PIPE
+     ngx_http_lua_pipe_init();
+ #endif
+--- a/nginx-mod-lua/src/ngx_http_lua_pcrefix.c
++++ b/nginx-mod-lua/src/ngx_http_lua_pcrefix.c
+@@ -14,19 +14,65 @@
+ #include "ngx_http_lua_pcrefix.h"
+ #include "stdio.h"
+-#if (NGX_PCRE)
++#if (NGX_PCRE || NGX_PCRE2)
+ static ngx_pool_t *ngx_http_lua_pcre_pool = NULL;
++
++#if (NGX_PCRE2)
++static ngx_uint_t  ngx_regex_direct_alloc;
++#else
+ static void *(*old_pcre_malloc)(size_t);
+ static void (*old_pcre_free)(void *ptr);
++#endif
+ /* XXX: work-around to nginx regex subsystem, must init a memory pool
+  * to use PCRE functions. As PCRE still has memory-leaking problems,
+  * and nginx overwrote pcre_malloc/free hooks with its own static
+  * functions, so nobody else can reuse nginx regex subsystem... */
+-static void *
++#if (NGX_PCRE2)
++
++void *
++ngx_http_lua_pcre_malloc(size_t size, void *data)
++{
++    dd("lua pcre pool is %p", ngx_http_lua_pcre_pool);
++
++    if (ngx_http_lua_pcre_pool) {
++        return ngx_palloc(ngx_http_lua_pcre_pool, size);
++    }
++
++    if (ngx_regex_direct_alloc) {
++        return ngx_alloc(size, ngx_cycle->log);
++    }
++
++    fprintf(stderr, "error: lua pcre malloc failed due to empty pcre pool");
++
++    return NULL;
++}
++
++
++void
++ngx_http_lua_pcre_free(void *ptr, void *data)
++{
++    dd("lua pcre pool is %p", ngx_http_lua_pcre_pool);
++
++    if (ngx_http_lua_pcre_pool) {
++        ngx_pfree(ngx_http_lua_pcre_pool, ptr);
++        return;
++    }
++
++    if (ngx_regex_direct_alloc) {
++        ngx_free(ptr);
++        return;
++    }
++
++    fprintf(stderr, "error: lua pcre free failed due to empty pcre pool");
++}
++
++#else
++
++void *
+ ngx_http_lua_pcre_malloc(size_t size)
+ {
+     dd("lua pcre pool is %p", ngx_http_lua_pcre_pool);
+@@ -54,6 +100,41 @@ ngx_http_lua_pcre_free(void *ptr)
+     fprintf(stderr, "error: lua pcre free failed due to empty pcre pool");
+ }
++#endif
++
++
++#if (NGX_PCRE2)
++
++ngx_pool_t *
++ngx_http_lua_pcre_malloc_init(ngx_pool_t *pool)
++{
++    ngx_pool_t          *old_pool;
++
++    dd("lua pcre pool was %p", ngx_http_lua_pcre_pool);
++
++    ngx_regex_direct_alloc = (pool == NULL) ? 1 : 0;
++
++    old_pool = ngx_http_lua_pcre_pool;
++    ngx_http_lua_pcre_pool = pool;
++
++    dd("lua pcre pool is %p", ngx_http_lua_pcre_pool);
++
++    return old_pool;
++}
++
++
++void
++ngx_http_lua_pcre_malloc_done(ngx_pool_t *old_pool)
++{
++    dd("lua pcre pool was %p", ngx_http_lua_pcre_pool);
++
++    ngx_http_lua_pcre_pool = old_pool;
++    ngx_regex_direct_alloc = 0;
++
++    dd("lua pcre pool is %p", ngx_http_lua_pcre_pool);
++}
++
++#else
+ ngx_pool_t *
+ ngx_http_lua_pcre_malloc_init(ngx_pool_t *pool)
+@@ -101,6 +182,7 @@ ngx_http_lua_pcre_malloc_done(ngx_pool_t
+     }
+ }
+-#endif /* NGX_PCRE */
++#endif
++#endif /* NGX_PCRE || NGX_PCRE2 */
+ /* vi:set ft=c ts=4 sw=4 et fdm=marker: */
+--- a/nginx-mod-lua/src/ngx_http_lua_pcrefix.h
++++ b/nginx-mod-lua/src/ngx_http_lua_pcrefix.h
+@@ -12,9 +12,16 @@
+ #include "ngx_http_lua_common.h"
+-#if (NGX_PCRE)
++#if (NGX_PCRE || NGX_PCRE2)
++
+ ngx_pool_t *ngx_http_lua_pcre_malloc_init(ngx_pool_t *pool);
+ void ngx_http_lua_pcre_malloc_done(ngx_pool_t *old_pool);
++
++#if NGX_PCRE2
++void *ngx_http_lua_pcre_malloc(size_t size, void *data);
++void ngx_http_lua_pcre_free(void *ptr, void *data);
++#endif
++
+ #endif
+--- a/nginx-mod-lua/src/ngx_http_lua_regex.c
++++ b/nginx-mod-lua/src/ngx_http_lua_regex.c
+@@ -9,21 +9,31 @@
+ #endif
+ #include "ddebug.h"
+-
+-#if (NGX_PCRE)
++#if (NGX_PCRE || NGX_PCRE2)
+ #include "ngx_http_lua_pcrefix.h"
+ #include "ngx_http_lua_script.h"
+ #include "ngx_http_lua_util.h"
+-#if (PCRE_MAJOR >= 6)
++#if (PCRE_MAJOR >= 6 || NGX_PCRE2)
+ #   define LUA_HAVE_PCRE_DFA 1
+ #else
+ #   define LUA_HAVE_PCRE_DFA 0
+ #endif
++#if (NGX_PCRE2)
++static pcre2_compile_context  *ngx_regex_compile_context;
++static pcre2_match_context    *ngx_regex_match_context;
++static pcre2_match_data       *ngx_regex_match_data;
++static ngx_uint_t              ngx_regex_match_data_size = 0;
++
++#define PCRE2_VERSION_SIZE     64
++static char                    ngx_pcre2_version[PCRE2_VERSION_SIZE];
++#endif
++
++
+ #define NGX_LUA_RE_MODE_DFA          (1<<1)
+ #define NGX_LUA_RE_MODE_JIT          (1<<2)
+ #define NGX_LUA_RE_NO_UTF8_CHECK     (1<<4)
+@@ -42,8 +52,17 @@ typedef struct {
+     int                           ncaptures;
+     int                          *captures;
++#if (NGX_PCRE2)
++    pcre2_code                   *regex;
++    /*
++     * pcre2 doesn't use pcre_extra any more,
++     * just for keeping same memory layout in the lua ffi cdef
++     */
++    void                         *regex_sd;
++#else
+     pcre                         *regex;
+     pcre_extra                   *regex_sd;
++#endif
+     ngx_http_lua_complex_value_t *replace;
+@@ -57,7 +76,11 @@ typedef struct {
+     ngx_pool_t   *pool;
+     ngx_int_t     options;
++#if (NGX_PCRE2)
++    pcre2_code   *regex;
++#else
+     pcre         *regex;
++#endif
+     int           captures;
+     ngx_str_t     err;
+ } ngx_http_lua_regex_compile_t;
+@@ -65,8 +88,12 @@ typedef struct {
+ typedef struct {
+     ngx_http_request_t      *request;
++#if (NGX_PCRE2)
++    pcre2_code              *regex;
++#else
+     pcre                    *regex;
+     pcre_extra              *regex_sd;
++#endif
+     int                      ncaptures;
+     int                     *captures;
+     int                      captures_len;
+@@ -74,8 +101,6 @@ typedef struct {
+ } ngx_http_lua_regex_ctx_t;
+-static void ngx_http_lua_regex_free_study_data(ngx_pool_t *pool,
+-    pcre_extra *sd);
+ static ngx_int_t ngx_http_lua_regex_compile(ngx_http_lua_regex_compile_t *rc);
+@@ -91,21 +116,155 @@ static ngx_int_t ngx_http_lua_regex_comp
+ static void
+-ngx_http_lua_regex_free_study_data(ngx_pool_t *pool, pcre_extra *sd)
++ngx_http_lua_regex_free_study_data(ngx_pool_t *pool, ngx_http_lua_regex_t *re)
+ {
+-    ngx_pool_t              *old_pool;
++    ngx_pool_t  *old_pool;
+-    old_pool = ngx_http_lua_pcre_malloc_init(pool);
++#if (NGX_PCRE2)
++    if (re && re->regex) {
++        old_pool = ngx_http_lua_pcre_malloc_init(pool);
++
++        pcre2_code_free(re->regex);
++
++        ngx_http_lua_pcre_malloc_done(old_pool);
++        re->regex = NULL;
++    }
++#else
++    if (re && re->regex_sd) {
++        old_pool = ngx_http_lua_pcre_malloc_init(pool);
+ #if LUA_HAVE_PCRE_JIT
+-    pcre_free_study(sd);
++        pcre_free_study(re->regex_sd);
+ #else
+-    pcre_free(sd);
++        pcre_free(re->regex_sd);
++#endif
++        ngx_http_lua_pcre_malloc_done(old_pool);
++
++        re->regex_sd = NULL;
++    }
+ #endif
++}
++
++
++#if (NGX_PCRE2)
++static ngx_int_t
++ngx_http_lua_regex_compile(ngx_http_lua_regex_compile_t *rc)
++{
++    int                     n, errcode;
++    char                   *p;
++    size_t                  erroff;
++    u_char                  errstr[128];
++    pcre2_code             *re;
++    ngx_pool_t             *old_pool;
++    pcre2_general_context  *gctx;
++    pcre2_compile_context  *cctx;
++
++    ngx_http_lua_main_conf_t    *lmcf;
++
++    if (ngx_regex_compile_context == NULL) {
++        /*
++         * Allocate a compile context if not yet allocated.  This uses
++         * direct allocations from heap, so the result can be cached
++         * even at runtime.
++         */
++
++        old_pool = ngx_http_lua_pcre_malloc_init(NULL);
++
++        gctx = pcre2_general_context_create(ngx_http_lua_pcre_malloc,
++                                            ngx_http_lua_pcre_free,
++                                            NULL);
++        if (gctx == NULL) {
++            ngx_http_lua_pcre_malloc_done(old_pool);
++            goto nomem;
++        }
++
++        cctx = pcre2_compile_context_create(gctx);
++        if (cctx == NULL) {
++            pcre2_general_context_free(gctx);
++            ngx_http_lua_pcre_malloc_done(old_pool);
++            goto nomem;
++        }
++
++        ngx_regex_compile_context = cctx;
++
++        ngx_regex_match_context = pcre2_match_context_create(gctx);
++        if (ngx_regex_match_context == NULL) {
++            pcre2_general_context_free(gctx);
++            ngx_http_lua_pcre_malloc_done(old_pool);
++            goto nomem;
++        }
++
++        lmcf = ngx_http_cycle_get_module_main_conf(ngx_cycle,
++                                                   ngx_http_lua_module);
++        if (lmcf && lmcf->regex_match_limit > 0) {
++            pcre2_set_match_limit(ngx_regex_match_context,
++                                  lmcf->regex_match_limit);
++        }
++
++        pcre2_general_context_free(gctx);
++        ngx_http_lua_pcre_malloc_done(old_pool);
++    }
++
++    old_pool = ngx_http_lua_pcre_malloc_init(rc->pool);
++
++    re = pcre2_compile(rc->pattern.data,
++                       rc->pattern.len, rc->options,
++                       &errcode, &erroff, ngx_regex_compile_context);
+     ngx_http_lua_pcre_malloc_done(old_pool);
++
++    if (re == NULL) {
++        pcre2_get_error_message(errcode, errstr, 128);
++
++        if ((size_t) erroff == rc->pattern.len) {
++            rc->err.len = ngx_snprintf(rc->err.data, rc->err.len,
++                                       "pcre2_compile() failed: %s in \"%V\"",
++                                       errstr, &rc->pattern)
++                          - rc->err.data;
++
++        } else {
++            rc->err.len = ngx_snprintf(rc->err.data, rc->err.len,
++                                       "pcre2_compile() failed: %s in "
++                                       "\"%V\" at \"%s\"", errstr, &rc->pattern,
++                                       rc->pattern.data + erroff)
++                          - rc->err.data;
++        }
++
++        return NGX_ERROR;
++    }
++
++    rc->regex = re;
++
++    n = pcre2_pattern_info(re, PCRE2_INFO_CAPTURECOUNT, &rc->captures);
++    if (n < 0) {
++        p = "pcre2_pattern_info(\"%V\", PCRE_INFO_CAPTURECOUNT) failed: %d";
++        goto failed;
++    }
++
++#if (NGX_DEBUG)
++    ngx_log_debug3(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
++                   "pcre2_compile: pattern[%V], options 0x%08Xd, ncaptures %d",
++                   &rc->pattern, rc->options, rc->captures);
++#endif
++
++    return NGX_OK;
++
++failed:
++
++    rc->err.len = ngx_snprintf(rc->err.data, rc->err.len, p, &rc->pattern, n)
++                  - rc->err.data;
++    return NGX_ERROR;
++
++nomem:
++
++    rc->err.len = ngx_snprintf(rc->err.data, rc->err.len,
++                               "regex \"%V\" compilation failed: no memory",
++                               &rc->pattern)
++                  - rc->err.data;
++    return NGX_ERROR;
+ }
++#else
+ static ngx_int_t
+ ngx_http_lua_regex_compile(ngx_http_lua_regex_compile_t *rc)
+@@ -159,13 +318,14 @@ failed:
+                   - rc->err.data;
+     return NGX_OK;
+ }
++#endif
+ ngx_int_t
+ ngx_http_lua_ffi_set_jit_stack_size(int size, u_char *errstr,
+     size_t *errstr_size)
+ {
+-#if LUA_HAVE_PCRE_JIT
++#if (NGX_PCRE2 || LUA_HAVE_PCRE_JIT)
+     ngx_http_lua_main_conf_t    *lmcf;
+     ngx_pool_t                  *pool, *old_pool;
+@@ -186,15 +346,24 @@ ngx_http_lua_ffi_set_jit_stack_size(int
+     if (lmcf->jit_stack) {
+         old_pool = ngx_http_lua_pcre_malloc_init(pool);
++#if (NGX_PCRE2)
++        pcre2_jit_stack_free(lmcf->jit_stack);
++#else
+         pcre_jit_stack_free(lmcf->jit_stack);
++#endif
+         ngx_http_lua_pcre_malloc_done(old_pool);
+     }
+     old_pool = ngx_http_lua_pcre_malloc_init(pool);
++#if (NGX_PCRE2)
++    lmcf->jit_stack = pcre2_jit_stack_create(NGX_LUA_RE_MIN_JIT_STACK_SIZE,
++                                             size, NULL);
++#else
+     lmcf->jit_stack = pcre_jit_stack_alloc(NGX_LUA_RE_MIN_JIT_STACK_SIZE,
+                                            size);
++#endif
+     ngx_http_lua_pcre_malloc_done(old_pool);
+@@ -214,8 +383,148 @@ ngx_http_lua_ffi_set_jit_stack_size(int
+                    - errstr;
+     return NGX_ERROR;
++#endif
++}
++
++
++#if (NGX_PCRE2)
++static void
++ngx_http_lua_regex_jit_compile(ngx_http_lua_regex_t *re, int flags,
++    ngx_pool_t *pool, ngx_http_lua_main_conf_t *lmcf,
++    ngx_http_lua_regex_compile_t *re_comp)
++{
++    ngx_int_t    ret;
++    ngx_pool_t  *old_pool;
++
++    if (flags & NGX_LUA_RE_MODE_JIT) {
++        old_pool = ngx_http_lua_pcre_malloc_init(pool);
++        ret = pcre2_jit_compile(re_comp->regex, PCRE2_JIT_COMPLETE);
++
++        if (ret != 0) {
++            ngx_log_error(NGX_LOG_INFO, ngx_cycle->log, 0,
++                          "pcre2_jit_compile() failed: %d in \"%V\", "
++                          "ignored",
++                          ret, &re_comp->pattern);
++
++#if (NGX_DEBUG)
++
++        } else {
++            ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
++                           "pcre2 JIT compiled successfully");
++#   endif /* !(NGX_DEBUG) */
++        }
++
++        ngx_http_lua_pcre_malloc_done(old_pool);
++
++    }
++
++    if (lmcf && lmcf->jit_stack) {
++        pcre2_jit_stack_assign(ngx_regex_match_context, NULL,
++                               lmcf->jit_stack);
++    }
++
++    return;
++}
++
++#else
++
++static void
++ngx_http_lua_regex_jit_compile(ngx_http_lua_regex_t *re, int flags,
++    ngx_pool_t *pool, ngx_http_lua_main_conf_t *lmcf,
++    ngx_http_lua_regex_compile_t *re_comp)
++{
++    const char  *msg;
++    pcre_extra  *sd = NULL;
++    ngx_pool_t  *old_pool;
++
++
++#if (LUA_HAVE_PCRE_JIT)
++    if (flags & NGX_LUA_RE_MODE_JIT) {
++        old_pool = ngx_http_lua_pcre_malloc_init(pool);
++        sd = pcre_study(re_comp->regex, PCRE_STUDY_JIT_COMPILE, &msg);
++        ngx_http_lua_pcre_malloc_done(old_pool);
++
++#   if (NGX_DEBUG)
++        if (msg != NULL) {
++            ngx_log_debug2(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
++                           "pcre study failed with PCRE_STUDY_JIT_COMPILE: "
++                           "%s (%p)", msg, sd);
++        }
++
++        if (sd != NULL) {
++            int         jitted;
++
++            old_pool = ngx_http_lua_pcre_malloc_init(pool);
++
++            pcre_fullinfo(re_comp->regex, sd, PCRE_INFO_JIT, &jitted);
++
++            ngx_http_lua_pcre_malloc_done(old_pool);
++
++            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
++                           "pcre JIT compiling result: %d", jitted);
++        }
++#   endif /* !(NGX_DEBUG) */
++
++    } else {
++        old_pool = ngx_http_lua_pcre_malloc_init(pool);
++        sd = pcre_study(re_comp->regex, 0, &msg);
++        ngx_http_lua_pcre_malloc_done(old_pool);
++    }
++
++    if (sd && lmcf && lmcf->jit_stack) {
++        pcre_assign_jit_stack(sd, NULL, lmcf->jit_stack);
++    }
++
++    if (sd
++        && lmcf && lmcf->regex_match_limit > 0
++        && !(flags & NGX_LUA_RE_MODE_DFA))
++    {
++        sd->flags |= PCRE_EXTRA_MATCH_LIMIT;
++        sd->match_limit = lmcf->regex_match_limit;
++    }
++
+ #endif /* LUA_HAVE_PCRE_JIT */
++
++    re->regex_sd = sd;
++}
++#endif
++
++
++#if (NGX_PCRE2)
++void
++ngx_http_lua_regex_cleanup(void *data)
++{
++    ngx_pool_t                *old_pool;
++    ngx_http_lua_main_conf_t  *lmcf;
++
++    lmcf = data;
++
++    if (ngx_regex_compile_context) {
++        old_pool = ngx_http_lua_pcre_malloc_init(NULL);
++        pcre2_compile_context_free(ngx_regex_compile_context);
++        ngx_regex_compile_context = NULL;
++        ngx_http_lua_pcre_malloc_done(old_pool);
++    }
++
++    if (lmcf && lmcf->jit_stack) {
++        old_pool = ngx_http_lua_pcre_malloc_init(NULL);
++
++        pcre2_jit_stack_free(lmcf->jit_stack);
++        lmcf->jit_stack = NULL;
++
++        ngx_http_lua_pcre_malloc_done(old_pool);
++    }
++
++    if (ngx_regex_match_data) {
++        old_pool = ngx_http_lua_pcre_malloc_init(NULL);
++        pcre2_match_data_free(ngx_regex_match_data);
++        ngx_regex_match_data = NULL;
++        ngx_regex_match_data_size = 0;
++        ngx_http_lua_pcre_malloc_done(old_pool);
++    }
++
+ }
++#endif
+ ngx_http_lua_regex_t *
+@@ -228,8 +537,7 @@ ngx_http_lua_ffi_compile_regex(const uns
+     ngx_int_t                rc;
+     const char              *msg;
+     ngx_pool_t              *pool, *old_pool;
+-    pcre_extra              *sd = NULL;
+-    ngx_http_lua_regex_t    *re;
++    ngx_http_lua_regex_t    *re = NULL;
+     ngx_http_lua_main_conf_t         *lmcf;
+     ngx_http_lua_regex_compile_t      re_comp;
+@@ -251,6 +559,8 @@ ngx_http_lua_ffi_compile_regex(const uns
+     }
+     re->pool = pool;
++    re->regex = NULL;
++    re->regex_sd = NULL;
+     re_comp.options      = pcre_opts;
+     re_comp.pattern.data = (u_char *) pat;
+@@ -274,54 +584,7 @@ ngx_http_lua_ffi_compile_regex(const uns
+     ngx_http_lua_assert(lmcf != NULL);
+-#if (LUA_HAVE_PCRE_JIT)
+-
+-    if (flags & NGX_LUA_RE_MODE_JIT) {
+-
+-        old_pool = ngx_http_lua_pcre_malloc_init(pool);
+-        sd = pcre_study(re_comp.regex, PCRE_STUDY_JIT_COMPILE, &msg);
+-        ngx_http_lua_pcre_malloc_done(old_pool);
+-
+-#   if (NGX_DEBUG)
+-        if (msg != NULL) {
+-            ngx_log_debug2(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
+-                           "pcre study failed with PCRE_STUDY_JIT_COMPILE: "
+-                           "%s (%p)", msg, sd);
+-        }
+-
+-        if (sd != NULL) {
+-            int         jitted;
+-
+-            old_pool = ngx_http_lua_pcre_malloc_init(pool);
+-
+-            pcre_fullinfo(re_comp.regex, sd, PCRE_INFO_JIT, &jitted);
+-
+-            ngx_http_lua_pcre_malloc_done(old_pool);
+-
+-            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
+-                           "pcre JIT compiling result: %d", jitted);
+-        }
+-#   endif /* !(NGX_DEBUG) */
+-
+-    } else {
+-        old_pool = ngx_http_lua_pcre_malloc_init(pool);
+-        sd = pcre_study(re_comp.regex, 0, &msg);
+-        ngx_http_lua_pcre_malloc_done(old_pool);
+-    }
+-
+-    if (sd && lmcf->jit_stack) {
+-        pcre_assign_jit_stack(sd, NULL, lmcf->jit_stack);
+-    }
+-
+-#endif /* LUA_HAVE_PCRE_JIT */
+-
+-    if (sd
+-        && lmcf && lmcf->regex_match_limit > 0
+-        && !(flags & NGX_LUA_RE_MODE_DFA))
+-    {
+-        sd->flags |= PCRE_EXTRA_MATCH_LIMIT;
+-        sd->match_limit = lmcf->regex_match_limit;
+-    }
++    ngx_http_lua_regex_jit_compile(re, flags, pool, lmcf, &re_comp);
+     if (flags & NGX_LUA_RE_MODE_DFA) {
+         ovecsize = 2;
+@@ -339,6 +602,31 @@ ngx_http_lua_ffi_compile_regex(const uns
+         goto error;
+     }
++#if (NGX_PCRE2)
++    if (pcre2_pattern_info(re_comp.regex, PCRE2_INFO_NAMECOUNT,
++                           &re->name_count) < 0)
++    {
++        msg = "cannot acquire named subpattern count";
++        goto error;
++    }
++
++    if (re->name_count > 0) {
++        if (pcre2_pattern_info(re_comp.regex, PCRE2_INFO_NAMEENTRYSIZE,
++                               &re->name_entry_size) != 0)
++        {
++            msg = "cannot acquire named subpattern entry size";
++            goto error;
++        }
++
++        if (pcre2_pattern_info(re_comp.regex, PCRE2_INFO_NAMETABLE,
++                               &re->name_table) != 0)
++        {
++            msg = "cannot acquire named subpattern table";
++            goto error;
++        }
++    }
++
++#else
+     if (pcre_fullinfo(re_comp.regex, NULL, PCRE_INFO_NAMECOUNT,
+                       &re->name_count) != 0)
+     {
+@@ -361,9 +649,9 @@ ngx_http_lua_ffi_compile_regex(const uns
+             goto error;
+         }
+     }
++#endif
+     re->regex = re_comp.regex;
+-    re->regex_sd = sd;
+     re->ncaptures = re_comp.captures;
+     re->captures = cap;
+     re->replace = NULL;
+@@ -379,9 +667,7 @@ error:
+     p = ngx_snprintf(errstr, errstr_size - 1, "%s", msg);
+     *p = '\0';
+-    if (sd) {
+-        ngx_http_lua_regex_free_study_data(pool, sd);
+-    }
++    ngx_http_lua_regex_free_study_data(pool, re);
+     if (pool) {
+         ngx_destroy_pool(pool);
+@@ -391,6 +677,103 @@ error:
+ }
++#if (NGX_PCRE2)
++int
++ngx_http_lua_ffi_exec_regex(ngx_http_lua_regex_t *re, int flags,
++    const u_char *s, size_t len, int pos)
++{
++    int          rc, exec_opts = 0;
++    size_t      *ov;
++    ngx_uint_t   ovecsize, n, i;
++    ngx_pool_t  *old_pool;
++
++    if (flags & NGX_LUA_RE_MODE_DFA) {
++        ovecsize = 2;
++        re->ncaptures = 0;
++
++    } else {
++        ovecsize = (re->ncaptures + 1) * 3;
++    }
++
++    old_pool = ngx_http_lua_pcre_malloc_init(NULL);
++
++    if (ngx_regex_match_data == NULL
++        || ovecsize > ngx_regex_match_data_size)
++    {
++        /*
++         * Allocate a match data if not yet allocated or smaller than
++         * needed.
++         */
++
++        if (ngx_regex_match_data) {
++            pcre2_match_data_free(ngx_regex_match_data);
++        }
++
++        ngx_regex_match_data_size = ovecsize;
++        ngx_regex_match_data = pcre2_match_data_create(ovecsize / 3, NULL);
++
++        if (ngx_regex_match_data == NULL) {
++            rc = PCRE2_ERROR_NOMEMORY;
++            goto failed;
++        }
++    }
++
++    if (flags & NGX_LUA_RE_NO_UTF8_CHECK) {
++        exec_opts = PCRE2_NO_UTF_CHECK;
++
++    } else {
++        exec_opts = 0;
++    }
++
++    if (flags & NGX_LUA_RE_MODE_DFA) {
++        int ws[NGX_LUA_RE_DFA_MODE_WORKSPACE_COUNT];
++        rc = pcre2_dfa_match(re->regex, s, len, pos, exec_opts,
++                             ngx_regex_match_data, ngx_regex_match_context,
++                             ws, sizeof(ws) / sizeof(ws[0]));
++
++
++    } else {
++        rc = pcre2_match(re->regex, s, len, pos, exec_opts,
++                         ngx_regex_match_data, ngx_regex_match_context);
++    }
++
++    if (rc < 0) {
++#if (NGX_DEBUG)
++        ngx_log_debug4(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
++                       "pcre2_match failed: flags 0x%05Xd, options 0x%08Xd, "
++                       "rc %d, ovecsize %ui", flags, exec_opts, rc, ovecsize);
++#endif
++
++        goto failed;
++    }
++
++    n = pcre2_get_ovector_count(ngx_regex_match_data);
++    ov = pcre2_get_ovector_pointer(ngx_regex_match_data);
++
++#if (NGX_DEBUG)
++    ngx_log_debug5(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
++                   "pcre2_match: flags 0x%05Xd, options 0x%08Xd, rc %d, "
++                   "n %ui, ovecsize %ui", flags, exec_opts, rc, n, ovecsize);
++#endif
++
++    if (!(flags & NGX_LUA_RE_MODE_DFA) && n > ovecsize / 3) {
++        n = ovecsize / 3;
++    }
++
++    for (i = 0; i < n; i++) {
++        re->captures[i * 2] = ov[i * 2];
++        re->captures[i * 2 + 1] = ov[i * 2 + 1];
++    }
++
++failed:
++
++    ngx_http_lua_pcre_malloc_done(old_pool);
++
++    return rc;
++}
++
++#else
++
+ int
+ ngx_http_lua_ffi_exec_regex(ngx_http_lua_regex_t *re, int flags,
+     const u_char *s, size_t len, int pos)
+@@ -427,7 +810,8 @@ ngx_http_lua_ffi_exec_regex(ngx_http_lua
+         int ws[NGX_LUA_RE_DFA_MODE_WORKSPACE_COUNT];
+         rc = ngx_http_lua_regex_dfa_exec(re->regex, sd, &subj,
+                                          (int) pos, cap, ovecsize, ws,
+-                                         sizeof(ws)/sizeof(ws[0]), exec_opts);
++                                         sizeof(ws) / sizeof(ws[0]),
++                                         exec_opts);
+ #else
+@@ -443,28 +827,19 @@ ngx_http_lua_ffi_exec_regex(ngx_http_lua
+     return rc;
+ }
++#endif
++
+ void
+ ngx_http_lua_ffi_destroy_regex(ngx_http_lua_regex_t *re)
+ {
+-    ngx_pool_t                  *old_pool;
+-
+     dd("destroy regex called");
+     if (re == NULL || re->pool == NULL) {
+         return;
+     }
+-    if (re->regex_sd) {
+-        old_pool = ngx_http_lua_pcre_malloc_init(re->pool);
+-#if LUA_HAVE_PCRE_JIT
+-        pcre_free_study(re->regex_sd);
+-#else
+-        pcre_free(re->regex_sd);
+-#endif
+-        ngx_http_lua_pcre_malloc_done(old_pool);
+-        re->regex_sd = NULL;
+-    }
++    ngx_http_lua_regex_free_study_data(re->pool, re);
+     ngx_destroy_pool(re->pool);
+ }
+@@ -592,11 +967,17 @@ ngx_http_lua_ffi_max_regex_cache_size(vo
+ const char *
+ ngx_http_lua_ffi_pcre_version(void)
+ {
++#if (NGX_PCRE2)
++    pcre2_config(PCRE2_CONFIG_VERSION, ngx_pcre2_version);
++
++    return ngx_pcre2_version;
++#else
+     return pcre_version();
++#endif
+ }
+-#endif /* NGX_PCRE */
++#endif /* NGX_PCRE || NGX_PCRE2 */
+ /* vi:set ft=c ts=4 sw=4 et fdm=marker: */
+--- a/nginx-mod-lua/t/028-req-header.t
++++ b/nginx-mod-lua/t/028-req-header.t
+@@ -275,7 +275,6 @@ Content-Type:
+ GET /bar
+ --- response_body eval
+ # Since nginx version 1.23.0, nginx combines same $http_* variable together
+-# wtf
+ $Test::Nginx::Util::NginxVersion >= 1.023000 ?
+ "Foo: a, b\n"
+--- a/nginx-mod-lua/t/034-match.t
++++ b/nginx-mod-lua/t/034-match.t
+@@ -361,8 +361,11 @@ he
+     }
+ --- request
+     GET /re
+---- response_body
+-error: pcre_compile() failed: missing ) in "(abc"
++--- response_body eval
++$Test::Nginx::Util::PcreVersion == 2 ?
++"error: pcre2_compile() failed: missing closing parenthesis in \"(abc\"\n"
++:
++"error: pcre_compile() failed: missing ) in \"(abc\"\n"
+ --- no_error_log
+ [error]
+@@ -648,8 +651,12 @@ regex: (?:>[\w\s]*</?\w{2,}>)
+     }
+ --- request
+     GET /re
+---- response_body
+-error: pcre_compile() failed: missing ) in "([0-9]+"
++--- response_body eval
++$Test::Nginx::Util::PcreVersion == 2 ?
++"error: pcre2_compile\(\) failed: missing closing parenthesis in \"\([0-9]+\"\n"
++:
++"error: pcre_compile\(\) failed: missing \) in \"\([0-9]+\"\n"
++
+ --- no_error_log
+ [error]
+@@ -939,8 +946,11 @@ nil
+     }
+ --- request
+ GET /t
+---- response_body_like chop
+-^error: pcre_exec\(\) failed: -10$
++--- response_body eval
++$Test::Nginx::Util::PcreVersion == 2 ?
++"error: pcre_exec\(\) failed: -4\n"
++:
++"error: pcre_exec\(\) failed: -10\n"
+ --- no_error_log
+ [error]
+@@ -1050,8 +1060,14 @@ end
+ --- request
+     GET /re
+---- response_body
+-error: pcre_exec() failed: -8
++--- response_body eval
++# lua_regex_match_limit uses pcre_extra->match_limit in the PCRE,
++# but PCRE2 replaces this with pcre2_set_match_limit interface,
++# which has different effects.
++$Test::Nginx::Util::PcreVersion == 2 ?
++"failed to match\n"
++:
++"error: pcre_exec() failed: -8\n"
+--- a/nginx-mod-lua/t/035-gmatch.t
++++ b/nginx-mod-lua/t/035-gmatch.t
+@@ -698,8 +698,11 @@ not matched!
+     }
+ --- request
+     GET /re
+---- response_body
+-error: pcre_compile() failed: missing ) in "(abc"
++--- response_body eval
++$Test::Nginx::Util::PcreVersion == 2 ?
++"error: pcre2_compile() failed: missing closing parenthesis in \"(abc\"\n"
++:
++"error: pcre_compile() failed: missing ) in \"(abc\"\n"
+ --- no_error_log
+ [error]
+@@ -735,8 +738,11 @@ error: pcre_compile() failed: missing )
+     }
+ --- request
+ GET /t
+---- response_body_like chop
+-error: pcre_exec\(\) failed: -10
++--- response_body eval
++$Test::Nginx::Util::PcreVersion == 2 ?
++"error: pcre_exec\(\) failed: -4\n"
++:
++"error: pcre_exec\(\) failed: -10\n"
+ --- no_error_log
+ [error]
+@@ -854,8 +860,14 @@ end
+ --- request
+     GET /re
+---- response_body
+-error: pcre_exec() failed: -8
++--- response_body eval
++# lua_regex_match_limit uses pcre_extra->match_limit in the PCRE,
++# but PCRE2 replaces this with pcre2_set_match_limit interface,
++# which has different effects.
++$Test::Nginx::Util::PcreVersion == 2 ?
++"failed to match\n"
++:
++"error: pcre_exec() failed: -8\n"
+--- a/nginx-mod-lua/t/036-sub.t
++++ b/nginx-mod-lua/t/036-sub.t
+@@ -480,8 +480,11 @@ a [b c] [b] [c] [] [] d
+     }
+ --- request
+     GET /re
+---- response_body
+-error: pcre_compile() failed: missing ) in "(abc"
++--- response_body eval
++$Test::Nginx::Util::PcreVersion == 2 ?
++"error: pcre2_compile() failed: missing closing parenthesis in \"(abc\"\n"
++:
++"error: pcre_compile() failed: missing ) in \"(abc\"\n"
+ --- no_error_log
+ [error]
+@@ -506,8 +509,11 @@ error: pcre_compile() failed: missing )
+     }
+ --- request
+ GET /t
+---- response_body_like chop
+-error: pcre_exec\(\) failed: -10
++--- response_body eval
++$Test::Nginx::Util::PcreVersion == 2 ?
++"error: pcre_exec\(\) failed: -4\n"
++:
++"error: pcre_exec\(\) failed: -10\n"
+ --- no_error_log
+ [error]
+@@ -610,8 +616,14 @@ ngx.say("sub: ", cnt)
+ --- request
+     GET /re
+---- response_body
+-error: pcre_exec() failed: -8
++--- response_body eval
++# lua_regex_match_limit uses pcre_extra->match_limit in the PCRE,
++# but PCRE2 replaces this with pcre2_set_match_limit interface,
++# which has different effects.
++$Test::Nginx::Util::PcreVersion == 2 ?
++"sub: 0\n"
++:
++"error: pcre_exec() failed: -8\n"
+--- a/nginx-mod-lua/t/037-gsub.t
++++ b/nginx-mod-lua/t/037-gsub.t
+@@ -423,8 +423,11 @@ n: 1
+     }
+ --- request
+ GET /t
+---- response_body_like chop
+-error: pcre_exec\(\) failed: -10
++--- response_body eval
++$Test::Nginx::Util::PcreVersion == 2 ?
++"error: pcre_exec\(\) failed: -4\n"
++:
++"error: pcre_exec\(\) failed: -10\n"
+ --- no_error_log
+ [error]
+@@ -531,8 +534,14 @@ ngx.say("gsub: ", cnt)
+ --- request
+     GET /re
+---- response_body
+-error: pcre_exec() failed: -8
++--- response_body eval
++# lua_regex_match_limit uses pcre_extra->match_limit in the PCRE,
++# but PCRE2 replaces this with pcre2_set_match_limit interface,
++# which has different effects.
++$Test::Nginx::Util::PcreVersion == 2 ?
++"gsub: 0\n"
++:
++"error: pcre_exec() failed: -8\n"
+--- a/nginx-mod-lua/t/038-match-o.t
++++ b/nginx-mod-lua/t/038-match-o.t
+@@ -336,8 +336,11 @@ he
+     }
+ --- request
+     GET /re
+---- response_body
+-error: pcre_compile() failed: missing ) in "(abc"
++--- response_body eval
++$Test::Nginx::Util::PcreVersion == 2 ?
++"error: pcre2_compile() failed: missing closing parenthesis in \"(abc\"\n"
++:
++"error: pcre_compile() failed: missing ) in \"(abc\"\n"
+ --- no_error_log
+ [error]
+--- a/nginx-mod-lua/t/047-match-jit.t
++++ b/nginx-mod-lua/t/047-match-jit.t
+@@ -32,8 +32,11 @@ __DATA__
+     GET /re
+ --- response_body
+ 1234
+---- error_log
+-pcre JIT compiling result: 1
++--- error_log eval
++$Test::Nginx::Util::PcreVersion == 2 ?
++"pcre2 JIT compiled successfully\n"
++:
++"pcre JIT compiling result: 1\n"
+@@ -53,8 +56,11 @@ pcre JIT compiling result: 1
+     GET /re
+ --- response_body
+ not matched!
+---- error_log
+-pcre JIT compiling result: 1
++--- error_log eval
++$Test::Nginx::Util::PcreVersion == 2 ?
++"pcre2 JIT compiled successfully\n"
++:
++"pcre JIT compiling result: 1\n"
+@@ -76,9 +82,15 @@ pcre JIT compiling result: 1
+ 1234
+ --- grep_error_log eval
+-qr/pcre JIT compiling result: \d+/
++$Test::Nginx::Util::PcreVersion == 2 ?
++"pcre2 JIT compiled successfully"
++:
++"pcre JIT compiling result: 1"
+ --- grep_error_log_out eval
++$Test::Nginx::Util::PcreVersion == 2 ?
++["pcre2 JIT compiled successfully\n", ""]
++:
+ ["pcre JIT compiling result: 1\n", ""]
+@@ -101,9 +113,15 @@ qr/pcre JIT compiling result: \d+/
+ not matched!
+ --- grep_error_log eval
+-qr/pcre JIT compiling result: \d+/
++$Test::Nginx::Util::PcreVersion == 2 ?
++"pcre2 JIT compiled successfully"
++:
++"pcre JIT compiling result: 1"
+ --- grep_error_log_out eval
++$Test::Nginx::Util::PcreVersion == 2 ?
++["pcre2 JIT compiled successfully\n", ""]
++:
+ ["pcre JIT compiling result: 1\n", ""]
+@@ -128,8 +146,11 @@ qr/pcre JIT compiling result: \d+/
+     }
+ --- request
+     GET /re
+---- response_body
+-error: pcre_compile() failed: missing ) in "(abc"
++--- response_body eval
++$Test::Nginx::Util::PcreVersion == 2 ?
++"error: pcre2_compile() failed: missing closing parenthesis in \"(abc\"\n"
++:
++"error: pcre_compile() failed: missing ) in \"(abc\"\n"
+ --- no_error_log
+ [error]
+@@ -170,8 +191,15 @@ end
+ --- request
+     GET /re
+---- response_body
+-error: pcre_exec() failed: -8
++--- response_body eval
++# lua_regex_match_limit uses pcre_extra->match_limit in the PCRE,
++# but PCRE2 replaces this with pcre2_set_match_limit interface,
++# which has different effects.
++$Test::Nginx::Util::PcreVersion == 2 ?
++# PCRE2_ERROR_MATCHLIMIT  (-47)
++"error: pcre_exec() failed: -47\n"
++:
++"error: pcre_exec() failed: -8\n"
+--- a/nginx-mod-lua/t/049-gmatch-jit.t
++++ b/nginx-mod-lua/t/049-gmatch-jit.t
+@@ -34,8 +34,11 @@ __DATA__
+ --- response_body
+ hello
+ world
+---- error_log
+-pcre JIT compiling result: 1
++--- error_log eval
++$Test::Nginx::Util::PcreVersion == 2 ?
++"pcre2 JIT compiled successfully\n"
++:
++"pcre JIT compiling result: 1\n"
+@@ -60,8 +63,11 @@ pcre JIT compiling result: 1
+ nil
+ nil
+ nil
+---- error_log
+-pcre JIT compiling result: 1
++--- error_log eval
++$Test::Nginx::Util::PcreVersion == 2 ?
++"pcre2 JIT compiled successfully\n"
++:
++"pcre JIT compiling result: 1\n"
+@@ -77,8 +83,11 @@ pcre JIT compiling result: 1
+     GET /re
+ --- response_body
+ done
+---- error_log
+-pcre JIT compiling result: 1
++--- error_log eval
++$Test::Nginx::Util::PcreVersion == 2 ?
++"pcre2 JIT compiled successfully\n"
++:
++"pcre JIT compiling result: 1\n"
+@@ -99,8 +108,11 @@ pcre JIT compiling result: 1
+     GET /re
+ --- response_body
+ hello
+---- error_log
+-pcre JIT compiling result: 1
++--- error_log eval
++$Test::Nginx::Util::PcreVersion == 2 ?
++"pcre2 JIT compiled successfully\n"
++:
++"pcre JIT compiling result: 1\n"
+@@ -124,9 +136,15 @@ hello
+ world
+ --- grep_error_log eval
+-qr/pcre JIT compiling result: \d+/
++$Test::Nginx::Util::PcreVersion == 2 ?
++"pcre2 JIT compiled successfully"
++:
++"pcre JIT compiling result: 1"
+ --- grep_error_log_out eval
++$Test::Nginx::Util::PcreVersion == 2 ?
++["pcre2 JIT compiled successfully\n", ""]
++:
+ ["pcre JIT compiling result: 1\n", ""]
+@@ -154,9 +172,15 @@ nil
+ nil
+ --- grep_error_log eval
+-qr/pcre JIT compiling result: \d+/
++$Test::Nginx::Util::PcreVersion == 2 ?
++"pcre2 JIT compiled successfully"
++:
++"pcre JIT compiling result: 1"
+ --- grep_error_log_out eval
++$Test::Nginx::Util::PcreVersion == 2 ?
++["pcre2 JIT compiled successfully\n", ""]
++:
+ ["pcre JIT compiling result: 1\n", ""]
+@@ -175,9 +199,15 @@ qr/pcre JIT compiling result: \d+/
+ done
+ --- grep_error_log eval
+-qr/pcre JIT compiling result: \d+/
++$Test::Nginx::Util::PcreVersion == 2 ?
++"pcre2 JIT compiled successfully"
++:
++"pcre JIT compiling result: 1"
+ --- grep_error_log_out eval
++$Test::Nginx::Util::PcreVersion == 2 ?
++["pcre2 JIT compiled successfully\n", ""]
++:
+ ["pcre JIT compiling result: 1\n", ""]
+@@ -201,9 +231,15 @@ qr/pcre JIT compiling result: \d+/
+ hello
+ --- grep_error_log eval
+-qr/pcre JIT compiling result: \d+/
++$Test::Nginx::Util::PcreVersion == 2 ?
++"pcre2 JIT compiled successfully"
++:
++"pcre JIT compiling result: 1"
+ --- grep_error_log_out eval
++$Test::Nginx::Util::PcreVersion == 2 ?
++["pcre2 JIT compiled successfully\n", ""]
++:
+ ["pcre JIT compiling result: 1\n", ""]
+@@ -222,7 +258,10 @@ qr/pcre JIT compiling result: \d+/
+     }
+ --- request
+     GET /re
+---- response_body
+-error: pcre_compile() failed: missing ) in "(abc"
++--- response_body eval
++$Test::Nginx::Util::PcreVersion == 2 ?
++"error: pcre2_compile() failed: missing closing parenthesis in \"(abc\"\n"
++:
++"error: pcre_compile() failed: missing ) in \"(abc\"\n"
+ --- no_error_log
+ [error]
+--- a/nginx-mod-lua/t/050-gmatch-dfa.t
++++ b/nginx-mod-lua/t/050-gmatch-dfa.t
+@@ -214,8 +214,11 @@ hello
+     }
+ --- request
+     GET /re
+---- response_body
+-error: pcre_compile() failed: missing ) in "(abc"
++--- response_body eval
++$Test::Nginx::Util::PcreVersion == 2 ?
++"error: pcre2_compile() failed: missing closing parenthesis in \"(abc\"\n"
++:
++"error: pcre_compile() failed: missing ) in \"(abc\"\n"
+ --- no_error_log
+ [error]
+--- a/nginx-mod-lua/t/051-sub-jit.t
++++ b/nginx-mod-lua/t/051-sub-jit.t
+@@ -32,8 +32,11 @@ __DATA__
+     GET /re
+ --- response_body
+ hello, world 5678: 1
+---- error_log
+-pcre JIT compiling result: 1
++--- error_log eval
++$Test::Nginx::Util::PcreVersion == 2 ?
++"pcre2 JIT compiled successfully\n"
++:
++"pcre JIT compiling result: 1\n"
+@@ -53,8 +56,11 @@ pcre JIT compiling result: 1
+     GET /re
+ --- response_body
+ hello, world: 0
+---- error_log
+-pcre JIT compiling result: 1
++--- error_log eval
++$Test::Nginx::Util::PcreVersion == 2 ?
++"pcre2 JIT compiled successfully\n"
++:
++"pcre JIT compiling result: 1\n"
+@@ -76,9 +82,15 @@ pcre JIT compiling result: 1
+ hello, world 5678: 1
+ --- grep_error_log eval
+-qr/pcre JIT compiling result: \d+/
++$Test::Nginx::Util::PcreVersion == 2 ?
++"pcre2 JIT compiled successfully"
++:
++"pcre JIT compiling result: 1"
+ --- grep_error_log_out eval
++$Test::Nginx::Util::PcreVersion == 2 ?
++["pcre2 JIT compiled successfully\n", ""]
++:
+ ["pcre JIT compiling result: 1\n", ""]
+@@ -101,9 +113,15 @@ qr/pcre JIT compiling result: \d+/
+ hello, world: 0
+ --- grep_error_log eval
+-qr/pcre JIT compiling result: \d+/
++$Test::Nginx::Util::PcreVersion == 2 ?
++"pcre2 JIT compiled successfully"
++:
++"pcre JIT compiling result: 1"
+ --- grep_error_log_out eval
++$Test::Nginx::Util::PcreVersion == 2 ?
++["pcre2 JIT compiled successfully\n", ""]
++:
+ ["pcre JIT compiling result: 1\n", ""]
+@@ -122,8 +140,11 @@ qr/pcre JIT compiling result: \d+/
+     }
+ --- request
+     GET /re
+---- response_body
+-error: pcre_compile() failed: missing ) in "(abc"
++--- response_body eval
++$Test::Nginx::Util::PcreVersion == 2 ?
++"error: pcre2_compile() failed: missing closing parenthesis in \"(abc\"\n"
++:
++"error: pcre_compile() failed: missing ) in \"(abc\"\n"
+ --- no_error_log
+ [error]
+@@ -143,7 +164,10 @@ error: pcre_compile() failed: missing )
+     }
+ --- request
+     GET /re
+---- response_body
+-error: pcre_compile() failed: missing ) in "(abc"
++--- response_body eval
++$Test::Nginx::Util::PcreVersion == 2 ?
++"error: pcre2_compile() failed: missing closing parenthesis in \"(abc\"\n"
++:
++"error: pcre_compile() failed: missing ) in \"(abc\"\n"
+ --- no_error_log
+ [error]
+--- a/nginx-mod-lua/t/052-sub-dfa.t
++++ b/nginx-mod-lua/t/052-sub-dfa.t
+@@ -107,8 +107,11 @@ hello, world: 0
+     }
+ --- request
+     GET /re
+---- response_body
+-error: pcre_compile() failed: missing ) in "(abc"
++--- response_body eval
++$Test::Nginx::Util::PcreVersion == 2 ?
++"error: pcre2_compile() failed: missing closing parenthesis in \"(abc\"\n"
++:
++"error: pcre_compile() failed: missing ) in \"(abc\"\n"
+ --- no_error_log
+ [error]
+@@ -129,8 +132,11 @@ error: pcre_compile() failed: missing )
+     }
+ --- request
+     GET /re
+---- response_body
+-error: pcre_compile() failed: missing ) in "(abc"
++--- response_body eval
++$Test::Nginx::Util::PcreVersion == 2 ?
++"error: pcre2_compile() failed: missing closing parenthesis in \"(abc\"\n"
++:
++"error: pcre_compile() failed: missing ) in \"(abc\"\n"
+ --- no_error_log
+ [error]
+--- a/nginx-mod-lua/t/053-gsub-jit.t
++++ b/nginx-mod-lua/t/053-gsub-jit.t
+@@ -32,8 +32,11 @@ __DATA__
+     GET /re
+ --- response_body
+ hello, world world: 2
+---- error_log
+-pcre JIT compiling result: 1
++--- error_log eval
++$Test::Nginx::Util::PcreVersion == 2 ?
++"pcre2 JIT compiled successfully\n"
++:
++"pcre JIT compiling result: 1\n"
+@@ -53,8 +56,11 @@ pcre JIT compiling result: 1
+     GET /re
+ --- response_body
+ hello, world: 0
+---- error_log
+-pcre JIT compiling result: 1
++--- error_log eval
++$Test::Nginx::Util::PcreVersion == 2 ?
++"pcre2 JIT compiled successfully\n"
++:
++"pcre JIT compiling result: 1\n"
+@@ -76,9 +82,15 @@ pcre JIT compiling result: 1
+ hello, world world: 2
+ --- grep_error_log eval
+-qr/pcre JIT compiling result: \d+/
++$Test::Nginx::Util::PcreVersion == 2 ?
++"pcre2 JIT compiled successfully"
++:
++"pcre JIT compiling result: 1"
+ --- grep_error_log_out eval
++$Test::Nginx::Util::PcreVersion == 2 ?
++["pcre2 JIT compiled successfully\n", ""]
++:
+ ["pcre JIT compiling result: 1\n", ""]
+@@ -101,9 +113,15 @@ qr/pcre JIT compiling result: \d+/
+ hello, world: 0
+ --- grep_error_log eval
+-qr/pcre JIT compiling result: \d+/
++$Test::Nginx::Util::PcreVersion == 2 ?
++"pcre2 JIT compiled successfully"
++:
++"pcre JIT compiling result: 1"
+ --- grep_error_log_out eval
++$Test::Nginx::Util::PcreVersion == 2 ?
++["pcre2 JIT compiled successfully\n", ""]
++:
+ ["pcre JIT compiling result: 1\n", ""]
+@@ -122,8 +140,11 @@ qr/pcre JIT compiling result: \d+/
+     }
+ --- request
+     GET /re
+---- response_body
+-error: pcre_compile() failed: missing ) in "(abc"
++--- response_body eval
++$Test::Nginx::Util::PcreVersion == 2 ?
++"error: pcre2_compile() failed: missing closing parenthesis in \"(abc\"\n"
++:
++"error: pcre_compile() failed: missing ) in \"(abc\"\n"
+ --- no_error_log
+ [error]
+@@ -143,7 +164,10 @@ error: pcre_compile() failed: missing )
+     }
+ --- request
+     GET /re
+---- response_body
+-error: pcre_compile() failed: missing ) in "(abc"
++--- response_body eval
++$Test::Nginx::Util::PcreVersion == 2 ?
++"error: pcre2_compile() failed: missing closing parenthesis in \"(abc\"\n"
++:
++"error: pcre_compile() failed: missing ) in \"(abc\"\n"
+ --- no_error_log
+ [error]
+--- a/nginx-mod-lua/t/054-gsub-dfa.t
++++ b/nginx-mod-lua/t/054-gsub-dfa.t
+@@ -107,8 +107,11 @@ hello, world: 0
+     }
+ --- request
+     GET /re
+---- response_body
+-error: pcre_compile() failed: missing ) in "(abc"
++--- response_body eval
++$Test::Nginx::Util::PcreVersion == 2 ?
++"error: pcre2_compile() failed: missing closing parenthesis in \"(abc\"\n"
++:
++"error: pcre_compile() failed: missing ) in \"(abc\"\n"
+@@ -126,8 +129,11 @@ error: pcre_compile() failed: missing )
+     }
+ --- request
+     GET /re
+---- response_body
+-error: pcre_compile() failed: missing ) in "(abc"
++--- response_body eval
++$Test::Nginx::Util::PcreVersion == 2 ?
++"error: pcre2_compile() failed: missing closing parenthesis in \"(abc\"\n"
++:
++"error: pcre_compile() failed: missing ) in \"(abc\"\n"
+ --- no_error_log
+ [error]
+--- a/nginx-mod-lua/t/120-re-find.t
++++ b/nginx-mod-lua/t/120-re-find.t
+@@ -354,8 +354,11 @@ matched: he
+     }
+ --- request
+     GET /re
+---- response_body
+-error: pcre_compile() failed: missing ) in "(abc"
++--- response_body eval
++$Test::Nginx::Util::PcreVersion == 2 ?
++"error: pcre2_compile() failed: missing closing parenthesis in \"(abc\"\n"
++:
++"error: pcre_compile() failed: missing ) in \"(abc\"\n"
+ --- no_error_log
+ [error]
+@@ -562,8 +565,11 @@ matched: hello, 1234
+     }
+ --- request
+ GET /t
+---- response_body_like chop
+-^error: pcre_exec\(\) failed: -10$
++--- response_body eval
++$Test::Nginx::Util::PcreVersion == 2 ?
++"error: pcre_exec\(\) failed: -4\n"
++:
++"error: pcre_exec\(\) failed: -10\n"
+ --- no_error_log
+ [error]
+@@ -587,6 +593,7 @@ GET /t
+         ';
+     }
+ --- stap
++# TODO: PCRE2 use different option values from PCRE
+ probe process("$LIBPCRE_PATH").function("pcre_compile") {
+     printf("compile opts: %x\n", $options)
+ }
+@@ -645,8 +652,14 @@ end
+ --- request
+     GET /re
+---- response_body
+-error: pcre_exec() failed: -8
++--- response_body eval
++# lua_regex_match_limit uses pcre_extra->match_limit in the PCRE,
++# but PCRE2 replaces this with pcre2_set_match_limit interface,
++# which has different effects.
++$Test::Nginx::Util::PcreVersion == 2 ?
++"failed to match.\n"
++:
++"error: pcre_exec() failed: -8\n"
+ --- no_error_log
+ [error]
+--- a/nginx-mod-lua/util/build-with-dd.sh
++++ b/nginx-mod-lua/util/build-with-dd.sh
+@@ -20,9 +20,13 @@ fi
+ disable_pcre2=--without-pcre2
+ answer=`$root/util/ver-ge "$NGINX_VERSION" 1.25.1`
+-if [ "$answer" = "N" ]; then
++if [ "$answer" = "N" ] || [ "$USE_PCRE2" = "Y" ]; then
+     disable_pcre2=""
+ fi
++if [ "$USE_PCRE2" = "Y" ]; then
++    PCRE_INC=$PCRE2_INC
++    PCRE_LIB=$PCRE2_LIB
++fi
+ time ngx-build $force $version \
+             --with-threads \
+--- a/nginx-mod-lua/util/build-without-ssl.sh
++++ b/nginx-mod-lua/util/build-without-ssl.sh
+@@ -26,9 +26,13 @@ add_fake_shm_module="--add-module=$root/
+ disable_pcre2=--without-pcre2
+ answer=`$root/util/ver-ge "$NGINX_VERSION" 1.25.1`
+-if [ "$answer" = "N" ]; then
++if [ "$answer" = "N" ] || [ "$USE_PCRE2" = "Y" ]; then
+     disable_pcre2=""
+ fi
++if [ "$USE_PCRE2" = "Y" ]; then
++    PCRE_INC=$PCRE2_INC
++    PCRE_LIB=$PCRE2_LIB
++fi
+ time ngx-build $force $version \
+             --with-threads \
+--- a/nginx-mod-lua/util/build.sh
++++ b/nginx-mod-lua/util/build.sh
+@@ -32,9 +32,13 @@ fi
+ disable_pcre2=--without-pcre2
+ answer=`$root/util/ver-ge "$NGINX_VERSION" 1.25.1`
+-if [ "$answer" = "N" ]; then
++if [ "$answer" = "N" ] || [ "$USE_PCRE2" = "Y" ]; then
+     disable_pcre2=""
+ fi
++if [ "$USE_PCRE2" = "Y" ]; then
++    PCRE_INC=$PCRE2_INC
++    PCRE_LIB=$PCRE2_LIB
++fi
+ time ngx-build $force $version \
+             --with-threads \
+--- a/nginx-mod-lua/valgrind.suppress
++++ b/nginx-mod-lua/valgrind.suppress
+@@ -234,3 +234,73 @@
+    fun:ngx_pass_open_channel
+    fun:ngx_start_privileged_agent_processes
+ }
++{
++   <insert_a_suppression_name_here>
++   Memcheck:Leak
++   match-leak-kinds: definite
++   fun:malloc
++   fun:ngx_alloc
++   fun:ngx_regex_malloc
++   fun:pcre2_compile_context_create_8
++   fun:ngx_regex_compile
++   fun:ngx_http_regex_compile
++   fun:ngx_http_core_regex_location
++   fun:ngx_http_core_location
++   fun:ngx_conf_handler
++   fun:ngx_conf_parse
++   fun:ngx_http_core_server
++   fun:ngx_conf_handler
++   fun:ngx_conf_parse
++   fun:ngx_http_block
++   fun:ngx_conf_handler
++   fun:ngx_conf_parse
++   fun:ngx_init_cycle
++   fun:main
++}
++{
++   <insert_a_suppression_name_here>
++   Memcheck:Leak
++   match-leak-kinds: definite
++   fun:malloc
++   fun:ngx_alloc
++   fun:ngx_regex_malloc
++   fun:pcre2_compile_context_create_8
++   fun:ngx_regex_compile
++   fun:ngx_http_regex_compile
++   fun:ngx_http_rewrite
++   fun:ngx_conf_handler
++   fun:ngx_conf_parse
++   fun:ngx_http_core_location
++   fun:ngx_conf_handler
++   fun:ngx_conf_parse
++   fun:ngx_http_core_server
++   fun:ngx_conf_handler
++   fun:ngx_conf_parse
++   fun:ngx_http_block
++   fun:ngx_conf_handler
++   fun:ngx_conf_parse
++   fun:ngx_init_cycle
++   fun:main
++}
++{
++   <insert_a_suppression_name_here>
++   Memcheck:Leak
++   match-leak-kinds: definite
++   fun:malloc
++   fun:ngx_alloc
++   fun:ngx_regex_malloc
++   fun:pcre2_compile_context_create_8
++   fun:ngx_regex_compile
++   fun:ngx_http_regex_compile
++   fun:ngx_http_rewrite
++   fun:ngx_conf_handler
++   fun:ngx_conf_parse
++   fun:ngx_http_core_server
++   fun:ngx_conf_handler
++   fun:ngx_conf_parse
++   fun:ngx_http_block
++   fun:ngx_conf_handler
++   fun:ngx_conf_parse
++   fun:ngx_init_cycle
++   fun:main
++}
+--- a/nginx-mod-lua/t/cert/test.crt
++++ b/nginx-mod-lua/t/cert/test.crt
+@@ -1,17 +1,22 @@
+ -----BEGIN CERTIFICATE-----
+-MIICqTCCAhICCQClDm1WkreW4jANBgkqhkiG9w0BAQUFADCBlzELMAkGA1UEBhMC
+-VVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDVNhbiBGcmFuY2lzY28x
+-EjAQBgNVBAoMCU9wZW5SZXN0eTESMBAGA1UECwwJT3BlblJlc3R5MREwDwYDVQQD
+-DAh0ZXN0LmNvbTEgMB4GCSqGSIb3DQEJARYRYWdlbnR6aEBnbWFpbC5jb20wIBcN
+-MTQwNzIxMDMyMzQ3WhgPMjE1MTA2MTMwMzIzNDdaMIGXMQswCQYDVQQGEwJVUzET
+-MBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzESMBAG
+-A1UECgwJT3BlblJlc3R5MRIwEAYDVQQLDAlPcGVuUmVzdHkxETAPBgNVBAMMCHRl
+-c3QuY29tMSAwHgYJKoZIhvcNAQkBFhFhZ2VudHpoQGdtYWlsLmNvbTCBnzANBgkq
+-hkiG9w0BAQEFAAOBjQAwgYkCgYEA6P18zUvtmaKQK2xePy8ZbFwSyTLw+jW6t9eZ
+-aiTec8X3ibN9WemrxHzkTRikxP3cAQoITRuZiQvF4Q7DO6wMkz/b0zwfgX5uedGq
+-047AJP6n/mwlDOjGSNomBLoXQzo7tVe60ikEm3ZyDUqnJPJMt3hImO5XSop4MPMu
+-Za9WhFcCAwEAATANBgkqhkiG9w0BAQUFAAOBgQA4OBb9bOyWB1//93nSXX1mdENZ
+-IQeyTK0Dd6My76lnZxnZ4hTWrvvd0b17KLDU6JnS2N5ee3ATVkojPidRLWLIhnh5
+-0eXrcKalbO2Ce6nShoFvQCQKXN2Txmq2vO/Mud2bHAWwJALg+qi1Iih/gVYB9sct
+-FLg8zFOzRlYiU+6Mmw==
++MIIDtzCCAp8CFCJnLifDCaXjYb2ARKBBhs+aAgYOMA0GCSqGSIb3DQEBCwUAMIGX
++MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2Fu
++IEZyYW5jaXNjbzESMBAGA1UECgwJT3BlblJlc3R5MRIwEAYDVQQLDAlPcGVuUmVz
++dHkxETAPBgNVBAMMCHRlc3QuY29tMSAwHgYJKoZIhvcNAQkBFhFhZ2VudHpoQGdt
++YWlsLmNvbTAeFw0yMzA5MDUwNDE5MjhaFw0zMzA5MDIwNDE5MjhaMIGXMQswCQYD
++VQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5j
++aXNjbzESMBAGA1UECgwJT3BlblJlc3R5MRIwEAYDVQQLDAlPcGVuUmVzdHkxETAP
++BgNVBAMMCHRlc3QuY29tMSAwHgYJKoZIhvcNAQkBFhFhZ2VudHpoQGdtYWlsLmNv
++bTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJzRMFoLDuYOwJ8szrS4
++nOibtiimiXZJGx3I/RcFZxaH4nL/WcEb1fwftMQxx73IBJnqnDYkDOzUmzItPMn0
++t2WrNYesC5GqLNRm87m6PVt010tZvq/WxTn6+9qruiGm1PhFxzLQfrClpEeOshlG
++UeoQjPOMrhCmofDM2NQo3D4wIQT0kCJxIPq6wCZt22/Yqz1EmR0UnF/R3ZtiB8O+
++SQGcsUKy4se3919xq+ZkzBdMxLneO5sofUiDC9MgRfiU960tbHPGX9I9P+kLK89S
++yajPEYaRUkSBFjV5kdDK3+L6XckdMbY2pvwhAnVXSmd13Bf2V9XisUrX2Mr4YlnS
++sy0CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAVPY/z6Mvjg5EGHzU8bXyuXqxrx8Q
++GBwf3PY25aDF6ofRrTCzMdIhthv8eRtGwHinkpgaK34D7hI/dPB7aswQTzED5c+l
++S2au5OzzCj454oXdhSRA5Rt0mu/+pxmQ+iNk+7XJxgTN0mk1dYQqodyZ+vC4NIYb
++javMlU4zDm4JPtwDs0Mz/d7gf14MU60jppF2vl6AYFHKYBLMHBmqxjy6H9YHjRjQ
++oe4TNpn0zxJAPu5LqMkfB2+eLOe6ced7DcLLbbeVJ4Xtqj6Y5KsAyVojWQxrk4vW
++3WO/953pHofO5F2ricS/rsf+5ivTmfiP8mQYTtp7k3T11sIZ4DOmtNwO4A==
+ -----END CERTIFICATE-----
+--- a/nginx-mod-lua/t/cert/test.key
++++ b/nginx-mod-lua/t/cert/test.key
+@@ -1,15 +1,28 @@
+------BEGIN RSA PRIVATE KEY-----
+-MIICXgIBAAKBgQDo/XzNS+2ZopArbF4/LxlsXBLJMvD6Nbq315lqJN5zxfeJs31Z
+-6avEfORNGKTE/dwBCghNG5mJC8XhDsM7rAyTP9vTPB+Bfm550arTjsAk/qf+bCUM
+-6MZI2iYEuhdDOju1V7rSKQSbdnINSqck8ky3eEiY7ldKingw8y5lr1aEVwIDAQAB
+-AoGBANgB66sKMga2SKN5nQdHS3LDCkevCutu1OWM5ZcbB4Kej5kC57xsf+tzPtab
+-emeIVGhCPOAALqB4YcT+QtMX967oM1MjcFbtH7si5oq6UYyp3i0G9Si6jIoVHz3+
+-8yOUaqwKbK+bRX8VS0YsHZmBsPK5ryN50iUwsU08nemoA94BAkEA9GS9Q5OPeFkM
+-tFxsIQ1f2FSsZAuN/1cpZgJqY+YaAN7MSPGTWyfd7nWG/Zgk3GO9/2ihh4gww+7B
+-To09GkmW4QJBAPQOHC2V+t2TA98+6Lj6+TYwcGEkhOENfVpH25mQ+kXgF/1Bd6rA
+-nosT1bdAY+SnmWXbSw6Kv5C20Em+bEX8WjcCQCSRRjhsRdVODbaW9Z7kb2jhEoJN
+-sEt6cTlQNzcHYPCsZYisjM3g4zYg47fiIfHQAsfKkhDDcfh/KvFj9LaQOEECQQCH
+-eBWYEDpSJ7rsfqT7mQQgWj7nDThdG/nK1TxGP71McBmg0Gg2dfkLRhVJRQqt74Is
+-kc9V4Rp4n6F6baL4Lh19AkEA6pZZer0kg3Kv9hjhaITIKUYdfIp9vYnDRWbQlBmR
+-atV8V9u9q2ETZvqfHpN+9Lu6NYR4yXIEIRf1bnIZ/mr9eQ==
+------END RSA PRIVATE KEY-----
++-----BEGIN PRIVATE KEY-----
++MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCc0TBaCw7mDsCf
++LM60uJzom7Yopol2SRsdyP0XBWcWh+Jy/1nBG9X8H7TEMce9yASZ6pw2JAzs1Jsy
++LTzJ9LdlqzWHrAuRqizUZvO5uj1bdNdLWb6v1sU5+vvaq7ohptT4Rccy0H6wpaRH
++jrIZRlHqEIzzjK4QpqHwzNjUKNw+MCEE9JAicSD6usAmbdtv2Ks9RJkdFJxf0d2b
++YgfDvkkBnLFCsuLHt/dfcavmZMwXTMS53jubKH1IgwvTIEX4lPetLWxzxl/SPT/p
++CyvPUsmozxGGkVJEgRY1eZHQyt/i+l3JHTG2Nqb8IQJ1V0pnddwX9lfV4rFK19jK
+++GJZ0rMtAgMBAAECggEABjaOkcllis1o/yrVZMPPabLpAHV6tZ5MuKfNiUOMSPr+
++HfF1OFQL7MxCdfyFQ1prqOp/9nAut+puMgp99wAfDQ7qanNGq7vgQKkfPSD+dy4V
++rUquELBJH6nh9SZqfpSqKaJgHlNe6vehHuRYikJRkrJwVzegGjuekm3B+y6Zl/gc
++e0p5Ha3MTLTFjocwYzgTjJlxD40wlbjpuVnmzKjo8AKNv1F1azMaqBmt1VfPiDn0
++Xyq4SPEsWKnEAl2kZdaIBR6zIx7Z3zNUwkfb32QwNoSyo8wS7lCgf2GVS7r1Eul6
++iiCE/Gd7w10alW4Pu96shVqkvKn7ROF2nBP9xOSPwQKBgQDCuD6mlNpA07iOX364
++aAzIAYookceVA0I9L/fbOQW7RgpvYpM8lxr31TQ3fBDkXSgjzMMYjnk4kz+xN+BB
++WFdjb4raUBtrvip8Q8QZ53DVQK/LodHh0XhipbOxZrDm+6o5nQD0fTqHCBIHSVFF
++tXX2Y90t1cxWMMleRhfNEuzkQQKBgQDOK0rs7mf04Xhc4ZIRIxOtNFnthGp4Kqp7
++SD8VQpbPOLV8iqZEtXIy/hvoTpfQW30c1931KgDQ3Pv5MZYpI7PLqrqkj4tGCQ91
++DJ03GWkSXcMwlPmJRbvgWIeCLgShU5PLxmQu3mH2DP+uGFUBq5/6miDDVjF9z6vb
++BwYlG66j7QKBgA0n/bOrowN2SqXz9c/n19U7pWYQU3fR/Iu9zfVV6Pk6RkI4WtJh
++M0VDdn+5Njr3wFqK3zOtjKsx57/FkrVXjq/9PVh6yR+CfcRfn8RQSuNdt4L+r/ud
++95BSuc1mrtUsc9for8PVIjs1ZGJxpbgcBphbLvqF04SPT0u7WKhWewMBAoGAcJO/
++RAUiitsbaExcADORKQDvIf0uThOuJ8dZevhzdQ/YOftTsy0JAMM05fMUfteWR8uw
++DZE0BNjGVlo3TpuKL+o4JGele0azRAzxRAcCEt9UGBEg+U40utpclD8glB8ZEypv
++xg/0mfCbJKtwr4rRvnuu7DsCp1pg0ybQui6VfDkCgYBXHwcrZwmv7kgr4pUG6oZj
++fzjFenQFqibvb2h7QESyCW13O885GxU13DKv4zg1yi6EqPIopz16qCiUNCvWr5Us
++6sI74wEVI3MzmzG0Htgl29q5yWpeY+7libC/fbZYG8GFgdINq58ko9be1u/8644S
++t2hoKM9/vrVFh9p9qGzckg==
++-----END PRIVATE KEY-----
index b51c5e4049172d612db0ba87e4b8bbdcf5e9cdc9..1572a4cbbf3b25d8a526815fc778c2ea520d3c01 100644 (file)
@@ -1,6 +1,6 @@
 --- a/nginx-mod-lua/src/ngx_http_lua_module.c
 +++ b/nginx-mod-lua/src/ngx_http_lua_module.c
-@@ -207,12 +207,14 @@ static ngx_command_t ngx_http_lua_cmds[]
+@@ -212,12 +212,14 @@ static ngx_command_t ngx_http_lua_cmds[]
        offsetof(ngx_http_lua_loc_conf_t, log_socket_errors),
        NULL },
  
@@ -15,7 +15,7 @@
  
      { ngx_string("init_by_lua"),
        NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
-@@ -228,12 +230,14 @@ static ngx_command_t ngx_http_lua_cmds[]
+@@ -233,12 +235,14 @@ static ngx_command_t ngx_http_lua_cmds[]
        0,
        (void *) ngx_http_lua_init_by_file },
  
@@ -30,7 +30,7 @@
  
      { ngx_string("init_worker_by_lua"),
        NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
-@@ -249,12 +253,14 @@ static ngx_command_t ngx_http_lua_cmds[]
+@@ -254,12 +258,14 @@ static ngx_command_t ngx_http_lua_cmds[]
        0,
        (void *) ngx_http_lua_init_worker_by_file },
  
@@ -45,7 +45,7 @@
  
      { ngx_string("exit_worker_by_lua_file"),
        NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
-@@ -264,6 +270,7 @@ static ngx_command_t ngx_http_lua_cmds[]
+@@ -269,6 +275,7 @@ static ngx_command_t ngx_http_lua_cmds[]
        (void *) ngx_http_lua_exit_worker_by_file },
  
  #if defined(NDK) && NDK
@@ -53,7 +53,7 @@
      /* set_by_lua_block $res { inline Lua code } */
      { ngx_string("set_by_lua_block"),
        NGX_HTTP_SRV_CONF|NGX_HTTP_SIF_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
-@@ -272,6 +279,7 @@ static ngx_command_t ngx_http_lua_cmds[]
+@@ -277,6 +284,7 @@ static ngx_command_t ngx_http_lua_cmds[]
        NGX_HTTP_LOC_CONF_OFFSET,
        0,
        (void *) ngx_http_lua_filter_set_by_lua_inline },
@@ -61,7 +61,7 @@
  
      /* set_by_lua $res <inline script> [$arg1 [$arg2 [...]]] */
      { ngx_string("set_by_lua"),
-@@ -292,6 +300,7 @@ static ngx_command_t ngx_http_lua_cmds[]
+@@ -297,6 +305,7 @@ static ngx_command_t ngx_http_lua_cmds[]
        (void *) ngx_http_lua_filter_set_by_lua_file },
  #endif
  
@@ -69,7 +69,7 @@
      /* server_rewrite_by_lua_block { <inline script> } */
      { ngx_string("server_rewrite_by_lua_block"),
          NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
-@@ -299,6 +308,7 @@ static ngx_command_t ngx_http_lua_cmds[]
+@@ -304,6 +313,7 @@ static ngx_command_t ngx_http_lua_cmds[]
          NGX_HTTP_SRV_CONF_OFFSET,
          0,
          (void *) ngx_http_lua_server_rewrite_handler_inline },
@@ -77,7 +77,7 @@
  
      /* server_rewrite_by_lua_file filename; */
      { ngx_string("server_rewrite_by_lua_file"),
-@@ -317,6 +327,7 @@ static ngx_command_t ngx_http_lua_cmds[]
+@@ -322,6 +332,7 @@ static ngx_command_t ngx_http_lua_cmds[]
        0,
        (void *) ngx_http_lua_rewrite_handler_inline },
  
@@ -85,7 +85,7 @@
      /* rewrite_by_lua_block { <inline script> } */
      { ngx_string("rewrite_by_lua_block"),
        NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
-@@ -325,6 +336,7 @@ static ngx_command_t ngx_http_lua_cmds[]
+@@ -330,6 +341,7 @@ static ngx_command_t ngx_http_lua_cmds[]
        NGX_HTTP_LOC_CONF_OFFSET,
        0,
        (void *) ngx_http_lua_rewrite_handler_inline },
@@ -93,7 +93,7 @@
  
      /* access_by_lua "<inline script>" */
      { ngx_string("access_by_lua"),
-@@ -335,6 +347,7 @@ static ngx_command_t ngx_http_lua_cmds[]
+@@ -340,6 +352,7 @@ static ngx_command_t ngx_http_lua_cmds[]
        0,
        (void *) ngx_http_lua_access_handler_inline },
  
      /* access_by_lua_block { <inline script> } */
      { ngx_string("access_by_lua_block"),
        NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
-@@ -343,6 +356,7 @@ static ngx_command_t ngx_http_lua_cmds[]
+@@ -348,6 +361,7 @@ static ngx_command_t ngx_http_lua_cmds[]
        NGX_HTTP_LOC_CONF_OFFSET,
        0,
        (void *) ngx_http_lua_access_handler_inline },
  
      /* content_by_lua "<inline script>" */
      { ngx_string("content_by_lua"),
-@@ -352,6 +366,7 @@ static ngx_command_t ngx_http_lua_cmds[]
+@@ -357,6 +371,7 @@ static ngx_command_t ngx_http_lua_cmds[]
        0,
        (void *) ngx_http_lua_content_handler_inline },
  
      /* content_by_lua_block { <inline script> } */
      { ngx_string("content_by_lua_block"),
        NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
-@@ -359,6 +374,7 @@ static ngx_command_t ngx_http_lua_cmds[]
+@@ -364,6 +379,7 @@ static ngx_command_t ngx_http_lua_cmds[]
        NGX_HTTP_LOC_CONF_OFFSET,
        0,
        (void *) ngx_http_lua_content_handler_inline },
  
      /* log_by_lua <inline script> */
      { ngx_string("log_by_lua"),
-@@ -369,6 +385,7 @@ static ngx_command_t ngx_http_lua_cmds[]
+@@ -374,6 +390,7 @@ static ngx_command_t ngx_http_lua_cmds[]
        0,
        (void *) ngx_http_lua_log_handler_inline },
  
      /* log_by_lua_block { <inline script> } */
      { ngx_string("log_by_lua_block"),
        NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
-@@ -377,6 +394,7 @@ static ngx_command_t ngx_http_lua_cmds[]
+@@ -382,6 +399,7 @@ static ngx_command_t ngx_http_lua_cmds[]
        NGX_HTTP_LOC_CONF_OFFSET,
        0,
        (void *) ngx_http_lua_log_handler_inline },
  
      { ngx_string("rewrite_by_lua_file"),
        NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
-@@ -433,6 +451,7 @@ static ngx_command_t ngx_http_lua_cmds[]
+@@ -438,6 +456,7 @@ static ngx_command_t ngx_http_lua_cmds[]
        0,
        (void *) ngx_http_lua_header_filter_inline },
  
      /* header_filter_by_lua_block { <inline script> } */
      { ngx_string("header_filter_by_lua_block"),
        NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
-@@ -441,6 +460,7 @@ static ngx_command_t ngx_http_lua_cmds[]
+@@ -446,6 +465,7 @@ static ngx_command_t ngx_http_lua_cmds[]
        NGX_HTTP_LOC_CONF_OFFSET,
        0,
        (void *) ngx_http_lua_header_filter_inline },
  
      { ngx_string("header_filter_by_lua_file"),
        NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
-@@ -458,6 +478,7 @@ static ngx_command_t ngx_http_lua_cmds[]
+@@ -463,6 +483,7 @@ static ngx_command_t ngx_http_lua_cmds[]
        0,
        (void *) ngx_http_lua_body_filter_inline },
  
      /* body_filter_by_lua_block { <inline script> } */
      { ngx_string("body_filter_by_lua_block"),
        NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
-@@ -466,6 +487,7 @@ static ngx_command_t ngx_http_lua_cmds[]
+@@ -471,6 +492,7 @@ static ngx_command_t ngx_http_lua_cmds[]
        NGX_HTTP_LOC_CONF_OFFSET,
        0,
        (void *) ngx_http_lua_body_filter_inline },
  
      { ngx_string("body_filter_by_lua_file"),
        NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
-@@ -475,12 +497,14 @@ static ngx_command_t ngx_http_lua_cmds[]
+@@ -480,12 +502,14 @@ static ngx_command_t ngx_http_lua_cmds[]
        0,
        (void *) ngx_http_lua_body_filter_file },
  
  
      { ngx_string("balancer_by_lua_file"),
        NGX_HTTP_UPS_CONF|NGX_CONF_TAKE1,
-@@ -585,12 +609,14 @@ static ngx_command_t ngx_http_lua_cmds[]
+@@ -590,12 +614,14 @@ static ngx_command_t ngx_http_lua_cmds[]
        offsetof(ngx_http_lua_loc_conf_t, ssl_ciphers),
        NULL },
  
  
      { ngx_string("ssl_client_hello_by_lua_file"),
        NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
-@@ -599,12 +625,14 @@ static ngx_command_t ngx_http_lua_cmds[]
+@@ -604,12 +630,14 @@ static ngx_command_t ngx_http_lua_cmds[]
        0,
        (void *) ngx_http_lua_ssl_client_hello_handler_file },
  
  
      { ngx_string("ssl_certificate_by_lua_file"),
        NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
-@@ -613,12 +641,14 @@ static ngx_command_t ngx_http_lua_cmds[]
+@@ -618,12 +646,14 @@ static ngx_command_t ngx_http_lua_cmds[]
        0,
        (void *) ngx_http_lua_ssl_cert_handler_file },
  
  
      { ngx_string("ssl_session_store_by_lua_file"),
        NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
-@@ -627,12 +657,14 @@ static ngx_command_t ngx_http_lua_cmds[]
+@@ -632,12 +662,14 @@ static ngx_command_t ngx_http_lua_cmds[]
        0,
        (void *) ngx_http_lua_ssl_sess_store_handler_file },