diff --git a/.github/workflows/staging.yml b/.github/workflows/staging.yml index a61b89d8a..97f146cbe 100644 --- a/.github/workflows/staging.yml +++ b/.github/workflows/staging.yml @@ -201,7 +201,7 @@ jobs: needs: [code-security, build-ui] uses: ./.github/workflows/staging-tests-ui.yml with: - MODE: STAGING + MODE: staging secrets: PRIVATE_REGISTRY: ${{ secrets.PRIVATE_REGISTRY }} PRIVATE_REGISTRY_TOKEN: ${{ secrets.PRIVATE_REGISTRY_TOKEN }} diff --git a/misc/integrations/k8s.mariadb.yml b/misc/integrations/k8s.mariadb.yml index 4b8ac0527..f294bee28 100644 --- a/misc/integrations/k8s.mariadb.yml +++ b/misc/integrations/k8s.mariadb.yml @@ -93,6 +93,8 @@ spec: periodSeconds: 1 timeoutSeconds: 1 failureThreshold: 3 + #imagePullSecrets: + #- name: secret-registry --- apiVersion: apps/v1 kind: Deployment @@ -120,6 +122,8 @@ spec: value: "yes" - name: "DATABASE_URI" value: "mariadb+pymysql://bunkerweb:changeme@svc-bunkerweb-db:3306/db" + #imagePullSecrets: + #- name: secret-registry --- apiVersion: apps/v1 kind: Deployment @@ -146,6 +150,8 @@ spec: value: "yes" - name: "DATABASE_URI" value: "mariadb+pymysql://bunkerweb:changeme@svc-bunkerweb-db:3306/db" + #imagePullSecrets: + #- name: secret-registry --- apiVersion: apps/v1 kind: Deployment diff --git a/src/deps/clone.sh b/src/deps/clone.sh index ce71e3c15..36d046573 100755 --- a/src/deps/clone.sh +++ b/src/deps/clone.sh @@ -152,13 +152,13 @@ fi echo "ℹ️ Downloading LuaJIT" git_secure_clone "https://github.com/openresty/luajit2.git" "8384278b14988390cf030b787537aa916a9709bb" -# lua-nginx-module v0.10.22 +# lua-nginx-module v0.10.23 echo "ℹ️ Downloading lua-nginx-module" -git_secure_clone "https://github.com/openresty/lua-nginx-module.git" "8d9032298ef542aef058fa02940a6ecd9cf25423" +git_secure_clone "https://github.com/openresty/lua-nginx-module.git" "5e05fa3adb0d2492ecaaf2cb76498e23765aa6ab" -# lua-resty-core v0.1.24 +# lua-resty-core v0.1.25 echo "ℹ️ Downloading lua-resty-core" -git_secure_clone "https://github.com/openresty/lua-resty-core.git" "c48e90a8fc9d974d8a6a369e031940cedf473789" +git_secure_clone "https://github.com/openresty/lua-resty-core.git" "0173d96c9eb77b513b989b765716fd2498f09dd9" # lua-resty-lrucache v0.13 echo "ℹ️ Downloading lua-resty-lrucache" diff --git a/src/deps/src/lua-nginx-module/.github/workflows/semantic-pull-request.yml b/src/deps/src/lua-nginx-module/.github/workflows/semantic-pull-request.yml new file mode 100644 index 000000000..12b87cb3c --- /dev/null +++ b/src/deps/src/lua-nginx-module/.github/workflows/semantic-pull-request.yml @@ -0,0 +1,30 @@ +name: "Lint PR" + +on: + pull_request_target: + types: + - opened + - edited + - synchronize + +jobs: + main: + name: Validate PR title + runs-on: ubuntu-latest + steps: + - uses: amannn/action-semantic-pull-request@v4 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + # Configure which types are allowed. + # Default: https://github.com/commitizen/conventional-commit-types + types: | + bugfix # bug fixes + change # backward incompatible changes + doc # documentation changes including code comments + editor # code editor related configurations + feature # implementing a new feature + optimize # performance optimizations + refactor # code refactoring and other code rearrangement + style # coding style changes + tests # test suite changes diff --git a/src/deps/src/lua-nginx-module/.travis.yml b/src/deps/src/lua-nginx-module/.travis.yml index f4cc579b3..54f2ab5b1 100644 --- a/src/deps/src/lua-nginx-module/.travis.yml +++ b/src/deps/src/lua-nginx-module/.travis.yml @@ -14,6 +14,7 @@ compiler: addons: apt: packages: + - ack - axel - cpanminus - libtest-base-perl @@ -36,7 +37,7 @@ env: - LUAJIT_LIB=$LUAJIT_PREFIX/lib - LUAJIT_INC=$LUAJIT_PREFIX/include/luajit-2.1 - LUA_INCLUDE_DIR=$LUAJIT_INC - - PCRE_VER=8.44 + - PCRE_VER=8.45 - PCRE_PREFIX=/opt/pcre - PCRE_LIB=$PCRE_PREFIX/lib - PCRE_INC=$PCRE_PREFIX/include @@ -51,7 +52,7 @@ env: - TEST_NGINX_SLEEP=0.006 jobs: - 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.1l OPENSSL_PATCH_VER=1.1.1f + - NGINX_VERSION=1.21.4 OPENSSL_VER=1.1.1s OPENSSL_PATCH_VER=1.1.1f services: - memcached @@ -129,8 +130,12 @@ script: - sudo make PATH=$PATH install_sw > build.log 2>&1 || (cat build.log && exit 1) - cd .. - export NGX_BUILD_CC=$CC + - sh util/build-without-ssl.sh $NGINX_VERSION > build.log 2>&1 || (cat build.log && exit 1) + - sh util/build-with-dd.sh $NGINX_VERSION > build.log 2>&1 || (cat build.log && exit 1) + - rm -fr buildroot - sh util/build.sh $NGINX_VERSION > build.log 2>&1 || (cat build.log && exit 1) - nginx -V + - python3 ./util/nc_server.py & - ldd `which nginx`|grep -E 'luajit|ssl|pcre' - export LD_PRELOAD=$PWD/mockeagain/mockeagain.so - export LD_LIBRARY_PATH=$PWD/mockeagain:$LD_LIBRARY_PATH @@ -138,4 +143,4 @@ script: - dig +short myip.opendns.com @resolver1.opendns.com || exit 0 - dig +short @$TEST_NGINX_RESOLVER openresty.org || exit 0 - dig +short @$TEST_NGINX_RESOLVER agentzh.org || exit 0 - - prove -I. -Itest-nginx/lib -r t + - prove -I. -Itest-nginx/lib -r t/ diff --git a/src/deps/src/lua-nginx-module/README.markdown b/src/deps/src/lua-nginx-module/README.markdown index d6560185c..d85c6b662 100644 --- a/src/deps/src/lua-nginx-module/README.markdown +++ b/src/deps/src/lua-nginx-module/README.markdown @@ -9,6 +9,8 @@ then you are essentially using OpenResty. *This module is not distributed with the Nginx source.* See [the installation instructions](#installation). +This is a core component of OpenResty. If you are using this module, then you are essentially using OpenResty :) + Table of Contents ================= @@ -347,6 +349,8 @@ Alternatively, ngx_lua can be manually compiled into Nginx: 1. Download the latest version of the ngx_devel_kit (NDK) module [HERE](https://github.com/simplresty/ngx_devel_kit/tags) 1. Download the latest version of ngx_lua [HERE](https://github.com/openresty/lua-nginx-module/tags) 1. Download the latest supported version of Nginx [HERE](https://nginx.org/) (See [Nginx Compatibility](#nginx-compatibility)) +1. Download the latest version of the lua-resty-core [HERE](https://github.com/openresty/lua-resty-core) +1. Download the latest version of the lua-resty-lrucache [HERE](https://github.com/openresty/lua-resty-lrucache) Build the source with this module: @@ -378,6 +382,18 @@ Build the source with this module: # machine. make -j2 make install + + # Note that this version of lug-nginx-module not allow to set `lua_load_resty_core off;` any more. + # So, you have to install `lua-resty-core` and `lua-resty-lrucache` manually as below. + + cd lua-resty-core + make install PREFIX=/opt/nginx + cd lua-resty-lrucache + make install PREFIX=/opt/nginx + + # add necessary `lua_package_path` directive to `nginx.conf`, in the http context + + lua_package_path "/opt/nginx/lib/lua/?.lua;;"; ``` [Back to TOC](#table-of-contents) @@ -952,12 +968,10 @@ TODO * cosocket: review and merge aviramc's [patch](https://github.com/openresty/lua-nginx-module/pull/290) for adding the `bsdrecv` method. * cosocket: add configure options for different strategies of handling the cosocket connection exceeding in the pools. * review and apply vadim-pavlov's patch for [ngx.location.capture](#ngxlocationcapture)'s `extra_headers` option -* use `ngx_hash_t` to optimize the built-in header look-up process for [ngx.req.set_header](#ngxreqset_header), [ngx.header.HEADER](#ngxheaderheader), and etc. -* add directives to run Lua codes when Nginx stops. +* use `ngx_hash_t` to optimize the built-in header look-up process for [ngx.req.set_header](#ngxreqset_header), and etc. * add `ignore_resp_headers`, `ignore_resp_body`, and `ignore_resp` options to [ngx.location.capture](#ngxlocationcapture) and [ngx.location.capture_multi](#ngxlocationcapture_multi) methods, to allow micro performance tuning on the user side. * add automatic Lua code time slicing support by yielding and resuming the Lua VM actively via Lua's debug hooks. * add `stat` mode similar to [mod_lua](https://httpd.apache.org/docs/trunk/mod/mod_lua.html). -* cosocket: add client SSL certificate support. [Back to TOC](#table-of-contents) @@ -1112,6 +1126,8 @@ Directives * [content_by_lua](#content_by_lua) * [content_by_lua_block](#content_by_lua_block) * [content_by_lua_file](#content_by_lua_file) +* [server_rewrite_by_lua_block](#server_rewrite_by_lua_block) +* [server_rewrite_by_lua_file](#server_rewrite_by_lua_file) * [rewrite_by_lua](#rewrite_by_lua) * [rewrite_by_lua_block](#rewrite_by_lua_block) * [rewrite_by_lua_file](#rewrite_by_lua_file) @@ -1438,9 +1454,33 @@ init_by_lua **NOTE** Use of this directive is *discouraged* following the `v0.9.17` release. Use the [init_by_lua_block](#init_by_lua_block) directive instead. -Runs the Lua code specified by the argument `` on the global Lua VM level when the Nginx master process (if any) is loading the Nginx config file. +Similar to the [init_by_lua_block](#init_by_lua_block) directive, but accepts the Lua source directly in an Nginx string literal (which requires +special character escaping). -When Nginx receives the `HUP` signal and starts reloading the config file, the Lua VM will also be re-created and `init_by_lua` will run again on the new Lua VM. In case that the [lua_code_cache](#lua_code_cache) directive is turned off (default on), the `init_by_lua` handler will run upon every request because in this special mode a standalone Lua VM is always created for each request. +For instance, + +```nginx + + init_by_lua ' + print("I need no extra escaping here, for example: \r\nblah") + ' +``` + +This directive was first introduced in the `v0.5.5` release. + +[Back to TOC](#directives) + +init_by_lua_block +----------------- + +**syntax:** *init_by_lua_block { lua-script }* + +**context:** *http* + +**phase:** *loading-config* + + +When Nginx receives the `HUP` signal and starts reloading the config file, the Lua VM will also be re-created and `init_by_lua_block` will run again on the new Lua VM. In case that the [lua_code_cache](#lua_code_cache) directive is turned off (default on), the `init_by_lua_block` handler will run upon every request because in this special mode a standalone Lua VM is always created for each request. Usually you can pre-load Lua modules at server start-up by means of this hook and take advantage of modern operating systems' copy-on-write (COW) optimization. Here is an example for pre-loading Lua modules: @@ -1481,11 +1521,11 @@ You can also initialize the [lua_shared_dict](#lua_shared_dict) shm storage at t } ``` -But note that, the [lua_shared_dict](#lua_shared_dict)'s shm storage will not be cleared through a config reload (via the `HUP` signal, for example). So if you do *not* want to re-initialize the shm storage in your `init_by_lua` code in this case, then you just need to set a custom flag in the shm storage and always check the flag in your `init_by_lua` code. +But note that, the [lua_shared_dict](#lua_shared_dict)'s shm storage will not be cleared through a config reload (via the `HUP` signal, for example). So if you do *not* want to re-initialize the shm storage in your `init_by_lua_block` code in this case, then you just need to set a custom flag in the shm storage and always check the flag in your `init_by_lua_block` code. Because the Lua code in this context runs before Nginx forks its worker processes (if any), data or code loaded here will enjoy the [Copy-on-write (COW)](https://en.wikipedia.org/wiki/Copy-on-write) feature provided by many operating systems among all the worker processes, thus saving a lot of memory. -Do *not* initialize your own Lua global variables in this context because use of Lua global variables have performance penalties and can lead to global namespace pollution (see the [Lua Variable Scope](#lua-variable-scope) section for more details). The recommended way is to use proper [Lua module](https://www.lua.org/manual/5.1/manual.html#5.3) files (but do not use the standard Lua function [module()](https://www.lua.org/manual/5.1/manual.html#pdf-module) to define Lua modules because it pollutes the global namespace as well) and call [require()](https://www.lua.org/manual/5.1/manual.html#pdf-require) to load your own module files in `init_by_lua` or other contexts ([require()](https://www.lua.org/manual/5.1/manual.html#pdf-require) does cache the loaded Lua modules in the global `package.loaded` table in the Lua registry so your modules will only loaded once for the whole Lua VM instance). +Do *not* initialize your own Lua global variables in this context because use of Lua global variables have performance penalties and can lead to global namespace pollution (see the [Lua Variable Scope](#lua-variable-scope) section for more details). The recommended way is to use proper [Lua module](https://www.lua.org/manual/5.1/manual.html#5.3) files (but do not use the standard Lua function [module()](https://www.lua.org/manual/5.1/manual.html#pdf-module) to define Lua modules because it pollutes the global namespace as well) and call [require()](https://www.lua.org/manual/5.1/manual.html#pdf-require) to load your own module files in `init_by_lua_block` or other contexts ([require()](https://www.lua.org/manual/5.1/manual.html#pdf-require) does cache the loaded Lua modules in the global `package.loaded` table in the Lua registry so your modules will only loaded once for the whole Lua VM instance). Only a small set of the [Nginx API for Lua](#nginx-api-for-lua) is supported in this context: @@ -1498,7 +1538,7 @@ Basically you can safely use Lua libraries that do blocking I/O in this very con You should be very careful about potential security vulnerabilities in your Lua code registered in this context because the Nginx master process is often run under the `root` account. -This directive was first introduced in the `v0.5.5` release. +This directive was first introduced in the `v0.9.17` release. See also the following blog posts for more details on OpenResty and Nginx's shared memory zones: @@ -1507,33 +1547,6 @@ See also the following blog posts for more details on OpenResty and Nginx's shar [Back to TOC](#directives) -init_by_lua_block ------------------ - -**syntax:** *init_by_lua_block { lua-script }* - -**context:** *http* - -**phase:** *loading-config* - -Similar to the [init_by_lua](#init_by_lua) directive except that this directive inlines -the Lua source directly -inside a pair of curly braces (`{}`) instead of in an Nginx string literal (which requires -special character escaping). - -For instance, - -```nginx - - init_by_lua_block { - print("I need no extra escaping here, for example: \r\nblah") - } -``` - -This directive was first introduced in the `v0.9.17` release. - -[Back to TOC](#directives) - init_by_lua_file ---------------- @@ -1543,7 +1556,7 @@ init_by_lua_file **phase:** *loading-config* -Equivalent to [init_by_lua](#init_by_lua), except that the file specified by `` contains the Lua code or [LuaJIT bytecode](#luajit-bytecode-support) to be executed. +Equivalent to [init_by_lua_block](#init_by_lua_block), except that the file specified by `` contains the Lua code or [LuaJIT bytecode](#luajit-bytecode-support) to be executed. When a relative path like `foo/bar.lua` is given, they will be turned into the absolute path relative to the `server prefix` path determined by the `-p PATH` command-line option while starting the Nginx server. @@ -1562,13 +1575,40 @@ init_worker_by_lua **NOTE** Use of this directive is *discouraged* following the `v0.9.17` release. Use the [init_worker_by_lua_block](#init_worker_by_lua_block) directive instead. -Runs the specified Lua code upon every Nginx worker process's startup when the master process is enabled. When the master process is disabled, this hook will just run after [init_by_lua*](#init_by_lua). +Similar to the [init_worker_by_lua_block](#init_worker_by_lua_block) directive, but accepts the Lua source directly in an Nginx string literal (which requires +special character escaping). + +For instance, + +```nginx + + init_worker_by_lua ' + print("I need no extra escaping here, for example: \r\nblah") + '; +``` + +This directive was first introduced in the `v0.9.5` release. + +This hook no longer runs in the cache manager and cache loader processes since the `v0.10.12` release. + +[Back to TOC](#directives) + +init_worker_by_lua_block +------------------------ + +**syntax:** *init_worker_by_lua_block { lua-script }* + +**context:** *http* + +**phase:** *starting-worker* + +Runs the specified Lua code upon every Nginx worker process's startup when the master process is enabled. When the master process is disabled, this hook will just run after [init_by_lua*](#init_by_lua_block). This hook is often used to create per-worker reoccurring timers (via the [ngx.timer.at](#ngxtimerat) Lua API), either for backend health-check or other timed routine work. Below is an example, ```nginx - init_worker_by_lua ' + init_worker_by_lua_block { local delay = 3 -- in seconds local new_timer = ngx.timer.at local log = ngx.log @@ -1595,35 +1635,6 @@ This hook is often used to create per-worker reoccurring timers (via the [ngx.ti end -- other job in init_worker_by_lua - '; -``` - -This directive was first introduced in the `v0.9.5` release. - -This hook no longer runs in the cache manager and cache loader processes since the `v0.10.12` release. - -[Back to TOC](#directives) - -init_worker_by_lua_block ------------------------- - -**syntax:** *init_worker_by_lua_block { lua-script }* - -**context:** *http* - -**phase:** *starting-worker* - -Similar to the [init_worker_by_lua](#init_worker_by_lua) directive except that this directive inlines -the Lua source directly -inside a pair of curly braces (`{}`) instead of in an Nginx string literal (which requires -special character escaping). - -For instance, - -```nginx - - init_worker_by_lua_block { - print("I need no extra escaping here, for example: \r\nblah") } ``` @@ -1642,7 +1653,7 @@ init_worker_by_lua_file **phase:** *starting-worker* -Similar to [init_worker_by_lua](#init_worker_by_lua), but accepts the file path to a Lua source file or Lua bytecode file. +Similar to [init_worker_by_lua_block](#init_worker_by_lua_block), but accepts the file path to a Lua source file or Lua bytecode file. This directive was first introduced in the `v0.9.5` release. @@ -1661,7 +1672,7 @@ exit_worker_by_lua_block Runs the specified Lua code upon every Nginx worker process's exit when the master process is enabled. When the master process is disabled, this hook will run before the Nginx process exits. -This hook is often used to release resources allocated by each worker (e.g. resources allocated by [init_worker_by_lua*](#init_worker_by_lua)), or to prevent workers from exiting abnormally. +This hook is often used to release resources allocated by each worker (e.g. resources allocated by [init_worker_by_lua*](#init_worker_by_lua_block)), or to prevent workers from exiting abnormally. For example, @@ -1704,48 +1715,16 @@ set_by_lua **NOTE** Use of this directive is *discouraged* following the `v0.9.17` release. Use the [set_by_lua_block](#set_by_lua_block) directive instead. -Executes code specified in `` with optional input arguments `$arg1 $arg2 ...`, and returns string output to `$res`. -The code in `` can make [API calls](#nginx-api-for-lua) and can retrieve input arguments from the `ngx.arg` table (index starts from `1` and increases sequentially). +Similar to the [set_by_lua_block](#set_by_lua_block) directive, but accepts the Lua source directly in an Nginx string literal (which requires +special character escaping), and +1. this directive support extra arguments after the Lua script. -This directive is designed to execute short, fast running code blocks as the Nginx event loop is blocked during code execution. Time consuming code sequences should therefore be avoided. - -This directive is implemented by injecting custom commands into the standard [ngx_http_rewrite_module](http://nginx.org/en/docs/http/ngx_http_rewrite_module.html)'s command list. Because [ngx_http_rewrite_module](http://nginx.org/en/docs/http/ngx_http_rewrite_module.html) does not support nonblocking I/O in its commands, Lua APIs requiring yielding the current Lua "light thread" cannot work in this directive. - -At least the following API functions are currently disabled within the context of `set_by_lua`: - -* Output API functions (e.g., [ngx.say](#ngxsay) and [ngx.send_headers](#ngxsend_headers)) -* Control API functions (e.g., [ngx.exit](#ngxexit)) -* Subrequest API functions (e.g., [ngx.location.capture](#ngxlocationcapture) and [ngx.location.capture_multi](#ngxlocationcapture_multi)) -* Cosocket API functions (e.g., [ngx.socket.tcp](#ngxsockettcp) and [ngx.req.socket](#ngxreqsocket)). -* Sleeping API function [ngx.sleep](#ngxsleep). - -In addition, note that this directive can only write out a value to a single Nginx variable at -a time. However, a workaround is possible using the [ngx.var.VARIABLE](#ngxvarvariable) interface. +For example, ```nginx - location /foo { - set $diff ''; # we have to predefine the $diff variable here - - set_by_lua $sum ' - local a = 32 - local b = 56 - - ngx.var.diff = a - b -- write to $diff directly - return a + b -- return the $sum value normally - '; - - echo "sum = $sum, diff = $diff"; - } -``` - -This directive can be freely mixed with all directives of the [ngx_http_rewrite_module](http://nginx.org/en/docs/http/ngx_http_rewrite_module.html), [set-misc-nginx-module](http://github.com/openresty/set-misc-nginx-module), and [array-var-nginx-module](http://github.com/openresty/array-var-nginx-module) modules. All of these directives will run in the same order as they appear in the config file. - -```nginx - - set $foo 32; - set_by_lua $bar 'return tonumber(ngx.var.foo) + 1'; - set $baz "bar: $bar"; # $baz == "bar: 33" + set_by_lua $res ' return 32 + math.cos(32) '; + # $res now has the value "32.834223360507" or alike. ``` As from the `v0.5.0rc29` release, Nginx variable interpolation is disabled in the `` argument of this directive and therefore, the dollar sign character (`$`) can be used directly. @@ -1763,23 +1742,54 @@ set_by_lua_block **phase:** *rewrite* -Similar to the [set_by_lua](#set_by_lua) directive except that +Executes code specified inside a pair of curly braces (`{}`), and returns string output to `$res`. +The code inside a pair of curly braces (`{}`) can make [API calls](#nginx-api-for-lua) and can retrieve input arguments from the `ngx.arg` table (index starts from `1` and increases sequentially). -1. this directive inlines the Lua source directly -inside a pair of curly braces (`{}`) instead of in an Nginx string literal (which requires -special character escaping), and -1. this directive does not support extra arguments after the Lua script as in [set_by_lua](#set_by_lua). +This directive is designed to execute short, fast running code blocks as the Nginx event loop is blocked during code execution. Time consuming code sequences should therefore be avoided. -For example, +This directive is implemented by injecting custom commands into the standard [ngx_http_rewrite_module](http://nginx.org/en/docs/http/ngx_http_rewrite_module.html)'s command list. Because [ngx_http_rewrite_module](http://nginx.org/en/docs/http/ngx_http_rewrite_module.html) does not support nonblocking I/O in its commands, Lua APIs requiring yielding the current Lua "light thread" cannot work in this directive. + +At least the following API functions are currently disabled within the context of `set_by_lua_block`: + +* Output API functions (e.g., [ngx.say](#ngxsay) and [ngx.send_headers](#ngxsend_headers)) +* Control API functions (e.g., [ngx.exit](#ngxexit)) +* Subrequest API functions (e.g., [ngx.location.capture](#ngxlocationcapture) and [ngx.location.capture_multi](#ngxlocationcapture_multi)) +* Cosocket API functions (e.g., [ngx.socket.tcp](#ngxsockettcp) and [ngx.req.socket](#ngxreqsocket)). +* Sleeping API function [ngx.sleep](#ngxsleep). + +In addition, note that this directive can only write out a value to a single Nginx variable at +a time. However, a workaround is possible using the [ngx.var.VARIABLE](#ngxvarvariable) interface. ```nginx - set_by_lua_block $res { return 32 + math.cos(32) } - # $res now has the value "32.834223360507" or alike. + location /foo { + set $diff ''; # we have to predefine the $diff variable here + + set_by_lua_block $sum { + local a = 32 + local b = 56 + + ngx.var.diff = a - b -- write to $diff directly + return a + b -- return the $sum value normally + } + + echo "sum = $sum, diff = $diff"; + } +``` + +This directive can be freely mixed with all directives of the [ngx_http_rewrite_module](http://nginx.org/en/docs/http/ngx_http_rewrite_module.html), [set-misc-nginx-module](http://github.com/openresty/set-misc-nginx-module), and [array-var-nginx-module](http://github.com/openresty/array-var-nginx-module) modules. All of these directives will run in the same order as they appear in the config file. + +```nginx + + set $foo 32; + set_by_lua_block $bar { return tonumber(ngx.var.foo) + 1 } + set $baz "bar: $bar"; # $baz == "bar: 33" ``` No special escaping is required in the Lua code block. +This directive requires the [ngx_devel_kit](https://github.com/simplresty/ngx_devel_kit) module. + This directive was first introduced in the `v0.9.17` release. [Back to TOC](#directives) @@ -1793,7 +1803,7 @@ set_by_lua_file **phase:** *rewrite* -Equivalent to [set_by_lua](#set_by_lua), except that the file specified by `` contains the Lua code, or, as from the `v0.5.0rc32` release, the [LuaJIT bytecode](#luajit-bytecode-support) to be executed. +Equivalent to [set_by_lua_block](#set_by_lua_block), except that the file specified by `` contains the Lua code, or, as from the `v0.5.0rc32` release, the [LuaJIT bytecode](#luajit-bytecode-support) to be executed. Nginx variable interpolation is supported in the `` argument string of this directive. But special care must be taken for injection attacks. @@ -1819,10 +1829,17 @@ content_by_lua **NOTE** Use of this directive is *discouraged* following the `v0.9.17` release. Use the [content_by_lua_block](#content_by_lua_block) directive instead. -Acts as a "content handler" and executes Lua code string specified in `` for every request. -The Lua code may make [API calls](#nginx-api-for-lua) and is executed as a new spawned coroutine in an independent global environment (i.e. a sandbox). +Similar to the [content_by_lua_block](#content_by_lua_block) directive, but accepts the Lua source directly in an Nginx string literal (which requires +special character escaping). -Do not use this directive and other content handler directives in the same location. For example, this directive and the [proxy_pass](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass) directive should not be used in the same location. +For instance, + +```nginx + + content_by_lua ' + ngx.say("I need no extra escaping here, for example: \r\nblah") + '; +``` [Back to TOC](#directives) @@ -1835,11 +1852,6 @@ content_by_lua_block **phase:** *content* -Similar to the [content_by_lua](#content_by_lua) directive except that this directive inlines -the Lua source directly -inside a pair of curly braces (`{}`) instead of in an Nginx string literal (which requires -special character escaping). - For instance, ```nginx @@ -1849,6 +1861,11 @@ For instance, } ``` +Acts as a "content handler" and executes Lua code string specified in `{ lua-script }` for every request. +The Lua code may make [API calls](#nginx-api-for-lua) and is executed as a new spawned coroutine in an independent global environment (i.e. a sandbox). + +Do not use this directive and other content handler directives in the same location. For example, this directive and the [proxy_pass](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass) directive should not be used in the same location. + This directive was first introduced in the `v0.9.17` release. [Back to TOC](#directives) @@ -1862,7 +1879,9 @@ content_by_lua_file **phase:** *content* -Equivalent to [content_by_lua](#content_by_lua), except that the file specified by `` contains the Lua code, or, as from the `v0.5.0rc32` release, the [LuaJIT bytecode](#luajit-bytecode-support) to be executed. +Equivalent to [content_by_lua_block](#content_by_lua_block), except that the file specified by `` contains the Lua code, or, as from the `v0.5.0rc32` release, the [LuaJIT bytecode](#luajit-bytecode-support) to be executed. + +If the file is not found, a `404 Not Found` status code will be returned, and a `503 Service Temporarily Unavailable` status code will be returned in case of errors in reading other files. Nginx variables can be used in the `` string to provide flexibility. This however carries some risks and is not ordinarily recommended. @@ -1889,6 +1908,97 @@ But be very careful about malicious user inputs and always carefully validate or [Back to TOC](#directives) +server_rewrite_by_lua_block +--------------------------- + +**syntax:** *server_rewrite_by_lua_block { lua-script }* + +**context:** *http, server* + +**phase:** *server rewrite* + +Acts as a server rewrite phase handler and executes Lua code string specified in `{ lua-script }` for every request. +The Lua code may make [API calls](#nginx-api-for-lua) and is executed as a new spawned coroutine in an independent global environment (i.e. a sandbox). + +```nginx + + server { + ... + + server_rewrite_by_lua_block { + ngx.ctx.a = "server_rewrite_by_lua_block in http" + } + + location /lua { + content_by_lua_block { + ngx.say(ngx.ctx.a) + ngx.log(ngx.INFO, ngx.ctx.a) + } + } + } +``` + +Just as any other rewrite phase handlers, [server_rewrite_by_lua_block](#server_rewrite_by_lua_block) also runs in subrequests. + +```nginx + + server { + server_rewrite_by_lua_block { + ngx.log(ngx.INFO, "is_subrequest:", ngx.is_subrequest) + } + + location /lua { + content_by_lua_block { + local res = ngx.location.capture("/sub") + ngx.print(res.body) + } + } + + location /sub { + content_by_lua_block { + ngx.say("OK") + } + } + } +``` + +Note that when calling `ngx.exit(ngx.OK)` within a [server_rewrite_by_lua_block](#server_rewrite_by_lua_block) handler, the Nginx request processing control flow will still continue to the content handler. To terminate the current request from within a [server_rewrite_by_lua_block](#server_rewrite_by_lua_block) handler, call [ngx.exit](#ngxexit) with status >= 200 (`ngx.HTTP_OK`) and status < 300 (`ngx.HTTP_SPECIAL_RESPONSE`) for successful quits and `ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)` (or its friends) for failures. + + +```nginx + + server_rewrite_by_lua_block { + ngx.exit(503) + } + + location /bar { + ... + # never exec + } +``` + + +[Back to TOC](#directives) + +server_rewrite_by_lua_file +-------------------------- + +**syntax:** *server_rewrite_by_lua_file <path-to-lua-script-file>* + +**context:** *http, server* + +**phase:** *server rewrite* + +Equivalent to [server_rewrite_by_lua_block](#server_rewrite_by_lua_block), except that the file specified by `` contains the Lua code, or, as from the `v0.10.22` release, the [LuaJIT bytecode](#luajit-bytecode-support) to be executed. + +Nginx variables can be used in the `` string to provide flexibility. This however carries some risks and is not ordinarily recommended. + +When a relative path like `foo/bar.lua` is given, they will be turned into the absolute path relative to the `server prefix` path determined by the `-p PATH` command-line option while starting the Nginx server. + +When the Lua code cache is turned on (by default), the user code is loaded once at the first request and cached and the Nginx config must be reloaded each time the Lua source file is modified. The Lua code cache can be temporarily disabled during development by switching [lua_code_cache](#lua_code_cache) `off` in `nginx.conf` to avoid reloading Nginx. + +[Back to TOC](#directives) + rewrite_by_lua -------------- @@ -1900,7 +2010,30 @@ rewrite_by_lua **NOTE** Use of this directive is *discouraged* following the `v0.9.17` release. Use the [rewrite_by_lua_block](#rewrite_by_lua_block) directive instead. -Acts as a rewrite phase handler and executes Lua code string specified in `` for every request. +Similar to the [rewrite_by_lua_block](#rewrite_by_lua_block) directive, but accepts the Lua source directly in an Nginx string literal (which requires +special character escaping). + +For instance, + +```nginx + + rewrite_by_lua ' + do_something("hello, world!\nhiya\n") + '; +``` + +[Back to TOC](#directives) + +rewrite_by_lua_block +-------------------- + +**syntax:** *rewrite_by_lua_block { lua-script }* + +**context:** *http, server, location, location if* + +**phase:** *rewrite tail* + +Acts as a rewrite phase handler and executes Lua code string specified in `{ lua-script }` for every request. The Lua code may make [API calls](#nginx-api-for-lua) and is executed as a new spawned coroutine in an independent global environment (i.e. a sandbox). Note that this handler always runs *after* the standard [ngx_http_rewrite_module](http://nginx.org/en/docs/http/ngx_http_rewrite_module.html). So the following will work as expected: @@ -1910,12 +2043,14 @@ Note that this handler always runs *after* the standard [ngx_http_rewrite_module location /foo { set $a 12; # create and initialize $a set $b ""; # create and initialize $b - rewrite_by_lua 'ngx.var.b = tonumber(ngx.var.a) + 1'; + rewrite_by_lua_block { + ngx.var.b = tonumber(ngx.var.a) + 1 + } echo "res = $b"; } ``` -because `set $a 12` and `set $b ""` run *before* [rewrite_by_lua](#rewrite_by_lua). +because `set $a 12` and `set $b ""` run *before* [rewrite_by_lua_block](#rewrite_by_lua_block). On the other hand, the following will not work as expected: @@ -1924,7 +2059,9 @@ On the other hand, the following will not work as expected: ? location /foo { ? set $a 12; # create and initialize $a ? set $b ''; # create and initialize $b - ? rewrite_by_lua 'ngx.var.b = tonumber(ngx.var.a) + 1'; + ? rewrite_by_lua_block { + ? ngx.var.b = tonumber(ngx.var.a) + 1 + ? } ? if ($b = '13') { ? rewrite ^ /bar redirect; ? break; @@ -1934,7 +2071,7 @@ On the other hand, the following will not work as expected: ? } ``` -because `if` runs *before* [rewrite_by_lua](#rewrite_by_lua) even if it is placed after [rewrite_by_lua](#rewrite_by_lua) in the config. +because `if` runs *before* [rewrite_by_lua_block](#rewrite_by_lua_block) even if it is placed after [rewrite_by_lua_block](#rewrite_by_lua_block) in the config. The right way of doing this is as follows: @@ -1943,18 +2080,18 @@ The right way of doing this is as follows: location /foo { set $a 12; # create and initialize $a set $b ''; # create and initialize $b - rewrite_by_lua ' + rewrite_by_lua_block { ngx.var.b = tonumber(ngx.var.a) + 1 if tonumber(ngx.var.b) == 13 then return ngx.redirect("/bar") end - '; + } echo "res = $b"; } ``` -Note that the [ngx_eval](http://www.grid.net.ru/nginx/eval.en.html) module can be approximated by using [rewrite_by_lua](#rewrite_by_lua). For example, +Note that the [ngx_eval](http://www.grid.net.ru/nginx/eval.en.html) module can be approximated by using [rewrite_by_lua_block](#rewrite_by_lua_block). For example, ```nginx @@ -1981,62 +2118,39 @@ can be implemented in ngx_lua as: } location / { - rewrite_by_lua ' + rewrite_by_lua_block { local res = ngx.location.capture("/check-spam") if res.body == "spam" then return ngx.redirect("/terms-of-use.html") end - '; + } fastcgi_pass ...; } ``` -Just as any other rewrite phase handlers, [rewrite_by_lua](#rewrite_by_lua) also runs in subrequests. +Just as any other rewrite phase handlers, [rewrite_by_lua_block](#rewrite_by_lua_block) also runs in subrequests. -Note that when calling `ngx.exit(ngx.OK)` within a [rewrite_by_lua](#rewrite_by_lua) handler, the Nginx request processing control flow will still continue to the content handler. To terminate the current request from within a [rewrite_by_lua](#rewrite_by_lua) handler, call [ngx.exit](#ngxexit) with status >= 200 (`ngx.HTTP_OK`) and status < 300 (`ngx.HTTP_SPECIAL_RESPONSE`) for successful quits and `ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)` (or its friends) for failures. +Note that when calling `ngx.exit(ngx.OK)` within a [rewrite_by_lua_block](#rewrite_by_lua_block) handler, the Nginx request processing control flow will still continue to the content handler. To terminate the current request from within a [rewrite_by_lua_block](#rewrite_by_lua_block) handler, call [ngx.exit](#ngxexit) with status >= 200 (`ngx.HTTP_OK`) and status < 300 (`ngx.HTTP_SPECIAL_RESPONSE`) for successful quits and `ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)` (or its friends) for failures. -If the [ngx_http_rewrite_module](http://nginx.org/en/docs/http/ngx_http_rewrite_module.html)'s [rewrite](http://nginx.org/en/docs/http/ngx_http_rewrite_module.html#rewrite) directive is used to change the URI and initiate location re-lookups (internal redirections), then any [rewrite_by_lua](#rewrite_by_lua) or [rewrite_by_lua_file](#rewrite_by_lua_file) code sequences within the current location will not be executed. For example, +If the [ngx_http_rewrite_module](http://nginx.org/en/docs/http/ngx_http_rewrite_module.html)'s [rewrite](http://nginx.org/en/docs/http/ngx_http_rewrite_module.html#rewrite) directive is used to change the URI and initiate location re-lookups (internal redirections), then any [rewrite_by_lua_block](#rewrite_by_lua_block) or [rewrite_by_lua_file_block](#rewrite_by_lua_file_block) code sequences within the current location will not be executed. For example, ```nginx location /foo { rewrite ^ /bar; - rewrite_by_lua 'ngx.exit(503)'; + rewrite_by_lua_block { + ngx.exit(503) + } } location /bar { ... } ``` -Here the Lua code `ngx.exit(503)` will never run. This will be the case if `rewrite ^ /bar last` is used as this will similarly initiate an internal redirection. If the `break` modifier is used instead, there will be no internal redirection and the `rewrite_by_lua` code will be executed. +Here the Lua code `ngx.exit(503)` will never run. This will be the case if `rewrite ^ /bar last` is used as this will similarly initiate an internal redirection. If the `break` modifier is used instead, there will be no internal redirection and the `rewrite_by_lua_block` code will be executed. -The `rewrite_by_lua` code will always run at the end of the `rewrite` request-processing phase unless [rewrite_by_lua_no_postpone](#rewrite_by_lua_no_postpone) is turned on. - -[Back to TOC](#directives) - -rewrite_by_lua_block --------------------- - -**syntax:** *rewrite_by_lua_block { lua-script }* - -**context:** *http, server, location, location if* - -**phase:** *rewrite tail* - -Similar to the [rewrite_by_lua](#rewrite_by_lua) directive except that this directive inlines -the Lua source directly -inside a pair of curly braces (`{}`) instead of in an Nginx string literal (which requires -special character escaping). - -For instance, - -```nginx - - rewrite_by_lua_block { - do_something("hello, world!\nhiya\n") - } -``` +The `rewrite_by_lua_block` code will always run at the end of the `rewrite` request-processing phase unless [rewrite_by_lua_no_postpone](#rewrite_by_lua_no_postpone) is turned on. This directive was first introduced in the `v0.9.17` release. @@ -2051,7 +2165,7 @@ rewrite_by_lua_file **phase:** *rewrite tail* -Equivalent to [rewrite_by_lua](#rewrite_by_lua), except that the file specified by `` contains the Lua code, or, as from the `v0.5.0rc32` release, the [LuaJIT bytecode](#luajit-bytecode-support) to be executed. +Equivalent to [rewrite_by_lua_block](#rewrite_by_lua_block), except that the file specified by `` contains the Lua code, or, as from the `v0.5.0rc32` release, the [LuaJIT bytecode](#luajit-bytecode-support) to be executed. Nginx variables can be used in the `` string to provide flexibility. This however carries some risks and is not ordinarily recommended. @@ -2076,7 +2190,30 @@ access_by_lua **NOTE** Use of this directive is *discouraged* following the `v0.9.17` release. Use the [access_by_lua_block](#access_by_lua_block) directive instead. -Acts as an access phase handler and executes Lua code string specified in `` for every request. +Similar to the [access_by_lua_block](#access_by_lua_block) directive, but accepts the Lua source directly in an Nginx string literal (which requires +special character escaping). + +For instance, + +```nginx + + access_by_lua ' + do_something("hello, world!\nhiya\n") + '; +``` + +[Back to TOC](#directives) + +access_by_lua_block +------------------- + +**syntax:** *access_by_lua_block { lua-script }* + +**context:** *http, server, location, location if* + +**phase:** *access tail* + +Acts as an access phase handler and executes Lua code string specified in `{ = 200 (`ngx.HTTP_OK`) and status < 300 (`ngx.HTTP_SPECIAL_RESPONSE`) for successful quits and `ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)` (or its friends) for failures. +Note that when calling `ngx.exit(ngx.OK)` within a [access_by_lua_block](#access_by_lua_block) handler, the Nginx request processing control flow will still continue to the content handler. To terminate the current request from within a [access_by_lua_block](#access_by_lua_block) handler, call [ngx.exit](#ngxexit) with status >= 200 (`ngx.HTTP_OK`) and status < 300 (`ngx.HTTP_SPECIAL_RESPONSE`) for successful quits and `ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)` (or its friends) for failures. Starting from the `v0.9.20` release, you can use the [access_by_lua_no_postpone](#access_by_lua_no_postpone) directive to control when to run this handler inside the "access" request-processing phase of Nginx. -[Back to TOC](#directives) - -access_by_lua_block -------------------- - -**syntax:** *access_by_lua_block { lua-script }* - -**context:** *http, server, location, location if* - -**phase:** *access tail* - -Similar to the [access_by_lua](#access_by_lua) directive except that this directive inlines -the Lua source directly -inside a pair of curly braces (`{}`) instead of in an Nginx string literal (which requires -special character escaping). - -For instance, - -```nginx - - access_by_lua_block { - do_something("hello, world!\nhiya\n") - } -``` - This directive was first introduced in the `v0.9.17` release. [Back to TOC](#directives) @@ -2180,7 +2292,7 @@ access_by_lua_file **phase:** *access tail* -Equivalent to [access_by_lua](#access_by_lua), except that the file specified by `` contains the Lua code, or, as from the `v0.5.0rc32` release, the [LuaJIT bytecode](#luajit-bytecode-support) to be executed. +Equivalent to [access_by_lua_block](#access_by_lua_block), except that the file specified by `` contains the Lua code, or, as from the `v0.5.0rc32` release, the [LuaJIT bytecode](#luajit-bytecode-support) to be executed. Nginx variables can be used in the `` string to provide flexibility. This however carries some risks and is not ordinarily recommended. @@ -2205,23 +2317,16 @@ header_filter_by_lua **NOTE** Use of this directive is *discouraged* following the `v0.9.17` release. Use the [header_filter_by_lua_block](#header_filter_by_lua_block) directive instead. -Uses Lua code specified in `` to define an output header filter. +Similar to the [header_filter_by_lua_block](#header_filter_by_lua_block) directive, but accepts the Lua source directly in an Nginx string literal (which requires +special character escaping). -Note that the following API functions are currently disabled within this context: - -* Output API functions (e.g., [ngx.say](#ngxsay) and [ngx.send_headers](#ngxsend_headers)) -* Control API functions (e.g., [ngx.redirect](#ngxredirect) and [ngx.exec](#ngxexec)) -* Subrequest API functions (e.g., [ngx.location.capture](#ngxlocationcapture) and [ngx.location.capture_multi](#ngxlocationcapture_multi)) -* Cosocket API functions (e.g., [ngx.socket.tcp](#ngxsockettcp) and [ngx.req.socket](#ngxreqsocket)). - -Here is an example of overriding a response header (or adding one if absent) in our Lua header filter: +For instance, ```nginx - location / { - proxy_pass http://mybackend; - header_filter_by_lua 'ngx.header.Foo = "blah"'; - } + header_filter_by_lua ' + ngx.header["content-length"] = nil + '; ``` This directive was first introduced in the `v0.2.1rc20` release. @@ -2237,17 +2342,24 @@ header_filter_by_lua_block **phase:** *output-header-filter* -Similar to the [header_filter_by_lua](#header_filter_by_lua) directive except that this directive inlines -the Lua source directly -inside a pair of curly braces (`{}`) instead of in an Nginx string literal (which requires -special character escaping). +Uses Lua code specified in `{ lua-script }` to define an output header filter. -For instance, +Note that the following API functions are currently disabled within this context: + +* Output API functions (e.g., [ngx.say](#ngxsay) and [ngx.send_headers](#ngxsend_headers)) +* Control API functions (e.g., [ngx.redirect](#ngxredirect) and [ngx.exec](#ngxexec)) +* Subrequest API functions (e.g., [ngx.location.capture](#ngxlocationcapture) and [ngx.location.capture_multi](#ngxlocationcapture_multi)) +* Cosocket API functions (e.g., [ngx.socket.tcp](#ngxsockettcp) and [ngx.req.socket](#ngxreqsocket)). + +Here is an example of overriding a response header (or adding one if absent) in our Lua header filter: ```nginx - header_filter_by_lua_block { - ngx.header["content-length"] = nil + location / { + proxy_pass http://mybackend; + header_filter_by_lua_block { + ngx.header.Foo = "blah" + } } ``` @@ -2264,7 +2376,7 @@ header_filter_by_lua_file **phase:** *output-header-filter* -Equivalent to [header_filter_by_lua](#header_filter_by_lua), except that the file specified by `` contains the Lua code, or as from the `v0.5.0rc32` release, the [LuaJIT bytecode](#luajit-bytecode-support) to be executed. +Equivalent to [header_filter_by_lua_block](#header_filter_by_lua_block), except that the file specified by `` contains the Lua code, or as from the `v0.5.0rc32` release, the [LuaJIT bytecode](#luajit-bytecode-support) to be executed. When a relative path like `foo/bar.lua` is given, they will be turned into the absolute path relative to the `server prefix` path determined by the `-p PATH` command-line option while starting the Nginx server. @@ -2283,7 +2395,32 @@ body_filter_by_lua **NOTE** Use of this directive is *discouraged* following the `v0.9.17` release. Use the [body_filter_by_lua_block](#body_filter_by_lua_block) directive instead. -Uses Lua code specified in `` to define an output body filter. +Similar to the [body_filter_by_lua_block](#body_filter_by_lua_block) directive, but accepts the Lua source directly in an Nginx string literal (which requires +special character escaping). + +For instance, + +```nginx + + body_filter_by_lua ' + local data, eof = ngx.arg[1], ngx.arg[2] + '; +``` + +This directive was first introduced in the `v0.5.0rc32` release. + +[Back to TOC](#directives) + +body_filter_by_lua_block +------------------------ + +**syntax:** *body_filter_by_lua_block { lua-script-str }* + +**context:** *http, server, location, location if* + +**phase:** *output-body-filter* + +Uses Lua code specified in `{ lua-script }` to define an output body filter. The input data chunk is passed via [ngx.arg](#ngxarg)\[1\] (as a Lua string value) and the "eof" flag indicating the end of the response body data stream is passed via [ngx.arg](#ngxarg)\[2\] (as a Lua boolean value). @@ -2304,7 +2441,9 @@ The Lua code can pass its own modified version of the input data chunk to the do location / { proxy_pass http://mybackend; - body_filter_by_lua 'ngx.arg[1] = string.upper(ngx.arg[1])'; + body_filter_by_lua_block { + ngx.arg[1] = string.upper(ngx.arg[1]) + } } ``` @@ -2318,7 +2457,7 @@ Likewise, new "eof" flag can also be specified by setting a boolean value to [ng echo hello world; echo hiya globe; - body_filter_by_lua ' + body_filter_by_lua_block { local chunk = ngx.arg[1] if string.match(chunk, "hello") then ngx.arg[2] = true -- new eof @@ -2327,7 +2466,7 @@ Likewise, new "eof" flag can also be specified by setting a boolean value to [ng -- just throw away any remaining chunk data ngx.arg[1] = nil - '; + } } ``` @@ -2346,8 +2485,12 @@ When the Lua code may change the length of the response body, then it is require location /foo { # fastcgi_pass/proxy_pass/... - header_filter_by_lua_block { ngx.header.content_length = nil } - body_filter_by_lua 'ngx.arg[1] = string.len(ngx.arg[1]) .. "\\n"'; + header_filter_by_lua_block { + ngx.header.content_length = nil + } + body_filter_by_lua_block { + ngx.arg[1] = string.len(ngx.arg[1]) .. "\n" + } } ``` @@ -2360,33 +2503,6 @@ Note that the following API functions are currently disabled within this context Nginx output filters may be called multiple times for a single request because response body may be delivered in chunks. Thus, the Lua code specified by in this directive may also run multiple times in the lifetime of a single HTTP request. -This directive was first introduced in the `v0.5.0rc32` release. - -[Back to TOC](#directives) - -body_filter_by_lua_block ------------------------- - -**syntax:** *body_filter_by_lua_block { lua-script-str }* - -**context:** *http, server, location, location if* - -**phase:** *output-body-filter* - -Similar to the [body_filter_by_lua](#body_filter_by_lua) directive except that this directive inlines -the Lua source directly -inside a pair of curly braces (`{}`) instead of in an Nginx string literal (which requires -special character escaping). - -For instance, - -```nginx - - body_filter_by_lua_block { - local data, eof = ngx.arg[1], ngx.arg[2] - } -``` - This directive was first introduced in the `v0.9.17` release. [Back to TOC](#directives) @@ -2400,7 +2516,7 @@ body_filter_by_lua_file **phase:** *output-body-filter* -Equivalent to [body_filter_by_lua](#body_filter_by_lua), except that the file specified by `` contains the Lua code, or, as from the `v0.5.0rc32` release, the [LuaJIT bytecode](#luajit-bytecode-support) to be executed. +Equivalent to [body_filter_by_lua_block](#body_filter_by_lua_block), except that the file specified by `` contains the Lua code, or, as from the `v0.5.0rc32` release, the [LuaJIT bytecode](#luajit-bytecode-support) to be executed. When a relative path like `foo/bar.lua` is given, they will be turned into the absolute path relative to the `server prefix` path determined by the `-p PATH` command-line option while starting the Nginx server. @@ -2419,7 +2535,32 @@ log_by_lua **NOTE** Use of this directive is *discouraged* following the `v0.9.17` release. Use the [log_by_lua_block](#log_by_lua_block) directive instead. -Runs the Lua source code inlined as the `` at the `log` request processing phase. This does not replace the current access logs, but runs before. +Similar to the [log_by_lua_block](#log_by_lua_block) directive, but accepts the Lua source directly in an Nginx string literal (which requires +special character escaping). + +For instance, + +```nginx + + log_by_lua ' + print("I need no extra escaping here, for example: \r\nblah") + '; +``` + +This directive was first introduced in the `v0.5.0rc31` release. + +[Back to TOC](#directives) + +log_by_lua_block +---------------- + +**syntax:** *log_by_lua_block { lua-script }* + +**context:** *http, server, location, location if* + +**phase:** *log* + +Runs the Lua source code inlined as the `{ lua-script }` at the `log` request processing phase. This does not replace the current access logs, but runs before. Note that the following API functions are currently disabled within this context: @@ -2438,7 +2579,7 @@ Here is an example of gathering average data for [$upstream_response_time](http: location / { proxy_pass http://mybackend; - log_by_lua ' + log_by_lua_block { local log_dict = ngx.shared.log_dict local upstream_time = tonumber(ngx.var.upstream_response_time) @@ -2451,7 +2592,7 @@ Here is an example of gathering average data for [$upstream_response_time](http: log_dict:add("upstream_time-nb", 0) log_dict:incr("upstream_time-nb", 1) end - '; + } } location = /status { @@ -2471,33 +2612,6 @@ Here is an example of gathering average data for [$upstream_response_time](http: } ``` -This directive was first introduced in the `v0.5.0rc31` release. - -[Back to TOC](#directives) - -log_by_lua_block ----------------- - -**syntax:** *log_by_lua_block { lua-script }* - -**context:** *http, server, location, location if* - -**phase:** *log* - -Similar to the [log_by_lua](#log_by_lua) directive except that this directive inlines -the Lua source directly -inside a pair of curly braces (`{}`) instead of in an Nginx string literal (which requires -special character escaping). - -For instance, - -```nginx - - log_by_lua_block { - print("I need no extra escaping here, for example: \r\nblah") - } -``` - This directive was first introduced in the `v0.9.17` release. [Back to TOC](#directives) @@ -2511,7 +2625,7 @@ log_by_lua_file **phase:** *log* -Equivalent to [log_by_lua](#log_by_lua), except that the file specified by `` contains the Lua code, or, as from the `v0.5.0rc32` release, the [LuaJIT bytecode](#luajit-bytecode-support) to be executed. +Equivalent to [log_by_lua_block](#log_by_lua_block), except that the file specified by `` contains the Lua code, or, as from the `v0.5.0rc32` release, the [LuaJIT bytecode](#luajit-bytecode-support) to be executed. When a relative path like `foo/bar.lua` is given, they will be turned into the absolute path relative to the `server prefix` path determined by the `-p PATH` command-line option while starting the Nginx server. @@ -2713,18 +2827,11 @@ This directive requires OpenSSL 1.1.1 or greater. If you are using the [official pre-built packages](https://openresty.org/en/linux-packages.html) for -[OpenResty](https://openresty.org/) 1.19.9.2 or later, then everything should +[OpenResty](https://openresty.org/) 1.21.4.1 or later, then everything should work out of the box. -If you are not using one of the [OpenSSL -packages](https://openresty.org/en/linux-packages.html) provided by -[OpenResty](https://openresty.org), you will need to apply patches to OpenSSL -in order to use this directive: - - - -Similarly, if you are not using the Nginx core shipped with -[OpenResty](https://openresty.org) 1.19.9.2 or later, you will need to apply +If you are not using the Nginx core shipped with +[OpenResty](https://openresty.org) 1.21.4.1 or later, you will need to apply patches to the standard Nginx core: @@ -2833,14 +2940,7 @@ packages](https://openresty.org/en/linux-packages.html) for [OpenResty](https://openresty.org/) 1.9.7.2 or later, then everything should work out of the box. -If you are not using one of the [OpenSSL -packages](https://openresty.org/en/linux-packages.html) provided by -[OpenResty](https://openresty.org), you will need to apply patches to OpenSSL -in order to use this directive: - - - -Similarly, if you are not using the Nginx core shipped with +If you are not using the Nginx core shipped with [OpenResty](https://openresty.org) 1.9.7.2 or later, you will need to apply patches to the standard Nginx core: @@ -3429,7 +3529,7 @@ lua_max_running_timers Controls the maximum number of "running timers" allowed. -Running timers are those timers whose user callback functions are still running. +Running timers are those timers whose user callback functions are still running or `lightthreads` spawned in callback functions are still running. When exceeding this limit, Nginx will stop running the callbacks of newly expired timers and log an error message "N lua_max_running_timers are not enough" where "N" is the current value of this directive. @@ -3582,7 +3682,9 @@ Nginx API for Lua * [udpsock:settimeout](#udpsocksettimeout) * [ngx.socket.stream](#ngxsocketstream) * [ngx.socket.tcp](#ngxsockettcp) +* [tcpsock:bind](#tcpsockbind) * [tcpsock:connect](#tcpsockconnect) +* [tcpsock:setclientcert](#tcpsocksetclientcert) * [tcpsock:sslhandshake](#tcpsocksslhandshake) * [tcpsock:send](#tcpsocksend) * [tcpsock:receive](#tcpsockreceive) @@ -3612,6 +3714,7 @@ Nginx API for Lua * [ngx.config.ngx_lua_version](#ngxconfigngx_lua_version) * [ngx.worker.exiting](#ngxworkerexiting) * [ngx.worker.pid](#ngxworkerpid) +* [ngx.worker.pids](#ngxworkerpids) * [ngx.worker.count](#ngxworkercount) * [ngx.worker.id](#ngxworkerid) * [ngx.semaphore](#ngxsemaphore) @@ -3735,7 +3838,8 @@ For example: } ``` -That is, Nginx variables cannot be created on-the-fly. +That is, Nginx variables cannot be created on-the-fly. Here is a list of pre-defined +[Nginx variables](http://nginx.org/en/docs/varindex.html). Some special Nginx variables like `$args` and `$limit_rate` can be assigned a value, many others are not, like `$query_string`, `$arg_PARAMETER`, and `$http_NAME`. @@ -3856,7 +3960,8 @@ HTTP status constants value = ngx.HTTP_CLOSE (444) (first added in the v0.9.20 release) value = ngx.HTTP_ILLEGAL (451) (first added in the v0.9.20 release) value = ngx.HTTP_INTERNAL_SERVER_ERROR (500) - value = ngx.HTTP_METHOD_NOT_IMPLEMENTED (501) + value = ngx.HTTP_NOT_IMPLEMENTED (501) + value = ngx.HTTP_METHOD_NOT_IMPLEMENTED (501) (kept for compatibility) value = ngx.HTTP_BAD_GATEWAY (502) (first added in the v0.9.20 release) value = ngx.HTTP_SERVICE_UNAVAILABLE (503) value = ngx.HTTP_GATEWAY_TIMEOUT (504) (first added in the v0.3.1rc38 release) @@ -4009,7 +4114,7 @@ Because HTTP request is created after SSL handshake, the `ngx.ctx` created in [ssl_certificate_by_lua*](#ssl_certificate_by_lua), [ssl_session_store_by_lua*](#ssl_session_store_by_lua), [ssl_session_fetch_by_lua*](#ssl_session_fetch_by_lua) and [ssl_client_hello_by_lua*](#ssl_client_hello_by_lua) is not available in the following phases like [rewrite_by_lua*](#rewrite_by_lua). -Since `dev`, the `ngx.ctx` created during a SSL handshake +Since `v0.10.18`, the `ngx.ctx` created during a SSL handshake will be inherited by the requests which share the same TCP connection established by the handshake. Note that overwrite values in `ngx.ctx` in the http request phases (like `rewrite_by_lua*`) will only take affect in the current http request. @@ -4399,7 +4504,9 @@ Lua tables can be used for both requests and responses when the number of subreq table.insert(reqs, { "/memcached" }) -- issue all the requests at once and wait until they all return - local resps = { ngx.location.capture_multi(reqs) } + local resps = { + ngx.location.capture_multi(reqs) + } -- loop over the responses table for i, resp in ipairs(resps) do @@ -4878,7 +4985,9 @@ Multi-value arguments are also supported: ngx.req.set_uri_args({ a = 3, b = {5, 6} }) ``` -which will result in a query string like `a=3&b=5&b=6`. +which will result in a query string like `a=3&b=5&b=6` or `b=5&b=6&a=3`. + +**Note that when using Lua table as the `arg` argument, the order of the arguments in the result query string which change from time to time. If you would like to get an ordered result, you need to use Lua string as the `arg` argument.** This interface was first introduced in the `v0.3.1rc13` release. @@ -4889,11 +4998,12 @@ See also [ngx.req.set_uri](#ngxreqset_uri). ngx.req.get_uri_args -------------------- -**syntax:** *args, err = ngx.req.get_uri_args(max_args?)* +**syntax:** *args, err = ngx.req.get_uri_args(max_args?, tab?)* **context:** *set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*, body_filter_by_lua*, log_by_lua*, balancer_by_lua** -Returns a Lua table holding all the current request URL query arguments. +Returns a Lua table holding all the current request URL query arguments. An optional `tab` argument +can be used to reuse the table returned by this method. ```nginx @@ -5202,6 +5312,8 @@ For security considerations, this method will automatically escape " ", """, "(" By default, all the subrequests subsequently initiated by [ngx.location.capture](#ngxlocationcapture) and [ngx.location.capture_multi](#ngxlocationcapture_multi) will inherit the new header. +It is not a Lua's equivalent of nginx `proxy_set_header` directive (same is true about [ngx.req.clear_header](#ngxreqclear_header)). `proxy_set_header` only affects the upstream request while `ngx.req.set_header` change the incoming request. Record the http headers in the access log file will show the difference. But you still can use it as an alternative of nginx `proxy_set_header` directive as long as you know the difference. + Here is an example of setting the `Content-Type` header: ```lua @@ -6137,7 +6249,9 @@ For example, ```nginx location = /md5 { - content_by_lua_block { ngx.say(ngx.md5("hello")) } + content_by_lua_block { + ngx.say(ngx.md5("hello")) + } } ``` @@ -7545,7 +7659,9 @@ ngx.socket.tcp Creates and returns a TCP or stream-oriented unix domain socket object (also known as one type of the "cosocket" objects). The following methods are supported on this object: +* [bind](#tcpsockbind) * [connect](#tcpsockconnect) +* [setclientcert](#tcpsocksetclientcert) * [sslhandshake](#tcpsocksslhandshake) * [send](#tcpsocksend) * [receive](#tcpsockreceive) @@ -7583,6 +7699,42 @@ See also [ngx.socket.udp](#ngxsocketudp). [Back to TOC](#nginx-api-for-lua) +tcpsock:bind +------------ +**syntax:** *ok, err = tcpsock:bind(address)* + +**context:** *rewrite_by_lua*, access_by_lua*, content_by_lua*, ngx.timer.*, ssl_certificate_by_lua*,ssl_session_fetch_by_lua*,ssl_client_hello_by_lua** + +Just like the standard [proxy_bind](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_bind) directive, this api makes the outgoing connection to a upstream server originate from the specified local IP address. + +Only IP addresses can be specified as the `address` argument. + +Here is an example for connecting to a TCP server from the specified local IP address: + +```nginx + + location /test { + content_by_lua_block { + local sock = ngx.socket.tcp() + -- assume "192.168.1.10" is the local ip address + local ok, err = sock:bind("192.168.1.10") + if not ok then + ngx.say("failed to bind") + return + end + local ok, err = sock:connect("192.168.1.67", 80) + if not ok then + ngx.say("failed to connect server: ", err) + return + end + ngx.say("successfully connected!") + sock:close() + } + } +``` + +[Back to TOC](#nginx-api-for-lua) + tcpsock:connect --------------- @@ -7705,6 +7857,31 @@ This method was first introduced in the `v0.5.0rc1` release. [Back to TOC](#nginx-api-for-lua) +tcpsock:setclientcert +--------------------- + +**syntax:** *ok, err = tcpsock:setclientcert(cert, pkey)* + +**context:** *rewrite_by_lua*, access_by_lua*, content_by_lua*, ngx.timer.*, ssl_certificate_by_lua*, ssl_session_fetch_by_lua*, ssl_client_hello_by_lua** + +Set client certificate chain and corresponding private key to the TCP socket object. +The certificate chain and private key provided will be used later by the [tcpsock:sslhandshake](#tcpsocksslhandshake) method. + +* `cert` specify a client certificate chain cdata object that will be used while handshaking with +remote server. These objects can be created using [ngx.ssl.parse\_pem\_cert](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md#parse_pem_cert) +function provided by lua-resty-core. Note that specifying the `cert` option requires +corresponding `pkey` be provided too. See below. +* `pkey` specify a private key corresponds to the `cert` option above. +These objects can be created using [ngx.ssl.parse\_pem\_priv\_key](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md#parse_pem_priv_key) +function provided by lua-resty-core. + +If both of `cert` and `pkey` are `nil`, this method will clear any existing client certificate and private key +that was previously set on the cosocket object. + +This method was first introduced in the `v0.10.22` release. + +[Back to TOC](#nginx-api-for-lua) + tcpsock:sslhandshake -------------------- @@ -8574,7 +8751,7 @@ be any Lua function, which will be invoked later in a background called automatically by the Nginx core with the arguments `premature`, `user_arg1`, `user_arg2`, and etc, where the `premature` argument takes a boolean value indicating whether it is a premature timer -expiration or not, and `user_arg1`, `user_arg2`, and etc, are +expiration or not(for the `0` delay timer it is always `false`), and `user_arg1`, `user_arg2`, and etc, are those (extra) user arguments specified when calling `ngx.timer.at` as the remaining arguments. @@ -8850,6 +9027,19 @@ This API was first introduced in the `0.9.5` release. [Back to TOC](#nginx-api-for-lua) +ngx.worker.pids +-------------- + +**syntax:** *pids = ngx.worker.pids()* + +**context:** *set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*, body_filter_by_lua*, log_by_lua*, ngx.timer.*, exit_worker_by_lua** + +This function returns a Lua table for all Nginx worker process ID (PID). Nginx uses channel to send the current worker PID to another worker in the worker process start or restart. So this API can get all current worker PID. + +This API was first introduced in the `0.10.23` release. + +[Back to TOC](#nginx-api-for-lua) + ngx.worker.count ---------------- @@ -9150,6 +9340,7 @@ Only the following ngx_lua APIs could be used in `function_name` function of the * `ngx.config.nginx_configure` * `ngx.config.ngx_lua_version` +* `ngx.shared.DICT` The first argument `threadpool` specifies the Nginx thread pool name defined by [thread_pool](https://nginx.org/en/docs/ngx_core_module.html#thread_pool). @@ -9201,6 +9392,8 @@ Example1: do md5 calculation. local function md5() return ngx.md5("hello") end + +return { md5=md5, } ``` Example2: write logs into the log file. diff --git a/src/deps/src/lua-nginx-module/config b/src/deps/src/lua-nginx-module/config index 14870a04e..c4068c852 100644 --- a/src/deps/src/lua-nginx-module/config +++ b/src/deps/src/lua-nginx-module/config @@ -94,7 +94,7 @@ END case "$NGX_PLATFORM" in Darwin:*) case "$NGX_MACHINE" in - amd64 | x86_64 | i386) + amd64 | arm64 | x86_64 | i386) echo "adding extra linking options needed by LuaJIT on $NGX_MACHINE" luajit_ld_opt="$luajit_ld_opt -pagezero_size 10000 -image_base 100000000" ngx_feature_libs="$ngx_feature_libs -pagezero_size 10000 -image_base 100000000" @@ -261,6 +261,7 @@ HTTP_LUA_SRCS=" \ $ngx_addon_dir/src/ngx_http_lua_util.c \ $ngx_addon_dir/src/ngx_http_lua_cache.c \ $ngx_addon_dir/src/ngx_http_lua_contentby.c \ + $ngx_addon_dir/src/ngx_http_lua_server_rewriteby.c \ $ngx_addon_dir/src/ngx_http_lua_rewriteby.c \ $ngx_addon_dir/src/ngx_http_lua_accessby.c \ $ngx_addon_dir/src/ngx_http_lua_setby.c \ @@ -325,6 +326,7 @@ HTTP_LUA_DEPS=" \ $ngx_addon_dir/src/ngx_http_lua_util.h \ $ngx_addon_dir/src/ngx_http_lua_cache.h \ $ngx_addon_dir/src/ngx_http_lua_contentby.h \ + $ngx_addon_dir/src/ngx_http_lua_server_rewriteby.c \ $ngx_addon_dir/src/ngx_http_lua_rewriteby.h \ $ngx_addon_dir/src/ngx_http_lua_accessby.h \ $ngx_addon_dir/src/ngx_http_lua_setby.h \ diff --git a/src/deps/src/lua-nginx-module/doc/HttpLuaModule.wiki b/src/deps/src/lua-nginx-module/doc/HttpLuaModule.wiki index 7b187bc6f..34751144b 100644 --- a/src/deps/src/lua-nginx-module/doc/HttpLuaModule.wiki +++ b/src/deps/src/lua-nginx-module/doc/HttpLuaModule.wiki @@ -8,6 +8,8 @@ then you are essentially using OpenResty. ''This module is not distributed with the Nginx source.'' See [[#Installation|the installation instructions]]. +This is a core component of OpenResty. If you are using this module, then you are essentially using OpenResty :) + = Status = Production ready. @@ -283,6 +285,8 @@ Alternatively, ngx_lua can be manually compiled into Nginx: # Download the latest version of the ngx_devel_kit (NDK) module [https://github.com/simplresty/ngx_devel_kit/tags HERE] # Download the latest version of ngx_lua [https://github.com/openresty/lua-nginx-module/tags HERE] # Download the latest supported version of Nginx [https://nginx.org/ HERE] (See [[#Nginx Compatibility|Nginx Compatibility]]) +# Download the latest version of the lua-resty-core [HERE](https://github.com/openresty/lua-resty-core) +# Download the latest version of the lua-resty-lrucache [HERE](https://github.com/openresty/lua-resty-lrucache) Build the source with this module: @@ -313,6 +317,18 @@ Build the source with this module: # machine. make -j2 make install + + # Note that this version of lug-nginx-module not allow to set `lua_load_resty_core off;` any more. + # So, you have to install `lua-resty-core` and `lua-resty-lrucache` manually as below. + + cd lua-resty-core + make install PREFIX=/opt/nginx + cd lua-resty-lrucache + make install PREFIX=/opt/nginx + + # add necessary `lua_package_path` directive to `nginx.conf`, in the http context + + lua_package_path "/opt/nginx/lib/lua/?.lua;;"; == Building as a dynamic module == @@ -792,12 +808,10 @@ phases. * cosocket: review and merge aviramc's [https://github.com/openresty/lua-nginx-module/pull/290 patch] for adding the bsdrecv method. * cosocket: add configure options for different strategies of handling the cosocket connection exceeding in the pools. * review and apply vadim-pavlov's patch for [[#ngx.location.capture|ngx.location.capture]]'s extra_headers option -* use ngx_hash_t to optimize the built-in header look-up process for [[#ngx.req.set_header|ngx.req.set_header]], [[#ngx.header.HEADER|ngx.header.HEADER]], and etc. -* add directives to run Lua codes when Nginx stops. +* use ngx_hash_t to optimize the built-in header look-up process for [[#ngx.req.set_header|ngx.req.set_header]], and etc. * add ignore_resp_headers, ignore_resp_body, and ignore_resp options to [[#ngx.location.capture|ngx.location.capture]] and [[#ngx.location.capture_multi|ngx.location.capture_multi]] methods, to allow micro performance tuning on the user side. * add automatic Lua code time slicing support by yielding and resuming the Lua VM actively via Lua's debug hooks. * add stat mode similar to [https://httpd.apache.org/docs/trunk/mod/mod_lua.html mod_lua]. -* cosocket: add client SSL certificate support. = Changes = @@ -1154,9 +1168,29 @@ As from the v0.5.0rc29 release, the special notation $prefix< '''NOTE''' Use of this directive is ''discouraged'' following the v0.9.17 release. Use the [[#init_by_lua_block|init_by_lua_block]] directive instead. -Runs the Lua code specified by the argument on the global Lua VM level when the Nginx master process (if any) is loading the Nginx config file. +Similar to the [[#init_by_lua_block|init_by_lua_block]] directive, but accepts the Lua source directly in an Nginx string literal (which requires +special character escaping). -When Nginx receives the HUP signal and starts reloading the config file, the Lua VM will also be re-created and init_by_lua will run again on the new Lua VM. In case that the [[#lua_code_cache|lua_code_cache]] directive is turned off (default on), the init_by_lua handler will run upon every request because in this special mode a standalone Lua VM is always created for each request. +For instance, + + + init_by_lua ' + print("I need no extra escaping here, for example: \r\nblah") + ' + + +This directive was first introduced in the v0.5.5 release. + +== init_by_lua_block == + +'''syntax:''' ''init_by_lua_block { lua-script }'' + +'''context:''' ''http'' + +'''phase:''' ''loading-config'' + + +When Nginx receives the HUP signal and starts reloading the config file, the Lua VM will also be re-created and init_by_lua_block will run again on the new Lua VM. In case that the [[#lua_code_cache|lua_code_cache]] directive is turned off (default on), the init_by_lua_block handler will run upon every request because in this special mode a standalone Lua VM is always created for each request. Usually you can pre-load Lua modules at server start-up by means of this hook and take advantage of modern operating systems' copy-on-write (COW) optimization. Here is an example for pre-loading Lua modules: @@ -1195,11 +1229,11 @@ You can also initialize the [[#lua_shared_dict|lua_shared_dict]] shm storage at } -But note that, the [[#lua_shared_dict|lua_shared_dict]]'s shm storage will not be cleared through a config reload (via the HUP signal, for example). So if you do ''not'' want to re-initialize the shm storage in your init_by_lua code in this case, then you just need to set a custom flag in the shm storage and always check the flag in your init_by_lua code. +But note that, the [[#lua_shared_dict|lua_shared_dict]]'s shm storage will not be cleared through a config reload (via the HUP signal, for example). So if you do ''not'' want to re-initialize the shm storage in your init_by_lua_block code in this case, then you just need to set a custom flag in the shm storage and always check the flag in your init_by_lua_block code. Because the Lua code in this context runs before Nginx forks its worker processes (if any), data or code loaded here will enjoy the [https://en.wikipedia.org/wiki/Copy-on-write Copy-on-write (COW)] feature provided by many operating systems among all the worker processes, thus saving a lot of memory. -Do *not* initialize your own Lua global variables in this context because use of Lua global variables have performance penalties and can lead to global namespace pollution (see the [[#Lua_Variable_Scope|Lua Variable Scope]] section for more details). The recommended way is to use proper [https://www.lua.org/manual/5.1/manual.html#5.3 Lua module] files (but do not use the standard Lua function [https://www.lua.org/manual/5.1/manual.html#pdf-module module()] to define Lua modules because it pollutes the global namespace as well) and call [https://www.lua.org/manual/5.1/manual.html#pdf-require require()] to load your own module files in init_by_lua or other contexts ([https://www.lua.org/manual/5.1/manual.html#pdf-require require()] does cache the loaded Lua modules in the global package.loaded table in the Lua registry so your modules will only loaded once for the whole Lua VM instance). +Do *not* initialize your own Lua global variables in this context because use of Lua global variables have performance penalties and can lead to global namespace pollution (see the [[#Lua_Variable_Scope|Lua Variable Scope]] section for more details). The recommended way is to use proper [https://www.lua.org/manual/5.1/manual.html#5.3 Lua module] files (but do not use the standard Lua function [https://www.lua.org/manual/5.1/manual.html#pdf-module module()] to define Lua modules because it pollutes the global namespace as well) and call [https://www.lua.org/manual/5.1/manual.html#pdf-require require()] to load your own module files in init_by_lua_block or other contexts ([https://www.lua.org/manual/5.1/manual.html#pdf-require require()] does cache the loaded Lua modules in the global package.loaded table in the Lua registry so your modules will only loaded once for the whole Lua VM instance). Only a small set of the [[#Nginx API for Lua|Nginx API for Lua]] is supported in this context: @@ -1212,36 +1246,13 @@ Basically you can safely use Lua libraries that do blocking I/O in this very con You should be very careful about potential security vulnerabilities in your Lua code registered in this context because the Nginx master process is often run under the root account. -This directive was first introduced in the v0.5.5 release. +This directive was first introduced in the v0.9.17 release. See also the following blog posts for more details on OpenResty and Nginx's shared memory zones: * [How OpenResty and Nginx Shared Memory Zones Consume RAM](https://blog.openresty.com/en/how-nginx-shm-consume-ram/?src=gh_ngxlua) * [Memory Fragmentation in OpenResty and Nginx's Shared Memory Zones](https://blog.openresty.com/en/nginx-shm-frag/?src=gh_ngxlua) -== init_by_lua_block == - -'''syntax:''' ''init_by_lua_block { lua-script }'' - -'''context:''' ''http'' - -'''phase:''' ''loading-config'' - -Similar to the [[#init_by_lua|init_by_lua]] directive except that this directive inlines -the Lua source directly -inside a pair of curly braces ({}) instead of in an Nginx string literal (which requires -special character escaping). - -For instance, - - - init_by_lua_block { - print("I need no extra escaping here, for example: \r\nblah") - } - - -This directive was first introduced in the v0.9.17 release. - == init_by_lua_file == '''syntax:''' ''init_by_lua_file '' @@ -1250,7 +1261,7 @@ This directive was first introduced in the v0.9.17 release. '''phase:''' ''loading-config'' -Equivalent to [[#init_by_lua|init_by_lua]], except that the file specified by contains the Lua code or [[#LuaJIT bytecode support|LuaJIT bytecode]] to be executed. +Equivalent to [[#init_by_lua_block|init_by_lua_block]], except that the file specified by contains the Lua code or [[#LuaJIT bytecode support|LuaJIT bytecode]] to be executed. When a relative path like foo/bar.lua is given, they will be turned into the absolute path relative to the server prefix path determined by the -p PATH command-line option while starting the Nginx server. @@ -1266,12 +1277,35 @@ This directive was first introduced in the v0.5.5 release. '''NOTE''' Use of this directive is ''discouraged'' following the v0.9.17 release. Use the [[#init_worker_by_lua_block|init_worker_by_lua_block]] directive instead. -Runs the specified Lua code upon every Nginx worker process's startup when the master process is enabled. When the master process is disabled, this hook will just run after [[#init_by_lua|init_by_lua*]]. +Similar to the [[#init_worker_by_lua_block|init_worker_by_lua_block]] directive, but accepts the Lua source directly in an Nginx string literal (which requires +special character escaping). + +For instance, + + + init_worker_by_lua ' + print("I need no extra escaping here, for example: \r\nblah") + '; + + +This directive was first introduced in the v0.9.5 release. + +This hook no longer runs in the cache manager and cache loader processes since the v0.10.12 release. + +== init_worker_by_lua_block == + +'''syntax:''' ''init_worker_by_lua_block { lua-script }'' + +'''context:''' ''http'' + +'''phase:''' ''starting-worker'' + +Runs the specified Lua code upon every Nginx worker process's startup when the master process is enabled. When the master process is disabled, this hook will just run after [[#init_by_lua_block|init_by_lua*]]. This hook is often used to create per-worker reoccurring timers (via the [[#ngx.timer.at|ngx.timer.at]] Lua API), either for backend health-check or other timed routine work. Below is an example, - init_worker_by_lua ' + init_worker_by_lua_block { local delay = 3 -- in seconds local new_timer = ngx.timer.at local log = ngx.log @@ -1298,31 +1332,6 @@ This hook is often used to create per-worker reoccurring timers (via the [[#ngx. end -- other job in init_worker_by_lua - '; - - -This directive was first introduced in the v0.9.5 release. - -This hook no longer runs in the cache manager and cache loader processes since the v0.10.12 release. - -== init_worker_by_lua_block == - -'''syntax:''' ''init_worker_by_lua_block { lua-script }'' - -'''context:''' ''http'' - -'''phase:''' ''starting-worker'' - -Similar to the [[#init_worker_by_lua|init_worker_by_lua]] directive except that this directive inlines -the Lua source directly -inside a pair of curly braces ({}) instead of in an Nginx string literal (which requires -special character escaping). - -For instance, - - - init_worker_by_lua_block { - print("I need no extra escaping here, for example: \r\nblah") } @@ -1338,7 +1347,7 @@ This hook no longer runs in the cache manager and cache loader processes since t '''phase:''' ''starting-worker'' -Similar to [[#init_worker_by_lua|init_worker_by_lua]], but accepts the file path to a Lua source file or Lua bytecode file. +Similar to [[#init_worker_by_lua_block|init_worker_by_lua_block]], but accepts the file path to a Lua source file or Lua bytecode file. This directive was first introduced in the v0.9.5 release. @@ -1354,7 +1363,7 @@ This hook no longer runs in the cache manager and cache loader processes since t Runs the specified Lua code upon every Nginx worker process's exit when the master process is enabled. When the master process is disabled, this hook will run before the Nginx process exits. -This hook is often used to release resources allocated by each worker (e.g. resources allocated by [[#init_worker_by_lua|init_worker_by_lua*]]), or to prevent workers from exiting abnormally. +This hook is often used to release resources allocated by each worker (e.g. resources allocated by [[#init_worker_by_lua_block|init_worker_by_lua*]]), or to prevent workers from exiting abnormally. For example, @@ -1390,46 +1399,15 @@ This directive was first introduced in the v0.10.18 release. '''NOTE''' Use of this directive is ''discouraged'' following the v0.9.17 release. Use the [[#set_by_lua_block|set_by_lua_block]] directive instead. -Executes code specified in with optional input arguments $arg1 $arg2 ..., and returns string output to $res. -The code in can make [[#Nginx API for Lua|API calls]] and can retrieve input arguments from the ngx.arg table (index starts from 1 and increases sequentially). +Similar to the [[#set_by_lua_block|set_by_lua_block]] directive, but accepts the Lua source directly in an Nginx string literal (which requires +special character escaping), and +# this directive support extra arguments after the Lua script. -This directive is designed to execute short, fast running code blocks as the Nginx event loop is blocked during code execution. Time consuming code sequences should therefore be avoided. - -This directive is implemented by injecting custom commands into the standard [[HttpRewriteModule]]'s command list. Because [[HttpRewriteModule]] does not support nonblocking I/O in its commands, Lua APIs requiring yielding the current Lua "light thread" cannot work in this directive. - -At least the following API functions are currently disabled within the context of set_by_lua: - -* Output API functions (e.g., [[#ngx.say|ngx.say]] and [[#ngx.send_headers|ngx.send_headers]]) -* Control API functions (e.g., [[#ngx.exit|ngx.exit]]) -* Subrequest API functions (e.g., [[#ngx.location.capture|ngx.location.capture]] and [[#ngx.location.capture_multi|ngx.location.capture_multi]]) -* Cosocket API functions (e.g., [[#ngx.socket.tcp|ngx.socket.tcp]] and [[#ngx.req.socket|ngx.req.socket]]). -* Sleeping API function [[#ngx.sleep|ngx.sleep]]. - -In addition, note that this directive can only write out a value to a single Nginx variable at -a time. However, a workaround is possible using the [[#ngx.var.VARIABLE|ngx.var.VARIABLE]] interface. +For example, - location /foo { - set $diff ''; # we have to predefine the $diff variable here - - set_by_lua $sum ' - local a = 32 - local b = 56 - - ngx.var.diff = a - b -- write to $diff directly - return a + b -- return the $sum value normally - '; - - echo "sum = $sum, diff = $diff"; - } - - -This directive can be freely mixed with all directives of the [[HttpRewriteModule]], [[HttpSetMiscModule]], and [[HttpArrayVarModule]] modules. All of these directives will run in the same order as they appear in the config file. - - - set $foo 32; - set_by_lua $bar 'return tonumber(ngx.var.foo) + 1'; - set $baz "bar: $bar"; # $baz == "bar: 33" + set_by_lua $res ' return 32 + math.cos(32) '; + # $res now has the value "32.834223360507" or alike. As from the v0.5.0rc29 release, Nginx variable interpolation is disabled in the argument of this directive and therefore, the dollar sign character ($) can be used directly. @@ -1444,22 +1422,52 @@ This directive requires the [https://github.com/simplresty/ngx_devel_kit ngx_dev '''phase:''' ''rewrite'' -Similar to the [[#set_by_lua|set_by_lua]] directive except that +Executes code specified inside a pair of curly braces ({}), and returns string output to $res. +The code inside a pair of curly braces ({}) can make [[#Nginx API for Lua|API calls]] and can retrieve input arguments from the ngx.arg table (index starts from 1 and increases sequentially). -# this directive inlines the Lua source directly -inside a pair of curly braces ({}) instead of in an Nginx string literal (which requires -special character escaping), and -# this directive does not support extra arguments after the Lua script as in [[#set_by_lua|set_by_lua]]. +This directive is designed to execute short, fast running code blocks as the Nginx event loop is blocked during code execution. Time consuming code sequences should therefore be avoided. -For example, +This directive is implemented by injecting custom commands into the standard [[HttpRewriteModule]]'s command list. Because [[HttpRewriteModule]] does not support nonblocking I/O in its commands, Lua APIs requiring yielding the current Lua "light thread" cannot work in this directive. + +At least the following API functions are currently disabled within the context of set_by_lua_block: + +* Output API functions (e.g., [[#ngx.say|ngx.say]] and [[#ngx.send_headers|ngx.send_headers]]) +* Control API functions (e.g., [[#ngx.exit|ngx.exit]]) +* Subrequest API functions (e.g., [[#ngx.location.capture|ngx.location.capture]] and [[#ngx.location.capture_multi|ngx.location.capture_multi]]) +* Cosocket API functions (e.g., [[#ngx.socket.tcp|ngx.socket.tcp]] and [[#ngx.req.socket|ngx.req.socket]]). +* Sleeping API function [[#ngx.sleep|ngx.sleep]]. + +In addition, note that this directive can only write out a value to a single Nginx variable at +a time. However, a workaround is possible using the [[#ngx.var.VARIABLE|ngx.var.VARIABLE]] interface. - set_by_lua_block $res { return 32 + math.cos(32) } - # $res now has the value "32.834223360507" or alike. + location /foo { + set $diff ''; # we have to predefine the $diff variable here + + set_by_lua_block $sum { + local a = 32 + local b = 56 + + ngx.var.diff = a - b -- write to $diff directly + return a + b -- return the $sum value normally + } + + echo "sum = $sum, diff = $diff"; + } + + +This directive can be freely mixed with all directives of the [[HttpRewriteModule]], [[HttpSetMiscModule]], and [[HttpArrayVarModule]] modules. All of these directives will run in the same order as they appear in the config file. + + + set $foo 32; + set_by_lua_block $bar { return tonumber(ngx.var.foo) + 1 } + set $baz "bar: $bar"; # $baz == "bar: 33" No special escaping is required in the Lua code block. +This directive requires the [https://github.com/simplresty/ngx_devel_kit ngx_devel_kit] module. + This directive was first introduced in the v0.9.17 release. == set_by_lua_file == @@ -1470,7 +1478,7 @@ This directive was first introduced in the v0.9.17 release. '''phase:''' ''rewrite'' -Equivalent to [[#set_by_lua|set_by_lua]], except that the file specified by contains the Lua code, or, as from the v0.5.0rc32 release, the [[#LuaJIT bytecode support|LuaJIT bytecode]] to be executed. +Equivalent to [[#set_by_lua_block|set_by_lua_block]], except that the file specified by contains the Lua code, or, as from the v0.5.0rc32 release, the [[#LuaJIT bytecode support|LuaJIT bytecode]] to be executed. Nginx variable interpolation is supported in the argument string of this directive. But special care must be taken for injection attacks. @@ -1493,10 +1501,16 @@ This directive requires the [https://github.com/simplresty/ngx_devel_kit ngx_dev '''NOTE''' Use of this directive is ''discouraged'' following the v0.9.17 release. Use the [[#content_by_lua_block|content_by_lua_block]] directive instead. -Acts as a "content handler" and executes Lua code string specified in for every request. -The Lua code may make [[#Nginx API for Lua|API calls]] and is executed as a new spawned coroutine in an independent global environment (i.e. a sandbox). +Similar to the [[#content_by_lua_block|content_by_lua_block]] directive, but accepts the Lua source directly in an Nginx string literal (which requires +special character escaping). -Do not use this directive and other content handler directives in the same location. For example, this directive and the [[HttpProxyModule#proxy_pass|proxy_pass]] directive should not be used in the same location. +For instance, + + + content_by_lua ' + ngx.say("I need no extra escaping here, for example: \r\nblah") + '; + == content_by_lua_block == @@ -1506,11 +1520,6 @@ Do not use this directive and other content handler directives in the same locat '''phase:''' ''content'' -Similar to the [[#content_by_lua|content_by_lua]] directive except that this directive inlines -the Lua source directly -inside a pair of curly braces ({}) instead of in an Nginx string literal (which requires -special character escaping). - For instance, @@ -1519,6 +1528,11 @@ For instance, } +Acts as a "content handler" and executes Lua code string specified in { lua-script } for every request. +The Lua code may make [[#Nginx API for Lua|API calls]] and is executed as a new spawned coroutine in an independent global environment (i.e. a sandbox). + +Do not use this directive and other content handler directives in the same location. For example, this directive and the [[HttpProxyModule#proxy_pass|proxy_pass]] directive should not be used in the same location. + This directive was first introduced in the v0.9.17 release. == content_by_lua_file == @@ -1529,7 +1543,7 @@ This directive was first introduced in the v0.9.17 release. '''phase:''' ''content'' -Equivalent to [[#content_by_lua|content_by_lua]], except that the file specified by contains the Lua code, or, as from the v0.5.0rc32 release, the [[#LuaJIT bytecode support|LuaJIT bytecode]] to be executed. +Equivalent to [[#content_by_lua_block|content_by_lua_block]], except that the file specified by contains the Lua code, or, as from the v0.5.0rc32 release, the [[#LuaJIT bytecode support|LuaJIT bytecode]] to be executed. Nginx variables can be used in the string to provide flexibility. This however carries some risks and is not ordinarily recommended. @@ -1553,6 +1567,88 @@ Nginx variables are supported in the file path for dynamic dispatch, for example But be very careful about malicious user inputs and always carefully validate or filter out the user-supplied path components. +== server_rewrite_by_lua_block == + +'''syntax:''' ''server_rewrite_by_lua_block { lua-script }'' + +'''context:''' ''http, server'' + +'''phase:''' ''server rewrite'' + +Acts as a server rewrite phase handler and executes Lua code string specified in { lua-script } for every request. +The Lua code may make [[#Nginx API for Lua|API calls]] and is executed as a new spawned coroutine in an independent global environment (i.e. a sandbox). + + +server { + ... + + server_rewrite_by_lua_block { + ngx.ctx.a = "server_rewrite_by_lua_block in http" + } + + location /lua { + content_by_lua_block { + ngx.say(ngx.ctx.a) + ngx.log(ngx.INFO, ngx.ctx.a) + } + } +} + + +Just as any other rewrite phase handlers, [[#server_rewrite_by_lua_block|server_rewrite_by_lua_block]] also runs in subrequests. + + +server { + server_rewrite_by_lua_block { + ngx.log(ngx.INFO, "is_subrequest:", ngx.is_subrequest) + } + + location /lua { + content_by_lua_block { + local res = ngx.location.capture("/sub") + ngx.print(res.body) + } + } + + location /sub { + content_by_lua_block { + ngx.say("OK") + } + } +} + + +Note that when calling ngx.exit(ngx.OK) within a [[#server_rewrite_by_lua_block|server_rewrite_by_lua_block]] handler, the Nginx request processing control flow will still continue to the content handler. To terminate the current request from within a [[#server_rewrite_by_lua_block|server_rewrite_by_lua_block]] handler, call [[#ngx.exit|ngx.exit]] with status >= 200 (ngx.HTTP_OK) and status < 300 (ngx.HTTP_SPECIAL_RESPONSE) for successful quits and ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) (or its friends) for failures. + + + + server_rewrite_by_lua_block { + ngx.exit(503) + } + + location /bar { + ... + # never exec + } + + + +== server_rewrite_by_lua_file == + +'''syntax:''' ''server_rewrite_by_lua_file '' + +'''context:''' ''http, server'' + +'''phase:''' ''server rewrite'' + +Equivalent to [[#server_rewrite_by_lua_block|server_rewrite_by_lua_block]], except that the file specified by contains the Lua code, or, as from the v0.10.22 release, the [[#LuaJIT bytecode support|LuaJIT bytecode]] to be executed. + +Nginx variables can be used in the string to provide flexibility. This however carries some risks and is not ordinarily recommended. + +When a relative path like foo/bar.lua is given, they will be turned into the absolute path relative to the server prefix path determined by the -p PATH command-line option while starting the Nginx server. + +When the Lua code cache is turned on (by default), the user code is loaded once at the first request and cached and the Nginx config must be reloaded each time the Lua source file is modified. The Lua code cache can be temporarily disabled during development by switching [[#lua_code_cache|lua_code_cache]] off in nginx.conf to avoid reloading Nginx. + == rewrite_by_lua == '''syntax:''' ''rewrite_by_lua '' @@ -1563,7 +1659,26 @@ But be very careful about malicious user inputs and always carefully validate or '''NOTE''' Use of this directive is ''discouraged'' following the v0.9.17 release. Use the [[#rewrite_by_lua_block|rewrite_by_lua_block]] directive instead. -Acts as a rewrite phase handler and executes Lua code string specified in for every request. +Similar to the [[#rewrite_by_lua_block|rewrite_by_lua_block]] directive, but accepts the Lua source directly in an Nginx string literal (which requires +special character escaping). + +For instance, + + + rewrite_by_lua ' + do_something("hello, world!\nhiya\n") + '; + + +== rewrite_by_lua_block == + +'''syntax:''' ''rewrite_by_lua_block { lua-script }'' + +'''context:''' ''http, server, location, location if'' + +'''phase:''' ''rewrite tail'' + +Acts as a rewrite phase handler and executes Lua code string specified in { lua-script } for every request. The Lua code may make [[#Nginx API for Lua|API calls]] and is executed as a new spawned coroutine in an independent global environment (i.e. a sandbox). Note that this handler always runs ''after'' the standard [[HttpRewriteModule]]. So the following will work as expected: @@ -1572,12 +1687,14 @@ Note that this handler always runs ''after'' the standard [[HttpRewriteModule]]. location /foo { set $a 12; # create and initialize $a set $b ""; # create and initialize $b - rewrite_by_lua 'ngx.var.b = tonumber(ngx.var.a) + 1'; + rewrite_by_lua_block { + ngx.var.b = tonumber(ngx.var.a) + 1 + } echo "res = $b"; } -because set $a 12 and set $b "" run ''before'' [[#rewrite_by_lua|rewrite_by_lua]]. +because set $a 12 and set $b "" run ''before'' [[#rewrite_by_lua_block|rewrite_by_lua_block]]. On the other hand, the following will not work as expected: @@ -1585,7 +1702,9 @@ On the other hand, the following will not work as expected: ? location /foo { ? set $a 12; # create and initialize $a ? set $b ''; # create and initialize $b - ? rewrite_by_lua 'ngx.var.b = tonumber(ngx.var.a) + 1'; + ? rewrite_by_lua_block { + ? ngx.var.b = tonumber(ngx.var.a) + 1 + ? } ? if ($b = '13') { ? rewrite ^ /bar redirect; ? break; @@ -1595,7 +1714,7 @@ On the other hand, the following will not work as expected: ? } -because if runs ''before'' [[#rewrite_by_lua|rewrite_by_lua]] even if it is placed after [[#rewrite_by_lua|rewrite_by_lua]] in the config. +because if runs ''before'' [[#rewrite_by_lua_block|rewrite_by_lua_block]] even if it is placed after [[#rewrite_by_lua_block|rewrite_by_lua_block]] in the config. The right way of doing this is as follows: @@ -1603,18 +1722,18 @@ The right way of doing this is as follows: location /foo { set $a 12; # create and initialize $a set $b ''; # create and initialize $b - rewrite_by_lua ' + rewrite_by_lua_block { ngx.var.b = tonumber(ngx.var.a) + 1 if tonumber(ngx.var.b) == 13 then return ngx.redirect("/bar") end - '; + } echo "res = $b"; } -Note that the [http://www.grid.net.ru/nginx/eval.en.html ngx_eval] module can be approximated by using [[#rewrite_by_lua|rewrite_by_lua]]. For example, +Note that the [http://www.grid.net.ru/nginx/eval.en.html ngx_eval] module can be approximated by using [[#rewrite_by_lua_block|rewrite_by_lua_block]]. For example, location / { @@ -1639,57 +1758,38 @@ can be implemented in ngx_lua as: } location / { - rewrite_by_lua ' + rewrite_by_lua_block { local res = ngx.location.capture("/check-spam") if res.body == "spam" then return ngx.redirect("/terms-of-use.html") end - '; + } fastcgi_pass ...; } -Just as any other rewrite phase handlers, [[#rewrite_by_lua|rewrite_by_lua]] also runs in subrequests. +Just as any other rewrite phase handlers, [[#rewrite_by_lua_block|rewrite_by_lua_block]] also runs in subrequests. -Note that when calling ngx.exit(ngx.OK) within a [[#rewrite_by_lua|rewrite_by_lua]] handler, the Nginx request processing control flow will still continue to the content handler. To terminate the current request from within a [[#rewrite_by_lua|rewrite_by_lua]] handler, call [[#ngx.exit|ngx.exit]] with status >= 200 (ngx.HTTP_OK) and status < 300 (ngx.HTTP_SPECIAL_RESPONSE) for successful quits and ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) (or its friends) for failures. +Note that when calling ngx.exit(ngx.OK) within a [[#rewrite_by_lua_block|rewrite_by_lua_block]] handler, the Nginx request processing control flow will still continue to the content handler. To terminate the current request from within a [[#rewrite_by_lua_block|rewrite_by_lua_block]] handler, call [[#ngx.exit|ngx.exit]] with status >= 200 (ngx.HTTP_OK) and status < 300 (ngx.HTTP_SPECIAL_RESPONSE) for successful quits and ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) (or its friends) for failures. -If the [[HttpRewriteModule]]'s [[HttpRewriteModule#rewrite|rewrite]] directive is used to change the URI and initiate location re-lookups (internal redirections), then any [[#rewrite_by_lua|rewrite_by_lua]] or [[#rewrite_by_lua_file|rewrite_by_lua_file]] code sequences within the current location will not be executed. For example, +If the [[HttpRewriteModule]]'s [[HttpRewriteModule#rewrite|rewrite]] directive is used to change the URI and initiate location re-lookups (internal redirections), then any [[#rewrite_by_lua_block|rewrite_by_lua_block]] or [[#rewrite_by_lua_file_block|rewrite_by_lua_file_block]] code sequences within the current location will not be executed. For example, location /foo { rewrite ^ /bar; - rewrite_by_lua 'ngx.exit(503)'; + rewrite_by_lua_block { + ngx.exit(503) + } } location /bar { ... } -Here the Lua code ngx.exit(503) will never run. This will be the case if rewrite ^ /bar last is used as this will similarly initiate an internal redirection. If the break modifier is used instead, there will be no internal redirection and the rewrite_by_lua code will be executed. +Here the Lua code ngx.exit(503) will never run. This will be the case if rewrite ^ /bar last is used as this will similarly initiate an internal redirection. If the break modifier is used instead, there will be no internal redirection and the rewrite_by_lua_block code will be executed. -The rewrite_by_lua code will always run at the end of the rewrite request-processing phase unless [[#rewrite_by_lua_no_postpone|rewrite_by_lua_no_postpone]] is turned on. - -== rewrite_by_lua_block == - -'''syntax:''' ''rewrite_by_lua_block { lua-script }'' - -'''context:''' ''http, server, location, location if'' - -'''phase:''' ''rewrite tail'' - -Similar to the [[#rewrite_by_lua|rewrite_by_lua]] directive except that this directive inlines -the Lua source directly -inside a pair of curly braces ({}) instead of in an Nginx string literal (which requires -special character escaping). - -For instance, - - - rewrite_by_lua_block { - do_something("hello, world!\nhiya\n") - } - +The rewrite_by_lua_block code will always run at the end of the rewrite request-processing phase unless [[#rewrite_by_lua_no_postpone|rewrite_by_lua_no_postpone]] is turned on. This directive was first introduced in the v0.9.17 release. @@ -1701,7 +1801,7 @@ This directive was first introduced in the v0.9.17 release. '''phase:''' ''rewrite tail'' -Equivalent to [[#rewrite_by_lua|rewrite_by_lua]], except that the file specified by contains the Lua code, or, as from the v0.5.0rc32 release, the [[#LuaJIT bytecode support|LuaJIT bytecode]] to be executed. +Equivalent to [[#rewrite_by_lua_block|rewrite_by_lua_block]], except that the file specified by contains the Lua code, or, as from the v0.5.0rc32 release, the [[#LuaJIT bytecode support|LuaJIT bytecode]] to be executed. Nginx variables can be used in the string to provide flexibility. This however carries some risks and is not ordinarily recommended. @@ -1723,7 +1823,26 @@ Nginx variables are supported in the file path for dynamic dispatch just as in [ '''NOTE''' Use of this directive is ''discouraged'' following the v0.9.17 release. Use the [[#access_by_lua_block|access_by_lua_block]] directive instead. -Acts as an access phase handler and executes Lua code string specified in for every request. +Similar to the [[#access_by_lua_block|access_by_lua_block]] directive, but accepts the Lua source directly in an Nginx string literal (which requires +special character escaping). + +For instance, + + + access_by_lua ' + do_something("hello, world!\nhiya\n") + '; + + +== access_by_lua_block == + +'''syntax:''' ''access_by_lua_block { lua-script }'' + +'''context:''' ''http, server, location, location if'' + +'''phase:''' ''access tail'' + +Acts as an access phase handler and executes Lua code string specified in { for every request. The Lua code may make [[#Nginx API for Lua|API calls]] and is executed as a new spawned coroutine in an independent global environment (i.e. a sandbox). Note that this handler always runs ''after'' the standard [[HttpAccessModule]]. So the following will work as expected: @@ -1735,18 +1854,18 @@ Note that this handler always runs ''after'' the standard [[HttpAccessModule]]. allow 10.1.1.0/16; deny all; - access_by_lua ' + access_by_lua_block { local res = ngx.location.capture("/mysql", { ... }) ... - '; + } # proxy_pass/fastcgi_pass/... } -That is, if a client IP address is in the blacklist, it will be denied before the MySQL query for more complex authentication is executed by [[#access_by_lua|access_by_lua]]. +That is, if a client IP address is in the blacklist, it will be denied before the MySQL query for more complex authentication is executed by [[#access_by_lua_block|access_by_lua_block]]. -Note that the [http://mdounin.ru/hg/ngx_http_auth_request_module/ ngx_auth_request] module can be approximated by using [[#access_by_lua|access_by_lua]]: +Note that the [http://mdounin.ru/hg/ngx_http_auth_request_module/ ngx_auth_request] module can be approximated by using [[#access_by_lua_block|access_by_lua_block]]: location / { @@ -1760,7 +1879,7 @@ can be implemented in ngx_lua as: location / { - access_by_lua ' + access_by_lua_block { local res = ngx.location.capture("/auth") if res.status == ngx.HTTP_OK then @@ -1772,41 +1891,20 @@ can be implemented in ngx_lua as: end ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) - '; + } # proxy_pass/fastcgi_pass/postgres_pass/... } -As with other access phase handlers, [[#access_by_lua|access_by_lua]] will ''not'' run in subrequests. +As with other access phase handlers, [[#access_by_lua_block|access_by_lua_block]] will ''not'' run in subrequests. -Note that when calling ngx.exit(ngx.OK) within a [[#access_by_lua|access_by_lua]] handler, the Nginx request processing control flow will still continue to the content handler. To terminate the current request from within a [[#access_by_lua|access_by_lua]] handler, call [[#ngx.exit|ngx.exit]] with status >= 200 (ngx.HTTP_OK) and status < 300 (ngx.HTTP_SPECIAL_RESPONSE) for successful quits and ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) (or its friends) for failures. +Note that when calling ngx.exit(ngx.OK) within a [[#access_by_lua_block|access_by_lua_block]] handler, the Nginx request processing control flow will still continue to the content handler. To terminate the current request from within a [[#access_by_lua_block|access_by_lua_block]] handler, call [[#ngx.exit|ngx.exit]] with status >= 200 (ngx.HTTP_OK) and status < 300 (ngx.HTTP_SPECIAL_RESPONSE) for successful quits and ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) (or its friends) for failures. Starting from the v0.9.20 release, you can use the [[#access_by_lua_no_postpone|access_by_lua_no_postpone]] directive to control when to run this handler inside the "access" request-processing phase of Nginx. -== access_by_lua_block == - -'''syntax:''' ''access_by_lua_block { lua-script }'' - -'''context:''' ''http, server, location, location if'' - -'''phase:''' ''access tail'' - -Similar to the [[#access_by_lua|access_by_lua]] directive except that this directive inlines -the Lua source directly -inside a pair of curly braces ({}) instead of in an Nginx string literal (which requires -special character escaping). - -For instance, - - - access_by_lua_block { - do_something("hello, world!\nhiya\n") - } - - This directive was first introduced in the v0.9.17 release. == access_by_lua_file == @@ -1817,7 +1915,7 @@ This directive was first introduced in the v0.9.17 release. '''phase:''' ''access tail'' -Equivalent to [[#access_by_lua|access_by_lua]], except that the file specified by contains the Lua code, or, as from the v0.5.0rc32 release, the [[#LuaJIT bytecode support|LuaJIT bytecode]] to be executed. +Equivalent to [[#access_by_lua_block|access_by_lua_block]], except that the file specified by contains the Lua code, or, as from the v0.5.0rc32 release, the [[#LuaJIT bytecode support|LuaJIT bytecode]] to be executed. Nginx variables can be used in the string to provide flexibility. This however carries some risks and is not ordinarily recommended. @@ -1839,7 +1937,28 @@ Nginx variables are supported in the file path for dynamic dispatch just as in [ '''NOTE''' Use of this directive is ''discouraged'' following the v0.9.17 release. Use the [[#header_filter_by_lua_block|header_filter_by_lua_block]] directive instead. -Uses Lua code specified in to define an output header filter. +Similar to the [[#header_filter_by_lua_block|header_filter_by_lua_block]] directive, but accepts the Lua source directly in an Nginx string literal (which requires +special character escaping). + +For instance, + + + header_filter_by_lua ' + ngx.header["content-length"] = nil + '; + + +This directive was first introduced in the v0.2.1rc20 release. + +== header_filter_by_lua_block == + +'''syntax:''' ''header_filter_by_lua_block { lua-script }'' + +'''context:''' ''http, server, location, location if'' + +'''phase:''' ''output-header-filter'' + +Uses Lua code specified in { lua-script } to define an output header filter. Note that the following API functions are currently disabled within this context: @@ -1853,30 +1972,9 @@ Here is an example of overriding a response header (or adding one if absent) in location / { proxy_pass http://mybackend; - header_filter_by_lua 'ngx.header.Foo = "blah"'; - } - - -This directive was first introduced in the v0.2.1rc20 release. - -== header_filter_by_lua_block == - -'''syntax:''' ''header_filter_by_lua_block { lua-script }'' - -'''context:''' ''http, server, location, location if'' - -'''phase:''' ''output-header-filter'' - -Similar to the [[#header_filter_by_lua|header_filter_by_lua]] directive except that this directive inlines -the Lua source directly -inside a pair of curly braces ({}) instead of in an Nginx string literal (which requires -special character escaping). - -For instance, - - - header_filter_by_lua_block { - ngx.header["content-length"] = nil + header_filter_by_lua_block { + ngx.header.Foo = "blah" + } } @@ -1890,7 +1988,7 @@ This directive was first introduced in the v0.9.17 release. '''phase:''' ''output-header-filter'' -Equivalent to [[#header_filter_by_lua|header_filter_by_lua]], except that the file specified by contains the Lua code, or as from the v0.5.0rc32 release, the [[#LuaJIT bytecode support|LuaJIT bytecode]] to be executed. +Equivalent to [[#header_filter_by_lua_block|header_filter_by_lua_block]], except that the file specified by contains the Lua code, or as from the v0.5.0rc32 release, the [[#LuaJIT bytecode support|LuaJIT bytecode]] to be executed. When a relative path like foo/bar.lua is given, they will be turned into the absolute path relative to the server prefix path determined by the -p PATH command-line option while starting the Nginx server. @@ -1906,7 +2004,28 @@ This directive was first introduced in the v0.2.1rc20 release. '''NOTE''' Use of this directive is ''discouraged'' following the v0.9.17 release. Use the [[#body_filter_by_lua_block|body_filter_by_lua_block]] directive instead. -Uses Lua code specified in to define an output body filter. +Similar to the [[#body_filter_by_lua_block|body_filter_by_lua_block]] directive, but accepts the Lua source directly in an Nginx string literal (which requires +special character escaping). + +For instance, + + + body_filter_by_lua ' + local data, eof = ngx.arg[1], ngx.arg[2] + '; + + +This directive was first introduced in the v0.5.0rc32 release. + +== body_filter_by_lua_block == + +'''syntax:''' ''body_filter_by_lua_block { lua-script-str }'' + +'''context:''' ''http, server, location, location if'' + +'''phase:''' ''output-body-filter'' + +Uses Lua code specified in { lua-script } to define an output body filter. The input data chunk is passed via [[#ngx.arg|ngx.arg]][1] (as a Lua string value) and the "eof" flag indicating the end of the response body data stream is passed via [[#ngx.arg|ngx.arg]][2] (as a Lua boolean value). @@ -1925,7 +2044,9 @@ The Lua code can pass its own modified version of the input data chunk to the do location / { proxy_pass http://mybackend; - body_filter_by_lua 'ngx.arg[1] = string.upper(ngx.arg[1])'; + body_filter_by_lua_block { + ngx.arg[1] = string.upper(ngx.arg[1]) + } } @@ -1938,7 +2059,7 @@ Likewise, new "eof" flag can also be specified by setting a boolean value to [[# echo hello world; echo hiya globe; - body_filter_by_lua ' + body_filter_by_lua_block { local chunk = ngx.arg[1] if string.match(chunk, "hello") then ngx.arg[2] = true -- new eof @@ -1947,7 +2068,7 @@ Likewise, new "eof" flag can also be specified by setting a boolean value to [[# -- just throw away any remaining chunk data ngx.arg[1] = nil - '; + } } @@ -1965,8 +2086,12 @@ When the Lua code may change the length of the response body, then it is require location /foo { # fastcgi_pass/proxy_pass/... - header_filter_by_lua_block { ngx.header.content_length = nil } - body_filter_by_lua 'ngx.arg[1] = string.len(ngx.arg[1]) .. "\\n"'; + header_filter_by_lua_block { + ngx.header.content_length = nil + } + body_filter_by_lua_block { + ngx.arg[1] = string.len(ngx.arg[1]) .. "\n" + } } @@ -1979,29 +2104,6 @@ Note that the following API functions are currently disabled within this context Nginx output filters may be called multiple times for a single request because response body may be delivered in chunks. Thus, the Lua code specified by in this directive may also run multiple times in the lifetime of a single HTTP request. -This directive was first introduced in the v0.5.0rc32 release. - -== body_filter_by_lua_block == - -'''syntax:''' ''body_filter_by_lua_block { lua-script-str }'' - -'''context:''' ''http, server, location, location if'' - -'''phase:''' ''output-body-filter'' - -Similar to the [[#body_filter_by_lua|body_filter_by_lua]] directive except that this directive inlines -the Lua source directly -inside a pair of curly braces ({}) instead of in an Nginx string literal (which requires -special character escaping). - -For instance, - - - body_filter_by_lua_block { - local data, eof = ngx.arg[1], ngx.arg[2] - } - - This directive was first introduced in the v0.9.17 release. == body_filter_by_lua_file == @@ -2012,7 +2114,7 @@ This directive was first introduced in the v0.9.17 release. '''phase:''' ''output-body-filter'' -Equivalent to [[#body_filter_by_lua|body_filter_by_lua]], except that the file specified by contains the Lua code, or, as from the v0.5.0rc32 release, the [[#LuaJIT bytecode support|LuaJIT bytecode]] to be executed. +Equivalent to [[#body_filter_by_lua_block|body_filter_by_lua_block]], except that the file specified by contains the Lua code, or, as from the v0.5.0rc32 release, the [[#LuaJIT bytecode support|LuaJIT bytecode]] to be executed. When a relative path like foo/bar.lua is given, they will be turned into the absolute path relative to the server prefix path determined by the -p PATH command-line option while starting the Nginx server. @@ -2028,7 +2130,28 @@ This directive was first introduced in the v0.5.0rc32 release. '''NOTE''' Use of this directive is ''discouraged'' following the v0.9.17 release. Use the [[#log_by_lua_block|log_by_lua_block]] directive instead. -Runs the Lua source code inlined as the at the log request processing phase. This does not replace the current access logs, but runs before. +Similar to the [[#log_by_lua_block|log_by_lua_block]] directive, but accepts the Lua source directly in an Nginx string literal (which requires +special character escaping). + +For instance, + + + log_by_lua ' + print("I need no extra escaping here, for example: \r\nblah") + '; + + +This directive was first introduced in the v0.5.0rc31 release. + +== log_by_lua_block == + +'''syntax:''' ''log_by_lua_block { lua-script }'' + +'''context:''' ''http, server, location, location if'' + +'''phase:''' ''log'' + +Runs the Lua source code inlined as the { lua-script } at the log request processing phase. This does not replace the current access logs, but runs before. Note that the following API functions are currently disabled within this context: @@ -2046,7 +2169,7 @@ Here is an example of gathering average data for [[HttpUpstreamModule#$upstream_ location / { proxy_pass http://mybackend; - log_by_lua ' + log_by_lua_block { local log_dict = ngx.shared.log_dict local upstream_time = tonumber(ngx.var.upstream_response_time) @@ -2059,7 +2182,7 @@ Here is an example of gathering average data for [[HttpUpstreamModule#$upstream_ log_dict:add("upstream_time-nb", 0) log_dict:incr("upstream_time-nb", 1) end - '; + } } location = /status { @@ -2079,29 +2202,6 @@ Here is an example of gathering average data for [[HttpUpstreamModule#$upstream_ } -This directive was first introduced in the v0.5.0rc31 release. - -== log_by_lua_block == - -'''syntax:''' ''log_by_lua_block { lua-script }'' - -'''context:''' ''http, server, location, location if'' - -'''phase:''' ''log'' - -Similar to the [[#log_by_lua|log_by_lua]] directive except that this directive inlines -the Lua source directly -inside a pair of curly braces ({}) instead of in an Nginx string literal (which requires -special character escaping). - -For instance, - - - log_by_lua_block { - print("I need no extra escaping here, for example: \r\nblah") - } - - This directive was first introduced in the v0.9.17 release. == log_by_lua_file == @@ -2112,7 +2212,7 @@ This directive was first introduced in the v0.9.17 release. '''phase:''' ''log'' -Equivalent to [[#log_by_lua|log_by_lua]], except that the file specified by contains the Lua code, or, as from the v0.5.0rc32 release, the [[#LuaJIT bytecode support|LuaJIT bytecode]] to be executed. +Equivalent to [[#log_by_lua_block|log_by_lua_block]], except that the file specified by contains the Lua code, or, as from the v0.5.0rc32 release, the [[#LuaJIT bytecode support|LuaJIT bytecode]] to be executed. When a relative path like foo/bar.lua is given, they will be turned into the absolute path relative to the server prefix path determined by the -p PATH command-line option while starting the Nginx server. @@ -2300,18 +2400,11 @@ This directive requires OpenSSL 1.1.1 or greater. If you are using the [official pre-built packages](https://openresty.org/en/linux-packages.html) for -[OpenResty](https://openresty.org/) 1.19.9.2 or later, then everything should +[OpenResty](https://openresty.org/) 1.21.4.1 or later, then everything should work out of the box. -If you are not using one of the [OpenSSL -packages](https://openresty.org/en/linux-packages.html) provided by -[OpenResty](https://openresty.org), you will need to apply patches to OpenSSL -in order to use this directive: - -https://openresty.org/en/openssl-patches.html - -Similarly, if you are not using the Nginx core shipped with -[OpenResty](https://openresty.org) 1.19.9.2 or later, you will need to apply +If you are not using the Nginx core shipped with +[OpenResty](https://openresty.org) 1.21.4.1 or later, you will need to apply patches to the standard Nginx core: https://openresty.org/en/nginx-ssl-patches.html @@ -2413,14 +2506,7 @@ packages](https://openresty.org/en/linux-packages.html) for [OpenResty](https://openresty.org/) 1.9.7.2 or later, then everything should work out of the box. -If you are not using one of the [OpenSSL -packages](https://openresty.org/en/linux-packages.html) provided by -[OpenResty](https://openresty.org), you will need to apply patches to OpenSSL -in order to use this directive: - -https://openresty.org/en/openssl-patches.html - -Similarly, if you are not using the Nginx core shipped with +If you are not using the Nginx core shipped with [OpenResty](https://openresty.org) 1.9.7.2 or later, you will need to apply patches to the standard Nginx core: @@ -3164,7 +3250,8 @@ These constants are usually used in [[#ngx.location.capture|ngx.location.capture value = ngx.HTTP_CLOSE (444) (first added in the v0.9.20 release) value = ngx.HTTP_ILLEGAL (451) (first added in the v0.9.20 release) value = ngx.HTTP_INTERNAL_SERVER_ERROR (500) - value = ngx.HTTP_METHOD_NOT_IMPLEMENTED (501) + value = ngx.HTTP_NOT_IMPLEMENTED (501) + value = ngx.HTTP_METHOD_NOT_IMPLEMENTED (501) (kept for compatibility) value = ngx.HTTP_BAD_GATEWAY (502) (first added in the v0.9.20 release) value = ngx.HTTP_SERVICE_UNAVAILABLE (503) value = ngx.HTTP_GATEWAY_TIMEOUT (504) (first added in the v0.3.1rc38 release) @@ -3300,7 +3387,7 @@ Because HTTP request is created after SSL handshake, the ngx.ctx cr in [[#ssl_certificate_by_lua|ssl_certificate_by_lua*]], [[#ssl_session_store_by_lua|ssl_session_store_by_lua*]], [[#ssl_session_fetch_by_lua|ssl_session_fetch_by_lua*]] and [[#ssl_client_hello_by_lua|ssl_client_hello_by_lua*]] is not available in the following phases like [[#rewrite_by_lua|rewrite_by_lua*]]. -Since dev, the ngx.ctx created during a SSL handshake +Since v0.10.18, the ngx.ctx created during a SSL handshake will be inherited by the requests which share the same TCP connection established by the handshake. Note that overwrite values in ngx.ctx in the http request phases (like `rewrite_by_lua*`) will only take affect in the current http request. @@ -3667,7 +3754,9 @@ Lua tables can be used for both requests and responses when the number of subreq table.insert(reqs, { "/memcached" }) -- issue all the requests at once and wait until they all return - local resps = { ngx.location.capture_multi(reqs) } + local resps = { + ngx.location.capture_multi(reqs) + } -- loop over the responses table for i, resp in ipairs(resps) do @@ -4093,11 +4182,12 @@ See also [[#ngx.req.set_uri|ngx.req.set_uri]]. == ngx.req.get_uri_args == -'''syntax:''' ''args, err = ngx.req.get_uri_args(max_args?)'' +'''syntax:''' ''args, err = ngx.req.get_uri_args(max_args?, tab?)'' '''context:''' ''set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*, body_filter_by_lua*, log_by_lua*, balancer_by_lua*'' -Returns a Lua table holding all the current request URL query arguments. +Returns a Lua table holding all the current request URL query arguments. An optional tab argument +can be used to reuse the table returned by this method. location = /test { @@ -4372,6 +4462,8 @@ For security considerations, this method will automatically escape " ", """, "(" By default, all the subrequests subsequently initiated by [[#ngx.location.capture|ngx.location.capture]] and [[#ngx.location.capture_multi|ngx.location.capture_multi]] will inherit the new header. +It is not a Lua's equivalent of nginx `proxy_set_header` directive (same is true about [ngx.req.clear_header](#ngxreqclear_header)). `proxy_set_header` only affects the upstream request while `ngx.req.set_header` change the incoming request. Record the http headers in the access log file will show the difference. But you still can use it as an alternative of nginx `proxy_set_header` directive as long as you know the difference. + Here is an example of setting the Content-Type header: @@ -5176,7 +5268,9 @@ For example, location = /md5 { - content_by_lua_block { ngx.say(ngx.md5("hello")) } + content_by_lua_block { + ngx.say(ngx.md5("hello")) + } } @@ -6404,7 +6498,9 @@ This API function was first added to the v0.10.1 release. Creates and returns a TCP or stream-oriented unix domain socket object (also known as one type of the "cosocket" objects). The following methods are supported on this object: +* [[#tcpsock:bind|bind]] * [[#tcpsock:connect|connect]] +* [[#tcpsock:setclientcert|setclientcert]] * [[#tcpsock:sslhandshake|sslhandshake]] * [[#tcpsock:send|send]] * [[#tcpsock:receive|receive]] @@ -6440,6 +6536,38 @@ This feature was first introduced in the v0.5.0rc1 release. See also [[#ngx.socket.udp|ngx.socket.udp]]. +== tcpsock:bind == +'''syntax:''' ''ok, err = tcpsock:bind(address)'' + +'''context:''' ''rewrite_by_lua*, access_by_lua*, content_by_lua*, ngx.timer.*, ssl_certificate_by_lua*'' + +Just like the standard [[HttpProxyModule#proxy_bind|proxy_bind]] directive, this api makes the outgoing connection to a upstream server originate from the specified local IP address. + +Only IP addresses can be specified as the address argument. + +Here is an example for connecting to a TCP server from the specified local IP address: + + + location /test { + content_by_lua_block { + local sock = ngx.socket.tcp() + -- assume "192.168.1.10" is the local ip address + local ok, err = sock:bind("192.168.1.10") + if not ok then + ngx.say("failed to bind") + return + end + local ok, err = sock:connect("192.168.1.67", 80) + if not ok then + ngx.say("failed to connect server: ", err) + return + end + ngx.say("successfully connected!") + sock:close() + } + } + + == tcpsock:connect == '''syntax:''' ''ok, err = tcpsock:connect(host, port, options_table?)'' @@ -6555,6 +6683,28 @@ The support for the options table argument was first introduced in the v0. This method was first introduced in the v0.5.0rc1 release. +== tcpsock:setclientcert == + +'''syntax:''' ''ok, err = tcpsock:setclientcert(cert, pkey)'' + +'''context:''' ''rewrite_by_lua*, access_by_lua*, content_by_lua*, ngx.timer.*, ssl_certificate_by_lua*, ssl_session_fetch_by_lua*, ssl_client_hello_by_lua*'' + +Set client certificate chain and corresponding private key to the TCP socket object. +The certificate chain and private key provided will be used later by the [tcpsock:sslhandshake](#tcpsocksslhandshake) method. + +* cert specify a client certificate chain cdata object that will be used while handshaking with +remote server. These objects can be created using [ngx.ssl.parse\_pem\_cert](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md#parse_pem_cert) +function provided by lua-resty-core. Note that specifying the cert option requires +corresponding pkey be provided too. See below. +* pkey specify a private key corresponds to the cert option above. +These objects can be created using [ngx.ssl.parse\_pem\_priv\_key](https://github.com/openresty/lua-resty-core/blob/master/lib/ngx/ssl.md#parse_pem_priv_key) +function provided by lua-resty-core. + +If both of cert and pkey are nil, this method will clear any existing client certificate and private key +that was previously set on the cosocket object. + +This method was first introduced in the `v0.10.22` release. + == tcpsock:sslhandshake == '''syntax:''' ''session, err = tcpsock:sslhandshake(reused_session?, server_name?, ssl_verify?, send_status_req?)'' @@ -7592,6 +7742,13 @@ This function returns a Lua number for the process ID (PID) of the current Nginx This API was first introduced in the 0.9.5 release. +== ngx.worker.pids == + +'''syntax:''' ''pid = ngx.worker.pids()'' + +'''context:''' ''set_by_lua*, rewrite_by_lua*, access_by_lua*, content_by_lua*, header_filter_by_lua*, body_filter_by_lua*, log_by_lua*, ngx.timer.*, exit_worker_by_lua*'' + +This function returns a Lua table for all Nginx worker process ID (PID). Nginx uses channel to send the current worker PID to another worker in the worker process start or restart. So this API can get all current worker PID. == ngx.worker.count == '''syntax:''' ''count = ngx.worker.count()'' diff --git a/src/deps/src/lua-nginx-module/src/api/ngx_http_lua_api.h b/src/deps/src/lua-nginx-module/src/api/ngx_http_lua_api.h index a1ef1f7cb..664698a72 100644 --- a/src/deps/src/lua-nginx-module/src/api/ngx_http_lua_api.h +++ b/src/deps/src/lua-nginx-module/src/api/ngx_http_lua_api.h @@ -19,7 +19,7 @@ /* Public API for other Nginx modules */ -#define ngx_http_lua_version 10022 +#define ngx_http_lua_version 10023 typedef struct { diff --git a/src/deps/src/lua-nginx-module/src/ngx_http_lua_balancer.c b/src/deps/src/lua-nginx-module/src/ngx_http_lua_balancer.c index e4ac57a30..af4da7338 100644 --- a/src/deps/src/lua-nginx-module/src/ngx_http_lua_balancer.c +++ b/src/deps/src/lua-nginx-module/src/ngx_http_lua_balancer.c @@ -90,7 +90,7 @@ ngx_http_lua_balancer_handler_inline(ngx_http_request_t *r, lscf->balancer.src.len, &lscf->balancer.src_ref, lscf->balancer.src_key, - "=balancer_by_lua"); + (const char *) lscf->balancer.chunkname); if (rc != NGX_OK) { return rc; } @@ -125,6 +125,8 @@ char * ngx_http_lua_balancer_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { + size_t chunkname_len; + u_char *chunkname; u_char *cache_key = NULL; u_char *name; ngx_str_t *value; @@ -172,8 +174,16 @@ ngx_http_lua_balancer_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, return NGX_CONF_ERROR; } + chunkname = ngx_http_lua_gen_chunk_name(cf, "balancer_by_lua", + sizeof("balancer_by_lua") - 1, + &chunkname_len); + if (chunkname == NULL) { + return NGX_CONF_ERROR; + } + /* Don't eval nginx variables for inline lua code */ lscf->balancer.src = value[1]; + lscf->balancer.chunkname = chunkname; } lscf->balancer.src_key = cache_key; diff --git a/src/deps/src/lua-nginx-module/src/ngx_http_lua_bodyfilterby.c b/src/deps/src/lua-nginx-module/src/ngx_http_lua_bodyfilterby.c index 902488911..a8a382ac4 100644 --- a/src/deps/src/lua-nginx-module/src/ngx_http_lua_bodyfilterby.c +++ b/src/deps/src/lua-nginx-module/src/ngx_http_lua_bodyfilterby.c @@ -161,7 +161,8 @@ ngx_http_lua_body_filter_inline(ngx_http_request_t *r, ngx_chain_t *in) llcf->body_filter_src.value.len, &llcf->body_filter_src_ref, llcf->body_filter_src_key, - "=body_filter_by_lua"); + (const char *) + llcf->body_filter_chunkname); if (rc != NGX_OK) { return NGX_ERROR; } @@ -298,7 +299,7 @@ ngx_http_lua_body_filter(ngx_http_request_t *r, ngx_chain_t *in) out = NULL; ngx_chain_update_chains(r->pool, &ctx->free_bufs, &ctx->filter_busy_bufs, &out, - (ngx_buf_tag_t) &ngx_http_lua_module); + (ngx_buf_tag_t) &ngx_http_lua_body_filter); if (rc != NGX_OK && ctx->filter_busy_bufs != NULL && (r->connection->buffered @@ -377,7 +378,7 @@ ngx_http_lua_body_filter(ngx_http_request_t *r, ngx_chain_t *in) ngx_chain_update_chains(r->pool, &ctx->free_bufs, &ctx->filter_busy_bufs, &out, - (ngx_buf_tag_t) &ngx_http_lua_module); + (ngx_buf_tag_t) &ngx_http_lua_body_filter); return rc; } @@ -395,51 +396,48 @@ ngx_http_lua_body_filter_init(void) int -ngx_http_lua_body_filter_param_get(lua_State *L, ngx_http_request_t *r) +ngx_http_lua_ffi_get_body_filter_param_eof(ngx_http_request_t *r) { - u_char *data, *p; - size_t size; ngx_chain_t *cl; - ngx_buf_t *b; - int idx; ngx_chain_t *in; ngx_http_lua_main_conf_t *lmcf; - idx = luaL_checkint(L, 2); - - dd("index: %d", idx); - - if (idx != 1 && idx != 2) { - lua_pushnil(L); - return 1; - } - lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module); in = lmcf->body_filter_chain; - if (idx == 2) { - /* asking for the eof argument */ + /* asking for the eof argument */ - for (cl = in; cl; cl = cl->next) { - if (cl->buf->last_buf || cl->buf->last_in_chain) { - lua_pushboolean(L, 1); - return 1; - } + for (cl = in; cl; cl = cl->next) { + if (cl->buf->last_buf || cl->buf->last_in_chain) { + return 1; } - - lua_pushboolean(L, 0); - return 1; } - /* idx == 1 */ + return 0; +} + + +int +ngx_http_lua_ffi_get_body_filter_param_body(ngx_http_request_t *r, + u_char **data_p, size_t *len_p) +{ + size_t size; + ngx_chain_t *cl; + ngx_buf_t *b; + ngx_chain_t *in; + + ngx_http_lua_main_conf_t *lmcf; + + lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module); + in = lmcf->body_filter_chain; size = 0; if (in == NULL) { /* being a cleared chain on the Lua land */ - lua_pushliteral(L, ""); - return 1; + *len_p = 0; + return NGX_OK; } if (in->next == NULL) { @@ -447,8 +445,9 @@ ngx_http_lua_body_filter_param_get(lua_State *L, ngx_http_request_t *r) dd("seen only single buffer"); b = in->buf; - lua_pushlstring(L, (char *) b->pos, b->last - b->pos); - return 1; + *data_p = b->pos; + *len_p = b->last - b->pos; + return NGX_OK; } dd("seen multiple buffers"); @@ -463,7 +462,26 @@ ngx_http_lua_body_filter_param_get(lua_State *L, ngx_http_request_t *r) } } - data = (u_char *) lua_newuserdata(L, size); + /* the buf is need and is not allocated from Lua land yet, return with + * the actual size */ + *len_p = size; + return NGX_AGAIN; +} + + +int +ngx_http_lua_ffi_copy_body_filter_param_body(ngx_http_request_t *r, + u_char *data) +{ + u_char *p; + ngx_chain_t *cl; + ngx_buf_t *b; + ngx_chain_t *in; + + ngx_http_lua_main_conf_t *lmcf; + + lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module); + in = lmcf->body_filter_chain; for (p = data, cl = in; cl; cl = cl->next) { b = cl->buf; @@ -474,8 +492,7 @@ ngx_http_lua_body_filter_param_get(lua_State *L, ngx_http_request_t *r) } } - lua_pushlstring(L, (char *) data, size); - return 1; + return NGX_OK; } @@ -640,6 +657,7 @@ ngx_http_lua_body_filter_param_set(lua_State *L, ngx_http_request_t *r, return luaL_error(L, "no memory"); } + cl->buf->tag = (ngx_buf_tag_t) &ngx_http_lua_body_filter; if (type == LUA_TTABLE) { cl->buf->last = ngx_http_lua_copy_str_in_table(L, 3, cl->buf->last); @@ -657,6 +675,8 @@ done: if (cl == NULL) { return luaL_error(L, "no memory"); } + + cl->buf->tag = (ngx_buf_tag_t) &ngx_http_lua_body_filter; } if (last) { diff --git a/src/deps/src/lua-nginx-module/src/ngx_http_lua_bodyfilterby.h b/src/deps/src/lua-nginx-module/src/ngx_http_lua_bodyfilterby.h index b108202fa..359646f2b 100644 --- a/src/deps/src/lua-nginx-module/src/ngx_http_lua_bodyfilterby.h +++ b/src/deps/src/lua-nginx-module/src/ngx_http_lua_bodyfilterby.h @@ -21,7 +21,6 @@ ngx_int_t ngx_http_lua_body_filter_inline(ngx_http_request_t *r, ngx_chain_t *in); ngx_int_t ngx_http_lua_body_filter_file(ngx_http_request_t *r, ngx_chain_t *in); -int ngx_http_lua_body_filter_param_get(lua_State *L, ngx_http_request_t *r); int ngx_http_lua_body_filter_param_set(lua_State *L, ngx_http_request_t *r, ngx_http_lua_ctx_t *ctx); diff --git a/src/deps/src/lua-nginx-module/src/ngx_http_lua_cache.c b/src/deps/src/lua-nginx-module/src/ngx_http_lua_cache.c index 0b1b8ecda..534424688 100644 --- a/src/deps/src/lua-nginx-module/src/ngx_http_lua_cache.c +++ b/src/deps/src/lua-nginx-module/src/ngx_http_lua_cache.c @@ -307,7 +307,13 @@ ngx_http_lua_cache_loadfile(ngx_log_t *log, lua_State *L, break; case LUA_ERRFILE: - errcode = NGX_HTTP_NOT_FOUND; + if (errno == ENOENT) { + errcode = NGX_HTTP_NOT_FOUND; + + } else { + errcode = NGX_HTTP_SERVICE_UNAVAILABLE; + } + /* fall through */ default: diff --git a/src/deps/src/lua-nginx-module/src/ngx_http_lua_common.h b/src/deps/src/lua-nginx-module/src/ngx_http_lua_common.h index 9f991d1aa..dafa729f8 100644 --- a/src/deps/src/lua-nginx-module/src/ngx_http_lua_common.h +++ b/src/deps/src/lua-nginx-module/src/ngx_http_lua_common.h @@ -31,6 +31,7 @@ typedef struct { size_t size; int ref; u_char *key; + u_char *chunkname; ngx_str_t script; } ngx_http_lua_set_var_data_t; #endif @@ -140,6 +141,7 @@ typedef struct { #define NGX_HTTP_LUA_CONTEXT_SSL_SESS_FETCH 0x1000 #define NGX_HTTP_LUA_CONTEXT_EXIT_WORKER 0x2000 #define NGX_HTTP_LUA_CONTEXT_SSL_CLIENT_HELLO 0x4000 +#define NGX_HTTP_LUA_CONTEXT_SERVER_REWRITE 0x8000 #define NGX_HTTP_LUA_FFI_NO_REQ_CTX -100 @@ -213,6 +215,8 @@ struct ngx_http_lua_main_conf_s { ngx_int_t lua_thread_cache_max_entries; + ngx_hash_t builtin_headers_out; + #if (NGX_PCRE) ngx_int_t regex_cache_entries; ngx_int_t regex_cache_max_entries; @@ -233,12 +237,15 @@ struct ngx_http_lua_main_conf_s { ngx_http_lua_main_conf_handler_pt init_handler; ngx_str_t init_src; + u_char *init_chunkname; ngx_http_lua_main_conf_handler_pt init_worker_handler; ngx_str_t init_worker_src; + u_char *init_worker_chunkname; ngx_http_lua_main_conf_handler_pt exit_worker_handler; ngx_str_t exit_worker_src; + u_char *exit_worker_chunkname; ngx_http_lua_balancer_peer_data_t *balancer_peer_data; /* neither yielding nor recursion is possible in @@ -276,6 +283,8 @@ struct ngx_http_lua_main_conf_s { of requests */ ngx_uint_t malloc_trim_req_count; + ngx_uint_t directive_line; + #if (nginx_version >= 1011011) /* the following 2 fields are only used by ngx.req.raw_headers() for now */ ngx_buf_t **busy_buf_ptrs; @@ -299,38 +308,50 @@ struct ngx_http_lua_main_conf_s { unsigned requires_log:1; unsigned requires_shm:1; unsigned requires_capture_log:1; + unsigned requires_server_rewrite:1; }; union ngx_http_lua_srv_conf_u { -#if (NGX_HTTP_SSL) struct { +#if (NGX_HTTP_SSL) ngx_http_lua_srv_conf_handler_pt ssl_cert_handler; ngx_str_t ssl_cert_src; u_char *ssl_cert_src_key; + u_char *ssl_cert_chunkname; int ssl_cert_src_ref; ngx_http_lua_srv_conf_handler_pt ssl_sess_store_handler; ngx_str_t ssl_sess_store_src; u_char *ssl_sess_store_src_key; + u_char *ssl_sess_store_chunkname; int ssl_sess_store_src_ref; ngx_http_lua_srv_conf_handler_pt ssl_sess_fetch_handler; ngx_str_t ssl_sess_fetch_src; u_char *ssl_sess_fetch_src_key; + u_char *ssl_sess_fetch_chunkname; int ssl_sess_fetch_src_ref; ngx_http_lua_srv_conf_handler_pt ssl_client_hello_handler; ngx_str_t ssl_client_hello_src; u_char *ssl_client_hello_src_key; + u_char *ssl_client_hello_chunkname; int ssl_client_hello_src_ref; - } srv; #endif + ngx_http_lua_srv_conf_handler_pt server_rewrite_handler; + ngx_http_complex_value_t server_rewrite_src; + u_char *server_rewrite_src_key; + u_char *server_rewrite_chunkname; + int server_rewrite_src_ref; + } srv; + struct { ngx_http_lua_srv_conf_handler_pt handler; ngx_str_t src; u_char *src_key; + u_char *chunkname; int src_ref; } balancer; }; @@ -365,6 +386,8 @@ typedef struct { ngx_http_output_body_filter_pt body_filter_handler; + + u_char *rewrite_chunkname; ngx_http_complex_value_t rewrite_src; /* rewrite_by_lua inline script/script @@ -401,6 +424,7 @@ typedef struct { inline script/script file path */ + u_char *header_filter_chunkname; u_char *header_filter_src_key; /* cached key for header_filter_src */ int header_filter_src_ref; @@ -408,6 +432,7 @@ typedef struct { ngx_http_complex_value_t body_filter_src; u_char *body_filter_src_key; + u_char *body_filter_chunkname; int body_filter_src_ref; ngx_msec_t keepalive_timeout; @@ -620,7 +645,7 @@ typedef struct ngx_http_lua_ctx_s { response headers */ unsigned mime_set:1; /* whether the user has set Content-Type response header */ - + unsigned entered_server_rewrite_phase:1; unsigned entered_rewrite_phase:1; unsigned entered_access_phase:1; unsigned entered_content_phase:1; diff --git a/src/deps/src/lua-nginx-module/src/ngx_http_lua_consts.c b/src/deps/src/lua-nginx-module/src/ngx_http_lua_consts.c index 47ba99857..f2dcf4a49 100644 --- a/src/deps/src/lua-nginx-module/src/ngx_http_lua_consts.c +++ b/src/deps/src/lua-nginx-module/src/ngx_http_lua_consts.c @@ -176,6 +176,10 @@ ngx_http_lua_inject_http_consts(lua_State *L) lua_pushinteger(L, NGX_HTTP_INTERNAL_SERVER_ERROR); lua_setfield(L, -2, "HTTP_INTERNAL_SERVER_ERROR"); + lua_pushinteger(L, NGX_HTTP_NOT_IMPLEMENTED); + lua_setfield(L, -2, "HTTP_NOT_IMPLEMENTED"); + + /* keep for backward compatibility */ lua_pushinteger(L, NGX_HTTP_NOT_IMPLEMENTED); lua_setfield(L, -2, "HTTP_METHOD_NOT_IMPLEMENTED"); diff --git a/src/deps/src/lua-nginx-module/src/ngx_http_lua_control.c b/src/deps/src/lua-nginx-module/src/ngx_http_lua_control.c index bb18d8f5d..99460456c 100644 --- a/src/deps/src/lua-nginx-module/src/ngx_http_lua_control.c +++ b/src/deps/src/lua-nginx-module/src/ngx_http_lua_control.c @@ -91,6 +91,7 @@ ngx_http_lua_ngx_exec(lua_State *L) } ngx_http_lua_check_context(L, ctx, NGX_HTTP_LUA_CONTEXT_REWRITE + | NGX_HTTP_LUA_CONTEXT_SERVER_REWRITE | NGX_HTTP_LUA_CONTEXT_ACCESS | NGX_HTTP_LUA_CONTEXT_CONTENT); @@ -232,6 +233,7 @@ ngx_http_lua_ngx_redirect(lua_State *L) } ngx_http_lua_check_context(L, ctx, NGX_HTTP_LUA_CONTEXT_REWRITE + | NGX_HTTP_LUA_CONTEXT_SERVER_REWRITE | NGX_HTTP_LUA_CONTEXT_ACCESS | NGX_HTTP_LUA_CONTEXT_CONTENT); @@ -358,6 +360,14 @@ ngx_http_lua_ffi_exit(ngx_http_request_t *r, int status, u_char *err, { ngx_http_lua_ctx_t *ctx; + if (status == NGX_AGAIN || status == NGX_DONE) { + *errlen = ngx_snprintf(err, *errlen, + "bad argument to 'ngx.exit': does not accept " + "NGX_AGAIN or NGX_DONE") + - err; + return NGX_ERROR; + } + ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); if (ctx == NULL) { *errlen = ngx_snprintf(err, *errlen, "no request ctx found") - err; @@ -365,6 +375,7 @@ ngx_http_lua_ffi_exit(ngx_http_request_t *r, int status, u_char *err, } if (ngx_http_lua_ffi_check_context(ctx, NGX_HTTP_LUA_CONTEXT_REWRITE + | NGX_HTTP_LUA_CONTEXT_SERVER_REWRITE | NGX_HTTP_LUA_CONTEXT_ACCESS | NGX_HTTP_LUA_CONTEXT_CONTENT | NGX_HTTP_LUA_CONTEXT_TIMER diff --git a/src/deps/src/lua-nginx-module/src/ngx_http_lua_directive.c b/src/deps/src/lua-nginx-module/src/ngx_http_lua_directive.c index 831132f12..f1623056b 100644 --- a/src/deps/src/lua-nginx-module/src/ngx_http_lua_directive.c +++ b/src/deps/src/lua-nginx-module/src/ngx_http_lua_directive.c @@ -17,6 +17,7 @@ #include "ngx_http_lua_cache.h" #include "ngx_http_lua_contentby.h" #include "ngx_http_lua_accessby.h" +#include "ngx_http_lua_server_rewriteby.h" #include "ngx_http_lua_rewriteby.h" #include "ngx_http_lua_logby.h" #include "ngx_http_lua_headerfilterby.h" @@ -32,6 +33,12 @@ #include "ngx_http_lua_log.h" +/* the max length is 60, after deducting the fixed four characters "=(:)" + * only 56 left. + */ +#define LJ_CHUNKNAME_MAX_LEN 56 + + typedef struct ngx_http_lua_block_parser_ctx_s ngx_http_lua_block_parser_ctx_t; @@ -43,8 +50,6 @@ typedef struct ngx_http_lua_block_parser_ctx_s static ngx_int_t ngx_http_lua_set_by_lua_init(ngx_http_request_t *r); #endif -static u_char *ngx_http_lua_gen_chunk_name(ngx_conf_t *cf, const char *tag, - size_t tag_len, size_t *chunkname_len); static ngx_int_t ngx_http_lua_conf_read_lua_token(ngx_conf_t *cf, ngx_http_lua_block_parser_ctx_t *ctx); static u_char *ngx_http_lua_strlstrn(u_char *s1, u_char *last, u_char *s2, @@ -280,6 +285,8 @@ ngx_http_lua_set_by_lua_block(ngx_conf_t *cf, ngx_command_t *cmd, char * ngx_http_lua_set_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { + size_t chunkname_len; + u_char *chunkname; u_char *cache_key; ngx_str_t *value; ngx_str_t target; @@ -312,7 +319,15 @@ ngx_http_lua_set_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) return NGX_CONF_ERROR; } + chunkname = ngx_http_lua_gen_chunk_name(cf, "set_by_lua", + sizeof("set_by_lua") - 1, + &chunkname_len); + if (chunkname == NULL) { + return NGX_CONF_ERROR; + } + filter_data->key = cache_key; + filter_data->chunkname = chunkname; filter_data->ref = LUA_REFNIL; filter_data->script = value[2]; filter_data->size = filter.size; @@ -375,6 +390,7 @@ ngx_http_lua_set_by_lua_file(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) filter_data->key = cache_key; filter_data->ref = LUA_REFNIL; filter_data->size = filter.size; + filter_data->chunkname = NULL; ngx_str_null(&filter_data->script); @@ -404,7 +420,8 @@ ngx_http_lua_filter_set_by_lua_inline(ngx_http_request_t *r, ngx_str_t *val, filter_data->script.data, filter_data->script.len, &filter_data->ref, - filter_data->key, "=set_by_lua"); + filter_data->key, + (const char *) filter_data->chunkname); if (rc != NGX_OK) { return NGX_ERROR; } @@ -574,6 +591,111 @@ ngx_http_lua_rewrite_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) } +char * +ngx_http_lua_server_rewrite_by_lua_block(ngx_conf_t *cf, + ngx_command_t *cmd, void *conf) +{ + char *rv; + ngx_conf_t save; + save = *cf; + cf->handler = ngx_http_lua_server_rewrite_by_lua; + cf->handler_conf = conf; + + rv = ngx_http_lua_conf_lua_block_parse(cf, cmd); + + *cf = save; + + return rv; +} + + +char * +ngx_http_lua_server_rewrite_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, + void *conf) +{ + size_t chunkname_len; + u_char *cache_key = NULL, *chunkname; + ngx_str_t *value; + ngx_http_lua_main_conf_t *lmcf; + ngx_http_lua_srv_conf_t *lscf = conf; + + ngx_http_compile_complex_value_t ccv; + + dd("enter"); + + /* must specify a content handler */ + if (cmd->post == NULL) { + return NGX_CONF_ERROR; + } + + if (lscf->srv.server_rewrite_handler) { + return "is duplicate"; + } + + value = cf->args->elts; + + if (value[1].len == 0) { + /* Oops...Invalid location conf */ + ngx_conf_log_error(NGX_LOG_ERR, cf, 0, + "invalid location config: no runnable Lua code"); + + return NGX_CONF_ERROR; + } + + if (cmd->post == ngx_http_lua_server_rewrite_handler_inline) { + chunkname = + ngx_http_lua_gen_chunk_name(cf, "server_rewrite_by_lua", + sizeof("server_rewrite_by_lua") - 1, + &chunkname_len); + if (chunkname == NULL) { + return NGX_CONF_ERROR; + } + + cache_key = + ngx_http_lua_gen_chunk_cache_key(cf, "server_rewrite_by_lua", + value[1].data, + value[1].len); + if (cache_key == NULL) { + return NGX_CONF_ERROR; + } + + /* Don't eval nginx variables for inline lua code */ + lscf->srv.server_rewrite_src.value = value[1]; + lscf->srv.server_rewrite_chunkname = chunkname; + + } else { + ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); + ccv.cf = cf; + ccv.value = &value[1]; + ccv.complex_value = &lscf->srv.server_rewrite_src; + + if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { + return NGX_CONF_ERROR; + } + + if (lscf->srv.server_rewrite_src.lengths == NULL) { + /* no variable found */ + cache_key = ngx_http_lua_gen_file_cache_key(cf, value[1].data, + value[1].len); + if (cache_key == NULL) { + return NGX_CONF_ERROR; + } + } + } + + lscf->srv.server_rewrite_src_key = cache_key; + lscf->srv.server_rewrite_handler = + (ngx_http_lua_srv_conf_handler_pt) cmd->post; + + lmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_lua_module); + + lmcf->requires_server_rewrite = 1; + lmcf->requires_capture_filter = 1; + + return NGX_CONF_OK; +} + + char * ngx_http_lua_access_by_lua_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) @@ -912,7 +1034,8 @@ char * ngx_http_lua_header_filter_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { - u_char *cache_key = NULL; + size_t chunkname_len; + u_char *cache_key = NULL, *chunkname; ngx_str_t *value; ngx_http_lua_main_conf_t *lmcf; ngx_http_lua_loc_conf_t *llcf = conf; @@ -947,8 +1070,15 @@ ngx_http_lua_header_filter_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, return NGX_CONF_ERROR; } + chunkname = ngx_http_lua_gen_chunk_name(cf, "header_filter_by_lua", + sizeof("header_filter_by_lua") - 1, &chunkname_len); + if (chunkname == NULL) { + return NGX_CONF_ERROR; + } + /* Don't eval nginx variables for inline lua code */ llcf->header_filter_src.value = value[1]; + llcf->header_filter_chunkname = chunkname; } else { ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); @@ -1004,7 +1134,8 @@ char * ngx_http_lua_body_filter_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { - u_char *cache_key = NULL; + size_t chunkname_len; + u_char *cache_key = NULL, *chunkname; ngx_str_t *value; ngx_http_lua_main_conf_t *lmcf; ngx_http_lua_loc_conf_t *llcf = conf; @@ -1039,8 +1170,16 @@ ngx_http_lua_body_filter_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, return NGX_CONF_ERROR; } + chunkname = ngx_http_lua_gen_chunk_name(cf, "body_filter_by_lua", + sizeof("body_filter_by_lua") - 1, &chunkname_len); + if (chunkname == NULL) { + return NGX_CONF_ERROR; + } + + /* Don't eval nginx variables for inline lua code */ llcf->body_filter_src.value = value[1]; + llcf->body_filter_chunkname = chunkname; } else { ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); @@ -1100,6 +1239,8 @@ ngx_http_lua_init_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, u_char *name; ngx_str_t *value; ngx_http_lua_main_conf_t *lmcf = conf; + size_t chunkname_len; + u_char *chunkname; dd("enter"); @@ -1135,6 +1276,15 @@ ngx_http_lua_init_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, } else { lmcf->init_src = value[1]; + + chunkname = ngx_http_lua_gen_chunk_name(cf, "init_by_lua", + sizeof("init_by_lua") - 1, + &chunkname_len); + if (chunkname == NULL) { + return NGX_CONF_ERROR; + } + + lmcf->init_chunkname = chunkname; } return NGX_CONF_OK; @@ -1167,6 +1317,8 @@ ngx_http_lua_init_worker_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, u_char *name; ngx_str_t *value; ngx_http_lua_main_conf_t *lmcf = conf; + size_t chunkname_len; + u_char *chunkname; dd("enter"); @@ -1195,6 +1347,14 @@ ngx_http_lua_init_worker_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, } else { lmcf->init_worker_src = value[1]; + + chunkname = ngx_http_lua_gen_chunk_name(cf, "init_worker_by_lua", + sizeof("init_worker_by_lua") - 1, &chunkname_len); + if (chunkname == NULL) { + return NGX_CONF_ERROR; + } + + lmcf->init_worker_chunkname = chunkname; } return NGX_CONF_OK; @@ -1227,6 +1387,8 @@ ngx_http_lua_exit_worker_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, u_char *name; ngx_str_t *value; ngx_http_lua_main_conf_t *lmcf = conf; + size_t chunkname_len; + u_char *chunkname; /* must specify a content handler */ if (cmd->post == NULL) { @@ -1253,6 +1415,15 @@ ngx_http_lua_exit_worker_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, } else { lmcf->exit_worker_src = value[1]; + + chunkname = ngx_http_lua_gen_chunk_name(cf, "exit_worker_by_lua", + sizeof("exit_worker_by_lua")- 1, + &chunkname_len); + if (chunkname == NULL) { + return NGX_CONF_ERROR; + } + + lmcf->exit_worker_chunkname = chunkname; } return NGX_CONF_OK; @@ -1296,12 +1467,20 @@ ngx_http_lua_set_by_lua_init(ngx_http_request_t *r) #endif -static u_char * +u_char * ngx_http_lua_gen_chunk_name(ngx_conf_t *cf, const char *tag, size_t tag_len, size_t *chunkname_len) { u_char *p, *out; size_t len; + ngx_uint_t start_line; + ngx_str_t *conf_prefix; + ngx_str_t *filename; + u_char *filename_end; + const char *pre_str = ""; + ngx_uint_t reserve_len; + + ngx_http_lua_main_conf_t *lmcf; len = sizeof("=(:)") - 1 + tag_len + cf->conf_file->file.name.len + NGX_INT64_LEN + 1; @@ -1311,27 +1490,56 @@ ngx_http_lua_gen_chunk_name(ngx_conf_t *cf, const char *tag, size_t tag_len, return NULL; } - if (cf->conf_file->file.name.len) { - p = cf->conf_file->file.name.data + cf->conf_file->file.name.len; - while (--p >= cf->conf_file->file.name.data) { - if (*p == '/' || *p == '\\') { - p++; + lmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_lua_module); + start_line = lmcf->directive_line > 0 + ? lmcf->directive_line : cf->conf_file->line; + p = ngx_snprintf(out, len, "%d", start_line); + reserve_len = tag_len + p - out; + + filename = &cf->conf_file->file.name; + filename_end = filename->data + filename->len; + if (filename->len > 0) { + if (filename->len >= 11) { + p = filename_end - 11; + if ((*p == '/' || *p == '\\') + && ngx_memcmp(p, "/nginx.conf", 11) == 0) + { + p++; /* now p is nginx.conf */ goto found; } } - p++; + conf_prefix = &cf->cycle->conf_prefix; + p = filename->data + conf_prefix->len; + if ((conf_prefix->len < filename->len) + && ngx_memcmp(conf_prefix->data, + filename->data, conf_prefix->len) == 0) + { + /* files in conf_prefix directory, use the relative path */ + if (filename_end - p + reserve_len > LJ_CHUNKNAME_MAX_LEN) { + p = filename_end - LJ_CHUNKNAME_MAX_LEN + reserve_len + 3; + pre_str = "..."; + } - } else { - p = cf->conf_file->file.name.data; + goto found; + } } + p = filename->data; + + if (filename->len + reserve_len <= LJ_CHUNKNAME_MAX_LEN) { + goto found; + } + + p = filename_end - LJ_CHUNKNAME_MAX_LEN + reserve_len + 3; + pre_str = "..."; + found: - p = ngx_snprintf(out, len, "=%*s(%*s:%d)%Z", - tag_len, tag, cf->conf_file->file.name.data - + cf->conf_file->file.name.len - p, - p, cf->conf_file->line); + + p = ngx_snprintf(out, len, "=%*s(%s%*s:%d)%Z", + tag_len, tag, pre_str, filename_end - p, + p, start_line); *chunkname_len = p - out - 1; /* exclude the trailing '\0' byte */ @@ -1343,6 +1551,7 @@ found: char * ngx_http_lua_conf_lua_block_parse(ngx_conf_t *cf, ngx_command_t *cmd) { + ngx_http_lua_main_conf_t *lmcf; ngx_http_lua_block_parser_ctx_t ctx; int level = 1; @@ -1376,6 +1585,9 @@ ngx_http_lua_conf_lua_block_parse(ngx_conf_t *cf, ngx_command_t *cmd) ctx.token_len = 0; start_line = cf->conf_file->line; + lmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_lua_module); + lmcf->directive_line = start_line; + dd("init start line: %d", (int) start_line); ctx.start_line = start_line; @@ -1494,6 +1706,8 @@ failed: done: + lmcf->directive_line = 0; + if (rc == NGX_ERROR) { return NGX_CONF_ERROR; } diff --git a/src/deps/src/lua-nginx-module/src/ngx_http_lua_directive.h b/src/deps/src/lua-nginx-module/src/ngx_http_lua_directive.h index adfba1276..4bec5e309 100644 --- a/src/deps/src/lua-nginx-module/src/ngx_http_lua_directive.h +++ b/src/deps/src/lua-nginx-module/src/ngx_http_lua_directive.h @@ -25,6 +25,10 @@ char *ngx_http_lua_content_by_lua_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); char *ngx_http_lua_content_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); +char *ngx_http_lua_server_rewrite_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, + void *conf); +char *ngx_http_lua_server_rewrite_by_lua_block(ngx_conf_t *cf, + ngx_command_t *cmd, void *conf); char *ngx_http_lua_rewrite_by_lua_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); char *ngx_http_lua_rewrite_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, @@ -81,7 +85,8 @@ char *ngx_http_lua_conf_lua_block_parse(ngx_conf_t *cf, ngx_command_t *cmd); char *ngx_http_lua_capture_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); - +u_char *ngx_http_lua_gen_chunk_name(ngx_conf_t *cf, const char *tag, + size_t tag_len, size_t *chunkname_len); #endif /* _NGX_HTTP_LUA_DIRECTIVE_H_INCLUDED_ */ diff --git a/src/deps/src/lua-nginx-module/src/ngx_http_lua_exitworkerby.c b/src/deps/src/lua-nginx-module/src/ngx_http_lua_exitworkerby.c index f1329566b..e8f65110a 100644 --- a/src/deps/src/lua-nginx-module/src/ngx_http_lua_exitworkerby.c +++ b/src/deps/src/lua-nginx-module/src/ngx_http_lua_exitworkerby.c @@ -95,9 +95,17 @@ ngx_http_lua_exit_worker_by_inline(ngx_log_t *log, ngx_http_lua_main_conf_t *lmcf, lua_State *L) { int status; + const char *chunkname; + + if (lmcf->exit_worker_chunkname == NULL) { + chunkname = "=exit_worker_by_lua"; + + } else { + chunkname = (const char *) lmcf->exit_worker_chunkname; + } status = luaL_loadbuffer(L, (char *) lmcf->exit_worker_src.data, - lmcf->exit_worker_src.len, "=exit_worker_by_lua") + lmcf->exit_worker_src.len, chunkname) || ngx_http_lua_do_call(log, L); return ngx_http_lua_report(log, L, status, "exit_worker_by_lua"); diff --git a/src/deps/src/lua-nginx-module/src/ngx_http_lua_headerfilterby.c b/src/deps/src/lua-nginx-module/src/ngx_http_lua_headerfilterby.c index 4741c7226..f2fe165bd 100644 --- a/src/deps/src/lua-nginx-module/src/ngx_http_lua_headerfilterby.c +++ b/src/deps/src/lua-nginx-module/src/ngx_http_lua_headerfilterby.c @@ -171,7 +171,8 @@ ngx_http_lua_header_filter_inline(ngx_http_request_t *r) llcf->header_filter_src.value.len, &llcf->header_filter_src_ref, llcf->header_filter_src_key, - "=header_filter_by_lua"); + (const char *) + llcf->header_filter_chunkname); if (rc != NGX_OK) { return NGX_ERROR; } diff --git a/src/deps/src/lua-nginx-module/src/ngx_http_lua_headers.c b/src/deps/src/lua-nginx-module/src/ngx_http_lua_headers.c index a376a0eac..9d03f4ed4 100644 --- a/src/deps/src/lua-nginx-module/src/ngx_http_lua_headers.c +++ b/src/deps/src/lua-nginx-module/src/ngx_http_lua_headers.c @@ -84,6 +84,12 @@ ngx_http_lua_ngx_req_http_version(lua_State *L) break; #endif +#ifdef NGX_HTTP_VERSION_30 + case NGX_HTTP_VERSION_30: + lua_pushnumber(L, 3.0); + break; +#endif + default: lua_pushnil(L); break; @@ -167,6 +173,12 @@ ngx_http_lua_ngx_req_raw_header(lua_State *L) size = 0; b = c->buffer; + if (mr->request_line.len == 0) { + /* return empty string on invalid request */ + lua_pushlstring(L, "", 0); + return 1; + } + if (mr->request_line.data[mr->request_line.len] == CR) { line_break_len = 2; @@ -1068,6 +1080,7 @@ ngx_http_lua_ffi_get_resp_header(ngx_http_request_t *r, { int found; u_char c, *p; + time_t last_modified; ngx_uint_t i; ngx_table_elt_t *h; ngx_list_part_t *part; @@ -1134,6 +1147,28 @@ ngx_http_lua_ffi_get_resp_header(ngx_http_request_t *r, break; + case 13: + if (ngx_strncasecmp(key_buf, (u_char *) "Last-Modified", 13) == 0) { + last_modified = r->headers_out.last_modified_time; + if (last_modified >= 0) { + p = ngx_palloc(r->pool, + sizeof("Mon, 28 Sep 1970 06:00:00 GMT")); + if (p == NULL) { + *errmsg = "no memory"; + return NGX_ERROR; + } + + values[0].data = p; + values[0].len = ngx_http_time(p, last_modified) - p; + + return 1; + } + + return 0; + } + + break; + default: break; } @@ -1211,4 +1246,16 @@ ngx_http_lua_ngx_raw_header_cleanup(void *data) #endif +#if (NGX_DARWIN) +int +ngx_http_lua_ffi_set_resp_header_macos(ngx_http_lua_set_resp_header_params_t *p) +{ + return ngx_http_lua_ffi_set_resp_header(p->r, p->key_data, p->key_len, + p->is_nil, p->sval, p->sval_len, + p->mvals, p->mvals_len, + p->override, p->errmsg); +} +#endif + + /* vi:set ft=c ts=4 sw=4 et fdm=marker: */ diff --git a/src/deps/src/lua-nginx-module/src/ngx_http_lua_headers_in.c b/src/deps/src/lua-nginx-module/src/ngx_http_lua_headers_in.c index 7626d1f94..440548140 100644 --- a/src/deps/src/lua-nginx-module/src/ngx_http_lua_headers_in.c +++ b/src/deps/src/lua-nginx-module/src/ngx_http_lua_headers_in.c @@ -152,9 +152,15 @@ static ngx_http_lua_set_header_t ngx_http_lua_set_handlers[] = { ngx_http_set_builtin_header }, #endif +#if defined(nginx_version) && nginx_version >= 1023000 + { ngx_string("Cookie"), + offsetof(ngx_http_headers_in_t, cookie), + ngx_http_set_builtin_multi_header }, +#else { ngx_string("Cookie"), offsetof(ngx_http_headers_in_t, cookies), ngx_http_set_builtin_multi_header }, +#endif { ngx_null_string, 0, ngx_http_set_header } }; @@ -580,6 +586,45 @@ static ngx_int_t ngx_http_set_builtin_multi_header(ngx_http_request_t *r, ngx_http_lua_header_val_t *hv, ngx_str_t *value) { +#if defined(nginx_version) && nginx_version >= 1023000 + ngx_table_elt_t **headers, **ph, *h; + int nelts; + + headers = (ngx_table_elt_t **) ((char *) &r->headers_in + hv->offset); + + if (!hv->no_override && *headers != NULL) { + nelts = 0; + for (h = *headers; h; h = h->next) { + nelts++; + } + + *headers = NULL; + + dd("clear multi-value headers: %d", nelts); + } + + if (ngx_http_set_header_helper(r, hv, value, &h) == NGX_ERROR) { + return NGX_ERROR; + } + + if (value->len == 0) { + return NGX_OK; + } + + dd("new multi-value header: %p", h); + + if (*headers) { + for (ph = headers; *ph; ph = &(*ph)->next) { /* void */ } + *ph = h; + + } else { + *headers = h; + } + + h->next = NULL; + + return NGX_OK; +#else ngx_array_t *headers; ngx_table_elt_t **v, *h; @@ -626,6 +671,7 @@ ngx_http_set_builtin_multi_header(ngx_http_request_t *r, *v = h; return NGX_OK; +#endif } @@ -669,7 +715,13 @@ ngx_http_lua_set_input_header(ngx_http_request_t *r, ngx_str_t key, return NGX_ERROR; } - hv.hash = ngx_hash_key_lc(key.data, key.len); + if (value.len > 0) { + hv.hash = ngx_hash_key_lc(key.data, key.len); + + } else { + hv.hash = 0; + } + hv.key = key; hv.offset = 0; diff --git a/src/deps/src/lua-nginx-module/src/ngx_http_lua_headers_out.c b/src/deps/src/lua-nginx-module/src/ngx_http_lua_headers_out.c index 6e1879c50..571723d9a 100644 --- a/src/deps/src/lua-nginx-module/src/ngx_http_lua_headers_out.c +++ b/src/deps/src/lua-nginx-module/src/ngx_http_lua_headers_out.c @@ -311,6 +311,69 @@ static ngx_int_t ngx_http_set_builtin_multi_header(ngx_http_request_t *r, ngx_http_lua_header_val_t *hv, ngx_str_t *value) { +#if defined(nginx_version) && nginx_version >= 1023000 + ngx_table_elt_t **headers, *h, *ho, **ph; + + headers = (ngx_table_elt_t **) ((char *) &r->headers_out + hv->offset); + + if (hv->no_override) { + for (h = *headers; h; h = h->next) { + if (!h->hash) { + h->value = *value; + h->hash = hv->hash; + return NGX_OK; + } + } + + goto create; + } + + /* override old values (if any) */ + + if (*headers) { + for (h = (*headers)->next; h; h = h->next) { + h->hash = 0; + h->value.len = 0; + } + + h = *headers; + + h->value = *value; + + if (value->len == 0) { + h->hash = 0; + + } else { + h->hash = hv->hash; + } + + return NGX_OK; + } + +create: + + for (ph = headers; *ph; ph = &(*ph)->next) { /* void */ } + + ho = ngx_list_push(&r->headers_out.headers); + if (ho == NULL) { + return NGX_ERROR; + } + + ho->value = *value; + + if (value->len == 0) { + ho->hash = 0; + + } else { + ho->hash = hv->hash; + } + + ho->key = hv->key; + ho->next = NULL; + *ph = ho; + + return NGX_OK; +#else ngx_array_t *pa; ngx_table_elt_t *ho, **ph; ngx_uint_t i; @@ -384,6 +447,7 @@ create: *ph = ho; return NGX_OK; +#endif } @@ -486,8 +550,9 @@ ngx_http_lua_set_output_header(ngx_http_request_t *r, ngx_http_lua_ctx_t *ctx, ngx_str_t key, ngx_str_t value, unsigned override) { ngx_http_lua_header_val_t hv; - ngx_http_lua_set_header_t *handlers = ngx_http_lua_set_handlers; - ngx_uint_t i; + ngx_http_lua_main_conf_t *lmcf; + ngx_http_lua_set_header_t *lsh; + ngx_hash_t *hash; dd("set header value: %.*s", (int) value.len, value.data); @@ -504,42 +569,20 @@ ngx_http_lua_set_output_header(ngx_http_request_t *r, ngx_http_lua_ctx_t *ctx, hv.offset = 0; hv.no_override = !override; - hv.handler = NULL; - - for (i = 0; handlers[i].name.len; i++) { - if (hv.key.len != handlers[i].name.len - || ngx_strncasecmp(hv.key.data, handlers[i].name.data, - handlers[i].name.len) != 0) - { - dd("hv key comparison: %s <> %s", handlers[i].name.data, - hv.key.data); - - continue; - } - - dd("Matched handler: %s %s", handlers[i].name.data, hv.key.data); - - hv.offset = handlers[i].offset; - hv.handler = handlers[i].handler; + hv.handler = ngx_http_set_header; + lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module); + hash = &lmcf->builtin_headers_out; + lsh = ngx_http_lua_hash_find_lc(hash, hv.hash, hv.key.data, hv.key.len); + if (lsh) { + dd("Matched handler: %s %s", lsh->name.data, hv.key.data); + hv.offset = lsh->offset; + hv.handler = lsh->handler; if (hv.handler == ngx_http_set_content_type_header) { ctx->mime_set = 1; } - - break; } - if (handlers[i].name.len == 0 && handlers[i].handler) { - hv.offset = handlers[i].offset; - hv.handler = handlers[i].handler; - } - -#if 1 - if (hv.handler == NULL) { - return NGX_ERROR; - } -#endif - return hv.handler(r, &hv, &value); } @@ -652,4 +695,48 @@ ngx_http_lua_get_output_header(lua_State *L, ngx_http_request_t *r, return 1; } + +ngx_int_t +ngx_http_lua_init_builtin_headers_out(ngx_conf_t *cf, + ngx_http_lua_main_conf_t *lmcf) +{ + ngx_array_t headers; + ngx_hash_key_t *hk; + ngx_hash_init_t hash; + ngx_http_lua_set_header_t *handlers = ngx_http_lua_set_handlers; + ngx_uint_t count; + + count = sizeof(ngx_http_lua_set_handlers) + / sizeof(ngx_http_lua_set_header_t); + + if (ngx_array_init(&headers, cf->temp_pool, count, sizeof(ngx_hash_key_t)) + != NGX_OK) + { + return NGX_ERROR; + } + + while (handlers->name.data) { + hk = ngx_array_push(&headers); + if (hk == NULL) { + return NGX_ERROR; + } + + hk->key = handlers->name; + hk->key_hash = ngx_hash_key_lc(handlers->name.data, handlers->name.len); + hk->value = (void *) handlers; + + handlers++; + } + + hash.hash = &lmcf->builtin_headers_out; + hash.key = ngx_hash_key_lc; + hash.max_size = 512; + hash.bucket_size = ngx_align(64, ngx_cacheline_size); + hash.name = "builtin_headers_out_hash"; + hash.pool = cf->pool; + hash.temp_pool = NULL; + + return ngx_hash_init(&hash, headers.elts, headers.nelts); +} + /* vi:set ft=c ts=4 sw=4 et fdm=marker: */ diff --git a/src/deps/src/lua-nginx-module/src/ngx_http_lua_headers_out.h b/src/deps/src/lua-nginx-module/src/ngx_http_lua_headers_out.h index 6ec1fe391..eb3c79472 100644 --- a/src/deps/src/lua-nginx-module/src/ngx_http_lua_headers_out.h +++ b/src/deps/src/lua-nginx-module/src/ngx_http_lua_headers_out.h @@ -12,10 +12,28 @@ #include "ngx_http_lua_common.h" +#if (NGX_DARWIN) +typedef struct { + ngx_http_request_t *r; + const char *key_data; + size_t key_len; + int is_nil; + const char *sval; + size_t sval_len; + void *mvals; + size_t mvals_len; + int override; + char **errmsg; +} ngx_http_lua_set_resp_header_params_t; +#endif + + ngx_int_t ngx_http_lua_set_output_header(ngx_http_request_t *r, ngx_http_lua_ctx_t *ctx, ngx_str_t key, ngx_str_t value, unsigned override); int ngx_http_lua_get_output_header(lua_State *L, ngx_http_request_t *r, ngx_http_lua_ctx_t *ctx, ngx_str_t *key); +ngx_int_t ngx_http_lua_init_builtin_headers_out(ngx_conf_t *cf, + ngx_http_lua_main_conf_t *lmcf); #endif /* _NGX_HTTP_LUA_HEADERS_OUT_H_INCLUDED_ */ diff --git a/src/deps/src/lua-nginx-module/src/ngx_http_lua_initby.c b/src/deps/src/lua-nginx-module/src/ngx_http_lua_initby.c index e8941da6c..1f956e7eb 100644 --- a/src/deps/src/lua-nginx-module/src/ngx_http_lua_initby.c +++ b/src/deps/src/lua-nginx-module/src/ngx_http_lua_initby.c @@ -18,9 +18,18 @@ ngx_http_lua_init_by_inline(ngx_log_t *log, ngx_http_lua_main_conf_t *lmcf, lua_State *L) { int status; + const char *chunkname; + + + if (lmcf->init_chunkname == NULL) { + chunkname = "=init_by_lua"; + + } else { + chunkname = (const char *) lmcf->init_chunkname; + } status = luaL_loadbuffer(L, (char *) lmcf->init_src.data, - lmcf->init_src.len, "=init_by_lua") + lmcf->init_src.len, chunkname) || ngx_http_lua_do_call(log, L); return ngx_http_lua_report(log, L, status, "init_by_lua"); diff --git a/src/deps/src/lua-nginx-module/src/ngx_http_lua_initworkerby.c b/src/deps/src/lua-nginx-module/src/ngx_http_lua_initworkerby.c index 94de796ad..449e604ac 100644 --- a/src/deps/src/lua-nginx-module/src/ngx_http_lua_initworkerby.c +++ b/src/deps/src/lua-nginx-module/src/ngx_http_lua_initworkerby.c @@ -118,14 +118,15 @@ ngx_http_lua_init_worker(ngx_cycle_t *cycle) ngx_queue_init(&fake_cycle->reusable_connections_queue); if (ngx_array_init(&fake_cycle->listening, cycle->pool, - cycle->listening.nelts || 1, + cycle->listening.nelts ? cycle->listening.nelts : 1, sizeof(ngx_listening_t)) != NGX_OK) { goto failed; } - if (ngx_array_init(&fake_cycle->paths, cycle->pool, cycle->paths.nelts || 1, + if (ngx_array_init(&fake_cycle->paths, cycle->pool, + cycle->paths.nelts ? cycle->paths.nelts : 1, sizeof(ngx_path_t *)) != NGX_OK) { @@ -135,7 +136,8 @@ ngx_http_lua_init_worker(ngx_cycle_t *cycle) part = &cycle->open_files.part; ofile = part->elts; - if (ngx_list_init(&fake_cycle->open_files, cycle->pool, part->nelts || 1, + if (ngx_list_init(&fake_cycle->open_files, cycle->pool, + part->nelts ? part->nelts : 1, sizeof(ngx_open_file_t)) != NGX_OK) { @@ -317,9 +319,17 @@ ngx_http_lua_init_worker_by_inline(ngx_log_t *log, ngx_http_lua_main_conf_t *lmcf, lua_State *L) { int status; + const char *chunkname; + + if (lmcf->init_worker_chunkname == NULL) { + chunkname = "=init_worker_by_lua"; + + } else { + chunkname = (const char *) lmcf->init_worker_chunkname; + } status = luaL_loadbuffer(L, (char *) lmcf->init_worker_src.data, - lmcf->init_worker_src.len, "=init_worker_by_lua") + lmcf->init_worker_src.len, chunkname) || ngx_http_lua_do_call(log, L); return ngx_http_lua_report(log, L, status, "init_worker_by_lua"); diff --git a/src/deps/src/lua-nginx-module/src/ngx_http_lua_misc.c b/src/deps/src/lua-nginx-module/src/ngx_http_lua_misc.c index 2300aa3e4..4e93f68f1 100644 --- a/src/deps/src/lua-nginx-module/src/ngx_http_lua_misc.c +++ b/src/deps/src/lua-nginx-module/src/ngx_http_lua_misc.c @@ -99,6 +99,17 @@ ngx_http_lua_ffi_set_resp_status(ngx_http_request_t *r, int status) } +int +ngx_http_lua_ffi_req_is_internal(ngx_http_request_t *r) +{ + if (r->connection->fd == (ngx_socket_t) -1) { + return NGX_HTTP_LUA_FFI_BAD_CONTEXT; + } + + return r->internal; +} + + int ngx_http_lua_ffi_is_subrequest(ngx_http_request_t *r) { diff --git a/src/deps/src/lua-nginx-module/src/ngx_http_lua_module.c b/src/deps/src/lua-nginx-module/src/ngx_http_lua_module.c index fbeba12a7..16f442464 100644 --- a/src/deps/src/lua-nginx-module/src/ngx_http_lua_module.c +++ b/src/deps/src/lua-nginx-module/src/ngx_http_lua_module.c @@ -14,6 +14,7 @@ #include "ngx_http_lua_directive.h" #include "ngx_http_lua_capturefilter.h" #include "ngx_http_lua_contentby.h" +#include "ngx_http_lua_server_rewriteby.h" #include "ngx_http_lua_rewriteby.h" #include "ngx_http_lua_accessby.h" #include "ngx_http_lua_logby.h" @@ -31,6 +32,7 @@ #include "ngx_http_lua_ssl_session_storeby.h" #include "ngx_http_lua_ssl_session_fetchby.h" #include "ngx_http_lua_headers.h" +#include "ngx_http_lua_headers_out.h" #include "ngx_http_lua_pipe.h" @@ -290,6 +292,22 @@ static ngx_command_t ngx_http_lua_cmds[] = { (void *) ngx_http_lua_filter_set_by_lua_file }, #endif + /* server_rewrite_by_lua_block { } */ + { ngx_string("server_rewrite_by_lua_block"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS, + ngx_http_lua_server_rewrite_by_lua_block, + NGX_HTTP_SRV_CONF_OFFSET, + 0, + (void *) ngx_http_lua_server_rewrite_handler_inline }, + + /* server_rewrite_by_lua_file filename; */ + { ngx_string("server_rewrite_by_lua_file"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, + ngx_http_lua_server_rewrite_by_lua, + NGX_HTTP_SRV_CONF_OFFSET, + 0, + (void *) ngx_http_lua_server_rewrite_handler_file }, + /* rewrite_by_lua "" */ { ngx_string("rewrite_by_lua"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF @@ -752,6 +770,16 @@ ngx_http_lua_init(ngx_conf_t *cf) cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); + if (lmcf->requires_server_rewrite) { + h = ngx_array_push( + &cmcf->phases[NGX_HTTP_SERVER_REWRITE_PHASE].handlers); + if (h == NULL) { + return NGX_ERROR; + } + + *h = ngx_http_lua_server_rewrite_handler; + } + if (lmcf->requires_rewrite) { h = ngx_array_push(&cmcf->phases[NGX_HTTP_REWRITE_PHASE].handlers); if (h == NULL) { @@ -1086,6 +1114,15 @@ ngx_http_lua_init_main_conf(ngx_conf_t *cf, void *conf) lmcf->worker_thread_vm_pool_size = 100; } + if (ngx_http_lua_init_builtin_headers_out(cf, lmcf) != NGX_OK) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "init header out error"); + + return NGX_CONF_ERROR; + } + + dd("init built in headers out hash size: %ld", + lmcf->builtin_headers_out.size); + return NGX_CONF_OK; } @@ -1103,22 +1140,27 @@ ngx_http_lua_create_srv_conf(ngx_conf_t *cf) /* set by ngx_pcalloc: * lscf->srv.ssl_client_hello_handler = NULL; * lscf->srv.ssl_client_hello_src = { 0, NULL }; + * lscf->srv.ssl_client_hello_chunkname = NULL; * lscf->srv.ssl_client_hello_src_key = NULL; * * lscf->srv.ssl_cert_handler = NULL; * lscf->srv.ssl_cert_src = { 0, NULL }; + * lscf->srv.ssl_cert_chunkname = NULL; * lscf->srv.ssl_cert_src_key = NULL; * * lscf->srv.ssl_session_store_handler = NULL; * lscf->srv.ssl_session_store_src = { 0, NULL }; + * lscf->srv.ssl_session_store_chunkname = NULL; * lscf->srv.ssl_session_store_src_key = NULL; * * lscf->srv.ssl_session_fetch_handler = NULL; * lscf->srv.ssl_session_fetch_src = { 0, NULL }; + * lscf->srv.ssl_session_fetch_chunkname = NULL; * lscf->srv.ssl_session_fetch_src_key = NULL; * * lscf->balancer.handler = NULL; * lscf->balancer.src = { 0, NULL }; + * lscf->balancer.chunkname = NULL; * lscf->balancer.src_key = NULL; */ @@ -1138,10 +1180,11 @@ ngx_http_lua_create_srv_conf(ngx_conf_t *cf) static char * ngx_http_lua_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) { + ngx_http_lua_srv_conf_t *conf = child; + ngx_http_lua_srv_conf_t *prev = parent; + #if (NGX_HTTP_SSL) - ngx_http_lua_srv_conf_t *prev = parent; - ngx_http_lua_srv_conf_t *conf = child; ngx_http_ssl_srv_conf_t *sscf; dd("merge srv conf"); @@ -1151,6 +1194,8 @@ ngx_http_lua_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) conf->srv.ssl_client_hello_src_ref = prev->srv.ssl_client_hello_src_ref; conf->srv.ssl_client_hello_src_key = prev->srv.ssl_client_hello_src_key; conf->srv.ssl_client_hello_handler = prev->srv.ssl_client_hello_handler; + conf->srv.ssl_client_hello_chunkname + = prev->srv.ssl_client_hello_chunkname; } if (conf->srv.ssl_client_hello_src.len) { @@ -1190,6 +1235,7 @@ ngx_http_lua_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) conf->srv.ssl_cert_src_ref = prev->srv.ssl_cert_src_ref; conf->srv.ssl_cert_src_key = prev->srv.ssl_cert_src_key; conf->srv.ssl_cert_handler = prev->srv.ssl_cert_handler; + conf->srv.ssl_cert_chunkname = prev->srv.ssl_cert_chunkname; } if (conf->srv.ssl_cert_src.len) { @@ -1229,6 +1275,7 @@ ngx_http_lua_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) conf->srv.ssl_sess_store_src_ref = prev->srv.ssl_sess_store_src_ref; conf->srv.ssl_sess_store_src_key = prev->srv.ssl_sess_store_src_key; conf->srv.ssl_sess_store_handler = prev->srv.ssl_sess_store_handler; + conf->srv.ssl_sess_store_chunkname = prev->srv.ssl_sess_store_chunkname; } if (conf->srv.ssl_sess_store_src.len) { @@ -1252,6 +1299,7 @@ ngx_http_lua_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) conf->srv.ssl_sess_fetch_src_ref = prev->srv.ssl_sess_fetch_src_ref; conf->srv.ssl_sess_fetch_src_key = prev->srv.ssl_sess_fetch_src_key; conf->srv.ssl_sess_fetch_handler = prev->srv.ssl_sess_fetch_handler; + conf->srv.ssl_sess_fetch_chunkname = prev->srv.ssl_sess_fetch_chunkname; } if (conf->srv.ssl_sess_fetch_src.len) { @@ -1271,6 +1319,16 @@ ngx_http_lua_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) } #endif /* NGX_HTTP_SSL */ + + if (conf->srv.server_rewrite_src.value.len == 0) { + conf->srv.server_rewrite_src = prev->srv.server_rewrite_src; + conf->srv.server_rewrite_src_ref = prev->srv.server_rewrite_src_ref; + conf->srv.server_rewrite_src_key = prev->srv.server_rewrite_src_key; + conf->srv.server_rewrite_handler = prev->srv.server_rewrite_handler; + conf->srv.server_rewrite_chunkname + = prev->srv.server_rewrite_chunkname; + } + return NGX_CONF_OK; } @@ -1393,6 +1451,7 @@ ngx_http_lua_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) conf->header_filter_handler = prev->header_filter_handler; conf->header_filter_src_ref = prev->header_filter_src_ref; conf->header_filter_src_key = prev->header_filter_src_key; + conf->header_filter_chunkname = prev->header_filter_chunkname; } if (conf->body_filter_src.value.len == 0) { @@ -1400,6 +1459,7 @@ ngx_http_lua_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) conf->body_filter_handler = prev->body_filter_handler; conf->body_filter_src_ref = prev->body_filter_src_ref; conf->body_filter_src_key = prev->body_filter_src_key; + conf->body_filter_chunkname = prev->body_filter_chunkname; } #if (NGX_HTTP_SSL) diff --git a/src/deps/src/lua-nginx-module/src/ngx_http_lua_output.c b/src/deps/src/lua-nginx-module/src/ngx_http_lua_output.c index 8d8c71d89..b2a98d133 100644 --- a/src/deps/src/lua-nginx-module/src/ngx_http_lua_output.c +++ b/src/deps/src/lua-nginx-module/src/ngx_http_lua_output.c @@ -63,6 +63,7 @@ ngx_http_lua_ngx_echo(lua_State *L, unsigned newline) } ngx_http_lua_check_context(L, ctx, NGX_HTTP_LUA_CONTEXT_REWRITE + | NGX_HTTP_LUA_CONTEXT_SERVER_REWRITE | NGX_HTTP_LUA_CONTEXT_ACCESS | NGX_HTTP_LUA_CONTEXT_CONTENT); @@ -499,6 +500,7 @@ ngx_http_lua_ngx_flush(lua_State *L) } ngx_http_lua_check_context(L, ctx, NGX_HTTP_LUA_CONTEXT_REWRITE + | NGX_HTTP_LUA_CONTEXT_SERVER_REWRITE | NGX_HTTP_LUA_CONTEXT_ACCESS | NGX_HTTP_LUA_CONTEXT_CONTENT); @@ -653,6 +655,7 @@ ngx_http_lua_ngx_eof(lua_State *L) } ngx_http_lua_check_context(L, ctx, NGX_HTTP_LUA_CONTEXT_REWRITE + | NGX_HTTP_LUA_CONTEXT_SERVER_REWRITE | NGX_HTTP_LUA_CONTEXT_ACCESS | NGX_HTTP_LUA_CONTEXT_CONTENT); @@ -715,6 +718,7 @@ ngx_http_lua_ngx_send_headers(lua_State *L) } ngx_http_lua_check_context(L, ctx, NGX_HTTP_LUA_CONTEXT_REWRITE + | NGX_HTTP_LUA_CONTEXT_SERVER_REWRITE | NGX_HTTP_LUA_CONTEXT_ACCESS | NGX_HTTP_LUA_CONTEXT_CONTENT); diff --git a/src/deps/src/lua-nginx-module/src/ngx_http_lua_pipe.c b/src/deps/src/lua-nginx-module/src/ngx_http_lua_pipe.c index 93dc7d5bc..8c0884bcc 100644 --- a/src/deps/src/lua-nginx-module/src/ngx_http_lua_pipe.c +++ b/src/deps/src/lua-nginx-module/src/ngx_http_lua_pipe.c @@ -78,10 +78,15 @@ static void ngx_http_lua_pipe_proc_read_stdout_cleanup(void *data); static void ngx_http_lua_pipe_proc_read_stderr_cleanup(void *data); static void ngx_http_lua_pipe_proc_write_cleanup(void *data); static void ngx_http_lua_pipe_proc_wait_cleanup(void *data); +static void ngx_http_lua_pipe_reap_pids(ngx_event_t *ev); +static void ngx_http_lua_pipe_reap_timer_handler(ngx_event_t *ev); +void ngx_http_lua_ffi_pipe_proc_destroy( + ngx_http_lua_ffi_pipe_proc_t *proc); static ngx_rbtree_t ngx_http_lua_pipe_rbtree; static ngx_rbtree_node_t ngx_http_lua_pipe_proc_sentinel; +static ngx_event_t ngx_reap_pid_event; #if (NGX_HTTP_LUA_HAVE_SIGNALFD) @@ -160,6 +165,15 @@ ngx_http_lua_pipe_add_signal_handler(ngx_cycle_t *cycle) struct sigaction sa; #endif + ngx_reap_pid_event.handler = ngx_http_lua_pipe_reap_timer_handler; + ngx_reap_pid_event.log = cycle->log; + ngx_reap_pid_event.data = cycle; + ngx_reap_pid_event.cancelable = 1; + + if (!ngx_reap_pid_event.timer_set) { + ngx_add_timer(&ngx_reap_pid_event, 1000); + } + #if (NGX_HTTP_LUA_HAVE_SIGNALFD) if (sigemptyset(&set) != 0) { ngx_log_error(NGX_LOG_ERR, cycle->log, ngx_errno, @@ -351,11 +365,7 @@ static void ngx_http_lua_pipe_sigchld_event_handler(ngx_event_t *ev) { int n; - int status; - ngx_pid_t pid; ngx_connection_t *c = ev->data; - ngx_rbtree_node_t *node; - ngx_http_lua_pipe_node_t *pipe_node; ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0, "lua pipe reaping children"); @@ -377,72 +387,99 @@ ngx_http_lua_pipe_sigchld_event_handler(ngx_event_t *ev) break; } - for ( ;; ) { - pid = waitpid(-1, &status, WNOHANG); + ngx_http_lua_pipe_reap_pids(ev); + } +} - if (pid == 0) { - break; + +static void +ngx_http_lua_pipe_reap_pids(ngx_event_t *ev) +{ + int status; + ngx_pid_t pid; + ngx_rbtree_node_t *node; + ngx_http_lua_pipe_node_t *pipe_node; + + for ( ;; ) { + pid = waitpid(-1, &status, WNOHANG); + + if (pid == 0) { + break; + } + + if (pid < 0) { + if (ngx_errno != NGX_ECHILD) { + ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, ngx_errno, + "lua pipe waitpid failed"); } - if (pid < 0) { - if (ngx_errno != NGX_ECHILD) { - ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, ngx_errno, - "lua pipe waitpid failed"); - } + break; + } - break; + /* This log is ported from Nginx's signal handler since we override + * or block it in this implementation. */ + ngx_log_error(NGX_LOG_NOTICE, ngx_cycle->log, 0, + "signal %d (SIGCHLD) received from %P", + SIGCHLD, pid); + + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, + "lua pipe SIGCHLD fd read pid:%P status:%d", pid, + status); + + node = ngx_http_lua_pipe_lookup_pid(pid); + if (node != NULL) { + pipe_node = (ngx_http_lua_pipe_node_t *) &node->color; + if (pipe_node->wait_co_ctx != NULL) { + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, + "lua pipe resume process:%p waiting for %P", + pipe_node->proc, pid); + + /* + * We need the extra parentheses around the first argument + * of ngx_post_event() just to work around macro issues in + * nginx cores older than 1.7.12 (exclusive). + */ + ngx_post_event((&pipe_node->wait_co_ctx->sleep), + &ngx_posted_events); } - /* This log is ported from Nginx's signal handler since we override - * or block it in this implementation. */ - ngx_log_error(NGX_LOG_NOTICE, ngx_cycle->log, 0, - "signal %d (SIGCHLD) received from %P", - SIGCHLD, pid); + /* TODO: we should proactively close and free up the pipe after + * the user consume all the data in the pipe. + */ + pipe_node->proc->pipe->dead = 1; - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, - "lua pipe SIGCHLD fd read pid:%P status:%d", pid, - status); + if (WIFSIGNALED(status)) { + pipe_node->status = WTERMSIG(status); + pipe_node->reason_code = REASON_SIGNAL_CODE; - node = ngx_http_lua_pipe_lookup_pid(pid); - if (node != NULL) { - pipe_node = (ngx_http_lua_pipe_node_t *) &node->color; - if (pipe_node->wait_co_ctx != NULL) { - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, - "lua pipe resume process:%p waiting for %P", - pipe_node->proc, pid); + } else if (WIFEXITED(status)) { + pipe_node->status = WEXITSTATUS(status); + pipe_node->reason_code = REASON_EXIT_CODE; - /* - * We need the extra parentheses around the first argument - * of ngx_post_event() just to work around macro issues in - * nginx cores older than 1.7.12 (exclusive). - */ - ngx_post_event((&pipe_node->wait_co_ctx->sleep), - &ngx_posted_events); - } - - pipe_node->proc->pipe->dead = 1; - - if (WIFSIGNALED(status)) { - pipe_node->status = WTERMSIG(status); - pipe_node->reason_code = REASON_SIGNAL_CODE; - - } else if (WIFEXITED(status)) { - pipe_node->status = WEXITSTATUS(status); - pipe_node->reason_code = REASON_EXIT_CODE; - - } else { - ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, 0, - "lua pipe unknown exit status %d from " - "process %P", status, pid); - pipe_node->status = status; - pipe_node->reason_code = REASON_UNKNOWN_CODE; - } + } else { + ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, 0, + "lua pipe unknown exit status %d from " + "process %P", status, pid); + pipe_node->status = status; + pipe_node->reason_code = REASON_UNKNOWN_CODE; } } } } +static void +ngx_http_lua_pipe_reap_timer_handler(ngx_event_t *ev) +{ + ngx_http_lua_pipe_reap_pids(ev); + + if (!ngx_exiting) { + ngx_add_timer(&ngx_reap_pid_event, 1000); + ngx_reap_pid_event.timedout = 0; + } +} + + static ssize_t ngx_http_lua_pipe_fd_read(ngx_connection_t *c, u_char *buf, size_t size) { @@ -562,7 +599,8 @@ ngx_http_lua_execvpe(const char *program, char * const argv[], int -ngx_http_lua_ffi_pipe_spawn(ngx_http_lua_ffi_pipe_proc_t *proc, +ngx_http_lua_ffi_pipe_spawn(ngx_http_request_t *r, + ngx_http_lua_ffi_pipe_proc_t *proc, const char *file, const char **argv, int merge_stderr, size_t buffer_size, const char **environ, u_char *errbuf, size_t *errbuf_size) { @@ -582,6 +620,7 @@ ngx_http_lua_ffi_pipe_spawn(ngx_http_lua_ffi_pipe_proc_t *proc, ngx_http_lua_pipe_node_t *pipe_node; struct sigaction sa; ngx_http_lua_pipe_signal_t *sig; + ngx_pool_cleanup_t *cln; sigset_t set; pool_size = ngx_align(NGX_MIN_POOL_SIZE + buffer_size * 2, @@ -773,10 +812,21 @@ ngx_http_lua_ffi_pipe_spawn(ngx_http_lua_ffi_pipe_proc_t *proc, } } - close(in[0]); - close(out[1]); + if (close(in[0]) == -1) { + ngx_log_error(NGX_LOG_EMERG, ngx_cycle->log, ngx_errno, + "lua pipe failed to close the in[0]"); + } + + if (close(out[1]) == -1) { + ngx_log_error(NGX_LOG_EMERG, ngx_cycle->log, ngx_errno, + "lua pipe failed to close the out[1]"); + } + if (!merge_stderr) { - close(err[1]); + if (close(err[1]) == -1) { + ngx_log_error(NGX_LOG_EMERG, ngx_cycle->log, ngx_errno, + "lua pipe failed to close the err[1]"); + } } if (environ != NULL) { @@ -858,6 +908,21 @@ ngx_http_lua_ffi_pipe_spawn(ngx_http_lua_ffi_pipe_proc_t *proc, pp->stderr_fd = stderr_fd; } + if (pp->cleanup == NULL) { + cln = ngx_pool_cleanup_add(r->pool, 0); + + if (cln == NULL) { + *errbuf_size = ngx_snprintf(errbuf, *errbuf_size, "no memory") + - errbuf; + goto close_in_out_err_fd; + } + + cln->handler = (ngx_pool_cleanup_pt) ngx_http_lua_ffi_pipe_proc_destroy; + cln->data = proc; + pp->cleanup = &cln->handler; + pp->r = r; + } + node = (ngx_rbtree_node_t *) (pp + 1); node->key = pid; pipe_node = (ngx_http_lua_pipe_node_t *) &node->color; @@ -1128,6 +1193,12 @@ ngx_http_lua_ffi_pipe_proc_destroy(ngx_http_lua_ffi_pipe_proc_t *proc) } } + if (pipe->cleanup != NULL) { + *pipe->cleanup = NULL; + ngx_http_lua_cleanup_free(pipe->r, pipe->cleanup); + pipe->cleanup = NULL; + } + ngx_http_lua_pipe_proc_finalize(proc); ngx_destroy_pool(pipe->pool); proc->pipe = NULL; @@ -1141,7 +1212,7 @@ ngx_http_lua_pipe_get_lua_ctx(ngx_http_request_t *r, int rc; *ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); - if (ctx == NULL) { + if (*ctx == NULL) { return NGX_HTTP_LUA_FFI_NO_REQ_CTX; } diff --git a/src/deps/src/lua-nginx-module/src/ngx_http_lua_pipe.h b/src/deps/src/lua-nginx-module/src/ngx_http_lua_pipe.h index ecb86c880..f1c928352 100644 --- a/src/deps/src/lua-nginx-module/src/ngx_http_lua_pipe.h +++ b/src/deps/src/lua-nginx-module/src/ngx_http_lua_pipe.h @@ -57,6 +57,8 @@ struct ngx_http_lua_pipe_s { ngx_http_lua_pipe_ctx_t *stdout_ctx; ngx_http_lua_pipe_ctx_t *stderr_ctx; ngx_http_lua_pipe_retval_handler retval_handler; + ngx_http_cleanup_pt *cleanup; + ngx_http_request_t *r; size_t buffer_size; unsigned closed:1; unsigned dead:1; diff --git a/src/deps/src/lua-nginx-module/src/ngx_http_lua_regex.c b/src/deps/src/lua-nginx-module/src/ngx_http_lua_regex.c index 03d1a4d32..5c17cfe09 100644 --- a/src/deps/src/lua-nginx-module/src/ngx_http_lua_regex.c +++ b/src/deps/src/lua-nginx-module/src/ngx_http_lua_regex.c @@ -173,6 +173,8 @@ ngx_http_lua_ffi_set_jit_stack_size(int size, u_char *errstr, lmcf = ngx_http_cycle_get_module_main_conf(ngx_cycle, ngx_http_lua_module); + ngx_http_lua_assert(lmcf != NULL); + if (size < NGX_LUA_RE_MIN_JIT_STACK_SIZE) { size = NGX_LUA_RE_MIN_JIT_STACK_SIZE; } @@ -270,6 +272,8 @@ ngx_http_lua_ffi_compile_regex(const unsigned char *pat, size_t pat_len, lmcf = ngx_http_cycle_get_module_main_conf(ngx_cycle, ngx_http_lua_module); + ngx_http_lua_assert(lmcf != NULL); + #if (LUA_HAVE_PCRE_JIT) if (flags & NGX_LUA_RE_MODE_JIT) { diff --git a/src/deps/src/lua-nginx-module/src/ngx_http_lua_req_body.c b/src/deps/src/lua-nginx-module/src/ngx_http_lua_req_body.c index d6e5640a0..935fafc8a 100644 --- a/src/deps/src/lua-nginx-module/src/ngx_http_lua_req_body.c +++ b/src/deps/src/lua-nginx-module/src/ngx_http_lua_req_body.c @@ -101,6 +101,7 @@ ngx_http_lua_ngx_req_read_body(lua_State *L) } ngx_http_lua_check_context(L, ctx, NGX_HTTP_LUA_CONTEXT_REWRITE + | NGX_HTTP_LUA_CONTEXT_SERVER_REWRITE | NGX_HTTP_LUA_CONTEXT_ACCESS | NGX_HTTP_LUA_CONTEXT_CONTENT); diff --git a/src/deps/src/lua-nginx-module/src/ngx_http_lua_server_rewriteby.c b/src/deps/src/lua-nginx-module/src/ngx_http_lua_server_rewriteby.c new file mode 100644 index 000000000..22bb69e8c --- /dev/null +++ b/src/deps/src/lua-nginx-module/src/ngx_http_lua_server_rewriteby.c @@ -0,0 +1,339 @@ + +/* + * Copyright (C) Xiaozhe Wang (chaoslawful) + * Copyright (C) Yichun Zhang (agentzh) + */ + + +#ifndef DDEBUG +#define DDEBUG 0 +#endif +#include "ddebug.h" + +#include +#include "ngx_http_lua_server_rewriteby.h" +#include "ngx_http_lua_util.h" +#include "ngx_http_lua_exception.h" +#include "ngx_http_lua_cache.h" + +static ngx_int_t ngx_http_lua_server_rewrite_by_chunk(lua_State *L, + ngx_http_request_t *r); + +ngx_int_t +ngx_http_lua_server_rewrite_handler(ngx_http_request_t *r) +{ + ngx_int_t rc; + lua_State *L; + ngx_http_lua_srv_conf_t *lscf; + ngx_http_lua_loc_conf_t *llcf; + ngx_http_lua_ctx_t *ctx; + + /* XXX we need to take into account ngx_rewrite's location dump */ + if (r->uri_changed) { + return NGX_DECLINED; + } + + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "lua server rewrite handler, uri:\"%V\" c:%ud", &r->uri, + r->main->count); + + lscf = ngx_http_get_module_srv_conf(r, ngx_http_lua_module); + llcf = ngx_http_get_module_loc_conf(r, ngx_http_lua_module); + L = ngx_http_lua_get_lua_vm(r, NULL); + + if (lscf->srv.server_rewrite_handler == NULL) { + dd("no rewrite handler found"); + return NGX_DECLINED; + } + + ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); + + dd("ctx = %p", ctx); + + if (ctx == NULL) { + ctx = ngx_http_lua_create_ctx(r); + if (ctx == NULL) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + } + + dd("entered? %d", (int) ctx->entered_server_rewrite_phase); + + if (ctx->entered_server_rewrite_phase) { + dd("rewriteby: calling wev handler"); + rc = ctx->resume_handler(r); + dd("rewriteby: wev handler returns %d", (int) rc); + + if (rc == NGX_OK) { + rc = NGX_DECLINED; + } + + if (rc == NGX_DECLINED) { + if (r->header_sent) { + dd("header already sent"); + + /* response header was already generated in rewrite_by_lua*, + * so it is no longer safe to proceed to later phases + * which may generate responses again */ + + if (!ctx->eof) { + dd("eof not yet sent"); + + rc = ngx_http_lua_send_chain_link(r, ctx, NULL + /* indicate last_buf */); + if (rc == NGX_ERROR || rc > NGX_OK) { + return rc; + } + } + + return NGX_HTTP_OK; + } + + r->write_event_handler = ngx_http_core_run_phases; + ctx->entered_server_rewrite_phase = 0; + + return NGX_DECLINED; + } + + return rc; + } + + if (ctx->waiting_more_body) { + return NGX_DONE; + } + + /* TODO: lscf do not have force_read_body */ + if (llcf->force_read_body && !ctx->read_body_done) { + r->request_body_in_single_buf = 1; + r->request_body_in_persistent_file = 1; + r->request_body_in_clean_file = 1; + + rc = ngx_http_read_client_request_body(r, + ngx_http_lua_generic_phase_post_read); + + if (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE) { + return rc; + } + + if (rc == NGX_AGAIN) { + ctx->waiting_more_body = 1; + return NGX_DONE; + } + } + + dd("calling server rewrite handler"); + return lscf->srv.server_rewrite_handler(r, lscf, L); +} + + +ngx_int_t +ngx_http_lua_server_rewrite_handler_inline(ngx_http_request_t *r, + ngx_http_lua_srv_conf_t *lscf, lua_State *L) +{ + ngx_int_t rc; + + dd("server_rewrite by lua inline"); + + + /* load Lua inline script (w/ cache) sp = 1 */ + rc = ngx_http_lua_cache_loadbuffer(r->connection->log, L, + lscf->srv.server_rewrite_src.value.data, + lscf->srv.server_rewrite_src.value.len, + &lscf->srv.server_rewrite_src_ref, + lscf->srv.server_rewrite_src_key, + (const char *) + lscf->srv.server_rewrite_chunkname); + if (rc != NGX_OK) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + return ngx_http_lua_server_rewrite_by_chunk(L, r); +} + + +ngx_int_t +ngx_http_lua_server_rewrite_handler_file(ngx_http_request_t *r, + ngx_http_lua_srv_conf_t *lscf, lua_State *L) +{ + ngx_int_t rc; + u_char *script_path; + ngx_str_t eval_src; + + + if (ngx_http_complex_value(r, &lscf->srv.server_rewrite_src, + &eval_src) != NGX_OK) + { + return NGX_ERROR; + } + + script_path = ngx_http_lua_rebase_path(r->pool, eval_src.data, + eval_src.len); + + if (script_path == NULL) { + return NGX_ERROR; + } + + /* load Lua script file (w/ cache) sp = 1 */ + rc = ngx_http_lua_cache_loadfile(r->connection->log, L, script_path, + &lscf->srv.server_rewrite_src_ref, + lscf->srv.server_rewrite_src_key); + if (rc != NGX_OK) { + if (rc < NGX_HTTP_SPECIAL_RESPONSE) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + return rc; + } + + return ngx_http_lua_server_rewrite_by_chunk(L, r); +} + + +static ngx_int_t +ngx_http_lua_server_rewrite_by_chunk(lua_State *L, ngx_http_request_t *r) +{ + int co_ref; + lua_State *co; + ngx_int_t rc; + ngx_uint_t nreqs; + ngx_event_t *rev; + ngx_connection_t *c; + ngx_http_lua_ctx_t *ctx; + ngx_http_cleanup_t *cln; + + ngx_http_lua_loc_conf_t *llcf; + + /* {{{ new coroutine to handle request */ + co = ngx_http_lua_new_thread(r, L, &co_ref); + + if (co == NULL) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "lua: failed to create new coroutine to handle request"); + + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + /* move code closure to new coroutine */ + lua_xmove(L, co, 1); + +#ifndef OPENRESTY_LUAJIT + /* set closure's env table to new coroutine's globals table */ + ngx_http_lua_get_globals_table(co); + lua_setfenv(co, -2); +#endif + + /* save nginx request in coroutine globals table */ + ngx_http_lua_set_req(co, r); + + /* {{{ initialize request context */ + ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); + + dd("ctx = %p", ctx); + + if (ctx == NULL) { + return NGX_ERROR; + } + + ngx_http_lua_reset_ctx(r, L, ctx); + + ctx->entered_server_rewrite_phase = 1; + + ctx->cur_co_ctx = &ctx->entry_co_ctx; + ctx->cur_co_ctx->co = co; + ctx->cur_co_ctx->co_ref = co_ref; +#ifdef NGX_LUA_USE_ASSERT + ctx->cur_co_ctx->co_top = 1; +#endif + + ngx_http_lua_attach_co_ctx_to_L(co, ctx->cur_co_ctx); + + /* }}} */ + + /* {{{ register request cleanup hooks */ + if (ctx->cleanup == NULL) { + cln = ngx_http_cleanup_add(r, 0); + if (cln == NULL) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + cln->handler = ngx_http_lua_request_cleanup_handler; + cln->data = ctx; + ctx->cleanup = &cln->handler; + } + /* }}} */ + + ctx->context = NGX_HTTP_LUA_CONTEXT_SERVER_REWRITE; + + llcf = ngx_http_get_module_loc_conf(r, ngx_http_lua_module); + + if (llcf->check_client_abort) { + r->read_event_handler = ngx_http_lua_rd_check_broken_connection; + +#if (NGX_HTTP_V2) + if (!r->stream) { +#endif + + rev = r->connection->read; + + if (!rev->active) { + if (ngx_add_event(rev, NGX_READ_EVENT, 0) != NGX_OK) { + return NGX_ERROR; + } + } + +#if (NGX_HTTP_V2) + } +#endif + + } else { + r->read_event_handler = ngx_http_block_reading; + } + + c = r->connection; + nreqs = c->requests; + + rc = ngx_http_lua_run_thread(L, r, ctx, 0); + + if (rc == NGX_ERROR || rc > NGX_OK) { + return rc; + } + + if (rc == NGX_AGAIN) { + rc = ngx_http_lua_run_posted_threads(c, L, r, ctx, nreqs); + + } else if (rc == NGX_DONE) { + ngx_http_lua_finalize_request(r, NGX_DONE); + rc = ngx_http_lua_run_posted_threads(c, L, r, ctx, nreqs); + } + + if (rc == NGX_OK || rc == NGX_DECLINED) { + if (r->header_sent) { + dd("header already sent"); + + /* response header was already generated in rewrite_by_lua*, + * so it is no longer safe to proceed to later phases + * which may generate responses again */ + + if (!ctx->eof) { + dd("eof not yet sent"); + + rc = ngx_http_lua_send_chain_link(r, ctx, NULL + /* indicate last_buf */); + if (rc == NGX_ERROR || rc > NGX_OK) { + return rc; + } + } + + return NGX_HTTP_OK; + } + + r->write_event_handler = ngx_http_core_run_phases; + ctx->entered_server_rewrite_phase = 0; + + return NGX_DECLINED; + } + + return rc; +} + +/* vi:set ft=c ts=4 sw=4 et fdm=marker: */ diff --git a/src/deps/src/lua-nginx-module/src/ngx_http_lua_server_rewriteby.h b/src/deps/src/lua-nginx-module/src/ngx_http_lua_server_rewriteby.h new file mode 100644 index 000000000..a35ebd2b7 --- /dev/null +++ b/src/deps/src/lua-nginx-module/src/ngx_http_lua_server_rewriteby.h @@ -0,0 +1,20 @@ + +/* + * Copyright (C) Xiaozhe Wang (chaoslawful) + * Copyright (C) Yichun Zhang (agentzh) + */ + +#ifndef _NGX_HTTP_LUA_SERVER_REWRITEBY_H_INCLUDED_ +#define _NGX_HTTP_LUA_SERVER_REWRITEBY_H_INCLUDED_ + +#include "ngx_http_lua_common.h" + +ngx_int_t ngx_http_lua_server_rewrite_handler(ngx_http_request_t *r); +ngx_int_t ngx_http_lua_server_rewrite_handler_inline(ngx_http_request_t *r, + ngx_http_lua_srv_conf_t *lscf, lua_State *L); +ngx_int_t ngx_http_lua_server_rewrite_handler_file(ngx_http_request_t *r, + ngx_http_lua_srv_conf_t *lscf, lua_State *L); + +#endif /* _NGX_HTTP_LUA_SERVER_REWRITEBY_H_INCLUDED_ */ + +/* vi:set ft=c ts=4 sw=4 et fdm=marker: */ diff --git a/src/deps/src/lua-nginx-module/src/ngx_http_lua_setby.c b/src/deps/src/lua-nginx-module/src/ngx_http_lua_setby.c index f00468c90..98e8d47f5 100644 --- a/src/deps/src/lua-nginx-module/src/ngx_http_lua_setby.c +++ b/src/deps/src/lua-nginx-module/src/ngx_http_lua_setby.c @@ -123,16 +123,15 @@ ngx_http_lua_set_by_chunk(lua_State *L, ngx_http_request_t *r, ngx_str_t *val, } -int -ngx_http_lua_setby_param_get(lua_State *L, ngx_http_request_t *r) +void +ngx_http_lua_ffi_get_setby_param(ngx_http_request_t *r, int idx, + u_char **data_p, size_t *len_p) { - int idx; int n; ngx_http_variable_value_t *v; ngx_http_lua_main_conf_t *lmcf; - idx = luaL_checkint(L, 2); idx--; lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module); @@ -144,13 +143,12 @@ ngx_http_lua_setby_param_get(lua_State *L, ngx_http_request_t *r) v = lmcf->setby_args; if (idx < 0 || idx > n - 1) { - lua_pushnil(L); + *len_p = 0; } else { - lua_pushlstring(L, (const char *) (v[idx].data), v[idx].len); + *data_p = v[idx].data; + *len_p = v[idx].len; } - - return 1; } diff --git a/src/deps/src/lua-nginx-module/src/ngx_http_lua_setby.h b/src/deps/src/lua-nginx-module/src/ngx_http_lua_setby.h index f43eef753..8fd1e2c7b 100644 --- a/src/deps/src/lua-nginx-module/src/ngx_http_lua_setby.h +++ b/src/deps/src/lua-nginx-module/src/ngx_http_lua_setby.h @@ -7,7 +7,6 @@ ngx_int_t ngx_http_lua_set_by_chunk(lua_State *L, ngx_http_request_t *r, ngx_str_t *val, ngx_http_variable_value_t *args, size_t nargs, ngx_str_t *script); -int ngx_http_lua_setby_param_get(lua_State *L, ngx_http_request_t *r); #endif /* _NGX_HTTP_LUA_SET_BY_H_INCLUDED_ */ diff --git a/src/deps/src/lua-nginx-module/src/ngx_http_lua_shdict.c b/src/deps/src/lua-nginx-module/src/ngx_http_lua_shdict.c index d841eb95e..27f3b100f 100644 --- a/src/deps/src/lua-nginx-module/src/ngx_http_lua_shdict.c +++ b/src/deps/src/lua-nginx-module/src/ngx_http_lua_shdict.c @@ -943,7 +943,7 @@ push_node: ngx_shmtx_unlock(&ctx->shpool->mutex); - lua_pushboolean(L, 0); + lua_pushnil(L); lua_pushliteral(L, "no memory"); return 2; } @@ -2092,4 +2092,38 @@ ngx_http_lua_ffi_shdict_free_space(ngx_shm_zone_t *zone) #endif +#if (NGX_DARWIN) +int +ngx_http_lua_ffi_shdict_get_macos(ngx_http_lua_shdict_get_params_t *p) +{ + return ngx_http_lua_ffi_shdict_get(p->zone, p->key, p->key_len, + p->value_type, p->str_value_buf, + p->str_value_len, p->num_value, + p->user_flags, p->get_stale, + p->is_stale, p->errmsg); +} + + +int +ngx_http_lua_ffi_shdict_store_macos(ngx_http_lua_shdict_store_params_t *p) +{ + return ngx_http_lua_ffi_shdict_store(p->zone, p->op, p->key, p->key_len, + p->value_type, p->str_value_buf, + p->str_value_len, p->num_value, + p->exptime, p->user_flags, + p->errmsg, p->forcible); +} + + +int +ngx_http_lua_ffi_shdict_incr_macos(ngx_http_lua_shdict_incr_params_t *p) +{ + return ngx_http_lua_ffi_shdict_incr(p->zone, p->key, p->key_len, + p->num_value, p->errmsg, + p->has_init, p->init, p->init_ttl, + p->forcible); +} +#endif + + /* vi:set ft=c ts=4 sw=4 et fdm=marker: */ diff --git a/src/deps/src/lua-nginx-module/src/ngx_http_lua_shdict.h b/src/deps/src/lua-nginx-module/src/ngx_http_lua_shdict.h index 90a0099f5..67dd4d4eb 100644 --- a/src/deps/src/lua-nginx-module/src/ngx_http_lua_shdict.h +++ b/src/deps/src/lua-nginx-module/src/ngx_http_lua_shdict.h @@ -55,6 +55,52 @@ typedef struct { } ngx_http_lua_shm_zone_ctx_t; +#if (NGX_DARWIN) +typedef struct { + void *zone; + const unsigned char *key; + size_t key_len; + int *value_type; + unsigned char **str_value_buf; + size_t *str_value_len; + double *num_value; + int *user_flags; + int get_stale; + int *is_stale; + char **errmsg; +} ngx_http_lua_shdict_get_params_t; + + +typedef struct { + void *zone; + int op; + const unsigned char *key; + size_t key_len; + int value_type; + const unsigned char *str_value_buf; + size_t str_value_len; + double num_value; + long exptime; + int user_flags; + char **errmsg; + int *forcible; +} ngx_http_lua_shdict_store_params_t; + + +typedef struct { + void *zone; + const unsigned char *key; + size_t key_len; + double *num_value; + char **errmsg; + int has_init; + double init; + long init_ttl; + int *forcible; +} ngx_http_lua_shdict_incr_params_t; +#endif + + ngx_int_t ngx_http_lua_shdict_init_zone(ngx_shm_zone_t *shm_zone, void *data); void ngx_http_lua_shdict_rbtree_insert_value(ngx_rbtree_node_t *temp, ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel); diff --git a/src/deps/src/lua-nginx-module/src/ngx_http_lua_socket_tcp.c b/src/deps/src/lua-nginx-module/src/ngx_http_lua_socket_tcp.c index 26467fddb..dcd27dc17 100644 --- a/src/deps/src/lua-nginx-module/src/ngx_http_lua_socket_tcp.c +++ b/src/deps/src/lua-nginx-module/src/ngx_http_lua_socket_tcp.c @@ -20,9 +20,12 @@ static int ngx_http_lua_socket_tcp(lua_State *L); +static int ngx_http_lua_socket_tcp_bind(lua_State *L); static int ngx_http_lua_socket_tcp_connect(lua_State *L); #if (NGX_HTTP_SSL) -static int ngx_http_lua_socket_tcp_sslhandshake(lua_State *L); +static void ngx_http_lua_ssl_handshake_handler(ngx_connection_t *c); +static int ngx_http_lua_ssl_handshake_retval_handler(ngx_http_request_t *r, + ngx_http_lua_socket_tcp_upstream_t *u, lua_State *L); #endif static int ngx_http_lua_socket_tcp_receive(lua_State *L); static int ngx_http_lua_socket_tcp_receiveany(lua_State *L); @@ -149,12 +152,6 @@ static void ngx_http_lua_socket_shutdown_pool_helper( ngx_http_lua_socket_pool_t *spool); static int ngx_http_lua_socket_prepare_error_retvals(ngx_http_request_t *r, ngx_http_lua_socket_tcp_upstream_t *u, lua_State *L, ngx_uint_t ft_type); -#if (NGX_HTTP_SSL) -static int ngx_http_lua_ssl_handshake_retval_handler(ngx_http_request_t *r, - ngx_http_lua_socket_tcp_upstream_t *u, lua_State *L); -static void ngx_http_lua_ssl_handshake_handler(ngx_connection_t *c); -static int ngx_http_lua_ssl_free_session(lua_State *L); -#endif static void ngx_http_lua_socket_tcp_close_connection(ngx_connection_t *c); @@ -164,14 +161,17 @@ enum { SOCKET_CONNECT_TIMEOUT_INDEX = 2, SOCKET_SEND_TIMEOUT_INDEX = 4, SOCKET_READ_TIMEOUT_INDEX = 5, + SOCKET_CLIENT_CERT_INDEX = 6 , + SOCKET_CLIENT_PKEY_INDEX = 7 , + SOCKET_BIND_INDEX = 8 /* only in upstream cosocket */ }; enum { - SOCKET_OP_CONNECT, - SOCKET_OP_READ, - SOCKET_OP_WRITE, - SOCKET_OP_RESUME_CONN, + SOCKET_OP_CONNECT = 0x01, + SOCKET_OP_READ = 0x02, + SOCKET_OP_WRITE = 0x04, + SOCKET_OP_RESUME_CONN = 0x08, }; @@ -222,9 +222,6 @@ static char ngx_http_lua_upstream_udata_metatable_key; static char ngx_http_lua_downstream_udata_metatable_key; static char ngx_http_lua_pool_udata_metatable_key; static char ngx_http_lua_pattern_udata_metatable_key; -#if (NGX_HTTP_SSL) -static char ngx_http_lua_ssl_session_metatable_key; -#endif #define ngx_http_lua_tcp_socket_metatable_literal_key "__tcp_cosocket_mt" @@ -319,18 +316,14 @@ ngx_http_lua_inject_socket_tcp_api(ngx_log_t *log, lua_State *L) /* {{{tcp object metatable */ lua_pushlightuserdata(L, ngx_http_lua_lightudata_mask( tcp_socket_metatable_key)); - lua_createtable(L, 0 /* narr */, 14 /* nrec */); + lua_createtable(L, 0 /* narr */, 16 /* nrec */); + + lua_pushcfunction(L, ngx_http_lua_socket_tcp_bind); + lua_setfield(L, -2, "bind"); lua_pushcfunction(L, ngx_http_lua_socket_tcp_connect); lua_setfield(L, -2, "connect"); -#if (NGX_HTTP_SSL) - - lua_pushcfunction(L, ngx_http_lua_socket_tcp_sslhandshake); - lua_setfield(L, -2, "sslhandshake"); - -#endif - lua_pushcfunction(L, ngx_http_lua_socket_tcp_receive); lua_setfield(L, -2, "receive"); @@ -404,19 +397,6 @@ ngx_http_lua_inject_socket_tcp_api(ngx_log_t *log, lua_State *L) lua_setfield(L, -2, "__gc"); lua_rawset(L, LUA_REGISTRYINDEX); /* }}} */ - -#if (NGX_HTTP_SSL) - - /* {{{ssl session userdata metatable */ - lua_pushlightuserdata(L, ngx_http_lua_lightudata_mask( - ssl_session_metatable_key)); - lua_createtable(L, 0 /* narr */, 1 /* nrec */); /* metatable */ - lua_pushcfunction(L, ngx_http_lua_ssl_free_session); - lua_setfield(L, -2, "__gc"); - lua_rawset(L, LUA_REGISTRYINDEX); - /* }}} */ - -#endif } @@ -451,7 +431,7 @@ ngx_http_lua_socket_tcp(lua_State *L) ngx_http_lua_check_context(L, ctx, NGX_HTTP_LUA_CONTEXT_YIELDABLE); - lua_createtable(L, 5 /* narr */, 1 /* nrec */); + lua_createtable(L, 7 /* narr */, 1 /* nrec */); lua_pushlightuserdata(L, ngx_http_lua_lightudata_mask( tcp_socket_metatable_key)); lua_rawget(L, LUA_REGISTRYINDEX); @@ -852,6 +832,61 @@ no_memory_and_not_resuming: } +static int +ngx_http_lua_socket_tcp_bind(lua_State *L) +{ + ngx_http_request_t *r; + ngx_http_lua_ctx_t *ctx; + int n; + u_char *text; + size_t len; + ngx_addr_t *local; + + n = lua_gettop(L); + + if (n != 2) { + return luaL_error(L, "expecting 2 arguments, but got %d", + lua_gettop(L)); + } + + r = ngx_http_lua_get_req(L); + if (r == NULL) { + return luaL_error(L, "no request found"); + } + + ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); + if (ctx == NULL) { + return luaL_error(L, "no ctx found"); + } + + ngx_http_lua_check_context(L, ctx, NGX_HTTP_LUA_CONTEXT_REWRITE + | NGX_HTTP_LUA_CONTEXT_ACCESS + | NGX_HTTP_LUA_CONTEXT_CONTENT + | NGX_HTTP_LUA_CONTEXT_TIMER + | NGX_HTTP_LUA_CONTEXT_SSL_CERT); + + luaL_checktype(L, 1, LUA_TTABLE); + + text = (u_char *) luaL_checklstring(L, 2, &len); + + local = ngx_http_lua_parse_addr(L, text, len); + if (local == NULL) { + lua_pushnil(L); + lua_pushfstring(L, "bad address"); + return 2; + } + + /* TODO: we may reuse the userdata here */ + lua_rawseti(L, 1, SOCKET_BIND_INDEX); + + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "lua tcp socket bind ip: %V", &local->name); + + lua_pushboolean(L, 1); + return 1; +} + + static int ngx_http_lua_socket_tcp_connect(lua_State *L) { @@ -863,6 +898,7 @@ ngx_http_lua_socket_tcp_connect(lua_State *L) size_t len; ngx_http_lua_loc_conf_t *llcf; ngx_peer_connection_t *pc; + ngx_addr_t *local; int connect_timeout, send_timeout, read_timeout; unsigned custom_pool; int key_index; @@ -1093,6 +1129,14 @@ ngx_http_lua_socket_tcp_connect(lua_State *L) dd("lua peer connection log: %p", pc->log); + lua_rawgeti(L, 1, SOCKET_BIND_INDEX); + local = lua_touserdata(L, -1); + lua_pop(L, 1); + + if (local) { + u->peer.local = local; + } + lua_rawgeti(L, 1, SOCKET_CONNECT_TIMEOUT_INDEX); lua_rawgeti(L, 1, SOCKET_SEND_TIMEOUT_INDEX); lua_rawgeti(L, 1, SOCKET_READ_TIMEOUT_INDEX); @@ -1559,64 +1603,73 @@ ngx_http_lua_socket_conn_error_retval_handler(ngx_http_request_t *r, #if (NGX_HTTP_SSL) -static int -ngx_http_lua_socket_tcp_sslhandshake(lua_State *L) +static const char * +ngx_http_lua_socket_tcp_check_busy(ngx_http_request_t *r, + ngx_http_lua_socket_tcp_upstream_t *u, unsigned int ops) { - int n, top; - ngx_int_t rc; - ngx_str_t name = ngx_null_string; + if ((ops & SOCKET_OP_CONNECT) && u->conn_waiting) { + return "socket busy connecting"; + } + + if ((ops & SOCKET_OP_READ) && u->read_waiting) { + return "socket busy reading"; + } + + if ((ops & SOCKET_OP_WRITE) + && (u->write_waiting + || (u->raw_downstream + && (r->connection->buffered & NGX_HTTP_LOWLEVEL_BUFFERED)))) + { + return "socket busy writing"; + } + + return NULL; +} + + +int +ngx_http_lua_ffi_socket_tcp_sslhandshake(ngx_http_request_t *r, + ngx_http_lua_socket_tcp_upstream_t *u, ngx_ssl_session_t *sess, + int enable_session_reuse, ngx_str_t *server_name, int verify, + int ocsp_status_req, STACK_OF(X509) *chain, EVP_PKEY *pkey, + const char **errmsg) +{ + ngx_int_t rc, i; ngx_connection_t *c; - ngx_ssl_session_t **psession; - ngx_http_request_t *r; ngx_http_lua_ctx_t *ctx; ngx_http_lua_co_ctx_t *coctx; - - ngx_http_lua_socket_tcp_upstream_t *u; - - /* Lua function arguments: self [,session] [,host] [,verify] - [,send_status_req] */ - - n = lua_gettop(L); - if (n < 1 || n > 5) { - return luaL_error(L, "ngx.socket sslhandshake: expecting 1 ~ 5 " - "arguments (including the object), but seen %d", n); - } - - r = ngx_http_lua_get_req(L); - if (r == NULL) { - return luaL_error(L, "no request found"); - } + const char *busy_msg; + ngx_ssl_conn_t *ssl_conn; + X509 *x509; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "lua tcp socket ssl handshake"); - luaL_checktype(L, 1, LUA_TTABLE); - - lua_rawgeti(L, 1, SOCKET_CTX_INDEX); - u = lua_touserdata(L, -1); - if (u == NULL || u->peer.connection == NULL || u->read_closed || u->write_closed) { - lua_pushnil(L); - lua_pushliteral(L, "closed"); - return 2; + *errmsg = "closed"; + return NGX_ERROR; } if (u->request != r) { - return luaL_error(L, "bad request"); + *errmsg = "bad request"; + return NGX_ERROR; } - ngx_http_lua_socket_check_busy_connecting(r, u, L); - ngx_http_lua_socket_check_busy_reading(r, u, L); - ngx_http_lua_socket_check_busy_writing(r, u, L); + busy_msg = ngx_http_lua_socket_tcp_check_busy(r, u, SOCKET_OP_CONNECT + | SOCKET_OP_READ + | SOCKET_OP_WRITE); + if (busy_msg != NULL) { + *errmsg = busy_msg; + return NGX_ERROR; + } if (u->raw_downstream || u->body_downstream) { - lua_pushnil(L); - lua_pushliteral(L, "not supported for downstream"); - return 2; + *errmsg = "not supported for downstream sockets"; + return NGX_ERROR; } c = u->peer.connection; @@ -1624,122 +1677,140 @@ ngx_http_lua_socket_tcp_sslhandshake(lua_State *L) u->ssl_session_reuse = 1; if (c->ssl && c->ssl->handshaked) { - switch (lua_type(L, 2)) { - case LUA_TUSERDATA: - lua_pushvalue(L, 2); - break; - - case LUA_TBOOLEAN: - if (!lua_toboolean(L, 2)) { - /* avoid generating the ssl session */ - lua_pushboolean(L, 1); - break; - } - /* fall through */ - - default: - ngx_http_lua_ssl_handshake_retval_handler(r, u, L); - break; + if (sess != NULL) { + return NGX_DONE; } - return 1; + u->ssl_session_reuse = enable_session_reuse; + + (void) ngx_http_lua_ssl_handshake_retval_handler(r, u, NULL); + + return NGX_OK; } if (ngx_ssl_create_connection(u->conf->ssl, c, NGX_SSL_BUFFER|NGX_SSL_CLIENT) != NGX_OK) { - lua_pushnil(L); - lua_pushliteral(L, "failed to create ssl connection"); - return 2; + *errmsg = "failed to create ssl connection"; + return NGX_ERROR; } + ssl_conn = c->ssl->connection; + ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); if (ctx == NULL) { - return luaL_error(L, "no ctx found"); + return NGX_HTTP_LUA_FFI_NO_REQ_CTX; } coctx = ctx->cur_co_ctx; c->sendfile = 0; - if (n >= 2) { - if (lua_type(L, 2) == LUA_TBOOLEAN) { - u->ssl_session_reuse = lua_toboolean(L, 2); + if (sess != NULL) { + if (ngx_ssl_set_session(c, sess) != NGX_OK) { + *errmsg = "ssl set session failed"; + return NGX_ERROR; + } - } else { - psession = lua_touserdata(L, 2); + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, + "lua ssl set session: %p", sess); - if (psession != NULL && *psession != NULL) { - if (ngx_ssl_set_session(c, *psession) != NGX_OK) { - lua_pushnil(L); - lua_pushliteral(L, "lua ssl set session failed"); - return 2; - } + } else { + u->ssl_session_reuse = enable_session_reuse; + } - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, - "lua ssl set session: %p", *psession); + if (chain != NULL) { + ngx_http_lua_assert(pkey != NULL); /* ensured by resty.core */ + + if (sk_X509_num(chain) < 1) { + ERR_clear_error(); + *errmsg = "invalid client certificate chain"; + return NGX_ERROR; + } + + x509 = sk_X509_value(chain, 0); + if (x509 == NULL) { + ERR_clear_error(); + *errmsg = "ssl fetch client certificate from chain failed"; + return NGX_ERROR; + } + + if (SSL_use_certificate(ssl_conn, x509) == 0) { + ERR_clear_error(); + *errmsg = "ssl set client certificate failed"; + return NGX_ERROR; + } + + /* read rest of the chain */ + + for (i = 1; i < sk_X509_num(chain); i++) { + x509 = sk_X509_value(chain, i); + if (x509 == NULL) { + ERR_clear_error(); + *errmsg = "ssl fetch client intermediate certificate from " + "chain failed"; + return NGX_ERROR; + } + + if (SSL_add1_chain_cert(ssl_conn, x509) == 0) { + ERR_clear_error(); + *errmsg = "ssl set client intermediate certificate failed"; + return NGX_ERROR; } } - if (n >= 3) { - name.data = (u_char *) lua_tolstring(L, 3, &name.len); - - if (name.data) { - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "lua ssl server name: \"%*s\"", name.len, - name.data); - -#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME - - if (SSL_set_tlsext_host_name(c->ssl->connection, - (char *) name.data) - == 0) - { - lua_pushnil(L); - lua_pushliteral(L, "SSL_set_tlsext_host_name failed"); - return 2; - } - -#else - - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, - "lua socket SNI disabled because the current " - "version of OpenSSL lacks the support"); - -#endif - } - - if (n >= 4) { - u->ssl_verify = lua_toboolean(L, 4); - - if (n >= 5) { - if (lua_toboolean(L, 5)) { -#ifdef NGX_HTTP_LUA_USE_OCSP - SSL_set_tlsext_status_type(c->ssl->connection, - TLSEXT_STATUSTYPE_ocsp); -#else - return luaL_error(L, "no OCSP support"); -#endif - } - } - } + if (SSL_use_PrivateKey(ssl_conn, pkey) == 0) { + ERR_clear_error(); + *errmsg = "ssl set client private key failed"; + return NGX_ERROR; } } - dd("found sni name: %.*s %p", (int) name.len, name.data, name.data); + if (server_name != NULL && server_name->data != NULL) { + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "lua ssl server name: \"%V\"", server_name); - if (name.len == 0) { +#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME + if (SSL_set_tlsext_host_name(c->ssl->connection, + (char *) server_name->data) + == 0) + { + *errmsg = "SSL_set_tlsext_host_name failed"; + return NGX_ERROR; + } + +#else + *errmsg = "no TLS extension support"; + return NGX_ERROR; +#endif + } + + u->ssl_verify = verify; + + if (ocsp_status_req) { +#ifdef NGX_HTTP_LUA_USE_OCSP + SSL_set_tlsext_status_type(c->ssl->connection, + TLSEXT_STATUSTYPE_ocsp); + +#else + *errmsg = "no OCSP support"; + return NGX_ERROR; +#endif + } + + if (server_name == NULL || server_name->len == 0) { u->ssl_name.len = 0; } else { if (u->ssl_name.data) { /* buffer already allocated */ - if (u->ssl_name.len >= name.len) { + if (u->ssl_name.len >= server_name->len) { /* reuse it */ - ngx_memcpy(u->ssl_name.data, name.data, name.len); - u->ssl_name.len = name.len; + ngx_memcpy(u->ssl_name.data, server_name->data, + server_name->len); + u->ssl_name.len = server_name->len; } else { ngx_free(u->ssl_name.data); @@ -1750,17 +1821,15 @@ ngx_http_lua_socket_tcp_sslhandshake(lua_State *L) new_ssl_name: - u->ssl_name.data = ngx_alloc(name.len, ngx_cycle->log); + u->ssl_name.data = ngx_alloc(server_name->len, ngx_cycle->log); if (u->ssl_name.data == NULL) { u->ssl_name.len = 0; - - lua_pushnil(L); - lua_pushliteral(L, "no memory"); - return 2; + *errmsg = "no memory"; + return NGX_ERROR; } - ngx_memcpy(u->ssl_name.data, name.data, name.len); - u->ssl_name.len = name.len; + ngx_memcpy(u->ssl_name.data, server_name->data, server_name->len); + u->ssl_name.len = server_name->len; } } @@ -1774,7 +1843,8 @@ new_ssl_name: rc = ngx_ssl_handshake(c); - dd("ngx_ssl_handshake returned %d", (int) rc); + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "ngx_ssl_handshake returned: %d", rc); if (rc == NGX_AGAIN) { if (c->write->timer_set) { @@ -1799,21 +1869,24 @@ new_ssl_name: r->write_event_handler = ngx_http_core_run_phases; } - return lua_yield(L, 0); + return NGX_AGAIN; } - top = lua_gettop(L); ngx_http_lua_ssl_handshake_handler(c); - return lua_gettop(L) - top; + + if (rc == NGX_ERROR) { + *errmsg = u->error_ret; + return NGX_ERROR; + } + + return NGX_OK; } static void ngx_http_lua_ssl_handshake_handler(ngx_connection_t *c) { - const char *err; int waiting; - lua_State *L; ngx_int_t rc; ngx_connection_t *dc; /* downstream connection */ ngx_http_request_t *r; @@ -1836,11 +1909,9 @@ ngx_http_lua_ssl_handshake_handler(ngx_connection_t *c) waiting = u->conn_waiting; dc = r->connection; - L = u->write_co_ctx->co; if (c->read->timedout) { - lua_pushnil(L); - lua_pushliteral(L, "timeout"); + u->error_ret = "timeout"; goto failed; } @@ -1849,19 +1920,18 @@ ngx_http_lua_ssl_handshake_handler(ngx_connection_t *c) } if (c->ssl->handshaked) { - if (u->ssl_verify) { rc = SSL_get_verify_result(c->ssl->connection); if (rc != X509_V_OK) { - lua_pushnil(L); - err = lua_pushfstring(L, "%d: %s", (int) rc, - X509_verify_cert_error_string(rc)); + u->error_ret = X509_verify_cert_error_string(rc); + u->openssl_error_code_ret = rc; llcf = ngx_http_get_module_loc_conf(r, ngx_http_lua_module); if (llcf->log_socket_errors) { ngx_log_error(NGX_LOG_ERR, dc->log, 0, "lua ssl " - "certificate verify error: (%s)", err); + "certificate verify error: (%d: %s)", + rc, u->error_ret); } goto failed; @@ -1872,8 +1942,7 @@ ngx_http_lua_ssl_handshake_handler(ngx_connection_t *c) if (u->ssl_name.len && ngx_ssl_check_host(c, &u->ssl_name) != NGX_OK) { - lua_pushnil(L); - lua_pushliteral(L, "certificate host mismatch"); + u->error_ret = "certificate host mismatch"; llcf = ngx_http_get_module_loc_conf(r, ngx_http_lua_module); if (llcf->log_socket_errors) { @@ -1892,7 +1961,7 @@ ngx_http_lua_ssl_handshake_handler(ngx_connection_t *c) ngx_http_lua_socket_handle_conn_success(r, u); } else { - (void) ngx_http_lua_ssl_handshake_retval_handler(r, u, L); + (void) ngx_http_lua_ssl_handshake_retval_handler(r, u, NULL); } if (waiting) { @@ -1902,60 +1971,83 @@ ngx_http_lua_ssl_handshake_handler(ngx_connection_t *c) return; } - lua_pushnil(L); - lua_pushliteral(L, "handshake failed"); + u->error_ret = "handshake failed"; failed: if (waiting) { u->write_prepare_retvals = - ngx_http_lua_socket_conn_error_retval_handler; - ngx_http_lua_socket_handle_conn_error(r, u, - NGX_HTTP_LUA_SOCKET_FT_SSL); + ngx_http_lua_socket_conn_error_retval_handler; + ngx_http_lua_socket_handle_conn_error(r, u, NGX_HTTP_LUA_SOCKET_FT_SSL); ngx_http_run_posted_requests(dc); } else { - (void) ngx_http_lua_socket_conn_error_retval_handler(r, u, L); + u->ft_type |= NGX_HTTP_LUA_SOCKET_FT_SSL; + + (void) ngx_http_lua_socket_conn_error_retval_handler(r, u, NULL); } } +int +ngx_http_lua_ffi_socket_tcp_get_sslhandshake_result(ngx_http_request_t *r, + ngx_http_lua_socket_tcp_upstream_t *u, ngx_ssl_session_t **sess, + const char **errmsg, int *openssl_error_code) +{ + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "lua cosocket get SSL handshake result for upstream: %p", u); + + if (u->error_ret != NULL) { + *errmsg = u->error_ret; + *openssl_error_code = u->openssl_error_code_ret; + + return NGX_ERROR; + } + + *sess = u->ssl_session_ret; + + return NGX_OK; +} + + static int ngx_http_lua_ssl_handshake_retval_handler(ngx_http_request_t *r, ngx_http_lua_socket_tcp_upstream_t *u, lua_State *L) { ngx_connection_t *c; - ngx_ssl_session_t *ssl_session, **ud; + ngx_ssl_session_t *ssl_session; if (!u->ssl_session_reuse) { - lua_pushboolean(L, 1); - return 1; + return 0; } - ud = lua_newuserdata(L, sizeof(ngx_ssl_session_t *)); - c = u->peer.connection; ssl_session = ngx_ssl_get_session(c); if (ssl_session == NULL) { - *ud = NULL; + u->ssl_session_ret = NULL; } else { - *ud = ssl_session; + u->ssl_session_ret = ssl_session; ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "lua ssl save session: %p", ssl_session); - - /* set up the __gc metamethod */ - lua_pushlightuserdata(L, ngx_http_lua_lightudata_mask( - ssl_session_metatable_key)); - lua_rawget(L, LUA_REGISTRYINDEX); - lua_setmetatable(L, -2); } - return 1; + return 0; } + +void +ngx_http_lua_ffi_ssl_free_session(ngx_ssl_session_t *sess) +{ + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, + "lua ssl free session: %p", sess); + + ngx_ssl_free_session(sess); +} + + #endif /* NGX_HTTP_SSL */ @@ -2008,12 +2100,14 @@ ngx_http_lua_socket_prepare_error_retvals(ngx_http_request_t *r, u_char errstr[NGX_MAX_ERROR_STR]; u_char *p; - if (ft_type & (NGX_HTTP_LUA_SOCKET_FT_RESOLVER - | NGX_HTTP_LUA_SOCKET_FT_SSL)) - { + if (ft_type & NGX_HTTP_LUA_SOCKET_FT_RESOLVER) { return 2; } + if (ft_type & NGX_HTTP_LUA_SOCKET_FT_SSL) { + return 0; + } + lua_pushnil(L); if (ft_type & NGX_HTTP_LUA_SOCKET_FT_TIMEOUT) { @@ -2441,6 +2535,14 @@ ngx_http_lua_socket_tcp_read(ngx_http_request_t *r, "lua tcp socket read data: wait:%d", (int) u->read_waiting); + /* ngx_shutdown_timer_handler will set c->close and c->error on timeout + * when worker_shutdown_timeout is configured. + * The rev->ready is false at that time, so we need to set u->eof. + */ + if (c->close && c->error) { + u->eof = 1; + } + b = &u->buffer; read = 0; @@ -3363,7 +3465,7 @@ ngx_http_lua_socket_send(ngx_http_request_t *r, ngx_chain_update_chains(r->pool, - &ctx->free_bufs, &ctx->busy_bufs, + &ctx->free_bufs, &u->busy_bufs, &u->request_bufs, (ngx_buf_tag_t) &ngx_http_lua_module); @@ -4642,6 +4744,7 @@ ngx_http_lua_socket_read_until(void *data, ssize_t bytes) u_char c; u_char *pat; size_t pat_len; + size_t pending_len; int i; int state; int old_state = 0; /* just to make old @@ -4770,11 +4873,12 @@ ngx_http_lua_socket_read_until(void *data, ssize_t bytes) /* matched */ - dd("adding pending data: %.*s", (int) (old_state + 1 - state), - (char *) pat); + pending_len = old_state + 1 - state; + + dd("adding pending data: %.*s", (int) pending_len, (char *) pat); rc = ngx_http_lua_socket_add_pending_data(r, u, b->pos, i, pat, - old_state + 1 - state, + pending_len, old_state); if (rc != NGX_OK) { @@ -4785,14 +4889,14 @@ ngx_http_lua_socket_read_until(void *data, ssize_t bytes) i++; if (u->length) { - if (u->rest <= (size_t) state) { + if (u->rest <= pending_len) { u->rest = 0; cp->state = state; b->pos += i; return NGX_OK; } else { - u->rest -= state; + u->rest -= pending_len; } } @@ -4906,6 +5010,7 @@ ngx_http_lua_req_socket(lua_State *L) } ngx_http_lua_check_context(L, ctx, NGX_HTTP_LUA_CONTEXT_REWRITE + | NGX_HTTP_LUA_CONTEXT_SERVER_REWRITE | NGX_HTTP_LUA_CONTEXT_ACCESS | NGX_HTTP_LUA_CONTEXT_CONTENT); @@ -5188,7 +5293,12 @@ ngx_http_lua_socket_tcp_setkeepalive(lua_State *L) pc = &u->peer; c = pc->connection; - if (c == NULL || u->read_closed || u->write_closed) { + /* When the server closes the connection, + * epoll will return EPOLLRDHUP event and nginx will set pending_eof. + */ + if (c == NULL || u->read_closed || u->write_closed + || c->read->eof || c->read->pending_eof) + { lua_pushnil(L); lua_pushliteral(L, "closed"); return 2; @@ -5218,8 +5328,7 @@ ngx_http_lua_socket_tcp_setkeepalive(lua_State *L) return 2; } - if (c->read->eof - || c->read->error + if (c->read->error || c->read->timedout || c->write->error || c->write->timedout) @@ -6101,27 +6210,6 @@ ngx_http_lua_coctx_cleanup(void *data) } -#if (NGX_HTTP_SSL) - -static int -ngx_http_lua_ssl_free_session(lua_State *L) -{ - ngx_ssl_session_t **psession; - - psession = lua_touserdata(L, 1); - if (psession && *psession != NULL) { - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, - "lua ssl free session: %p", *psession); - - ngx_ssl_free_session(*psession); - } - - return 0; -} - -#endif /* NGX_HTTP_SSL */ - - void ngx_http_lua_cleanup_conn_pools(lua_State *L) { diff --git a/src/deps/src/lua-nginx-module/src/ngx_http_lua_socket_tcp.h b/src/deps/src/lua-nginx-module/src/ngx_http_lua_socket_tcp.h index a0a5a5181..0cc664153 100644 --- a/src/deps/src/lua-nginx-module/src/ngx_http_lua_socket_tcp.h +++ b/src/deps/src/lua-nginx-module/src/ngx_http_lua_socket_tcp.h @@ -120,8 +120,13 @@ struct ngx_http_lua_socket_tcp_upstream_s { #if (NGX_HTTP_SSL) ngx_str_t ssl_name; + ngx_ssl_session_t *ssl_session_ret; + const char *error_ret; + int openssl_error_code_ret; #endif + ngx_chain_t *busy_bufs; + unsigned ft_type:16; unsigned no_close:1; unsigned conn_waiting:1; diff --git a/src/deps/src/lua-nginx-module/src/ngx_http_lua_socket_udp.c b/src/deps/src/lua-nginx-module/src/ngx_http_lua_socket_udp.c index 4f970e6cc..cbb6621b4 100644 --- a/src/deps/src/lua-nginx-module/src/ngx_http_lua_socket_udp.c +++ b/src/deps/src/lua-nginx-module/src/ngx_http_lua_socket_udp.c @@ -24,7 +24,7 @@ #endif -#define UDP_MAX_DATAGRAM_SIZE 8192 +#define UDP_MAX_DATAGRAM_SIZE 65536 static int ngx_http_lua_socket_udp(lua_State *L); diff --git a/src/deps/src/lua-nginx-module/src/ngx_http_lua_ssl_certby.c b/src/deps/src/lua-nginx-module/src/ngx_http_lua_ssl_certby.c index b561122b1..0499bfb35 100644 --- a/src/deps/src/lua-nginx-module/src/ngx_http_lua_ssl_certby.c +++ b/src/deps/src/lua-nginx-module/src/ngx_http_lua_ssl_certby.c @@ -70,7 +70,8 @@ ngx_http_lua_ssl_cert_handler_inline(ngx_http_request_t *r, lscf->srv.ssl_cert_src.len, &lscf->srv.ssl_cert_src_ref, lscf->srv.ssl_cert_src_key, - "=ssl_certificate_by_lua"); + (const char *) + lscf->srv.ssl_cert_chunkname); if (rc != NGX_OK) { return rc; } @@ -115,6 +116,8 @@ ngx_http_lua_ssl_cert_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, #else + size_t chunkname_len; + u_char *chunkname; u_char *cache_key = NULL; u_char *name; ngx_str_t *value; @@ -163,8 +166,15 @@ ngx_http_lua_ssl_cert_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, return NGX_CONF_ERROR; } + chunkname = ngx_http_lua_gen_chunk_name(cf, "ssl_certificate_by_lua", + sizeof("ssl_certificate_by_lua") - 1, &chunkname_len); + if (chunkname == NULL) { + return NGX_CONF_ERROR; + } + /* Don't eval nginx variables for inline lua code */ lscf->srv.ssl_cert_src = value[1]; + lscf->srv.ssl_cert_chunkname = chunkname; } lscf->srv.ssl_cert_src_key = cache_key; @@ -1042,7 +1052,7 @@ ngx_http_lua_ffi_cert_pem_to_der(const u_char *pem, size_t pem_len, u_char *der, int ngx_http_lua_ffi_priv_key_pem_to_der(const u_char *pem, size_t pem_len, - u_char *der, char **err) + const u_char *passphrase, u_char *der, char **err) { int len; BIO *in; @@ -1055,7 +1065,7 @@ ngx_http_lua_ffi_priv_key_pem_to_der(const u_char *pem, size_t pem_len, return NGX_ERROR; } - pkey = PEM_read_bio_PrivateKey(in, NULL, NULL, NULL); + pkey = PEM_read_bio_PrivateKey(in, NULL, NULL, (void *) passphrase); if (pkey == NULL) { BIO_free(in); *err = "PEM_read_bio_PrivateKey() failed"; @@ -1479,4 +1489,15 @@ failed: } +ngx_ssl_conn_t * +ngx_http_lua_ffi_get_req_ssl_pointer(ngx_http_request_t *r) +{ + if (r->connection == NULL || r->connection->ssl == NULL) { + return NULL; + } + + return r->connection->ssl->connection; +} + + #endif /* NGX_HTTP_SSL */ diff --git a/src/deps/src/lua-nginx-module/src/ngx_http_lua_ssl_client_helloby.c b/src/deps/src/lua-nginx-module/src/ngx_http_lua_ssl_client_helloby.c index a65b6e88f..10500d89e 100644 --- a/src/deps/src/lua-nginx-module/src/ngx_http_lua_ssl_client_helloby.c +++ b/src/deps/src/lua-nginx-module/src/ngx_http_lua_ssl_client_helloby.c @@ -61,7 +61,7 @@ ngx_http_lua_ssl_client_hello_handler_inline(ngx_http_request_t *r, lscf->srv.ssl_client_hello_src.len, &lscf->srv.ssl_client_hello_src_ref, lscf->srv.ssl_client_hello_src_key, - "=ssl_client_hello_by_lua"); + (const char *) lscf->srv.ssl_client_hello_chunkname); if (rc != NGX_OK) { return rc; } @@ -106,6 +106,8 @@ ngx_http_lua_ssl_client_hello_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, #else + size_t chunkname_len; + u_char *chunkname; u_char *cache_key = NULL; u_char *name; ngx_str_t *value; @@ -154,9 +156,16 @@ ngx_http_lua_ssl_client_hello_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, return NGX_CONF_ERROR; } + chunkname = ngx_http_lua_gen_chunk_name(cf, "ssl_client_hello_by_lua", + sizeof("ssl_client_helloo_by_lua")- 1, + &chunkname_len); + if (chunkname == NULL) { + return NGX_CONF_ERROR; + } + /* Don't eval nginx variables for inline lua code */ lscf->srv.ssl_client_hello_src = value[1]; - + lscf->srv.ssl_client_hello_chunkname = chunkname; } lscf->srv.ssl_client_hello_src_key = cache_key; diff --git a/src/deps/src/lua-nginx-module/src/ngx_http_lua_ssl_session_fetchby.c b/src/deps/src/lua-nginx-module/src/ngx_http_lua_ssl_session_fetchby.c index 6584e6ab5..66e984855 100644 --- a/src/deps/src/lua-nginx-module/src/ngx_http_lua_ssl_session_fetchby.c +++ b/src/deps/src/lua-nginx-module/src/ngx_http_lua_ssl_session_fetchby.c @@ -66,7 +66,7 @@ ngx_http_lua_ssl_sess_fetch_handler_inline(ngx_http_request_t *r, lscf->srv.ssl_sess_fetch_src.len, &lscf->srv.ssl_sess_fetch_src_ref, lscf->srv.ssl_sess_fetch_src_key, - "=ssl_session_fetch_by_lua_block"); + (const char *) lscf->srv.ssl_sess_fetch_chunkname); if (rc != NGX_OK) { return rc; } @@ -102,6 +102,8 @@ char * ngx_http_lua_ssl_sess_fetch_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { + size_t chunkname_len; + u_char *chunkname; u_char *cache_key = NULL; u_char *name; ngx_str_t *value; @@ -153,8 +155,15 @@ ngx_http_lua_ssl_sess_fetch_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, return NGX_CONF_ERROR; } + chunkname = ngx_http_lua_gen_chunk_name(cf, "ssl_session_fetch_by_lua", + sizeof("ssl_session_fetch_by_lua") - 1, &chunkname_len); + if (chunkname == NULL) { + return NGX_CONF_ERROR; + } + /* Don't eval nginx variables for inline lua code */ lscf->srv.ssl_sess_fetch_src = value[1]; + lscf->srv.ssl_sess_fetch_chunkname = chunkname; } lscf->srv.ssl_sess_fetch_src_key = cache_key; diff --git a/src/deps/src/lua-nginx-module/src/ngx_http_lua_ssl_session_storeby.c b/src/deps/src/lua-nginx-module/src/ngx_http_lua_ssl_session_storeby.c index 0654d9371..b25cbcc2c 100644 --- a/src/deps/src/lua-nginx-module/src/ngx_http_lua_ssl_session_storeby.c +++ b/src/deps/src/lua-nginx-module/src/ngx_http_lua_ssl_session_storeby.c @@ -64,7 +64,7 @@ ngx_http_lua_ssl_sess_store_handler_inline(ngx_http_request_t *r, lscf->srv.ssl_sess_store_src.len, &lscf->srv.ssl_sess_store_src_ref, lscf->srv.ssl_sess_store_src_key, - "=ssl_session_store_by_lua_block"); + (const char *) lscf->srv.ssl_sess_store_chunkname); if (rc != NGX_OK) { return rc; } @@ -100,6 +100,8 @@ char * ngx_http_lua_ssl_sess_store_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { + size_t chunkname_len; + u_char *chunkname; u_char *cache_key = NULL; u_char *name; ngx_str_t *value; @@ -151,8 +153,15 @@ ngx_http_lua_ssl_sess_store_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, return NGX_CONF_ERROR; } + chunkname = ngx_http_lua_gen_chunk_name(cf, "ssl_session_store_by_lua", + sizeof("ssl_session_store_by_lua") - 1, &chunkname_len); + if (chunkname == NULL) { + return NGX_CONF_ERROR; + } + /* Don't eval nginx variables for inline lua code */ lscf->srv.ssl_sess_store_src = value[1]; + lscf->srv.ssl_sess_store_chunkname = chunkname; } lscf->srv.ssl_sess_store_src_key = cache_key; diff --git a/src/deps/src/lua-nginx-module/src/ngx_http_lua_time.c b/src/deps/src/lua-nginx-module/src/ngx_http_lua_time.c index 61324f37a..72704b23a 100644 --- a/src/deps/src/lua-nginx-module/src/ngx_http_lua_time.c +++ b/src/deps/src/lua-nginx-module/src/ngx_http_lua_time.c @@ -39,6 +39,13 @@ ngx_http_lua_ffi_time(void) } +long +ngx_http_lua_ffi_monotonic_msec(void) +{ + return (long) ngx_current_msec; +} + + void ngx_http_lua_ffi_update_time(void) { diff --git a/src/deps/src/lua-nginx-module/src/ngx_http_lua_timer.c b/src/deps/src/lua-nginx-module/src/ngx_http_lua_timer.c index e82e3406c..060cab543 100644 --- a/src/deps/src/lua-nginx-module/src/ngx_http_lua_timer.c +++ b/src/deps/src/lua-nginx-module/src/ngx_http_lua_timer.c @@ -565,6 +565,8 @@ ngx_http_lua_timer_handler(ngx_event_t *ev) c = ngx_http_lua_create_fake_connection(tctx.pool); if (c == NULL) { errmsg = "could not create fake connection"; + /* tctx.pool is freed in ngx_http_lua_create_fake_connection */ + tctx.pool = NULL; goto failed; } @@ -821,7 +823,7 @@ ngx_http_lua_abort_pending_timers(ngx_event_t *ev) prev = NULL; events = ngx_pcalloc(ngx_cycle->pool, - lmcf->pending_timers * sizeof(ngx_event_t)); + lmcf->pending_timers * sizeof(ngx_event_t *)); if (events == NULL) { return; } diff --git a/src/deps/src/lua-nginx-module/src/ngx_http_lua_uri.c b/src/deps/src/lua-nginx-module/src/ngx_http_lua_uri.c index 0f88846fe..c4d65f290 100644 --- a/src/deps/src/lua-nginx-module/src/ngx_http_lua_uri.c +++ b/src/deps/src/lua-nginx-module/src/ngx_http_lua_uri.c @@ -92,12 +92,14 @@ ngx_http_lua_ngx_req_set_uri(lua_State *L) return luaL_error(L, "no ctx found"); } - dd("rewrite: %d, access: %d, content: %d", + dd("server_rewrite: %d, rewrite: %d, access: %d, content: %d", + (int) ctx->entered_server_rewrite_phase, (int) ctx->entered_rewrite_phase, (int) ctx->entered_access_phase, (int) ctx->entered_content_phase); - ngx_http_lua_check_context(L, ctx, NGX_HTTP_LUA_CONTEXT_REWRITE); + ngx_http_lua_check_context(L, ctx, NGX_HTTP_LUA_CONTEXT_REWRITE + | NGX_HTTP_LUA_CONTEXT_SERVER_REWRITE); ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "lua set uri jump to \"%*s\"", len, p); diff --git a/src/deps/src/lua-nginx-module/src/ngx_http_lua_uthread.c b/src/deps/src/lua-nginx-module/src/ngx_http_lua_uthread.c index d30ffb404..2208b2a81 100644 --- a/src/deps/src/lua-nginx-module/src/ngx_http_lua_uthread.c +++ b/src/deps/src/lua-nginx-module/src/ngx_http_lua_uthread.c @@ -125,6 +125,9 @@ ngx_http_lua_uthread_wait(lua_State *L) coctx = ctx->cur_co_ctx; nargs = lua_gettop(L); + if (nargs == 0) { + return luaL_error(L, "at least one coroutine should be specified"); + } for (i = 1; i <= nargs; i++) { sub_co = lua_tothread(L, i); diff --git a/src/deps/src/lua-nginx-module/src/ngx_http_lua_util.c b/src/deps/src/lua-nginx-module/src/ngx_http_lua_util.c index bae59daf3..8fd26561a 100644 --- a/src/deps/src/lua-nginx-module/src/ngx_http_lua_util.c +++ b/src/deps/src/lua-nginx-module/src/ngx_http_lua_util.c @@ -119,7 +119,6 @@ static int ngx_http_lua_thread_traceback(lua_State *L, lua_State *co, static void ngx_http_lua_inject_ngx_api(lua_State *L, ngx_http_lua_main_conf_t *lmcf, ngx_log_t *log); static void ngx_http_lua_inject_arg_api(lua_State *L); -static int ngx_http_lua_param_get(lua_State *L); static int ngx_http_lua_param_set(lua_State *L); static ngx_int_t ngx_http_lua_output_filter(ngx_http_request_t *r, ngx_chain_t *in); @@ -281,7 +280,6 @@ ngx_http_lua_new_state(lua_State *parent_vm, ngx_cycle_t *cycle, lua_pushliteral(L, LUA_DEFAULT_CPATH ";"); /* package default */ lua_getfield(L, -2, "cpath"); /* package default old */ - old_cpath = lua_tolstring(L, -1, &old_cpath_len); lua_concat(L, 2); /* package new */ lua_setfield(L, -2, "cpath"); /* package */ #endif @@ -827,7 +825,7 @@ static void ngx_http_lua_inject_ngx_api(lua_State *L, ngx_http_lua_main_conf_t *lmcf, ngx_log_t *log) { - lua_createtable(L, 0 /* narr */, 113 /* nrec */); /* ngx.* */ + lua_createtable(L, 0 /* narr */, 115 /* nrec */); /* ngx.* */ lua_pushcfunction(L, ngx_http_lua_get_raw_phase_context); lua_setfield(L, -2, "_phase_ctx"); @@ -1005,6 +1003,7 @@ ngx_http_lua_reset_ctx(ngx_http_request_t *r, lua_State *L, ctx->entry_co_ctx.co_ref = LUA_NOREF; + ctx->entered_server_rewrite_phase = 0; ctx->entered_rewrite_phase = 0; ctx->entered_access_phase = 0; ctx->entered_content_phase = 0; @@ -3100,9 +3099,6 @@ ngx_http_lua_inject_arg_api(lua_State *L) lua_createtable(L, 0 /* narr */, 2 /* nrec */); /* the metatable */ - lua_pushcfunction(L, ngx_http_lua_param_get); - lua_setfield(L, -2, "__index"); - lua_pushcfunction(L, ngx_http_lua_param_set); lua_setfield(L, -2, "__newindex"); @@ -3114,35 +3110,6 @@ ngx_http_lua_inject_arg_api(lua_State *L) } -static int -ngx_http_lua_param_get(lua_State *L) -{ - ngx_http_lua_ctx_t *ctx; - ngx_http_request_t *r; - - r = ngx_http_lua_get_req(L); - if (r == NULL) { - return 0; - } - - ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); - if (ctx == NULL) { - return luaL_error(L, "ctx not found"); - } - - ngx_http_lua_check_context(L, ctx, NGX_HTTP_LUA_CONTEXT_SET - | NGX_HTTP_LUA_CONTEXT_BODY_FILTER); - - if (ctx->context & (NGX_HTTP_LUA_CONTEXT_SET)) { - return ngx_http_lua_setby_param_get(L, r); - } - - /* ctx->context & (NGX_HTTP_LUA_CONTEXT_BODY_FILTER) */ - - return ngx_http_lua_body_filter_param_get(L, r); -} - - static int ngx_http_lua_param_set(lua_State *L) { @@ -4429,4 +4396,77 @@ ngx_http_lua_copy_escaped_header(ngx_http_request_t *r, return NGX_OK; } + +ngx_addr_t * +ngx_http_lua_parse_addr(lua_State *L, u_char *text, size_t len) +{ + ngx_addr_t *addr; + size_t socklen; + in_addr_t inaddr; + ngx_uint_t family; + struct sockaddr_in *sin; +#if (NGX_HAVE_INET6) + struct in6_addr inaddr6; + struct sockaddr_in6 *sin6; + + /* + * prevent MSVC8 warning: + * potentially uninitialized local variable 'inaddr6' used + */ + ngx_memzero(&inaddr6, sizeof(struct in6_addr)); +#endif + + inaddr = ngx_inet_addr(text, len); + + if (inaddr != INADDR_NONE) { + family = AF_INET; + socklen = sizeof(struct sockaddr_in); + +#if (NGX_HAVE_INET6) + + } else if (ngx_inet6_addr(text, len, inaddr6.s6_addr) == NGX_OK) { + family = AF_INET6; + socklen = sizeof(struct sockaddr_in6); +#endif + + } else { + return NULL; + } + + addr = lua_newuserdata(L, sizeof(ngx_addr_t) + socklen + len); + if (addr == NULL) { + luaL_error(L, "no memory"); + return NULL; + } + + addr->sockaddr = (struct sockaddr *) ((u_char *) addr + sizeof(ngx_addr_t)); + + ngx_memzero(addr->sockaddr, socklen); + + addr->sockaddr->sa_family = (u_char) family; + addr->socklen = socklen; + + switch (family) { + +#if (NGX_HAVE_INET6) + case AF_INET6: + sin6 = (struct sockaddr_in6 *) addr->sockaddr; + ngx_memcpy(sin6->sin6_addr.s6_addr, inaddr6.s6_addr, 16); + break; +#endif + + default: /* AF_INET */ + sin = (struct sockaddr_in *) addr->sockaddr; + sin->sin_addr.s_addr = inaddr; + break; + } + + addr->name.data = (u_char *) addr->sockaddr + socklen; + addr->name.len = len; + ngx_memcpy(addr->name.data, text, len); + + return addr; +} + + /* vi:set ft=c ts=4 sw=4 et fdm=marker: */ diff --git a/src/deps/src/lua-nginx-module/src/ngx_http_lua_util.h b/src/deps/src/lua-nginx-module/src/ngx_http_lua_util.h index 348a8666a..faea7a072 100644 --- a/src/deps/src/lua-nginx-module/src/ngx_http_lua_util.h +++ b/src/deps/src/lua-nginx-module/src/ngx_http_lua_util.h @@ -33,6 +33,7 @@ #define NGX_HTTP_LUA_ESCAPE_HEADER_VALUE 8 #define NGX_HTTP_LUA_CONTEXT_YIELDABLE (NGX_HTTP_LUA_CONTEXT_REWRITE \ + | NGX_HTTP_LUA_CONTEXT_SERVER_REWRITE \ | NGX_HTTP_LUA_CONTEXT_ACCESS \ | NGX_HTTP_LUA_CONTEXT_CONTENT \ | NGX_HTTP_LUA_CONTEXT_TIMER \ @@ -48,6 +49,7 @@ #define ngx_http_lua_context_name(c) \ ((c) == NGX_HTTP_LUA_CONTEXT_SET ? "set_by_lua*" \ : (c) == NGX_HTTP_LUA_CONTEXT_REWRITE ? "rewrite_by_lua*" \ + : (c) == NGX_HTTP_LUA_CONTEXT_SERVER_REWRITE ? "server_rewrite_by_lua*" \ : (c) == NGX_HTTP_LUA_CONTEXT_ACCESS ? "access_by_lua*" \ : (c) == NGX_HTTP_LUA_CONTEXT_CONTENT ? "content_by_lua*" \ : (c) == NGX_HTTP_LUA_CONTEXT_LOG ? "log_by_lua*" \ @@ -260,6 +262,8 @@ void ngx_http_lua_cleanup_free(ngx_http_request_t *r, void ngx_http_lua_set_sa_restart(ngx_log_t *log); #endif +ngx_addr_t *ngx_http_lua_parse_addr(lua_State *L, u_char *text, size_t len); + size_t ngx_http_lua_escape_log(u_char *dst, u_char *src, size_t size); @@ -564,7 +568,7 @@ ngx_http_lua_free_thread(ngx_http_request_t *r, lua_State *L, int co_ref, { #ifdef HAVE_LUA_RESETTHREAD ngx_queue_t *q; - ngx_http_lua_thread_ref_t *tref ; + ngx_http_lua_thread_ref_t *tref; ngx_http_lua_ctx_t *ctx; ngx_log_debug2(NGX_LOG_DEBUG_HTTP, @@ -685,6 +689,43 @@ ngx_http_lua_new_cached_thread(lua_State *L, lua_State **out_co, } +static ngx_inline void * +ngx_http_lua_hash_find_lc(ngx_hash_t *hash, ngx_uint_t key, u_char *name, + size_t len) +{ + ngx_uint_t i; + ngx_hash_elt_t *elt; + + elt = hash->buckets[key % hash->size]; + + if (elt == NULL) { + return NULL; + } + + while (elt->value) { + if (len != (size_t) elt->len) { + goto next; + } + + for (i = 0; i < len; i++) { + if (ngx_tolower(name[i]) != elt->name[i]) { + goto next; + } + } + + return elt->value; + + next: + + elt = (ngx_hash_elt_t *) ngx_align_ptr(&elt->name[0] + elt->len, + sizeof(void *)); + continue; + } + + return NULL; +} + + extern ngx_uint_t ngx_http_lua_location_hash; extern ngx_uint_t ngx_http_lua_content_length_hash; diff --git a/src/deps/src/lua-nginx-module/src/ngx_http_lua_worker.c b/src/deps/src/lua-nginx-module/src/ngx_http_lua_worker.c index 0ca2d414e..52ec34a84 100644 --- a/src/deps/src/lua-nginx-module/src/ngx_http_lua_worker.c +++ b/src/deps/src/lua-nginx-module/src/ngx_http_lua_worker.c @@ -8,6 +8,7 @@ #define DDEBUG 0 #endif #include "ddebug.h" +#include #define NGX_PROCESS_PRIVILEGED_AGENT 99 @@ -20,6 +21,36 @@ ngx_http_lua_ffi_worker_pid(void) } +int +ngx_http_lua_ffi_worker_pids(int *pids, size_t *pids_len) +{ + ngx_int_t i, n; + + n = 0; + for (i = 0; i < NGX_MAX_PROCESSES; i++) { + if (i != ngx_process_slot && ngx_processes[i].pid == 0) { + break; + } + + if (i == ngx_process_slot && ngx_processes[i].pid == 0) { + pids[n++] = ngx_pid; + } + + if (ngx_processes[i].pid > 0) { + pids[n++] = ngx_processes[i].pid; + } + } + + if (n == 0) { + return NGX_ERROR; + } + + *pids_len = n; + + return NGX_OK; +} + + int ngx_http_lua_ffi_worker_id(void) { diff --git a/src/deps/src/lua-nginx-module/src/ngx_http_lua_worker_thread.c b/src/deps/src/lua-nginx-module/src/ngx_http_lua_worker_thread.c index 5f785ffb2..ed7b08929 100644 --- a/src/deps/src/lua-nginx-module/src/ngx_http_lua_worker_thread.c +++ b/src/deps/src/lua-nginx-module/src/ngx_http_lua_worker_thread.c @@ -16,7 +16,12 @@ #include "ngx_http_lua_util.h" #include "ngx_http_lua_string.h" #include "ngx_http_lua_config.h" +#include "ngx_http_lua_shdict.h" +#ifndef STRINGIFY +#define TOSTRING(x) #x +#define STRINGIFY(x) TOSTRING(x) +#endif #if (NGX_THREADS) @@ -24,6 +29,7 @@ #include #include +#define LUA_COPY_MAX_DEPTH 100 typedef struct ngx_http_lua_task_ctx_s { lua_State *vm; @@ -139,14 +145,16 @@ ngx_http_lua_get_task_ctx(lua_State *L, ngx_http_request_t *r) lua_setfield(vm, -2, "path"); lua_pushlstring(vm, cpath, cpath_len); lua_setfield(vm, -2, "cpath"); + lua_pop(vm, 1); /* pop path, cpath and "package" table from L */ lua_pop(L, 3); /* inject API from C */ - lua_newtable(L); /* ngx.* */ + lua_newtable(vm); /* ngx.* */ ngx_http_lua_inject_string_api(vm); ngx_http_lua_inject_config_api(vm); + ngx_http_lua_inject_shdict_api(lmcf, vm); lua_setglobal(vm, "ngx"); /* inject API via ffi */ @@ -174,6 +182,14 @@ ngx_http_lua_get_task_ctx(lua_State *L, ngx_http_request_t *r) return NULL; } + lua_getglobal(vm, "require"); + lua_pushstring(vm, "resty.core.shdict"); + if (lua_pcall(vm, 1, 0, 0) != 0) { + lua_close(vm); + ngx_free(ctx); + return NULL; + } + } else { ctx = ctxpool->next; ctxpool->next = ctx->next; @@ -197,7 +213,7 @@ ngx_http_lua_free_task_ctx(ngx_http_lua_task_ctx_t *ctx) static int ngx_http_lua_xcopy(lua_State *from, lua_State *to, int idx, - const int allow_nil) + const int allow_nil, const int depth, const char **err) { size_t len = 0; const char *str; @@ -224,6 +240,13 @@ ngx_http_lua_xcopy(lua_State *from, lua_State *to, int idx, return LUA_TSTRING; case LUA_TTABLE: + if (depth >= LUA_COPY_MAX_DEPTH) { + *err = "suspicious circular references, " + "table depth exceed max depth: " + STRINGIFY(LUA_COPY_MAX_DEPTH); + return LUA_TNONE; + } + top_from = lua_gettop(from); top_to = lua_gettop(to); @@ -237,8 +260,9 @@ ngx_http_lua_xcopy(lua_State *from, lua_State *to, int idx, lua_pushnil(from); while (lua_next(from, idx) != 0) { - if (ngx_http_lua_xcopy(from, to, -2, 0) != LUA_TNONE - && ngx_http_lua_xcopy(from, to, -1, 0) != LUA_TNONE) + if (ngx_http_lua_xcopy(from, to, -2, 0, depth + 1, err) != LUA_TNONE + && ngx_http_lua_xcopy(from, to, -1, 0, + depth + 1, err) != LUA_TNONE) { lua_rawset(to, -3); @@ -258,16 +282,24 @@ ngx_http_lua_xcopy(lua_State *from, lua_State *to, int idx, lua_pushnil(to); return LUA_TNIL; } - /* fall through */ - /* - * ignore unsupported values: - * LUA_TNONE - * LUA_TFUNCTION - * LUA_TUSERDATA - * LUA_TTHREAD - */ + *err = "unsupported Lua type: LUA_TNIL"; + return LUA_TNONE; + + case LUA_TFUNCTION: + *err = "unsupported Lua type: LUA_TFUNCTION"; + return LUA_TNONE; + + case LUA_TUSERDATA: + *err = "unsupported Lua type: LUA_TUSERDATA"; + return LUA_TNONE; + + case LUA_TTHREAD: + *err = "unsupported Lua type: LUA_TTHREAD"; + return LUA_TNONE; + default: + *err = "unsupported Lua type"; return LUA_TNONE; } } @@ -346,6 +378,7 @@ ngx_http_lua_worker_thread_event_handler(ngx_event_t *ev) ngx_http_lua_ctx_t *ctx; lua_State *vm; int saved_top; + const char *err; worker_thread_ctx = ev->data; @@ -381,10 +414,12 @@ ngx_http_lua_worker_thread_event_handler(ngx_event_t *ev) lua_pushboolean(L, 1); nresults = lua_gettop(vm) + 1; for (i = 1; i < nresults; i++) { - if (ngx_http_lua_xcopy(vm, L, i, 1) == LUA_TNONE) { + err = NULL; + if (ngx_http_lua_xcopy(vm, L, i, 1, 1, &err) == LUA_TNONE) { lua_settop(L, saved_top); lua_pushboolean(L, 0); - lua_pushstring(L, "unsupported return value"); + lua_pushfstring(L, "%s in the return value", + err != NULL ? err : "unsupoorted Lua type"); nresults = 2; break; } @@ -546,9 +581,11 @@ ngx_http_lua_run_worker_thread(lua_State *L) /* copying passed arguments */ for (i = 4; i <= n_args; i++) { - if (ngx_http_lua_xcopy(L, vm, i, 1) == LUA_TNONE) { + err = NULL; + if (ngx_http_lua_xcopy(L, vm, i, 1, 1, &err) == LUA_TNONE) { lua_pushboolean(L, 0); - lua_pushstring(L, "unsupported argument type"); + lua_pushfstring(L, "%s in the argument", + err != NULL ? err : "unsupoorted Lua type"); ngx_http_lua_free_task_ctx(tctx); return 2; } diff --git a/src/deps/src/lua-nginx-module/t/001-set.t b/src/deps/src/lua-nginx-module/t/001-set.t index 62dec1a7f..db18f0258 100644 --- a/src/deps/src/lua-nginx-module/t/001-set.t +++ b/src/deps/src/lua-nginx-module/t/001-set.t @@ -573,7 +573,7 @@ GET /lua --- response_body_like: 500 Internal Server Error --- error_code: 500 --- error_log -failed to run set_by_lua*: set_by_lua:1: Bad +failed to run set_by_lua*: set_by_lua(nginx.conf:40):1: Bad diff --git a/src/deps/src/lua-nginx-module/t/002-content.t b/src/deps/src/lua-nginx-module/t/002-content.t index d6a360044..54de40ebd 100644 --- a/src/deps/src/lua-nginx-module/t/002-content.t +++ b/src/deps/src/lua-nginx-module/t/002-content.t @@ -10,7 +10,7 @@ use Test::Nginx::Socket::Lua; repeat_each(2); #repeat_each(1); -plan tests => repeat_each() * (blocks() * 2 + 24); +plan tests => repeat_each() * (blocks() * 2 + 32); #no_diff(); #no_long_string(); @@ -849,4 +849,252 @@ GET /lua --- response_body_like: 500 Internal Server Error --- error_code: 500 --- error_log eval -qr/failed to load inlined Lua code: / +qr/failed to load inlined Lua code: content_by_lua\(nginx.conf:40\)/ + + + +=== TEST 43: syntax error in content_by_lua_block +--- config + location /lua { + + content_by_lua_block { + 'for end'; + } + } +--- request +GET /lua +--- response_body_like: 500 Internal Server Error +--- error_code: 500 +--- error_log eval +qr/failed to load inlined Lua code: content_by_lua\(nginx.conf:41\)/ + + + +=== TEST 44: syntax error in second content_by_lua_block +--- config + location /foo { + content_by_lua_block { + 'for end'; + } + } + + location /lua { + content_by_lua_block { + 'for end'; + } + } +--- request +GET /lua +--- response_body_like: 500 Internal Server Error +--- error_code: 500 +--- error_log eval +qr/failed to load inlined Lua code: content_by_lua\(nginx.conf:46\)/ + + + +=== TEST 45: syntax error in thrid content_by_lua_block +--- config + location /foo { + content_by_lua_block { + 'for end'; + } + } + + location /bar { + content_by_lua_block { + 'for end'; + } + } + + location /lua { + content_by_lua_block { + 'for end'; + } + } +--- request +GET /lua +--- response_body_like: 500 Internal Server Error +--- error_code: 500 +--- error_log eval +qr/failed to load inlined Lua code: content_by_lua\(nginx.conf:52\)/ + + + +=== TEST 46: syntax error in included file +--- config + location /foo { + content_by_lua_block { + 'for end'; + } + } + + location /bar { + content_by_lua_block { + 'for end'; + } + } + + include ../html/lua.conf; +--- user_files +>>> lua.conf + location /lua { + content_by_lua_block { + 'for end'; + } + } +--- request +GET /lua +--- response_body_like: 500 Internal Server Error +--- error_code: 500 +--- error_log +failed to load inlined Lua code: content_by_lua(../html/lua.conf:2):2: unexpected symbol near ''for end'' + + + +=== TEST 47: syntax error with very long filename +--- config + location /foo { + content_by_lua_block { + 'for end'; + } + } + + location /bar { + content_by_lua_block { + 'for end'; + } + } + + include ../html/1234567890123456789012345678901234.conf; +--- user_files +>>> 1234567890123456789012345678901234.conf + location /lua { + content_by_lua_block { + 'for end'; + } + } +--- request +GET /lua +--- response_body_like: 500 Internal Server Error +--- error_code: 500 +--- error_log +failed to load inlined Lua code: content_by_lua(...234567890123456789012345678901234.conf:2) + + + +=== TEST 48: syntax error in /tmp/lua.conf +--- config + location /foo { + content_by_lua_block { + 'for end'; + } + } + + location /bar { + content_by_lua_block { + 'for end'; + } + } + + include /tmp/lua.conf; +--- user_files +>>> /tmp/lua.conf + location /lua { + content_by_lua_block { + 'for end'; + } + } +--- request +GET /lua +--- response_body_like: 500 Internal Server Error +--- error_code: 500 +--- error_log +failed to load inlined Lua code: content_by_lua(/tmp/lua.conf:2) + + + +=== TEST 49: syntax error in /tmp/12345678901234567890123456789012345.conf +--- config + location /foo { + content_by_lua_block { + 'for end'; + } + } + + location /bar { + content_by_lua_block { + 'for end'; + } + } + + include /tmp/12345678901234567890123456789012345.conf; + +--- user_files +>>> /tmp/12345678901234567890123456789012345.conf + location /lua { + content_by_lua_block { + 'for end'; + } + } +--- request +GET /lua +--- response_body_like: 500 Internal Server Error +--- error_code: 500 +--- error_log +failed to load inlined Lua code: content_by_lua(...345678901234567890123456789012345.conf:2) + + + +=== TEST 50: the error line number greater than 9 +--- config + location /foo { + content_by_lua_block { + 'for end'; + } + } + + location /bar { + content_by_lua_block { + 'for end'; + } + } + + include /tmp/12345678901234567890123456789012345.conf; + +--- user_files +>>> /tmp/12345678901234567890123456789012345.conf + location /lua { + + + + + + + + + + + + + content_by_lua_block { + 'for end'; + } + } +--- request +GET /lua +--- response_body_like: 500 Internal Server Error +--- error_code: 500 +--- error_log +failed to load inlined Lua code: content_by_lua(...45678901234567890123456789012345.conf:14) + + + +=== TEST 51: Lua file permission denied +--- config + location /lua { + content_by_lua_file /etc/shadow; + } +--- request +GET /lua +--- response_body_like: 503 Service Temporarily Unavailable +--- error_code: 503 diff --git a/src/deps/src/lua-nginx-module/t/005-exit.t b/src/deps/src/lua-nginx-module/t/005-exit.t index ef4e0f303..eb123bd17 100644 --- a/src/deps/src/lua-nginx-module/t/005-exit.t +++ b/src/deps/src/lua-nginx-module/t/005-exit.t @@ -724,3 +724,98 @@ GET /t --- response_body --- no_error_log [error] + + + +=== TEST 25: 501 Method Not Implemented +--- config + location /lua { + content_by_lua ' + ngx.exit(ngx.HTTP_NOT_IMPLEMENTED) + '; + } +--- request +GET /lua +--- error_code: 501 +--- response_body_like: 501 (?:Method )?Not Implemented +--- no_error_log +[error] + + + +=== TEST 26: accepts NGX_OK +--- config + location = /t { + content_by_lua_block { + ngx.exit(ngx.OK) + } + } +--- request +GET /t +--- response_body +--- no_error_log +[error] + + + +=== TEST 27: accepts NGX_ERROR +--- config + location = /t { + content_by_lua_block { + ngx.exit(ngx.ERROR) + } + } +--- request +GET /t +--- error_code: +--- response_body +--- no_error_log +[error] + + + +=== TEST 28: accepts NGX_DECLINED +--- config + location = /t { + content_by_lua_block { + ngx.exit(ngx.DECLINED) + } + } +--- request +GET /t +--- error_code: +--- response_body +--- no_error_log +[error] + + + +=== TEST 29: refuses NGX_AGAIN +--- config + location = /t { + content_by_lua_block { + ngx.exit(ngx.AGAIN) + } + } +--- request +GET /t +--- error_code: 500 +--- response_body_like: 500 Internal Server Error +--- error_log eval +qr/\[error\] .*? bad argument to 'ngx.exit': does not accept NGX_AGAIN or NGX_DONE/ + + + +=== TEST 30: refuses NGX_DONE +--- config + location = /t { + content_by_lua_block { + ngx.exit(ngx.DONE) + } + } +--- request +GET /t +--- error_code: 500 +--- response_body_like: 500 Internal Server Error +--- error_log eval +qr/\[error\] .*? bad argument to 'ngx.exit': does not accept NGX_AGAIN or NGX_DONE/ diff --git a/src/deps/src/lua-nginx-module/t/009-log.t b/src/deps/src/lua-nginx-module/t/009-log.t index c4597698e..4446c7127 100644 --- a/src/deps/src/lua-nginx-module/t/009-log.t +++ b/src/deps/src/lua-nginx-module/t/009-log.t @@ -243,7 +243,7 @@ GET /log --- response_body 32 --- error_log eval -qr/\[error\] \S+: \S+ \[lua\] set_by_lua:2: HELLO,/ +qr/\[error\] \S+: \S+ \[lua\] set_by_lua\(nginx.conf:43\):2: HELLO,/ @@ -261,7 +261,7 @@ GET /log --- response_body 32 --- error_log eval -qr/\[error\] \S+: \S+ \[lua\] set_by_lua:2: truefalsenil,/ +qr/\[error\] \S+: \S+ \[lua\] set_by_lua\(nginx.conf:43\):2: truefalsenil,/ @@ -368,7 +368,7 @@ GET /log --- response_headers foo: 32 --- error_log eval -qr/\[notice\] .*? \[lua\] header_filter_by_lua:2: hello world/ +qr/\[notice\] .*? \[lua\] header_filter_by_lua\(nginx.conf:43\):2: hello world/ --- response_body hi @@ -390,7 +390,7 @@ foo: 32 --- response_body hi --- error_log eval -qr/\[error\] .*? \[lua\] header_filter_by_lua:2: howdy, lua!/ +qr/\[error\] .*? \[lua\] header_filter_by_lua\(nginx.conf:43\):2: howdy, lua!/ diff --git a/src/deps/src/lua-nginx-module/t/014-bugs.t b/src/deps/src/lua-nginx-module/t/014-bugs.t index 8c93920bc..bfc86c9e9 100644 --- a/src/deps/src/lua-nginx-module/t/014-bugs.t +++ b/src/deps/src/lua-nginx-module/t/014-bugs.t @@ -8,7 +8,8 @@ log_level('debug'); repeat_each(3); -plan tests => repeat_each() * (blocks() * 2 + 33); +# NB: the shutdown_error_log block is independent from repeat times +plan tests => repeat_each() * (blocks() * 2 + 33) + 1; our $HtmlDir = html_dir; #warn $html_dir; @@ -1239,3 +1240,46 @@ res: true --- must_die --- error_log eval qr/\[emerg\] \d+#\d+: unexpected "A" in/ + + + +=== TEST 47: cosocket does not exit on worker_shutdown_timeout +--- main_config +worker_shutdown_timeout 1; +--- config +location /t { + content_by_lua_block { + local function thread_func() + local sock = ngx.socket.tcp() + local ok, err = sock:connect("127.0.0.1", 65110) + local bytes, err = sock:send("hello") + if bytes ~= 5 then + sock:close() + return ngx.exit(500) + end + + local data, err = sock:receive(20) + local line, err, partial = sock:receive() + if not line then + ngx.log(ngx.ERR, "failed to read a line: ", err) + return + end + + ngx.log(ngx.ERR, "successfully read a line: ", line) + end + + local function timer_func() + ngx.thread.spawn(thread_func) + end + + ngx.timer.at(1, timer_func) + ngx.say("Hello world") + } +} +--- request + GET /t +--- response_body +Hello world +--- shutdown_error_log eval +qr|failed to read a line: closed| +--- timeout: 1.2 diff --git a/src/deps/src/lua-nginx-module/t/016-resp-header.t b/src/deps/src/lua-nginx-module/t/016-resp-header.t index b558415b2..65c5d75a8 100644 --- a/src/deps/src/lua-nginx-module/t/016-resp-header.t +++ b/src/deps/src/lua-nginx-module/t/016-resp-header.t @@ -2141,3 +2141,88 @@ hi --- error_log my Content-Length: 8589934591 upstream prematurely closed connection while sending to client + + + +=== TEST 95: Expose the 'Last-Modified' response header as ngx.header["Last-Modified"] +--- config + location /a.txt { + header_filter_by_lua_block { + local last_modified = ngx.header["Last-Modified"] + if last_modified == nil then + ngx.log(ngx.ERR, "can not get lasted modified") + ngx.exit(500) + return + end + + local last_mod = ngx.parse_http_time(last_modified) + local age = ngx.time() - last_mod + ngx.header["Age"] = age + } + } +--- user_files +>>> a.txt +Foo +--- request +GET /a.txt +--- raw_response_headers_like chomp +Age: \d\r\n +--- no_error_log +[error] + + + +=== TEST 96: 'Last-Modified' from upstream +--- config + location /test/ { + proxy_pass http://127.0.0.1:$server_port/; + + header_filter_by_lua_block { + local last_modified = ngx.header["Last-Modified"] + if last_modified == nil then + ngx.log(ngx.ERR, "can not get lasted modified") + ngx.exit(500) + return + end + + local last_mod = ngx.parse_http_time(last_modified) + local age = ngx.time() - last_mod + ngx.header["Age"] = age + } + } + +--- user_files +>>> a.txt +Foo +--- request +GET /test/a.txt +--- raw_response_headers_like chomp +Age: \d\r\n +--- no_error_log +[error] + + + +=== TEST 97: 'Last-Modified' does not exist +--- config + location /test { + header_filter_by_lua_block { + local last_modified = ngx.header["Last-Modified"] + if last_modified == nil then + ngx.log(ngx.INFO, "Last-Modified is nil as expected") + return + end + + ngx.log(ngx.ERR, "Last-Modified expected to be nil, but got ", last_modified) + } + + content_by_lua_block { + ngx.say("Hello World") + } + } +--- request +GET /test +--- response_body +Hello World +--- no_error_log +[error] diff --git a/src/deps/src/lua-nginx-module/t/025-codecache.t b/src/deps/src/lua-nginx-module/t/025-codecache.t index cf62ff018..ebe4f61b7 100644 --- a/src/deps/src/lua-nginx-module/t/025-codecache.t +++ b/src/deps/src/lua-nginx-module/t/025-codecache.t @@ -1862,17 +1862,17 @@ code cache hit (key='log_by_lua_nhli_8a9441d0a30531ba8bb34ab11c55cfc3', ref=12) "] --- error_log eval [ -qr/balancer_by_lua:\d+: hello/, -qr/ssl_session_fetch_by_lua_block:\d+: hello/, -qr/ssl_certificate_by_lua:\d+: hello/, -qr/ssl_session_store_by_lua_block:\d+: hello/, -qr/set_by_lua:\d+: hello/, +qr/balancer_by_lua\(nginx\.conf:\d+\):\d+: hello/, +qr/ssl_session_fetch_by_lua\(nginx\.conf:\d+\):\d+: hello/, +qr/ssl_certificate_by_lua\(nginx\.conf:\d+\):\d+: hello/, +qr/ssl_session_store_by_lua\(nginx\.conf:\d+\):\d+: hello/, +qr/set_by_lua\(nginx\.conf:\d+\):\d+: hello/, qr/rewrite_by_lua\(nginx\.conf:\d+\):\d+: hello/, qr/access_by_lua\(nginx\.conf:\d+\):\d+: hello/, qr/content_by_lua\(nginx\.conf:\d+\):\d+: hello/, -qr/header_filter_by_lua:\d+: hello/, -qr/body_filter_by_lua:\d+: hello/, -qr/log_by_lua\(nginx\.conf:\d+\):\d+: hello/, +qr/header_filter_by_lua\(nginx\.conf:\d+\):\d+: hello/, +qr/body_filter_by_lua\(nginx\.conf:\d+\):\d+: hello/, +qr/log_by_lua\(nginx.conf:\d+\):\d+: hello/, ] --- log_level: debug --- no_error_log diff --git a/src/deps/src/lua-nginx-module/t/041-header-filter.t b/src/deps/src/lua-nginx-module/t/041-header-filter.t index 0adc699c6..be390b325 100644 --- a/src/deps/src/lua-nginx-module/t/041-header-filter.t +++ b/src/deps/src/lua-nginx-module/t/041-header-filter.t @@ -462,7 +462,7 @@ GET /lua GET /lua --- ignore_response --- error_log -failed to run header_filter_by_lua*: header_filter_by_lua:2: Something bad +failed to run header_filter_by_lua*: header_filter_by_lua(nginx.conf:47):2: Something bad --- no_error_log [alert] @@ -799,3 +799,77 @@ GET /t --- error_code: 302 --- no_error_log [error] + + + +=== TEST 42: syntax error in header_filter_by_lua_block +--- config + location /lua { + + header_filter_by_lua_block { + 'for end'; + } + content_by_lua_block { + ngx.say("Hello world") + } + } +--- request +GET /lua +--- ignore_response +--- error_log +failed to load inlined Lua code: header_filter_by_lua(nginx.conf:41):2: unexpected symbol near ''for end'' +--- no_error_log +no_such_error + + + +=== TEST 43: syntax error in second content_by_lua_block +--- config + location /foo { + header_filter_by_lua_block { + 'for end'; + } + content_by_lua_block { + ngx.say("Hello world") + } + } + + location /lua { + header_filter_by_lua_block { + 'for end'; + } + content_by_lua_block { + ngx.say("Hello world") + } + } +--- request +GET /lua +--- ignore_response +--- error_log +failed to load inlined Lua code: header_filter_by_lua(nginx.conf:49):2: unexpected symbol near ''for end'' +--- no_error_log +no_such_error + + + +=== TEST 44: syntax error in /tmp/12345678901234567890123456789012345.conf +--- config + location /lua { + content_by_lua_block { + ngx.say("Hello world") + } + + include /tmp/12345678901234567890123456789012345.conf; + } +--- user_files +>>> /tmp/12345678901234567890123456789012345.conf + header_filter_by_lua_block { + 'for end'; + } +--- request +GET /lua +--- ignore_response +--- error_log +failed to load inlined Lua code: header_filter_by_lua(...901234567890123456789012345.conf:1):2: unexpected symbol near ''for end'' +--- no_error_log +[alert] diff --git a/src/deps/src/lua-nginx-module/t/058-tcp-socket.t b/src/deps/src/lua-nginx-module/t/058-tcp-socket.t index 593e49461..6ffb32f58 100644 --- a/src/deps/src/lua-nginx-module/t/058-tcp-socket.t +++ b/src/deps/src/lua-nginx-module/t/058-tcp-socket.t @@ -4,7 +4,7 @@ use Test::Nginx::Socket::Lua; repeat_each(2); -plan tests => repeat_each() * 231; +plan tests => repeat_each() * (blocks() * 3 + 21); our $HtmlDir = html_dir; @@ -4367,3 +4367,69 @@ connect failed: missing the port number finish --- no_error_log [error] + + + +=== TEST 73: reset the buffer pos when keepalive +--- config + server_tokens off; + location /t { + set $port $TEST_NGINX_SERVER_PORT; + + content_by_lua_block { + for i = 1, 10 + do + local sock = ngx.socket.tcp() + local port = ngx.var.port + local ok, err = sock:connect("127.0.0.1", port) + if not ok then + ngx.say("failed to connect: ", err) + return + end + + local req = "GET /hi HTTP/1.1\r\nHost: localhost\r\n\r\n" + + local bytes, err = sock:send(req) + if not bytes then + ngx.say("failed to send request: ", err) + return + end + + local line, err, part = sock:receive() + if not line then + ngx.say("receive err: ", err) + return + end + + data, err = sock:receiveany(4096) + if not data then + ngx.say("receiveany er: ", err) + return + end + + ok, err = sock:setkeepalive(10000, 32) + if not ok then + ngx.say("reused times: ", i, ", setkeepalive err: ", err) + return + end + end + ngx.say("END") + } + } + + location /hi { + keepalive_requests 3; + content_by_lua_block { + ngx.say("Hello") + } + + more_clear_headers Date; + } + +--- request +GET /t +--- response_body +reused times: 3, setkeepalive err: closed +--- no_error_log +[error] +--- skip_eval: 3: $ENV{TEST_NGINX_EVENT_TYPE} && $ENV{TEST_NGINX_EVENT_TYPE} ne 'epoll' diff --git a/src/deps/src/lua-nginx-module/t/062-count.t b/src/deps/src/lua-nginx-module/t/062-count.t index 598441c51..ad464ba2d 100644 --- a/src/deps/src/lua-nginx-module/t/062-count.t +++ b/src/deps/src/lua-nginx-module/t/062-count.t @@ -34,7 +34,7 @@ __DATA__ --- request GET /test --- response_body -ngx: 114 +ngx: 116 --- no_error_log [error] @@ -55,7 +55,7 @@ ngx: 114 --- request GET /test --- response_body -114 +116 --- no_error_log [error] @@ -83,7 +83,7 @@ GET /test --- request GET /test --- response_body -n = 114 +n = 116 --- no_error_log [error] @@ -305,7 +305,7 @@ GET /t --- response_body_like: 404 Not Found --- error_code: 404 --- error_log -ngx. entry count: 114 +ngx. entry count: 116 @@ -438,7 +438,7 @@ thread: 3 --- request GET /test --- response_body -worker: 4 +worker: 5 --- no_error_log [error] @@ -459,7 +459,7 @@ worker: 4 --- request GET /test --- response_body -n = 14 +n = 16 --- no_error_log [error] diff --git a/src/deps/src/lua-nginx-module/t/066-socket-receiveuntil.t b/src/deps/src/lua-nginx-module/t/066-socket-receiveuntil.t index 89d2abf37..1182a536c 100644 --- a/src/deps/src/lua-nginx-module/t/066-socket-receiveuntil.t +++ b/src/deps/src/lua-nginx-module/t/066-socket-receiveuntil.t @@ -1027,7 +1027,7 @@ close: 1 nil local reader = sock:receiveuntil("--abc") - for i = 1, 7 do + for i = 1, 6 do local line, err, part = reader(4) if line then ngx.say("read: ", line) @@ -1055,7 +1055,6 @@ read: hell read: o, w read: orld read: -- -read: failed to read a line: nil [nil] failed to read a line: closed [ ] @@ -1104,7 +1103,7 @@ close: 1 nil local reader = sock:receiveuntil("--abc") - for i = 1, 7 do + for i = 1, 6 do local line, err, part = reader(4) if line then ngx.say("read: ", line) @@ -1132,7 +1131,6 @@ read: hell read: o, w read: orld read: -- -read: failed to read a line: nil [nil] failed to read a line: closed [ ] @@ -1329,3 +1327,78 @@ this exposed a memory leak in receiveuntil ok --- no_error_log [error] + + + +=== TEST 20: add pending bytes +--- config + server_tokens off; + location /t { + set $port $TEST_NGINX_SERVER_PORT; + lua_socket_buffer_size 1; + + content_by_lua ' + -- collectgarbage("collect") + + local sock = ngx.socket.tcp() + local port = ngx.var.port + + local ok, err = sock:connect("127.0.0.1", port) + if not ok then + ngx.say("failed to connect: ", err) + return + end + + ngx.say("connected: ", ok) + + local req = "GET /foo HTTP/1.0\\r\\nHost: localhost\\r\\nConnection: close\\r\\n\\r\\n" + + local bytes, err = sock:send(req) + if not bytes then + ngx.say("failed to send request: ", err) + return + end + ngx.say("request sent: ", bytes) + + local read_headers = sock:receiveuntil("\\r\\n\\r\\n") + local headers, err, part = read_headers() + if not headers then + ngx.say("failed to read headers: ", err, " [", part, "]") + end + + local reader = sock:receiveuntil("--abc") + + for i = 1, 4 do + local line, err, part = reader(2) + if line then + ngx.say("read: ", line) + + else + ngx.say("failed to read a line: ", err, " [", part, "]") + end + end + + ok, err = sock:close() + ngx.say("close: ", ok, " ", err) + '; + } + + location /foo { + echo -- -----abc; + more_clear_headers Date; + } +--- request +GET /t + +--- response_body eval +qq{connected: 1 +request sent: 57 +read: -- +read: - +failed to read a line: nil [nil] +failed to read a line: closed [ +] +close: 1 nil +} +--- no_error_log +[error] diff --git a/src/deps/src/lua-nginx-module/t/071-idle-socket.t b/src/deps/src/lua-nginx-module/t/071-idle-socket.t index c9002be8e..49d45a1b5 100644 --- a/src/deps/src/lua-nginx-module/t/071-idle-socket.t +++ b/src/deps/src/lua-nginx-module/t/071-idle-socket.t @@ -367,7 +367,7 @@ Transfer-Encoding: chunked\r Connection: close\r \r 6\r -failed to set keepalive: (?:unread data in buffer|connection in dubious state) +failed to set keepalive: (?:unread data in buffer|closed|connection in dubious state) } --- no_error_log [error] diff --git a/src/deps/src/lua-nginx-module/t/082-body-filter.t b/src/deps/src/lua-nginx-module/t/082-body-filter.t index 5f765fa43..a69c78fa7 100644 --- a/src/deps/src/lua-nginx-module/t/082-body-filter.t +++ b/src/deps/src/lua-nginx-module/t/082-body-filter.t @@ -317,7 +317,7 @@ hiya globe GET /t --- ignore_response --- error_log -failed to run body_filter_by_lua*: body_filter_by_lua:4: something bad happened! +failed to run body_filter_by_lua*: body_filter_by_lua(nginx.conf:49):4: something bad happened! @@ -838,3 +838,55 @@ GET /lua --- ignore_response --- error_log API disabled in the context of body_filter_by_lua* + + + +=== TEST 27: syntax error in body_filter_by_lua_block +--- config + location /lua { + + body_filter_by_lua_block { + 'for end'; + } + content_by_lua_block { + ngx.say("Hello world") + } + } +--- request +GET /lua +--- ignore_response +--- error_log +failed to load inlined Lua code: body_filter_by_lua(nginx.conf:41):2: unexpected symbol near ''for end'' +--- no_error_log +no_such_error1 +no_such_error2 + + + +=== TEST 28: syntax error in second body_by_lua_block +--- config + location /foo { + body_filter_by_lua_block { + 'for end'; + } + content_by_lua_block { + ngx.say("Hello world") + } + } + + location /lua { + body_filter_by_lua_block { + 'for end'; + } + content_by_lua_block { + ngx.say("Hello world") + } + } +--- request +GET /lua +--- ignore_response +--- error_log +failed to load inlined Lua code: body_filter_by_lua(nginx.conf:49):2: unexpected symbol near ''for end'' +--- no_error_log +no_such_error1 +no_such_error2 diff --git a/src/deps/src/lua-nginx-module/t/084-inclusive-receiveuntil.t b/src/deps/src/lua-nginx-module/t/084-inclusive-receiveuntil.t index 66be893d5..eb5aa1ecd 100644 --- a/src/deps/src/lua-nginx-module/t/084-inclusive-receiveuntil.t +++ b/src/deps/src/lua-nginx-module/t/084-inclusive-receiveuntil.t @@ -619,7 +619,7 @@ bad "inclusive" option value type: string local reader = sock:receiveuntil("--abc", { inclusive = true }) - for i = 1, 7 do + for i = 1, 6 do local line, err, part = reader(4) if line then ngx.say("read: ", line) @@ -646,8 +646,7 @@ request sent: 57 read: hell read: o, w read: orld -read: -- -read: --abc +read: ----abc failed to read a line: nil [nil] failed to read a line: closed [ ] diff --git a/src/deps/src/lua-nginx-module/t/086-init-by.t b/src/deps/src/lua-nginx-module/t/086-init-by.t index bea34a461..04f8160eb 100644 --- a/src/deps/src/lua-nginx-module/t/086-init-by.t +++ b/src/deps/src/lua-nginx-module/t/086-init-by.t @@ -321,3 +321,47 @@ INIT 2: foo = 3 failed to init --- error_log [error] + + + +=== TEST 13: syntax error in init_by_lua_block +--- http_config + init_by_lua_block { + ngx.log(ngx.debug, "pass") + error("failed to init" + ngx.log(ngx.debug, "unreachable") + } +--- config + location /lua { + content_by_lua_block { + ngx.say("hello world") + } + } +--- must_die +--- error_log +init_by_lua error: init_by_lua(nginx.conf:25):4: ')' expected (to close '(' at line 3) near 'ngx' +--- no_error_log +no_such_error_log + + + +=== TEST 14: syntax error in init_by_lua_file +--- http_config + init_by_lua_file html/init.lua; +--- config + location /lua { + content_by_lua_block { + ngx.say("hello world") + } + } +--- user_files +>>> init.lua + ngx.log(ngx.debug, "pass") + error("failed to init" + ngx.log(ngx.debug, "unreachable") + +--- must_die +--- error_log eval +qr|init_by_lua_file error: .*?/t/servroot\w*?/html/init.lua:3: '\)' expected \(to close '\(' at line 2\) near 'ngx'| +--- no_error_log +no_such_error_log diff --git a/src/deps/src/lua-nginx-module/t/087-udp-socket.t b/src/deps/src/lua-nginx-module/t/087-udp-socket.t index 80c5e3651..6c26b9387 100644 --- a/src/deps/src/lua-nginx-module/t/087-udp-socket.t +++ b/src/deps/src/lua-nginx-module/t/087-udp-socket.t @@ -69,7 +69,7 @@ GET /t [error] --- log_level: debug --- error_log -lua udp socket receive buffer size: 8192 +lua udp socket receive buffer size: 65536 @@ -595,7 +595,7 @@ received a good response. [error] --- log_level: debug --- error_log -lua udp socket receive buffer size: 8192 +lua udp socket receive buffer size: 65536 --- no_check_leak @@ -662,7 +662,7 @@ received a good response. [error] --- log_level: debug --- error_log -lua udp socket receive buffer size: 8192 +lua udp socket receive buffer size: 65536 --- no_check_leak diff --git a/src/deps/src/lua-nginx-module/t/089-phase.t b/src/deps/src/lua-nginx-module/t/089-phase.t index a7405f2d5..028c400c7 100644 --- a/src/deps/src/lua-nginx-module/t/089-phase.t +++ b/src/deps/src/lua-nginx-module/t/089-phase.t @@ -8,7 +8,7 @@ log_level('warn'); repeat_each(2); -plan tests => repeat_each() * (blocks() * 2 + 1) + 2; +plan tests => repeat_each() * (blocks() * 2 + 2) + 2; #no_diff(); #no_long_string(); @@ -198,6 +198,26 @@ GET /lua ok --- shutdown_error_log eval [ -qr/exit_worker_by_lua:\d+: exit_worker/, +qr/exit_worker_by_lua\(nginx\.conf:\d+\):\d+: exit_worker/, qr/exiting now$/, ] + + + +=== TEST 12: server_rewrite_by_lua_block in http +--- http_config + server_rewrite_by_lua_block { + ngx.ctx.phase = ngx.get_phase() + } +--- config + location /lua { + content_by_lua_block { + ngx.say(ngx.ctx.phase) + } + } +--- request +GET /lua +--- response_body +server_rewrite +--- no_error_log +[error] diff --git a/src/deps/src/lua-nginx-module/t/091-coroutine.t b/src/deps/src/lua-nginx-module/t/091-coroutine.t index b9b3d9d38..fafc5a45c 100644 --- a/src/deps/src/lua-nginx-module/t/091-coroutine.t +++ b/src/deps/src/lua-nginx-module/t/091-coroutine.t @@ -1691,7 +1691,7 @@ GET /t --- error_log eval [ qr/\[notice\] .*? in wrapped coroutine/, - qr/\[error\] .*? failed to run header_filter_by_lua\*: header_filter_by_lua:\d+: header_filter_by_lua:\d+: something went wrong/, + qr/\[error\] .*? failed to run header_filter_by_lua\*: header_filter_by_lua\(nginx.conf:\d+\):\d+: header_filter_by_lua\(nginx.conf:\d+\):\d+: something went wrong/, "stack traceback:", "in function 'co'" ] @@ -1713,9 +1713,9 @@ GET /t --- config --- must_die ---- grep_error_log eval: qr/init_by_lua error: .*? something went wrong/ +--- grep_error_log eval: qr/init_by_lua\(nginx.conf:25\).*? something went wrong/ --- grep_error_log_out -init_by_lua error: init_by_lua:7: init_by_lua:4: something went wrong +init_by_lua(nginx.conf:25):7: init_by_lua(nginx.conf:25):4: something went wrong diff --git a/src/deps/src/lua-nginx-module/t/098-uthread-wait.t b/src/deps/src/lua-nginx-module/t/098-uthread-wait.t index c2819ae88..e2818e008 100644 --- a/src/deps/src/lua-nginx-module/t/098-uthread-wait.t +++ b/src/deps/src/lua-nginx-module/t/098-uthread-wait.t @@ -1321,3 +1321,22 @@ $s; --- no_error_log [error] [alert] + + + +=== TEST 23: no parameters for ngx.thread.wait +--- config + location /lua { + content_by_lua_block { + ngx.thread.wait() + ngx.say("ok") + } + } +--- request +GET /lua +--- response_body_like: 500 Internal Server Error +--- error_code: 500 +--- error_log +at least one coroutine should be specified +--- no_error_log +[crit] diff --git a/src/deps/src/lua-nginx-module/t/104-req-raw-header.t b/src/deps/src/lua-nginx-module/t/104-req-raw-header.t index f147b2bcf..aa6663048 100644 --- a/src/deps/src/lua-nginx-module/t/104-req-raw-header.t +++ b/src/deps/src/lua-nginx-module/t/104-req-raw-header.t @@ -1017,3 +1017,36 @@ client sent invalid header line: "\x20..." while reading client request headers [error] --- skip_nginx 3: < 1.21.1 + + + +=== TEST 35: bugfix: invalid http request +--- log_level: error +--- http_config + lua_package_path "../lua-resty-core/lib/?.lua;;"; +--- config + location /t { + content_by_lua_block { + local sock = ngx.socket.tcp() + local ok, err = sock:connect("127.0.0.1", $TEST_NGINX_SERVER_PORT) + if not ok then + ngx.log(ngx.ERR, "failed to connect to memc: ", err) + return + end + sock:send("\n") + sock:close() + + ngx.say("OK") + } + } + + log_by_lua_block { + local h = ngx.req.raw_header() + } + +--- request +GET /t +--- response_body +OK +--- no_error_log +[error] diff --git a/src/deps/src/lua-nginx-module/t/109-timer-hup.t b/src/deps/src/lua-nginx-module/t/109-timer-hup.t index 2c197c282..bff1b3346 100644 --- a/src/deps/src/lua-nginx-module/t/109-timer-hup.t +++ b/src/deps/src/lua-nginx-module/t/109-timer-hup.t @@ -336,7 +336,7 @@ lua found 100 pending timers lua_shared_dict test_dict 1m; server { - listen 12355; + listen $TEST_NGINX_RAND_PORT_1; location = /foo { echo 'foo'; } @@ -350,7 +350,7 @@ lua found 100 pending timers -- Connect the socket local sock = ngx.socket.tcp() - local ok,err = sock:connect("127.0.0.1", 12355) + local ok,err = sock:connect("127.0.0.1", $TEST_NGINX_RAND_PORT_1) if not ok then ngx.log(ngx.ERR, err) end diff --git a/src/deps/src/lua-nginx-module/t/122-worker.t b/src/deps/src/lua-nginx-module/t/122-worker.t index b74c81fbc..244c3142d 100644 --- a/src/deps/src/lua-nginx-module/t/122-worker.t +++ b/src/deps/src/lua-nginx-module/t/122-worker.t @@ -9,7 +9,7 @@ use Test::Nginx::Socket::Lua; repeat_each(2); -plan tests => repeat_each() * (blocks() * 3); +plan tests => repeat_each() * (blocks() * 4 - 4); #no_diff(); no_long_string(); @@ -79,3 +79,33 @@ worker pid: \d+ worker pid is correct\. --- no_error_log [error] + + + +=== TEST 4: content_by_lua + ngx.worker.pids +--- config + location /lua { + content_by_lua ' + local pids = ngx.worker.pids() + local pid = ngx.worker.pid() + ngx.say("worker pid: ", pid) + local count = ngx.worker.count() + if count ~= #pids then + ngx.say("worker pids is wrong.") + end + for i = 1, count do + if pids[i] == pid then + ngx.say("worker pid is correct.") + return + end + end + ngx.say("worker pid is wrong.") + '; + } +--- request +GET /lua +--- response_body_like +worker pid: \d+ +worker pid is correct\. +--- no_error_log +[error] diff --git a/src/deps/src/lua-nginx-module/t/124-init-worker.t b/src/deps/src/lua-nginx-module/t/124-init-worker.t index b7e17a07f..57df4a5b3 100644 --- a/src/deps/src/lua-nginx-module/t/124-init-worker.t +++ b/src/deps/src/lua-nginx-module/t/124-init-worker.t @@ -842,6 +842,11 @@ lua close the global Lua VM \3 in the cache helper process \d+ lua close the global Lua VM \3 lua close the global Lua VM \3 in the cache helper process \d+ )(?:lua close the global Lua VM [0-9A-F]+ +|lua close the global Lua VM ([0-9A-F]+) +lua close the global Lua VM \4 in the cache helper process \d+ +lua close the global Lua VM \4 in the cache helper process \d+ +lua close the global Lua VM \4 +lua close the global Lua VM \4 )*\z/ --- no_error_log [error] @@ -975,3 +980,53 @@ qr/lua close the global Lua VM ([0-9A-F]+)$/, --- no_error_log [error] start privileged agent process + + + +=== TEST 25: syntax error in init_worker_by_lua_block +--- http_config + init_worker_by_lua_block { + ngx.log(ngx.debug, "pass") + error("failed to init" + ngx.log(ngx.debug, "unreachable") + } +--- config + location /t { + content_by_lua_block { + ngx.say("hello world") + } + } +--- request + GET /t +--- response_body +hello world +--- error_log +init_worker_by_lua error: init_worker_by_lua(nginx.conf:25):4: ')' expected (to close '(' at line 3) near 'ngx' +--- no_error_log +no_such_error_log + + + +=== TEST 26: syntax error in init_worker_by_lua_file +--- http_config + init_worker_by_lua_file html/init.lua; +--- config + location /t { + content_by_lua_block { + ngx.say("hello world") + } + } +--- user_files +>>> init.lua + ngx.log(ngx.debug, "pass") + error("failed to init" + ngx.log(ngx.debug, "unreachable") + +--- request + GET /t +--- response_body +hello world +--- error_log eval +qr|init_worker_by_lua_file error: .*?t/servroot\w*/html/init.lua:3: '\)' expected \(to close '\(' at line 2\) near 'ngx'| +--- no_error_log +no_such_error_log diff --git a/src/deps/src/lua-nginx-module/t/129-ssl-socket.t b/src/deps/src/lua-nginx-module/t/129-ssl-socket.t index c26f0cec5..81ca51ca4 100644 --- a/src/deps/src/lua-nginx-module/t/129-ssl-socket.t +++ b/src/deps/src/lua-nginx-module/t/129-ssl-socket.t @@ -39,7 +39,7 @@ run_tests(); __DATA__ -=== TEST 1: www.google.com +=== TEST 1: www.bing.com --- config server_tokens off; resolver $TEST_NGINX_RESOLVER ipv6=off; @@ -48,7 +48,7 @@ __DATA__ set $port $TEST_NGINX_MEMCACHED_PORT; content_by_lua ' - -- avoid flushing google in "check leak" testing mode: + -- avoid flushing bing in "check leak" testing mode: local counter = package.loaded.counter if not counter then counter = 1 @@ -62,7 +62,7 @@ __DATA__ do local sock = ngx.socket.tcp() sock:settimeout(2000) - local ok, err = sock:connect("www.google.com", 443) + local ok, err = sock:connect("www.bing.com", 443) if not ok then ngx.say("failed to connect: ", err) return @@ -78,7 +78,7 @@ __DATA__ ngx.say("ssl handshake: ", type(sess)) - local req = "GET / HTTP/1.1\\r\\nHost: www.google.com\\r\\nConnection: close\\r\\n\\r\\n" + local req = "GET / HTTP/1.1\\r\\nHost: www.bing.com\\r\\nConnection: close\\r\\n\\r\\n" local bytes, err = sock:send(req) if not bytes then ngx.say("failed to send http request: ", err) @@ -106,8 +106,8 @@ __DATA__ GET /t --- response_body_like chop \Aconnected: 1 -ssl handshake: userdata -sent http request: 59 bytes. +ssl handshake: cdata +sent http request: 57 bytes. received: HTTP/1.1 (?:200 OK|302 Found) close: 1 nil \z @@ -190,7 +190,7 @@ SSL reused session GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 53 bytes. received: HTTP/1.1 201 Created close: 1 nil @@ -271,7 +271,7 @@ SSL reused session GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 58 bytes. received: HTTP/1.1 302 Moved Temporarily close: 1 nil @@ -355,12 +355,12 @@ SSL reused session GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 56 bytes. received: HTTP/1.1 200 OK close: 1 nil connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 56 bytes. received: HTTP/1.1 200 OK close: 1 nil @@ -603,7 +603,7 @@ SSL reused session GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 80 bytes. received: HTTP/1.1 404 Not Found close: 1 nil @@ -688,7 +688,7 @@ $::DSTRootCertificate" GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 58 bytes. received: HTTP/1.1 302 Moved Temporarily close: 1 nil @@ -1008,7 +1008,7 @@ $::DSTRootCertificate" GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 58 bytes. received: HTTP/1.1 302 Moved Temporarily close: 1 nil @@ -1087,7 +1087,7 @@ SSL reused session GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 58 bytes. received: HTTP/1.1 302 Moved Temporarily close: 1 nil @@ -1179,7 +1179,7 @@ SSL reused session GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 53 bytes. received: HTTP/1.1 200 OK close: 1 nil @@ -1269,7 +1269,7 @@ SSL reused session GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 53 bytes. received: HTTP/1.1 200 OK close: 1 nil @@ -1418,13 +1418,13 @@ $::DSTRootCertificate" GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata set keepalive: 1 nil connected: 1 -ssl handshake: userdata +ssl handshake: cdata set keepalive: 1 nil connected: 1 -ssl handshake: userdata +ssl handshake: cdata set keepalive: 1 nil --- log_level: debug @@ -1494,13 +1494,13 @@ $::DSTRootCertificate" GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata set keepalive: 1 nil connected: 1 -ssl handshake: userdata +ssl handshake: cdata set keepalive: 1 nil connected: 1 -ssl handshake: userdata +ssl handshake: cdata set keepalive: 1 nil --- log_level: debug @@ -1637,7 +1637,7 @@ attempt to call method 'sslhandshake' (a nil value) GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 56 bytes. received: HTTP/1.1 201 Created received: Server: nginx @@ -1742,7 +1742,7 @@ SSL reused session GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 56 bytes. received: HTTP/1.1 201 Created received: Server: nginx @@ -2031,8 +2031,8 @@ SSL reused session GET /t --- response_body connected: 1 -ssl handshake: userdata -ssl handshake: userdata +ssl handshake: cdata +ssl handshake: cdata sent http request: 58 bytes. received: HTTP/1.1 302 Moved Temporarily close: 1 nil @@ -2232,7 +2232,7 @@ SSL reused session GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata --- user_files eval ">>> test.key @@ -2405,7 +2405,7 @@ SSL reused session GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 56 bytes. received: HTTP/1.1 201 Created received: Server: nginx @@ -2529,7 +2529,7 @@ SSL reused session -=== TEST 31: handshake, too many arguments +=== TEST 31: handshake, too few arguments --- config server_tokens off; resolver $TEST_NGINX_RESOLVER ipv6=off; @@ -2633,7 +2633,7 @@ qr/\[error\] .* ngx.socket sslhandshake: expecting 1 ~ 5 arguments \(including t GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 53 bytes. received: HTTP/1.1 200 OK close: 1 nil @@ -2726,7 +2726,7 @@ SSL reused session GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 53 bytes. received: HTTP/1.1 200 OK close: 1 nil diff --git a/src/deps/src/lua-nginx-module/t/138-balancer.t b/src/deps/src/lua-nginx-module/t/138-balancer.t index dca178467..d9c943388 100644 --- a/src/deps/src/lua-nginx-module/t/138-balancer.t +++ b/src/deps/src/lua-nginx-module/t/138-balancer.t @@ -38,7 +38,7 @@ __DATA__ --- error_code: 502 --- error_log eval [ -'[lua] balancer_by_lua:2: hello from balancer by lua! while connecting to upstream,', +'[lua] balancer_by_lua(nginx.conf:27):2: hello from balancer by lua! while connecting to upstream,', qr{\[crit\] .*? connect\(\) to 0\.0\.0\.1:80 failed .*?, upstream: "http://0\.0\.0\.1:80/t"}, ] --- no_error_log @@ -64,7 +64,7 @@ qr{\[crit\] .*? connect\(\) to 0\.0\.0\.1:80 failed .*?, upstream: "http://0\.0\ --- response_body_like: 403 Forbidden --- error_code: 403 --- error_log -[lua] balancer_by_lua:2: hello from balancer by lua! while connecting to upstream, +[lua] balancer_by_lua(nginx.conf:27):2: hello from balancer by lua! while connecting to upstream, --- no_error_log eval [ '[warn]', @@ -92,7 +92,7 @@ qr{\[crit\] .*? connect\(\) to 0\.0\.0\.1:80 failed .*?, upstream: "http://0\.0\ --- error_code: 502 --- error_log eval [ -'[lua] balancer_by_lua:2: hello from balancer by lua! while connecting to upstream,', +'[lua] balancer_by_lua(nginx.conf:27):2: hello from balancer by lua! while connecting to upstream,', qr{\[crit\] .*? connect\(\) to 0\.0\.0\.1:80 failed .*?, upstream: "http://0\.0\.0\.1:80/t"}, ] --- no_error_log @@ -257,7 +257,7 @@ qr{\[crit\] .*? connect\(\) to 0\.0\.0\.1:80 failed .*?, upstream: "http://0\.0\ --- response_body_like: 500 Internal Server Error --- error_code: 500 --- error_log eval -qr/\[error\] .*? failed to run balancer_by_lua\*: balancer_by_lua:2: API disabled in the context of balancer_by_lua\*/ +qr/\[error\] .*? failed to run balancer_by_lua\*: balancer_by_lua\(nginx\.conf:27\):2: API disabled in the context of balancer_by_lua\*/ @@ -278,7 +278,7 @@ qr/\[error\] .*? failed to run balancer_by_lua\*: balancer_by_lua:2: API disable --- response_body_like: 500 Internal Server Error --- error_code: 500 --- error_log eval -qr/\[error\] .*? failed to run balancer_by_lua\*: balancer_by_lua:2: API disabled in the context of balancer_by_lua\*/ +qr/\[error\] .*? failed to run balancer_by_lua\*: balancer_by_lua\(nginx\.conf:27\):2: API disabled in the context of balancer_by_lua\*/ @@ -427,7 +427,7 @@ ctx counter: nil --- error_code: 502 --- error_log eval [ -'[lua] balancer_by_lua:2: hello from balancer by lua! while connecting to upstream,', +'[lua] balancer_by_lua(nginx.conf:27):2: hello from balancer by lua! while connecting to upstream,', qr{\[crit\] .*? connect\(\) to 0\.0\.0\.1:80 failed .*?, upstream: "http://0\.0\.0\.1:80/t"}, ] --- no_error_log @@ -535,7 +535,7 @@ failed to set more tries: reduced tries due to limit lua_package_path "../lua-resty-core/lib/?.lua;;"; server { - listen 127.0.0.1:8888; + listen 127.0.0.1:$TEST_NGINX_RAND_PORT_1; location / { return 200 "it works"; @@ -543,8 +543,8 @@ failed to set more tries: reduced tries due to limit } upstream foo { - server 127.0.0.1:8888 max_fails=0; - server 127.0.0.1:8889 max_fails=0 weight=9999; + server 127.0.0.1:$TEST_NGINX_RAND_PORT_1 max_fails=0; + server 127.0.0.1:$TEST_NGINX_RAND_PORT_2 max_fails=0 weight=9999; balancer_by_lua_block { local bal = require "ngx.balancer" @@ -567,3 +567,26 @@ connect() failed (111: Connection refused) while connecting to upstream --- no_error_log upstream sent more data than specified in "Content-Length" header while reading upstream [alert] + + + +=== TEST 18: error in balancer_by_llua_block +--- http_config + upstream backend { + server 0.0.0.1; + balancer_by_lua_block { + ngx.say("hello" + } + } +--- config + location = /t { + proxy_pass http://backend; + } +--- request + GET /t +--- response_body_like: 500 Internal Server Error +--- error_code: 500 +--- error_log eval + "failed to load inlined Lua code: balancer_by_lua(nginx.conf:27):3: ')' expected (to close '(' at line 2) near ''", +--- no_error_log +[warn] diff --git a/src/deps/src/lua-nginx-module/t/139-ssl-cert-by.t b/src/deps/src/lua-nginx-module/t/139-ssl-cert-by.t index d7e20bafe..218046690 100644 --- a/src/deps/src/lua-nginx-module/t/139-ssl-cert-by.t +++ b/src/deps/src/lua-nginx-module/t/139-ssl-cert-by.t @@ -100,7 +100,7 @@ __DATA__ GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 56 bytes. received: HTTP/1.1 201 Created received: Server: nginx @@ -117,18 +117,18 @@ lua ssl server name: "test.com" --- no_error_log [error] [alert] ---- grep_error_log eval: qr/ssl_certificate_by_lua:.*?,|\bssl cert: connection reusable: \d+|\breusable connection: \d+/ +--- grep_error_log eval: qr/ssl_certificate_by_lua\(nginx.conf:\d+\):.*?,|\bssl cert: connection reusable: \d+|\breusable connection: \d+/ --- grep_error_log_out eval # Since nginx version 1.17.9, nginx call ngx_reusable_connection(c, 0) # before call ssl callback function $Test::Nginx::Util::NginxVersion >= 1.017009 ? qr/reusable connection: 0 ssl cert: connection reusable: 0 -ssl_certificate_by_lua:1: ssl cert by lua is running!,/ +ssl_certificate_by_lua\(nginx.conf:28\):1: ssl cert by lua is running!,/ : qr /reusable connection: 1 ssl cert: connection reusable: 1 reusable connection: 0 -ssl_certificate_by_lua:1: ssl cert by lua is running!,/ +ssl_certificate_by_lua\(nginx.conf:28\):1: ssl cert by lua is running!,/ @@ -209,7 +209,7 @@ ssl_certificate_by_lua:1: ssl cert by lua is running!,/ GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 56 bytes. received: HTTP/1.1 201 Created received: Server: nginx @@ -314,7 +314,7 @@ qr/elapsed in ssl cert by lua: 0.(?:09|1\d)\d+,/, GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 56 bytes. received: HTTP/1.1 201 Created received: Server: nginx @@ -432,7 +432,7 @@ my timer run! GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 56 bytes. received: HTTP/1.1 201 Created received: Server: nginx @@ -456,7 +456,7 @@ received memc reply: OK === TEST 5: ngx.exit(0) - no yield --- http_config server { - listen 127.0.0.2:8080 ssl; + listen 127.0.0.2:$TEST_NGINX_RAND_PORT_1 ssl; server_name test.com; ssl_certificate_by_lua_block { ngx.exit(0) @@ -484,7 +484,7 @@ received memc reply: OK sock:settimeout(2000) - local ok, err = sock:connect("127.0.0.2", 8080) + local ok, err = sock:connect("127.0.0.2", $TEST_NGINX_RAND_PORT_1) if not ok then ngx.say("failed to connect: ", err) return @@ -523,7 +523,7 @@ should never reached here === TEST 6: ngx.exit(ngx.ERROR) - no yield --- http_config server { - listen 127.0.0.2:8080 ssl; + listen 127.0.0.2:$TEST_NGINX_RAND_PORT_1 ssl; server_name test.com; ssl_certificate_by_lua_block { ngx.exit(ngx.ERROR) @@ -551,7 +551,7 @@ should never reached here sock:settimeout(2000) - local ok, err = sock:connect("127.0.0.2", 8080) + local ok, err = sock:connect("127.0.0.2", $TEST_NGINX_RAND_PORT_1) if not ok then ngx.say("failed to connect: ", err) return @@ -593,7 +593,7 @@ should never reached here === TEST 7: ngx.exit(0) - yield --- http_config server { - listen 127.0.0.2:8080 ssl; + listen 127.0.0.2:$TEST_NGINX_RAND_PORT_1 ssl; server_name test.com; ssl_certificate_by_lua_block { ngx.sleep(0.001) @@ -623,7 +623,7 @@ should never reached here sock:settimeout(2000) - local ok, err = sock:connect("127.0.0.2", 8080) + local ok, err = sock:connect("127.0.0.2", $TEST_NGINX_RAND_PORT_1) if not ok then ngx.say("failed to connect: ", err) return @@ -662,7 +662,7 @@ should never reached here === TEST 8: ngx.exit(ngx.ERROR) - yield --- http_config server { - listen 127.0.0.2:8080 ssl; + listen 127.0.0.2:$TEST_NGINX_RAND_PORT_1 ssl; server_name test.com; ssl_certificate_by_lua_block { ngx.sleep(0.001) @@ -692,7 +692,7 @@ should never reached here sock:settimeout(2000) - local ok, err = sock:connect("127.0.0.2", 8080) + local ok, err = sock:connect("127.0.0.2", $TEST_NGINX_RAND_PORT_1) if not ok then ngx.say("failed to connect: ", err) return @@ -734,7 +734,7 @@ should never reached here === TEST 9: lua exception - no yield --- http_config server { - listen 127.0.0.2:8080 ssl; + listen 127.0.0.2:$TEST_NGINX_RAND_PORT_1 ssl; server_name test.com; ssl_certificate_by_lua_block { error("bad bad bad") @@ -762,7 +762,7 @@ should never reached here sock:settimeout(2000) - local ok, err = sock:connect("127.0.0.2", 8080) + local ok, err = sock:connect("127.0.0.2", $TEST_NGINX_RAND_PORT_1) if not ok then ngx.say("failed to connect: ", err) return @@ -789,7 +789,7 @@ failed to do SSL handshake: handshake failed --- error_log eval [ -'runtime error: ssl_certificate_by_lua:2: bad bad bad', +'runtime error: ssl_certificate_by_lua(nginx.conf:28):2: bad bad bad', 'lua_certificate_by_lua: handler return value: 500, cert cb exit code: 0', qr/\[info\] .*? SSL_do_handshake\(\) failed .*?cert cb error/, qr/context: ssl_certificate_by_lua\*, client: \d+\.\d+\.\d+\.\d+, server: \d+\.\d+\.\d+\.\d+:\d+/, @@ -805,7 +805,7 @@ should never reached here === TEST 10: lua exception - yield --- http_config server { - listen 127.0.0.2:8080 ssl; + listen 127.0.0.2:$TEST_NGINX_RAND_PORT_1 ssl; server_name test.com; ssl_certificate_by_lua_block { ngx.sleep(0.001) @@ -834,7 +834,7 @@ should never reached here sock:settimeout(2000) - local ok, err = sock:connect("127.0.0.2", 8080) + local ok, err = sock:connect("127.0.0.2", $TEST_NGINX_RAND_PORT_1) if not ok then ngx.say("failed to connect: ", err) return @@ -861,7 +861,7 @@ failed to do SSL handshake: handshake failed --- error_log eval [ -'runtime error: ssl_certificate_by_lua:3: bad bad bad', +'runtime error: ssl_certificate_by_lua(nginx.conf:28):3: bad bad bad', 'lua_certificate_by_lua: cert cb exit code: 0', qr/\[info\] .*? SSL_do_handshake\(\) failed .*?cert cb error/, ] @@ -924,7 +924,7 @@ should never reached here GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata --- error_log lua ssl server name: "test.com" @@ -1050,7 +1050,7 @@ failed to do SSL handshake: handshake failed --- error_log eval [ 'lua ssl server name: "test.com"', -'ssl_certificate_by_lua:1: API disabled in the context of ssl_certificate_by_lua*', +'ssl_certificate_by_lua(nginx.conf:28):1: API disabled in the context of ssl_certificate_by_lua*', qr/\[info\] .*?cert cb error/, ] @@ -1137,7 +1137,7 @@ print("ssl cert by lua is running!") GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 56 bytes. received: HTTP/1.1 201 Created received: Server: nginx @@ -1248,7 +1248,7 @@ a.lua:1: ssl cert by lua is running! GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 56 bytes. received: HTTP/1.1 201 Created received: Server: nginx @@ -1372,7 +1372,7 @@ lua ssl server name: "test.com" GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 56 bytes. received: HTTP/1.1 201 Created received: Server: nginx @@ -1468,7 +1468,7 @@ GitHub openresty/lua-resty-core#42 GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 56 bytes. received: HTTP/1.1 201 Created received: Server: nginx @@ -1481,7 +1481,7 @@ close: 1 nil --- error_log lua ssl server name: "test.com" -ssl_certificate_by_lua:1: ssl cert by lua is running! +ssl_certificate_by_lua(nginx.conf:25):1: ssl cert by lua is running! --- no_error_log [error] @@ -1566,7 +1566,7 @@ github issue #723 GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 56 bytes. received: HTTP/1.1 201 Created received: Server: nginx @@ -1668,7 +1668,7 @@ ssl_certificate_by_lua:1: ssl cert by lua is running! GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 59 bytes. received: HTTP/1.1 200 OK received: Server: nginx @@ -1681,7 +1681,7 @@ close: 1 nil --- error_log eval [ -'ssl_certificate_by_lua:1: ssl cert by lua is running!', +'ssl_certificate_by_lua(nginx.conf:29):1: ssl cert by lua is running!', 'lua ssl server name: "test.com"', ] --- no_error_log @@ -1963,7 +1963,7 @@ qr/\[info\] .*? SSL_do_handshake\(\) failed\b/, GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 56 bytes. received: HTTP/1.1 201 Created received: Server: nginx @@ -2063,7 +2063,7 @@ client ip: 127.0.0.1 GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 56 bytes. received: HTTP/1.1 201 Created received: Server: nginx @@ -2221,7 +2221,7 @@ qr/elapsed in ssl_certificate_by_lua\*: 0\.(?:09|1\d)\d+,/, GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata --- no_error_log [error] [alert] @@ -2311,7 +2311,7 @@ ssl handshake: userdata GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata --- no_error_log [error] [alert] diff --git a/src/deps/src/lua-nginx-module/t/140-ssl-c-api.t b/src/deps/src/lua-nginx-module/t/140-ssl-c-api.t index 1c5913549..5b2ae018f 100644 --- a/src/deps/src/lua-nginx-module/t/140-ssl-c-api.t +++ b/src/deps/src/lua-nginx-module/t/140-ssl-c-api.t @@ -36,7 +36,8 @@ ffi.cdef[[ size_t pem_len, unsigned char *der, char **err); int ngx_http_lua_ffi_priv_key_pem_to_der(const unsigned char *pem, - size_t pem_len, unsigned char *der, char **err); + size_t pem_len, const unsigned char *passphrase, + unsigned char *der, char **err); int ngx_http_lua_ffi_ssl_set_der_certificate(void *r, const char *data, size_t len, char **err); @@ -58,12 +59,12 @@ ffi.cdef[[ int ngx_http_lua_ffi_set_priv_key(void *r, void *cdata, char **err); + void *ngx_http_lua_ffi_get_req_ssl_pointer(void *r); + void ngx_http_lua_ffi_free_cert(void *cdata); void ngx_http_lua_ffi_free_priv_key(void *cdata); - int ngx_http_lua_ffi_ssl_clear_certs(void *r, char **err); - int ngx_http_lua_ffi_ssl_verify_client(void *r, void *cdata, int depth, char **err); @@ -132,7 +133,7 @@ __DATA__ out = ffi.new("char [?]", #pkey) - local rc = ffi.C.ngx_http_lua_ffi_priv_key_pem_to_der(pkey, #pkey, out, errmsg) + local rc = ffi.C.ngx_http_lua_ffi_priv_key_pem_to_der(pkey, #pkey, nil, out, errmsg) if rc < 1 then ngx.log(ngx.ERR, "failed to parse PEM priv key: ", ffi.string(errmsg[0])) @@ -216,7 +217,7 @@ __DATA__ GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 56 bytes. received: HTTP/1.1 201 Created received: Server: nginx @@ -286,7 +287,7 @@ lua ssl server name: "test.com" out = ffi.new("char [?]", #pkey) - local rc = ffi.C.ngx_http_lua_ffi_priv_key_pem_to_der(pkey, #pkey, out, errmsg) + local rc = ffi.C.ngx_http_lua_ffi_priv_key_pem_to_der(pkey, #pkey, nil, out, errmsg) if rc < 1 then ngx.log(ngx.ERR, "failed to parse PEM priv key: ", ffi.string(errmsg[0])) @@ -370,7 +371,7 @@ lua ssl server name: "test.com" GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 56 bytes. received: HTTP/1.1 201 Created received: Server: nginx @@ -424,7 +425,7 @@ lua ssl server name: "test.com" out = ffi.new("char [?]", #pkey) - local rc = ffi.C.ngx_http_lua_ffi_priv_key_pem_to_der(pkey, #pkey, out, errmsg) + local rc = ffi.C.ngx_http_lua_ffi_priv_key_pem_to_der(pkey, #pkey, nil, out, errmsg) if rc < 1 then ngx.log(ngx.ERR, "failed to parse PEM priv key: ", ffi.string(errmsg[0])) @@ -498,7 +499,7 @@ lua ssl server name: "test.com" GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 56 bytes. received: HTTP/1.1 201 Created received: Server: nginx @@ -649,7 +650,7 @@ failed to parse PEM priv key: PEM_read_bio_PrivateKey() failed GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 56 bytes. received: HTTP/1.1 201 Created received: Server: nginx @@ -799,7 +800,7 @@ lua ssl server name: "test.com" GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 56 bytes. received: HTTP/1.1 201 Created received: Server: nginx @@ -1026,3 +1027,299 @@ client certificate subject: nil --- no_error_log [error] [alert] + + + +=== TEST 9: simple cert + private key with passphrase +--- http_config + server { + listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl; + server_name test.com; + + ssl_certificate_by_lua_block { + collectgarbage() + + local ffi = require "ffi" + + ffi.cdef[[ + int ngx_http_lua_ffi_cert_pem_to_der(const unsigned char *pem, + size_t pem_len, unsigned char *der, char **err); + + int ngx_http_lua_ffi_priv_key_pem_to_der(const unsigned char *pem, + size_t pem_len, const unsigned char *passphrase, + unsigned char *der, char **err); + + int ngx_http_lua_ffi_ssl_set_der_certificate(void *r, + const char *data, size_t len, char **err); + + int ngx_http_lua_ffi_ssl_set_der_private_key(void *r, + const char *data, size_t len, char **err); + + int ngx_http_lua_ffi_ssl_clear_certs(void *r, char **err); + ]] + + local errmsg = ffi.new("char *[1]") + + local r = require "resty.core.base" .get_request() + if not r then + ngx.log(ngx.ERR, "no request found") + return + end + + ffi.C.ngx_http_lua_ffi_ssl_clear_certs(r, errmsg) + + local f = assert(io.open("t/cert/test_passphrase.crt", "rb")) + local cert = f:read("*all") + f:close() + + local out = ffi.new("char [?]", #cert) + + local rc = ffi.C.ngx_http_lua_ffi_cert_pem_to_der(cert, #cert, out, errmsg) + if rc < 1 then + ngx.log(ngx.ERR, "failed to parse PEM cert: ", + ffi.string(errmsg[0])) + return + end + + local cert_der = ffi.string(out, rc) + + local rc = ffi.C.ngx_http_lua_ffi_ssl_set_der_certificate(r, cert_der, #cert_der, errmsg) + if rc ~= 0 then + ngx.log(ngx.ERR, "failed to set DER cert: ", + ffi.string(errmsg[0])) + return + end + + f = assert(io.open("t/cert/test_passphrase.key", "rb")) + local pkey = f:read("*all") + f:close() + + local passphrase = "123456" + + out = ffi.new("char [?]", #pkey) + + local rc = ffi.C.ngx_http_lua_ffi_priv_key_pem_to_der(pkey, #pkey, passphrase, out, errmsg) + if rc < 1 then + ngx.log(ngx.ERR, "failed to parse PEM priv key: ", + ffi.string(errmsg[0])) + return + end + + local pkey_der = ffi.string(out, rc) + + local rc = ffi.C.ngx_http_lua_ffi_ssl_set_der_private_key(r, pkey_der, #pkey_der, errmsg) + if rc ~= 0 then + ngx.log(ngx.ERR, "failed to set DER priv key: ", + ffi.string(errmsg[0])) + return + end + } + + ssl_certificate ../../cert/test2.crt; + ssl_certificate_key ../../cert/test2.key; + + server_tokens off; + location /foo { + default_type 'text/plain'; + content_by_lua_block { ngx.status = 201 ngx.say("foo") ngx.exit(201) } + more_clear_headers Date; + } + } +--- config + server_tokens off; + lua_ssl_trusted_certificate ../../cert/test_passphrase.crt; + + location /t { + content_by_lua_block { + do + local sock = ngx.socket.tcp() + + sock:settimeout(2000) + + local ok, err = sock:connect("unix:$TEST_NGINX_HTML_DIR/nginx.sock") + if not ok then + ngx.say("failed to connect: ", err) + return + end + + ngx.say("connected: ", ok) + + local sess, err = sock:sslhandshake(nil, "test.com", false) + if not sess then + ngx.say("failed to do SSL handshake: ", err) + return + end + + ngx.say("ssl handshake: ", type(sess)) + + local req = "GET /foo HTTP/1.0\r\nHost: test.com\r\nConnection: close\r\n\r\n" + local bytes, err = sock:send(req) + if not bytes then + ngx.say("failed to send http request: ", err) + return + end + + ngx.say("sent http request: ", bytes, " bytes.") + + while true do + local line, err = sock:receive() + if not line then + -- ngx.say("failed to recieve response status line: ", err) + break + end + + ngx.say("received: ", line) + end + + local ok, err = sock:close() + ngx.say("close: ", ok, " ", err) + end -- do + -- collectgarbage() + } + } + +--- request +GET /t +--- response_body +connected: 1 +ssl handshake: cdata +sent http request: 56 bytes. +received: HTTP/1.1 201 Created +received: Server: nginx +received: Content-Type: text/plain +received: Content-Length: 4 +received: Connection: close +received: +received: foo +close: 1 nil + +--- error_log +lua ssl server name: "test.com" + +--- no_error_log +[error] +[alert] + + + +=== TEST 10: Raw SSL pointer +--- http_config + server { + listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl; + server_name test.com; + + ssl_certificate_by_lua_block { + collectgarbage() + + local ffi = require "ffi" + require "defines" + + local r = require "resty.core.base" .get_request() + if not r then + ngx.log(ngx.ERR, "no request found") + return + end + + local ssl = ffi.C.ngx_http_lua_ffi_get_req_ssl_pointer(r); + if ssl == nil then + ngx.log(ngx.ERR, "failed to retrieve SSL*") + return + end + + ffi.cdef[[ + const char *SSL_get_servername(const void *, const int); + ]] + local TLSEXT_NAMETYPE_host_name = 0 + local sni = ffi.C.SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name) + if sni == nil then + ngx.log(ngx.ERR, "failed to get sni") + return + end + + ngx.log(ngx.INFO, "SNI is ", ffi.string(sni)) + } + + ssl_certificate ../../cert/test.crt; + ssl_certificate_key ../../cert/test.key; + + server_tokens off; + location /foo { + default_type 'text/plain'; + content_by_lua_block { ngx.status = 201 ngx.say("foo") ngx.exit(201) } + more_clear_headers Date; + } + } +--- config + server_tokens off; + lua_ssl_trusted_certificate ../../cert/test.crt; + + location /t { + content_by_lua_block { + do + local sock = ngx.socket.tcp() + + sock:settimeout(2000) + + local ok, err = sock:connect("unix:$TEST_NGINX_HTML_DIR/nginx.sock") + if not ok then + ngx.say("failed to connect: ", err) + return + end + + ngx.say("connected: ", ok) + + local sess, err = sock:sslhandshake(nil, "test.com", true) + if not sess then + ngx.say("failed to do SSL handshake: ", err) + return + end + + ngx.say("ssl handshake: ", type(sess)) + + local req = "GET /foo HTTP/1.0\r\nHost: test.com\r\nConnection: close\r\n\r\n" + local bytes, err = sock:send(req) + if not bytes then + ngx.say("failed to send http request: ", err) + return + end + + ngx.say("sent http request: ", bytes, " bytes.") + + while true do + local line, err = sock:receive() + if not line then + -- ngx.say("failed to receive response status line: ", err) + break + end + + ngx.say("received: ", line) + end + + local ok, err = sock:close() + ngx.say("close: ", ok, " ", err) + end -- do + -- collectgarbage() + } + } + +--- request +GET /t +--- response_body +connected: 1 +ssl handshake: cdata +sent http request: 56 bytes. +received: HTTP/1.1 201 Created +received: Server: nginx +received: Content-Type: text/plain +received: Content-Length: 4 +received: Connection: close +received: +received: foo +close: 1 nil + +--- error_log +SNI is test.com + +--- no_error_log +[error] +[alert] diff --git a/src/deps/src/lua-nginx-module/t/142-ssl-session-store.t b/src/deps/src/lua-nginx-module/t/142-ssl-session-store.t index 14e90574b..61598732b 100644 --- a/src/deps/src/lua-nginx-module/t/142-ssl-session-store.t +++ b/src/deps/src/lua-nginx-module/t/142-ssl-session-store.t @@ -77,7 +77,7 @@ __DATA__ GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata close: 1 nil --- error_log @@ -86,11 +86,11 @@ lua ssl server name: "test.com" --- no_error_log [error] [alert] ---- grep_error_log eval: qr/ssl_session_store_by_lua_block:.*?,|\bssl session store: connection reusable: \d+|\breusable connection: \d+/ +--- grep_error_log eval: qr/ssl_session_store_by_lua\(nginx.conf:\d+\):.*?,|\bssl session store: connection reusable: \d+|\breusable connection: \d+/ --- grep_error_log_out eval qr/^reusable connection: 0 ssl session store: connection reusable: 0 -ssl_session_store_by_lua_block:1: ssl session store by lua is running!, +ssl_session_store_by_lua\(nginx\.conf:25\):1: ssl session store by lua is running!, /m, @@ -152,7 +152,7 @@ ssl_session_store_by_lua_block:1: ssl session store by lua is running!, GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata close: 1 nil --- error_log @@ -227,7 +227,7 @@ API disabled in the context of ssl_session_store_by_lua* GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata close: 1 nil --- error_log @@ -319,7 +319,7 @@ my timer run! GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata close: 1 nil --- error_log @@ -390,7 +390,7 @@ API disabled in the context of ssl_session_store_by_lua* GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata close: 1 nil --- error_log @@ -462,7 +462,7 @@ ngx.exit does not yield and the error code is eaten. GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata close: 1 nil --- error_log @@ -532,11 +532,11 @@ ssl_session_store_by_lua*: handler return value: 0, sess new cb exit code: 0 GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata close: 1 nil --- error_log -failed to run session_store_by_lua*: ssl_session_store_by_lua_block:2: bad bad bad +failed to run session_store_by_lua*: ssl_session_store_by_lua(nginx.conf:25):2: bad bad bad --- no_error_log should never reached here @@ -600,7 +600,7 @@ should never reached here GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata close: 1 nil --- error_log @@ -671,14 +671,14 @@ get_phase: ssl_session_store GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata close: 1 nil --- error_log eval [ 'lua ssl server name: "test.com"', qr/elapsed in ssl cert by lua: 0.(?:09|1[01])\d+,/, -'ssl_session_store_by_lua_block:1: ssl store session by lua is running!', +'ssl_session_store_by_lua(nginx.conf:25):1: ssl store session by lua is running!', ] --- no_error_log @@ -744,7 +744,7 @@ print("ssl store session by lua is running!") GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata close: 1 nil --- error_log @@ -820,7 +820,7 @@ a.lua:1: ssl store session by lua is running! GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata close: 1 nil --- no_error_log @@ -891,12 +891,12 @@ qr/\[emerg\] .*? "ssl_session_store_by_lua_block" directive is not allowed here GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata close: 1 nil --- error_log lua ssl server name: "test.com" -ssl_session_store_by_lua_block:1: ssl session store by lua is running! +ssl_session_store_by_lua(nginx.conf:25):1: ssl session store by lua is running! --- no_error_log [error] @@ -955,7 +955,7 @@ ssl_session_store_by_lua_block:1: ssl session store by lua is running! GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata close: 1 nil --- error_log eval qr/ssl_session_store_by_lua\*: skipped since TLS version >= 1\.3 \(\d+\)/ diff --git a/src/deps/src/lua-nginx-module/t/143-ssl-session-fetch.t b/src/deps/src/lua-nginx-module/t/143-ssl-session-fetch.t index 084e7d596..8c5174dd9 100644 --- a/src/deps/src/lua-nginx-module/t/143-ssl-session-fetch.t +++ b/src/deps/src/lua-nginx-module/t/143-ssl-session-fetch.t @@ -80,10 +80,10 @@ __DATA__ GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata close: 1 nil ---- grep_error_log eval: qr/ssl_session_fetch_by_lua_block:.*?,|\bssl session fetch: connection reusable: \d+|\breusable connection: \d+/ +--- grep_error_log eval: qr/ssl_session_fetch_by_lua\(nginx\.conf:\d+\):.*?,|\bssl session fetch: connection reusable: \d+|\breusable connection: \d+/ --- grep_error_log_out eval # Since nginx version 1.17.9, nginx call ngx_reusable_connection(c, 0) @@ -93,11 +93,11 @@ $Test::Nginx::Util::NginxVersion >= 1.017009 ? qr/\A(?:reusable connection: [01]\n)+\z/s, qr/^reusable connection: 0 ssl session fetch: connection reusable: 0 -ssl_session_fetch_by_lua_block:1: ssl fetch sess by lua is running!, +ssl_session_fetch_by_lua\(nginx\.conf:25\):1: ssl fetch sess by lua is running!, /m, qr/^reusable connection: 0 ssl session fetch: connection reusable: 0 -ssl_session_fetch_by_lua_block:1: ssl fetch sess by lua is running!, +ssl_session_fetch_by_lua\(nginx\.conf:25\):1: ssl fetch sess by lua is running!, /m, ] : @@ -106,12 +106,12 @@ qr/\A(?:reusable connection: [01]\n)+\z/s, qr/^reusable connection: 1 ssl session fetch: connection reusable: 1 reusable connection: 0 -ssl_session_fetch_by_lua_block:1: ssl fetch sess by lua is running!, +ssl_session_fetch_by_lua\(nginx\.conf:25\):1: ssl fetch sess by lua is running!, /m, qr/^reusable connection: 1 ssl session fetch: connection reusable: 1 reusable connection: 0 -ssl_session_fetch_by_lua_block:1: ssl fetch sess by lua is running!, +ssl_session_fetch_by_lua\(nginx\.conf:25\):1: ssl fetch sess by lua is running!, /m, ] --- no_error_log @@ -180,7 +180,7 @@ ssl_session_fetch_by_lua_block:1: ssl fetch sess by lua is running!, GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata close: 1 nil --- grep_error_log eval @@ -264,7 +264,7 @@ qr/elapsed in ssl fetch session by lua: 0.(?:09|1[01])\d+,/, GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata close: 1 nil --- grep_error_log eval @@ -365,7 +365,7 @@ qr/my timer run!/s GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata close: 1 nil --- grep_error_log eval @@ -446,7 +446,7 @@ qr/received memc reply: OK/s GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata close: 1 nil --- grep_error_log eval @@ -527,7 +527,7 @@ should never reached here GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata close: 1 nil --- grep_error_log eval @@ -609,7 +609,7 @@ should never reached here GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata close: 1 nil --- grep_error_log eval @@ -690,18 +690,18 @@ should never reached here GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata close: 1 nil --- grep_error_log eval -qr/ssl_session_fetch_by_lua_block:2: bad bad bad/s +qr/ssl_session_fetch_by_lua\(nginx.conf:\d+\):2: bad bad bad/s --- grep_error_log_out eval [ '', -'ssl_session_fetch_by_lua_block:2: bad bad bad +'ssl_session_fetch_by_lua(nginx.conf:25):2: bad bad bad ', -'ssl_session_fetch_by_lua_block:2: bad bad bad +'ssl_session_fetch_by_lua(nginx.conf:25):2: bad bad bad ', ] @@ -773,19 +773,19 @@ should never reached here GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata close: 1 nil --- grep_error_log eval -qr/ssl_session_fetch_by_lua_block:3: bad bad bad|ssl_session_fetch_by_lua\*: sess get cb exit code: 0/s +qr/ssl_session_fetch_by_lua\(nginx.conf:\d+\):3: bad bad bad|ssl_session_fetch_by_lua\*: sess get cb exit code: 0/s --- grep_error_log_out eval [ '', -'ssl_session_fetch_by_lua_block:3: bad bad bad +'ssl_session_fetch_by_lua(nginx.conf:25):3: bad bad bad ssl_session_fetch_by_lua*: sess get cb exit code: 0 ', -'ssl_session_fetch_by_lua_block:3: bad bad bad +'ssl_session_fetch_by_lua(nginx.conf:25):3: bad bad bad ssl_session_fetch_by_lua*: sess get cb exit code: 0 ', @@ -853,7 +853,7 @@ should never reached here GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata close: 1 nil --- grep_error_log eval @@ -939,7 +939,7 @@ qr/get_phase: ssl_session_fetch/s GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata close: 1 nil --- grep_error_log eval @@ -1025,7 +1025,7 @@ print("ssl fetch sess by lua is running!") GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata close: 1 nil --- grep_error_log eval @@ -1109,18 +1109,18 @@ qr/\S+:\d+: ssl fetch sess by lua is running!/s GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata close: 1 nil --- grep_error_log eval -qr/ssl_session_fetch_by_lua_block:1: ssl fetch sess by lua is running!/s +qr/ssl_session_fetch_by_lua\(nginx.conf:\d+\):1: ssl fetch sess by lua is running!/s --- grep_error_log_out eval [ '', -'ssl_session_fetch_by_lua_block:1: ssl fetch sess by lua is running! +'ssl_session_fetch_by_lua(nginx.conf:25):1: ssl fetch sess by lua is running! ', -'ssl_session_fetch_by_lua_block:1: ssl fetch sess by lua is running! +'ssl_session_fetch_by_lua(nginx.conf:25):1: ssl fetch sess by lua is running! ', ] @@ -1285,7 +1285,7 @@ GET /t GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata close: 1 nil --- no_error_log [warn] @@ -1346,9 +1346,9 @@ close: 1 nil GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata close: 1 nil ---- grep_error_log eval: qr/ssl_session_fetch_by_lua_block:.*?,|\bssl session fetch: connection reusable: \d+|\breusable connection: \d+/ +--- grep_error_log eval: qr/ssl_session_fetch_by_lua\(nginx\.conf:\d+\):.*?,|\bssl session fetch: connection reusable: \d+|\breusable connection: \d+/ --- grep_error_log_out eval # Since nginx version 1.17.9, nginx call ngx_reusable_connection(c, 0) # before call ssl callback function @@ -1357,11 +1357,11 @@ $Test::Nginx::Util::NginxVersion >= 1.017009 ? qr/\A(?:reusable connection: [01]\n)+\z/s, qr/^reusable connection: 0 ssl session fetch: connection reusable: 0 -ssl_session_fetch_by_lua_block:1: ssl_session_fetch_by_lua\* is running!, +ssl_session_fetch_by_lua\(nginx\.conf:\d+\):1: ssl_session_fetch_by_lua\* is running!, /m, qr/^reusable connection: 0 ssl session fetch: connection reusable: 0 -ssl_session_fetch_by_lua_block:1: ssl_session_fetch_by_lua\* is running!, +ssl_session_fetch_by_lua\(nginx\.conf:\d+\):1: ssl_session_fetch_by_lua\* is running!, /m, ] : @@ -1370,12 +1370,12 @@ qr/\A(?:reusable connection: [01]\n)+\z/s, qr/^reusable connection: 1 ssl session fetch: connection reusable: 1 reusable connection: 0 -ssl_session_fetch_by_lua_block:1: ssl_session_fetch_by_lua\* is running!, +ssl_session_fetch_by_lua\(nginx\.conf:\d+\):1: ssl_session_fetch_by_lua\* is running!, /m, qr/^reusable connection: 1 ssl session fetch: connection reusable: 1 reusable connection: 0 -ssl_session_fetch_by_lua_block:1: ssl_session_fetch_by_lua\* is running!, +ssl_session_fetch_by_lua\(nginx\.conf:\d+\):1: ssl_session_fetch_by_lua\* is running!, /m, ] --- no_error_log @@ -1444,7 +1444,7 @@ ssl_session_fetch_by_lua_block:1: ssl_session_fetch_by_lua\* is running!, GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata close: 1 nil --- grep_error_log eval qr/elapsed in ssl_session_fetch_by_lua\*: 0\.(?:09|1[01])\d+,/, @@ -1537,7 +1537,7 @@ qr/elapsed in ssl_session_fetch_by_lua\*: 0\.(?:09|1[01])\d+,/, GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata close: 1 nil --- grep_error_log eval: qr/received memc reply of \d+ bytes/ --- grep_error_log_out eval @@ -1632,7 +1632,7 @@ close: 1 nil GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata close: 1 nil --- grep_error_log eval: qr/uthread: [^.,]+/ --- grep_error_log_out eval @@ -1732,7 +1732,7 @@ uthread: failed to kill: already waited or killed GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata close: 1 nil --- grep_error_log eval: qr/uthread: [^.,]+/ --- grep_error_log_out eval diff --git a/src/deps/src/lua-nginx-module/t/145-shdict-list.t b/src/deps/src/lua-nginx-module/t/145-shdict-list.t index 6a4759cd0..5672adbc5 100644 --- a/src/deps/src/lua-nginx-module/t/145-shdict-list.t +++ b/src/deps/src/lua-nginx-module/t/145-shdict-list.t @@ -827,3 +827,27 @@ GET /test aa list value: nil --- no_error_log [error] + + + +=== TEST 22: lpush return nil +--- http_config + lua_shared_dict dogs 100k; +--- config + location = /test { + content_by_lua_block { + local dogs = ngx.shared.dogs + for i = 1, 2920 + do + local len, err = dogs:lpush("foo", "bar") + end + local len, err = dogs:lpush("foo", "bar") + ngx.say(len) + } + } +--- request +GET /test +--- response_body +nil +--- no_error_log +[error] diff --git a/src/deps/src/lua-nginx-module/t/155-tls13.t b/src/deps/src/lua-nginx-module/t/155-tls13.t index 9f7cf86d2..4e684cd33 100644 --- a/src/deps/src/lua-nginx-module/t/155-tls13.t +++ b/src/deps/src/lua-nginx-module/t/155-tls13.t @@ -91,7 +91,7 @@ __DATA__ GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata --- user_files eval ">>> test.key diff --git a/src/deps/src/lua-nginx-module/t/158-global-var.t b/src/deps/src/lua-nginx-module/t/158-global-var.t index def3b7418..3f5db60fa 100644 --- a/src/deps/src/lua-nginx-module/t/158-global-var.t +++ b/src/deps/src/lua-nginx-module/t/158-global-var.t @@ -60,10 +60,10 @@ __DATA__ --- response_body_like chomp \A[12]\n\z --- grep_error_log eval -qr/(old foo: \d+|\[\w+\].*?writing a global Lua variable \('[^'\s]+'\)|set_by_lua:\d+: in main chunk, )/ +qr/(old foo: \d+|\[\w+\].*?writing a global Lua variable \('[^'\s]+'\)|set_by_lua\(nginx.conf:\d+\):\d+: in main chunk, )/ --- grep_error_log_out eval [qr/\A\[warn\] .*?writing a global Lua variable \('foo'\) -set_by_lua:3: in main chunk, \n\z/, "old foo: 1\n"] +set_by_lua\(nginx.conf:40\):3: in main chunk, \n\z/, "old foo: 1\n"] @@ -154,10 +154,10 @@ content_by_lua\(nginx\.conf:\d+\):\d+: in main chunk, \n\z/, "old foo: 1\n"] --- response_body_like chomp \A(?:nil|1)\n\z --- grep_error_log eval -qr/(old foo: \d+|\[\w+\].*?writing a global Lua variable \('[^'\s]+'\)|\w+_by_lua:\d+: in main chunk, )/ +qr/(old foo: \d+|\[\w+\].*?writing a global Lua variable \('[^'\s]+'\)|\w+_by_lua\(nginx\.conf:\d+\):\d+: in main chunk, )/ --- grep_error_log_out eval [qr/\A\[warn\] .*?writing a global Lua variable \('foo'\) -header_filter_by_lua:3: in main chunk, \n\z/, "old foo: 1\n"] +header_filter_by_lua\(nginx.conf:43\):3: in main chunk, \n\z/, "old foo: 1\n"] @@ -179,10 +179,10 @@ header_filter_by_lua:3: in main chunk, \n\z/, "old foo: 1\n"] --- response_body_like chomp \A(?:nil|2)\n\z --- grep_error_log eval -qr/(old foo: \d+|\[\w+\].*?writing a global Lua variable \('[^'\s]+'\)|\w+_by_lua:\d+: in main chunk,)/ +qr/(old foo: \d+|\[\w+\].*?writing a global Lua variable \('[^'\s]+'\)|\w+_by_lua\(nginx\.conf:\d+\):\d+: in main chunk,)/ --- grep_error_log_out eval [qr/\[warn\] .*?writing a global Lua variable \('foo'\) -body_filter_by_lua:3: in main chunk, +body_filter_by_lua\(nginx.conf:43\):3: in main chunk, old foo: 1\n\z/, "old foo: 2\nold foo: 3\n"] @@ -297,10 +297,10 @@ log_by_lua\(nginx\.conf:\d+\):\d+: in main chunk\n\z/, "old foo: 1\n"] --- response_body_like chomp \A[12]done\n\z --- grep_error_log eval -qr/(old foo: \d+|\[\w+\].*?writing a global Lua variable \('[^'\s]+'\)|\w+_by_lua:\d+: in main chunk)/ +qr/(old foo: \d+|\[\w+\].*?writing a global Lua variable \('[^'\s]+'\)|\w+_by_lua\(nginx.conf:\d+\):\d+: in main chunk)/ --- grep_error_log_out eval [qr/\A\[warn\] .*?writing a global Lua variable \('foo'\) -ssl_certificate_by_lua:3: in main chunk\n\z/, "old foo: 1\n"] +ssl_certificate_by_lua\(nginx.conf:28\):3: in main chunk\n\z/, "old foo: 1\n"] diff --git a/src/deps/src/lua-nginx-module/t/160-disable-init-by-lua.t b/src/deps/src/lua-nginx-module/t/160-disable-init-by-lua.t index dd0098d0d..e98c136dc 100644 --- a/src/deps/src/lua-nginx-module/t/160-disable-init-by-lua.t +++ b/src/deps/src/lua-nginx-module/t/160-disable-init-by-lua.t @@ -12,6 +12,9 @@ my $http_config = <<_EOC_; function set_up_ngx_tmp_conf(conf) if conf == nil then conf = [[ + # to prevent the test process from overwriting the + # original pid file + pid logs/test_nginx.pid; events { worker_connections 64; } @@ -150,6 +153,7 @@ qr/\[error\] .*? init_by_lua:\d+: run init_by_lua/ location = /t { content_by_lua_block { local conf = [[ + pid logs/test_nginx.pid; events { worker_connections 64; } diff --git a/src/deps/src/lua-nginx-module/t/162-exit-worker.t b/src/deps/src/lua-nginx-module/t/162-exit-worker.t index 313861761..7aff2a619 100644 --- a/src/deps/src/lua-nginx-module/t/162-exit-worker.t +++ b/src/deps/src/lua-nginx-module/t/162-exit-worker.t @@ -6,7 +6,7 @@ master_on(); repeat_each(2); # NB: the shutdown_error_log block is independent from repeat times -plan tests => repeat_each() * (blocks() * 2 + 1) + 13; +plan tests => repeat_each() * (blocks() * 2 + 1) + 15; #log_level("warn"); no_long_string(); @@ -194,3 +194,49 @@ qr/cache loader process \d+ exited/, qr/cache manager process \d+ exited/, qr/hello from exit worker by lua, process type: worker/, ] + + + +=== TEST 8: syntax error in exit_worker_by_lua_block +--- http_config + exit_worker_by_lua_block { + ngx.log(ngx.debug, "pass") + error("failed to init" + ngx.log(ngx.debug, "unreachable") + } +--- config + location /t { + content_by_lua_block { + ngx.say("hello world") + } + } +--- request + GET /t +--- response_body +hello world +--- shutdown_error_log +exit_worker_by_lua error: exit_worker_by_lua(nginx.conf:25):4: ')' expected (to close '(' at line 3) near 'ngx' + + + +=== TEST 9: syntax error in exit_worker_by_lua_file +--- http_config + exit_worker_by_lua_file html/exit.lua; +--- config + location /t { + content_by_lua_block { + ngx.say("hello world") + } + } +--- user_files +>>> exit.lua + ngx.log(ngx.debug, "pass") + error("failed to init" + ngx.log(ngx.debug, "unreachable") + +--- request + GET /t +--- response_body +hello world +--- shutdown_error_log eval +qr|exit_worker_by_lua_file error: .*?t/servroot\w*/html/exit.lua:3: '\)' expected \(to close '\(' at line 2\) near 'ngx'| diff --git a/src/deps/src/lua-nginx-module/t/162-socket-tls-handshake.t b/src/deps/src/lua-nginx-module/t/162-socket-tls-handshake.t new file mode 100644 index 000000000..80fb2f982 --- /dev/null +++ b/src/deps/src/lua-nginx-module/t/162-socket-tls-handshake.t @@ -0,0 +1,373 @@ +# vim:set ft= ts=4 sw=4 et fdm=marker: + +use Test::Nginx::Socket::Lua; + +repeat_each(2); + +plan tests => repeat_each() * 43; + +$ENV{TEST_NGINX_RESOLVER} ||= '8.8.8.8'; + +log_level 'debug'; + +no_long_string(); +#no_diff(); + +sub read_file { + my $infile = shift; + open my $in, $infile + or die "cannot open $infile for reading: $!"; + my $cert = do { local $/; <$in> }; + close $in; + $cert; +} + +our $MTLSCA = read_file("t/cert/mtls_ca.crt"); +our $MTLSClient = read_file("t/cert/mtls_client.crt"); +our $MTLSClientKey = read_file("t/cert/mtls_client.key"); +our $MTLSServer = read_file("t/cert/mtls_server.crt"); +our $MTLSServerKey = read_file("t/cert/mtls_server.key"); + +our $HtmlDir = html_dir; + +our $mtls_http_config = <<"_EOC_"; +server { + listen unix:$::HtmlDir/mtls.sock ssl; + + ssl_certificate $::HtmlDir/mtls_server.crt; + ssl_certificate_key $::HtmlDir/mtls_server.key; + ssl_client_certificate $::HtmlDir/mtls_ca.crt; + ssl_verify_client on; + server_tokens off; + + location / { + return 200 "hello, \$ssl_client_s_dn"; + } +} +_EOC_ + +our $mtls_user_files = <<"_EOC_"; +>>> mtls_server.key +$::MTLSServerKey +>>> mtls_server.crt +$::MTLSServer +>>> mtls_ca.crt +$::MTLSCA +>>> mtls_client.key +$::MTLSClientKey +>>> mtls_client.crt +$::MTLSClient +_EOC_ + +run_tests(); + +__DATA__ + +=== TEST 1: sanity: www.bing.com +--- config + server_tokens off; + resolver $TEST_NGINX_RESOLVER ipv6=off; + + location /t { + content_by_lua_block { + -- avoid flushing bing in "check leak" testing mode: + local counter = package.loaded.counter + if not counter then + counter = 1 + elseif counter >= 2 then + return ngx.exit(503) + else + counter = counter + 1 + end + + package.loaded.counter = counter + + do + local sock = ngx.socket.tcp() + sock:settimeout(2000) + + local ok, err = sock:connect("www.bing.com", 443) + if not ok then + ngx.say("failed to connect: ", err) + return + end + + ngx.say("connected: ", ok) + + local sess, err = sock:sslhandshake() + if not sess then + ngx.say("failed to do SSL handshake: ", err) + return + end + + ngx.say("ssl handshake: ", type(sess)) + + local req = "GET / HTTP/1.1\r\nHost: www.bing.com\r\nConnection: close\r\n\r\n" + local bytes, err = sock:send(req) + if not bytes then + ngx.say("failed to send http request: ", err) + return + end + + ngx.say("sent http request: ", bytes, " bytes.") + + local line, err = sock:receive() + if not line then + ngx.say("failed to receive response status line: ", err) + return + end + + ngx.say("received: ", line) + + local ok, err = sock:close() + ngx.say("close: ", ok, " ", err) + end -- do + + collectgarbage() + } + } +--- request +GET /t +--- response_body_like chop +\Aconnected: 1 +ssl handshake: cdata +sent http request: 57 bytes. +received: HTTP/1.1 (?:200 OK|302 Found) +close: 1 nil +\z +--- grep_error_log eval: qr/lua ssl (?:set|save|free) session: [0-9A-F]+/ +--- grep_error_log_out eval +qr/^lua ssl save session: ([0-9A-F]+) +lua ssl free session: ([0-9A-F]+) +$/ +--- no_error_log +lua ssl server name: +SSL reused session +[error] +[alert] +--- timeout: 5 + + + +=== TEST 2: mutual TLS handshake, upstream is not accessible without client certs +--- http_config eval: $::mtls_http_config +--- config eval +" + location /t { + content_by_lua_block { + local sock = ngx.socket.tcp() + local ok, err = sock:connect('unix:$::HtmlDir/mtls.sock') + if not ok then + ngx.say('failed to connect: ', err) + end + + assert(sock:sslhandshake()) + + ngx.say('connected: ', ok) + + local req = 'GET /\\r\\n' + + local bytes, err = sock:send(req) + if not bytes then + ngx.say('failed to send request: ', err) + return + end + + ngx.say('request sent: ', bytes) + + ngx.say(sock:receive('*a')) + + assert(sock:close()) + } + } +" +--- user_files eval: $::mtls_user_files +--- request +GET /t +--- response_body_like: 400 No required SSL certificate was sent +--- no_error_log +[alert] +[error] +[crit] +[emerg] + + + +=== TEST 3: mutual TLS handshake, upstream is accessible with client certs +--- http_config eval: $::mtls_http_config +--- config eval +" + location /t { + content_by_lua_block { + local sock = ngx.socket.tcp() + local ok, err = sock:connect('unix:$::HtmlDir/mtls.sock') + if not ok then + ngx.say('failed to connect: ', err) + end + + local f = assert(io.open('$::HtmlDir/mtls_client.crt')) + local cert_data = f:read('*a') + f:close() + + f = assert(io.open('$::HtmlDir/mtls_client.key')) + local key_data = f:read('*a') + f:close() + + local ssl = require('ngx.ssl') + + local chain = assert(ssl.parse_pem_cert(cert_data)) + local priv = assert(ssl.parse_pem_priv_key(key_data)) + + sock:setclientcert(chain, priv) + + assert(sock:sslhandshake()) + + ngx.say('connected: ', ok) + + local req = 'GET /\\r\\n' + + local bytes, err = sock:send(req) + if not bytes then + ngx.say('failed to send request: ', err) + return + end + + ngx.say('request sent: ', bytes) + + ngx.say(sock:receive('*a')) + + assert(sock:close()) + } + } +" +--- user_files eval: $::mtls_user_files +--- request +GET /t +--- response_body +connected: 1 +request sent: 7 +hello, CN=foo@example.com,O=OpenResty,ST=California,C=US +--- no_error_log +[alert] +[error] +[crit] +[emerg] + + + +=== TEST 4: incorrect type of client cert +--- config + location /t { + content_by_lua_block { + local sock = ngx.socket.tcp() + + local ok, err = sock:setclientcert("doesnt", "work") + if not ok then + ngx.say('failed to setclientcert: ', err) + return + end + + assert(sock:close()) + } + } +--- request +GET /t +--- response_body +failed to setclientcert: bad cert arg: cdata expected, got string +--- no_error_log +[alert] +[error] +[crit] +[emerg] + + + +=== TEST 5: incorrect type of client key +--- config eval +" + location /t { + content_by_lua_block { + local sock = ngx.socket.tcp() + + local f = assert(io.open('$::HtmlDir/mtls_client.crt')) + local cert_data = f:read('*a') + f:close() + + local ssl = require('ngx.ssl') + + local chain = assert(ssl.parse_pem_cert(cert_data)) + + local ok, err = sock:setclientcert(chain, 'work') + if not ok then + ngx.say('failed to setclientcert: ', err) + return + end + + assert(sock:close()) + } + } +" +--- user_files eval: $::mtls_user_files +--- request +GET /t +--- response_body +failed to setclientcert: bad pkey arg: cdata expected, got string +--- no_error_log +[alert] +[error] +[crit] +[emerg] + + + +=== TEST 6: missing client cert +--- config + location /t { + content_by_lua_block { + local sock = ngx.socket.tcp() + + local ok, err = sock:setclientcert(nil, "work") + if not ok then + ngx.say('failed to setclientcert: ', err) + return + end + + assert(sock:close()) + } + } +--- request +GET /t +--- response_body +failed to setclientcert: client certificate must be supplied with corresponding private key +--- no_error_log +[alert] +[error] +[crit] +[emerg] + + + +=== TEST 7: missing private key +--- config + location /t { + content_by_lua_block { + local sock = ngx.socket.tcp() + + local ok, err = sock:setclientcert('doesnt', nil) + if not ok then + ngx.say('failed to setclientcert: ', err) + return + end + + assert(sock:close()) + } + } +--- request +GET /t +--- response_body +failed to setclientcert: client certificate must be supplied with corresponding private key +--- no_error_log +[alert] +[error] +[crit] +[emerg] diff --git a/src/deps/src/lua-nginx-module/t/166-ssl-client-hello.t b/src/deps/src/lua-nginx-module/t/166-ssl-client-hello.t index 79787f63a..da021300a 100644 --- a/src/deps/src/lua-nginx-module/t/166-ssl-client-hello.t +++ b/src/deps/src/lua-nginx-module/t/166-ssl-client-hello.t @@ -100,7 +100,7 @@ __DATA__ GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 56 bytes. received: HTTP/1.1 201 Created received: Server: nginx @@ -209,7 +209,7 @@ ssl_client_hello_by_lua:1: ssl client hello by lua is running!,/ GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 56 bytes. received: HTTP/1.1 201 Created received: Server: nginx @@ -314,7 +314,7 @@ qr/elapsed in ssl client hello by lua: 0.(?:09|1\d)\d+,/, GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 56 bytes. received: HTTP/1.1 201 Created received: Server: nginx @@ -432,7 +432,7 @@ my timer run! GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 56 bytes. received: HTTP/1.1 201 Created received: Server: nginx @@ -924,7 +924,7 @@ should never reached here GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata --- error_log lua ssl server name: "test.com" @@ -1135,7 +1135,7 @@ print("ssl client hello by lua is running!") GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 56 bytes. received: HTTP/1.1 201 Created received: Server: nginx @@ -1246,7 +1246,7 @@ a.lua:1: ssl client hello by lua is running! GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 56 bytes. received: HTTP/1.1 201 Created received: Server: nginx @@ -1370,7 +1370,7 @@ lua ssl server name: "test.com" GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 56 bytes. received: HTTP/1.1 201 Created received: Server: nginx @@ -1466,7 +1466,7 @@ GitHub openresty/lua-resty-core#42 GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 56 bytes. received: HTTP/1.1 201 Created received: Server: nginx @@ -1561,7 +1561,7 @@ ssl_client_hello_by_lua:1: ssl client hello by lua is running! GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 56 bytes. received: HTTP/1.1 201 Created received: Server: nginx @@ -1817,7 +1817,7 @@ ssl_client_hello_by_lua:1: ssl client hello by lua is running! GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 56 bytes. received: HTTP/1.1 201 Created received: Server: nginx @@ -2005,7 +2005,7 @@ ssl_client_hello_by_lua:1: ssl client hello by lua is running! GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 57 bytes. received: HTTP/1.1 201 Created received: Server: nginx @@ -2103,7 +2103,7 @@ ssl_client_hello_by_lua:1: ssl client hello by lua in server2 is running! GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 56 bytes. received: HTTP/1.1 201 Created received: Server: nginx @@ -2208,7 +2208,7 @@ ssl_client_hello_by_lua:1: ssl client hello by lua is running! GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 56 bytes. received: HTTP/1.1 201 Created received: Server: nginx @@ -2308,7 +2308,7 @@ client ip: 127.0.0.1 GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 56 bytes. received: HTTP/1.1 201 Created received: Server: nginx @@ -2465,7 +2465,7 @@ qr/elapsed in ssl_client_hello_by_lua\*: 0\.(?:09|1\d)\d+,/, GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata --- no_error_log [error] [alert] @@ -2555,7 +2555,7 @@ ssl handshake: userdata GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata --- no_error_log [error] [alert] diff --git a/src/deps/src/lua-nginx-module/t/166-worker-thread.t b/src/deps/src/lua-nginx-module/t/166-worker-thread.t index 3288f3a15..fd7fdd756 100644 --- a/src/deps/src/lua-nginx-module/t/166-worker-thread.t +++ b/src/deps/src/lua-nginx-module/t/166-worker-thread.t @@ -229,7 +229,7 @@ return {hello=hello} --- request GET /hello --- response_body -false : unsupported argument type +false : unsupported Lua type: LUA_TFUNCTION in the argument @@ -491,7 +491,7 @@ return {hello=hello} --- request GET /hello --- response_body -false : unsupported argument type +false : unsupported Lua type: LUA_TFUNCTION in the argument @@ -524,7 +524,7 @@ return {hello=hello} --- request GET /hello --- response_body -false , unsupported return value +false , unsupported Lua type: LUA_TFUNCTION in the return value @@ -1220,7 +1220,7 @@ GET /hello location /write_log_file { default_type 'text/plain'; - content_by_lua_block { + access_by_lua_block { local ok, err = ngx.run_worker_thread("testpool", "write_log_file", "log", ngx.var.arg_str) if not ok then ngx.say(ok, " : ", err) @@ -1246,3 +1246,513 @@ return {log=log} GET /write_log_file?str=hello --- response_body true + + + +=== TEST 40: shdict get, int value +--- main_config + thread_pool testpool threads=100; +--- http_config eval +" + lua_shared_dict dogs 10m; + lua_package_path '$::HtmlDir/?.lua;./?.lua;;'; +" +--- config +location /dictget { + default_type 'text/plain'; + + access_by_lua_block { + local dogs = ngx.shared.dogs + dogs:set("Jim", 8) + local ok, err = ngx.run_worker_thread("testpool", "test_shdict", "dictget") + ngx.say(ok, ",", err) + } +} +--- user_files +>>> test_shdict.lua +local function dictget(str) + local dogs = ngx.shared.dogs + return dogs:get("Jim") +end +return {dictget=dictget} +--- request +GET /dictget +--- response_body +true,8 + + + +=== TEST 41: shdict set nil in main thread +--- main_config + thread_pool testpool threads=100; +--- http_config eval +" + lua_shared_dict dogs 10m; + lua_package_path '$::HtmlDir/?.lua;./?.lua;;'; +" +--- config +location /dictget { + default_type 'text/plain'; + + access_by_lua_block { + local dogs = ngx.shared.dogs + dogs:set("Jim", 8) + local ok, err = ngx.run_worker_thread("testpool", "test_shdict", "dictget") + ngx.say(ok, ",", err) + dogs:set("Jim", nil) + local ok, err = ngx.run_worker_thread("testpool", "test_shdict", "dictget") + ngx.say(ok, ",", err) + } +} +--- user_files +>>> test_shdict.lua +local function dictget(str) + local dogs = ngx.shared.dogs + return dogs:get("Jim") +end +return {dictget=dictget} +--- request +GET /dictget +--- response_body +true,8 +true,nil + + + +=== TEST 42: shdict set nil in worker thread +--- main_config + thread_pool testpool threads=100; +--- http_config eval +" + lua_shared_dict dogs 10m; + lua_package_path '$::HtmlDir/?.lua;./?.lua;;'; +" +--- config +location /dictsetnil { + default_type 'text/plain'; + + access_by_lua_block { + local dogs = ngx.shared.dogs + dogs:set("Jim", 8) + local ok, err = ngx.run_worker_thread("testpool", "test_shdict", "dictsetnil") + ngx.say(ok, ",", err) + ngx.say(ok, ",", dogs:get("Jim")) + } +} +--- user_files +>>> test_shdict.lua +local function dictsetnil(str) + local dogs = ngx.shared.dogs + return dogs:set("Jim", nil) +end +return {dictsetnil=dictsetnil} +--- request +GET /dictsetnil +--- response_body +true,true +true,nil + + + +=== TEST 43: shdict get_stale +--- main_config + thread_pool testpool threads=100; +--- http_config eval +" + lua_shared_dict dogs 10m; + lua_package_path '$::HtmlDir/?.lua;./?.lua;;'; +" +--- config +location /dictget { + default_type 'text/plain'; + + access_by_lua_block { + local dogs = ngx.shared.dogs + dogs:set("Jim", 8, 1) + ngx.sleep(2) + local ok, err = ngx.run_worker_thread("testpool", "test_shdict", "dictget") + ngx.say(ok, ",", err) + } +} +--- user_files +>>> test_shdict.lua +local function dictget(str) + local dogs = ngx.shared.dogs + return dogs:get_stale("Jim") +end +return {dictget=dictget} +--- request +GET /dictget +--- response_body +true,8 + + + +=== TEST 44: shdict add failed +--- main_config + thread_pool testpool threads=100; +--- http_config eval +" + lua_shared_dict dogs 10m; + lua_package_path '$::HtmlDir/?.lua;./?.lua;;'; +" +--- config +location /dictadd { + default_type 'text/plain'; + + access_by_lua_block { + local dogs = ngx.shared.dogs + dogs:set("Jim", 8) + local ok, err, err2 = ngx.run_worker_thread("testpool", "test_shdict", "dictadd") + ngx.say(ok, ",", err, ",", err2) + } +} +--- user_files +>>> test_shdict.lua +local function dictadd(str) + local dogs = ngx.shared.dogs + local success, err = dogs:add("Jim", "hello") + return success, err +end +return {dictadd=dictadd} +--- request +GET /dictadd +--- response_body +true,false,exists + + + +=== TEST 45: shdict force add +--- main_config + thread_pool testpool threads=100; +--- http_config eval +" + lua_shared_dict dogs 6m; + lua_package_path '$::HtmlDir/?.lua;./?.lua;;'; +" +--- config +location /dictadd { + default_type 'text/plain'; + + access_by_lua_block { + local dogs = ngx.shared.dogs + local bigstr = string.rep("A", 1024*1024*3) + dogs:set("Jim", bigstr) + local ok, ret, err, forcible = ngx.run_worker_thread("testpool", "test_shdict", "dictadd") + ngx.say(ok, ",", ret, ",", forcible, ",", dogs:get("Jim")) + } +} +--- user_files +>>> test_shdict.lua +local function dictadd(str) + local dogs = ngx.shared.dogs + local bigstr = string.rep("A", 1024*1024*5) + local success, err, forcible = dogs:add("King", bigstr) + return success, err, forcible +end +return {dictadd=dictadd} +--- request +GET /dictadd +--- response_body +true,true,true,nil + + + +=== TEST 46: shdict replace +--- main_config + thread_pool testpool threads=100; +--- http_config eval +" + lua_shared_dict dogs 6m; + lua_package_path '$::HtmlDir/?.lua;./?.lua;;'; +" +--- config +location /dictreplace { + default_type 'text/plain'; + + access_by_lua_block { + local dogs = ngx.shared.dogs + local bigstr = string.rep("A", 1024*1024*3) + dogs:set("Jim", bigstr) + local ok, ret, err = ngx.run_worker_thread("testpool", "test_shdict", "dictreplace") + ngx.say(ok, ",", ret, ",", err, ",", dogs:get("Jim")) + } +} +--- user_files +>>> test_shdict.lua +local function dictreplace(str) + local dogs = ngx.shared.dogs + local success, err = dogs:replace("Jim", 8) + return success, err +end +return {dictreplace=dictreplace} +--- request +GET /dictreplace +--- response_body +true,true,nil,8 + + + +=== TEST 47: shdict replace not found +--- main_config + thread_pool testpool threads=100; +--- http_config eval +" + lua_shared_dict dogs 6m; + lua_package_path '$::HtmlDir/?.lua;./?.lua;;'; +" +--- config +location /dictreplace { + default_type 'text/plain'; + + access_by_lua_block { + local dogs = ngx.shared.dogs + local ok, ret, err = ngx.run_worker_thread("testpool", "test_shdict", "dictreplace") + ngx.say(ok, ",", ret, ",", err) + } +} +--- user_files +>>> test_shdict.lua +local function dictreplace(str) + local dogs = ngx.shared.dogs + local success, err = dogs:replace("Jim", 8) + return success, err +end +return {dictreplace=dictreplace} +--- request +GET /dictreplace +--- response_body +true,false,not found + + + +=== TEST 48: shdict incr +--- main_config + thread_pool testpool threads=100; +--- http_config eval +" + lua_shared_dict dogs 6m; + lua_package_path '$::HtmlDir/?.lua;./?.lua;;'; +" +--- config +location /dictincr { + default_type 'text/plain'; + + access_by_lua_block { + local dogs = ngx.shared.dogs + local success, err = dogs:set("Jim", 8) + local ok, ret, err = ngx.run_worker_thread("testpool", "test_shdict", "dictincr") + ngx.say(ok, ",", ret, ",", err, ",", dogs:get("Jim")) + } +} +--- user_files +>>> test_shdict.lua +local function dictincr(str) + local dogs = ngx.shared.dogs + local success, err = dogs:incr("Jim", 1) + return success, err +end +return {dictincr=dictincr} +--- request +GET /dictincr +--- response_body +true,9,nil,9 + + + +=== TEST 49: shdict lpush lpop +--- main_config + thread_pool testpool threads=100; +--- http_config eval +" + lua_shared_dict dogs 6m; + lua_package_path '$::HtmlDir/?.lua;./?.lua;;'; +" +--- config +location /dictlpush { + default_type 'text/plain'; + + access_by_lua_block { + local dogs = ngx.shared.dogs + dogs:lpush("Jim", 8) + dogs:lpush("Jim", 9) + local ok, val, len, err = ngx.run_worker_thread("testpool", "test_shdict", "dictlpush") + ngx.say(ok, ",", val, ",", len, ",", err, ",", dogs:lpop("Jim")) + } +} +--- user_files +>>> test_shdict.lua +local function dictlpush(str) + local dogs = ngx.shared.dogs + local val = dogs:lpop("Jim") + local len, err = dogs:lpush("Jim", 7) + return val, len, err +end +return {dictlpush=dictlpush} +--- request +GET /dictlpush +--- response_body +true,9,2,nil,7 + + + +=== TEST 50: shdict expire ttl +--- main_config + thread_pool testpool threads=100; +--- http_config eval +" + lua_shared_dict dogs 6m; + lua_package_path '$::HtmlDir/?.lua;./?.lua;;'; +" +--- config +location /dictexpire { + default_type 'text/plain'; + + access_by_lua_block { + local dogs = ngx.shared.dogs + dogs:set("Jim", 8) + local ok, success, err = ngx.run_worker_thread("testpool", "test_shdict", "dictexpire") + ngx.say(ok, ",", success, ",", err, ",", dogs:ttl("Jim") <= 1) + } +} +--- user_files +>>> test_shdict.lua +local function dictexpire(str) + local dogs = ngx.shared.dogs + local success, err = dogs:expire("Jim", 1) + return success, err +end +return {dictexpire=dictexpire} +--- request +GET /dictexpire +--- response_body +true,true,nil,true + + + +=== TEST 51: shdict flush_all +--- main_config + thread_pool testpool threads=100; +--- http_config eval +" + lua_shared_dict dogs 6m; + lua_package_path '$::HtmlDir/?.lua;./?.lua;;'; +" +--- config +location /dictexpire { + default_type 'text/plain'; + + access_by_lua_block { + local dogs = ngx.shared.dogs + dogs:set("Jim", 8) + dogs:set("King", 9) + local ok = ngx.run_worker_thread("testpool", "test_shdict", "dictexpire") + ngx.say(ok, ",", dogs:get("Jim"), ",", dogs:get("King")) + } +} +--- user_files +>>> test_shdict.lua +local function dictexpire(str) + local dogs = ngx.shared.dogs + dogs:flush_all() +end +return {dictexpire=dictexpire} +--- request +GET /dictexpire +--- response_body +true,nil,nil + + + +=== TEST 52: shdict get_keys +--- main_config + thread_pool testpool threads=100; +--- http_config eval +" + lua_shared_dict dogs 6m; + lua_package_path '$::HtmlDir/?.lua;./?.lua;;'; +" +--- config +location /dictgetkeys { + default_type 'text/plain'; + + access_by_lua_block { + local dogs = ngx.shared.dogs + dogs:set("Jim", 8) + dogs:set("King", 9) + local ok, keys = ngx.run_worker_thread("testpool", "test_shdict", "dictgetkeys") + ngx.say(ok, ",", table.concat(keys, ":")) + } +} +--- user_files +>>> test_shdict.lua +local function dictgetkeys(str) + local dogs = ngx.shared.dogs + return dogs:get_keys() +end +return {dictgetkeys=dictgetkeys} +--- request +GET /dictgetkeys +--- response_body +true,Jim:King + + + +=== TEST 53: unsupported argument type in self-reference table +--- main_config + thread_pool testpool threads=100; +--- http_config eval + "lua_package_path '$::HtmlDir/?.lua;./?.lua;;';" +--- config +location /hello { + default_type 'text/plain'; + + content_by_lua_block { + local t = {} + t.a = t + local ok, ok_or_err = ngx.run_worker_thread("testpool", "hello", "hello", t) + ngx.say(ok, " , ", ok_or_err) + } +} +--- user_files +>>> hello.lua +local function hello(arg1) + return true +end +return {hello=hello} +--- request +GET /hello +--- response_body +false , suspicious circular references, table depth exceed max depth: 100 in the argument + + + +=== TEST 54: unsupported argument type in circular-reference table +--- main_config + thread_pool testpool threads=100; +--- http_config eval + "lua_package_path '$::HtmlDir/?.lua;./?.lua;;';" +--- config +location /hello { + default_type 'text/plain'; + + content_by_lua_block { + local t = {} + local s = {} + t.a = s + s.b = t + + local ok, ok_or_err = ngx.run_worker_thread("testpool", "hello", "hello", t) + ngx.say(ok, " , ", ok_or_err) + } +} +--- user_files +>>> hello.lua +local function hello(arg1) + return true +end +return {hello=hello} +--- request +GET /hello +--- response_body +false , suspicious circular references, table depth exceed max depth: 100 in the argument diff --git a/src/deps/src/lua-nginx-module/t/167-server-rewrite.t b/src/deps/src/lua-nginx-module/t/167-server-rewrite.t new file mode 100644 index 000000000..152c5ce35 --- /dev/null +++ b/src/deps/src/lua-nginx-module/t/167-server-rewrite.t @@ -0,0 +1,488 @@ +# vim:set ft= ts=4 sw=4 et fdm=marker: + +use Test::Nginx::Socket::Lua; +use t::StapThread; + +our $GCScript = <<_EOC_; +$t::StapThread::GCScript + +F(ngx_http_lua_check_broken_connection) { + println("lua check broken conn") +} + +F(ngx_http_lua_request_cleanup) { + println("lua req cleanup") +} +_EOC_ + +our $StapScript = $t::StapThread::StapScript; + +repeat_each(2); + +plan tests => repeat_each() * (blocks() * 3 + 10); + +#log_level("info"); +#no_long_string(); + +run_tests(); + +__DATA__ + +=== TEST 1: server_rewrite_by_lua_block in http +--- http_config + server_rewrite_by_lua_block { + ngx.ctx.a = "server_rewrite_by_lua_block in http" + } +--- config + location /lua { + content_by_lua_block { + ngx.say(ngx.ctx.a) + ngx.log(ngx.INFO, ngx.ctx.a) + } + } +--- request +GET /lua +--- response_body +server_rewrite_by_lua_block in http +--- error_log +server_rewrite_by_lua_block in http +--- no_error_log +[error] + + + +=== TEST 2: server_rewrite_by_lua_block in server +--- config + server_rewrite_by_lua_block { + ngx.log(ngx.INFO, "server_rewrite_by_lua_block in server") + } + location /lua { + content_by_lua_block { + ngx.say("OK") + } + } +--- request +GET /lua +--- response_body +OK +--- error_log +server_rewrite_by_lua_block in server +--- no_error_log +[error] + + + +=== TEST 3: redirect +--- config + server_rewrite_by_lua_block { + ngx.redirect("/foo") + } +--- request +GET /lua +--- raw_response_headers_like: Location: /foo\r\n +--- response_body_like: 302 Found +--- error_code: 302 +--- no_error_log +[error] + + + +=== TEST 4: flush +--- config + server_rewrite_by_lua_block { + ngx.say("foo") + ngx.flush(true) + } + location /lua { + content_by_lua_block { + ngx.say("OK") + } + } +--- request +GET /lua +--- response_body +foo +--- no_error_log +[error] + + + +=== TEST 5: eof +--- config + server_rewrite_by_lua_block { + ngx.say("foo") + ngx.eof() + } + location /lua { + content_by_lua_block { + ngx.say("OK") + } + } +--- request +GET /lua +--- response_body +foo +--- no_error_log +[error] + + + +=== TEST 6: send_headers +--- config + server_rewrite_by_lua_block { + ngx.header["Foox"] = {"conx1", "conx2" } + ngx.header["Fooy"] = {"cony1", "cony2" } + ngx.send_headers() + } + location /lua { + content_by_lua_block { + ngx.say("OK") + } + } +--- request +GET /lua +--- response_body +--- response_headers +Foox: conx1, conx2 +Fooy: cony1, cony2 +--- no_error_log +[error] + + + +=== TEST 7: read_body +--- config + server_rewrite_by_lua_block { + ngx.req.read_body() + ngx.say(ngx.var.request_body) + } +--- request +POST /lua +hello, world +--- response_body +hello, world +--- no_error_log +[error] + + + +=== TEST 8: req_sock +--- config + server_rewrite_by_lua_block { + local sock = ngx.req.socket() + sock:receive(2) + sock:receive(2) + sock:receive(1) + ngx.sleep(1) + } + location /lua { + content_by_lua_block { + ngx.say("OK") + } + } +--- request +POST /lua +hello + +--- stap2 eval: $::StapScript +--- stap eval: $::GCScript +--- stap_out +lua check broken conn +lua check broken conn +lua req cleanup +delete thread 1 + +--- wait: 1 +--- timeout: 0.2 +--- abort +--- ignore_response +--- no_error_log +[error] + + + +=== TEST 9: rewrite args (not break cycle by default) +--- config + location /bar { + echo "bar: $uri?$args"; + } + server_rewrite_by_lua_block { + if ngx.var.uri ~= "/bar" then + ngx.req.set_uri_args("hello") + ngx.req.set_uri("/bar", true) + end + } + location /foo { + + echo "foo: $uri?$args"; + } +--- request + GET /foo?world +--- response_body +bar: /bar?hello + + + +=== TEST 10: server_rewrite_by_lua_block overwrite by server +--- http_config + server_rewrite_by_lua_block { + ngx.log(ngx.INFO, "server_rewrite_by_lua_block in http") + } +--- config + server_rewrite_by_lua_block { + ngx.log(ngx.INFO, "server_rewrite_by_lua_block in server") + } + location /lua { + content_by_lua_block { + ngx.say("OK") + } + } +--- request +GET /lua +--- response_body +OK +--- error_log +server_rewrite_by_lua_block in server +--- no_error_log +[error] + + + +=== TEST 11: sleep +--- config + server_rewrite_by_lua_block { + ngx.sleep(0.001) + ngx.log(ngx.INFO, "server_rewrite_by_lua_block in server") + } + location /lua { + content_by_lua_block { + ngx.say("OK") + } + } +--- request +GET /lua +--- response_body +OK +--- error_log +server_rewrite_by_lua_block in server +--- no_error_log +[error] + + + +=== TEST 12: ngx.exit(ngx.OK) +--- config + server_rewrite_by_lua_block { + ngx.log(ngx.INFO, "ngx.exit") + ngx.exit(ngx.OK) + } + location /lua { + content_by_lua_block { + ngx.say("OK") + } + } +--- request +GET /lua +--- response_body +OK +--- error_log +ngx.exit +--- no_error_log +[error] + + + +=== TEST 13: ngx.exit(503) +--- config + server_rewrite_by_lua_block { + ngx.exit(503) + } + location /lua { + content_by_lua_block { + ngx.log(ngx.ERR, "content_by_lua") + ngx.say("OK") + } + } +--- request +GET /lua +--- error_code: 503 +--- no_error_log +[error] + + + +=== TEST 14: subrequests +--- config + server_rewrite_by_lua_block { + ngx.log(ngx.INFO, "is_subrequest:", ngx.is_subrequest) + } + + location /lua { + content_by_lua_block { + local res = ngx.location.capture("/sub") + ngx.print(res.body) + } + } + + location /sub { + content_by_lua_block { + ngx.say("OK") + } + } + +--- request +GET /lua +--- response_body +OK +--- error_log +is_subrequest:false +is_subrequest:true +--- no_error_log +[error] + + + +=== TEST 15: rewrite by ngx_http_rewrite_module +--- config + server_rewrite_by_lua_block { + ngx.log(ngx.INFO, "uri is ", ngx.var.uri) + } + + rewrite ^ /re; + + location /re { + content_by_lua_block { + ngx.say("RE") + } + } + + location /ok { + content_by_lua_block { + ngx.say("OK") + } + } + +--- request +GET /lua +--- response_body +RE +--- error_log +uri is /lua +--- no_error_log +[error] + + + +=== TEST 16: exec +--- config + server_rewrite_by_lua_block { + if ngx.var.uri ~= "/ok" then + ngx.exec("/ok") + end + ngx.log(ngx.INFO, "uri is ", ngx.var.uri) + } + + location /ok { + content_by_lua_block { + ngx.say("OK") + } + } + +--- request +GET /lua +--- response_body +OK +--- error_log +uri is /ok +--- no_error_log +[error] + + + +=== TEST 17: server_rewrite_by_lua and rewrite_by_lua +--- http_config + server_rewrite_by_lua_block { + ngx.log(ngx.INFO, "server_rewrite_by_lua_block in http") + } +--- config + location /lua { + rewrite_by_lua_block { + ngx.log(ngx.INFO, "rewrite_by_lua_block in location") + } + content_by_lua_block { + ngx.say("OK") + } + } +--- request +GET /lua +--- response_body +OK +--- error_log +server_rewrite_by_lua_block in http +rewrite_by_lua_block in location +--- no_error_log +[error] + + + +=== TEST 18: server_rewrite_by_lua_file +--- http_config + server_rewrite_by_lua_file 'html/foo.lua'; +--- config + location /lua { + content_by_lua_block { + ngx.say("OK") + } + } +--- request +GET /lua +--- user_files +>>> foo.lua +ngx.log(ngx.INFO, "rewrite_by_lua_file in server") +--- response_body +OK +--- error_log +rewrite_by_lua_file in server +--- no_error_log +[error] + + + +=== TEST 19: syntax error server_rewrite_by_lua_block in http +--- http_config + server_rewrite_by_lua_block { + 'for end'; + } +--- config + location /lua { + content_by_lua_block { + ngx.say("OK") + } + } +--- request +GET /lua +--- ignore_response +--- error_log +failed to load inlined Lua code: server_rewrite_by_lua(nginx.conf:25):2: unexpected symbol near ''for end'' +--- no_error_log +no_such_error + + + +=== TEST 20: syntax error server_rewrite_by_lua_block in server +--- config + server_rewrite_by_lua_block { + 'for end'; + } + location /lua { + content_by_lua_block { + ngx.say("Hello world") + } + } +--- request +GET /lua +--- ignore_response +--- error_log +failed to load inlined Lua code: server_rewrite_by_lua(nginx.conf:39):2: unexpected symbol near ''for end'' +--- no_error_log +no_such_error diff --git a/src/deps/src/lua-nginx-module/t/168-tcp-socket-bind.t b/src/deps/src/lua-nginx-module/t/168-tcp-socket-bind.t new file mode 100644 index 000000000..a2aa50b4e --- /dev/null +++ b/src/deps/src/lua-nginx-module/t/168-tcp-socket-bind.t @@ -0,0 +1,367 @@ +# vim:set ft= ts=4 sw=4 et fdm=marker: + +use Test::Nginx::Socket::Lua; + +# more times than usual(2) for test case 6 +repeat_each(4); + +plan tests => repeat_each() * (blocks() * 3 + 7); + +our $HtmlDir = html_dir; + +# get ip address in the dev which is default route outgoing dev +my $dev = `ip route | awk '/default/ {printf "%s", \$5}'`; +my $local_ip = `ip route | grep $dev | grep -o "src .*" | head -n 1 | awk '{print \$2}'`; +chomp $local_ip; + +$ENV{TEST_NGINX_HTML_DIR} = $HtmlDir; +$ENV{TEST_NGINX_NOT_EXIST_IP} ||= '8.8.8.8'; +$ENV{TEST_NGINX_INVALID_IP} ||= '127.0.0.1:8899'; +$ENV{TEST_NGINX_SERVER_IP} ||= $local_ip; + +no_long_string(); +#no_diff(); + +#log_level 'warn'; +log_level 'debug'; + +no_shuffle(); + +run_tests(); + +__DATA__ + +=== TEST 1: upstream sockets bind 127.0.0.1 +--- config + server_tokens off; + location /t { + set $port $TEST_NGINX_SERVER_PORT; + content_by_lua_block { + local ip = "127.0.0.1" + local port = ngx.var.port + + local sock = ngx.socket.tcp() + local ok, err = sock:bind(ip) + if not ok then + ngx.say("failed to bind", err) + return + end + + local ok, err = sock:connect("127.0.0.1", port) + if not ok then + ngx.say("failed to connect: ", err) + return + end + + ngx.say("connected: ", ok) + + local bytes, err = sock:send("GET /foo HTTP/1.1\r\nHost: localhost\r\nConnection: keepalive\r\n\r\n") + if not bytes then + ngx.say("failed to send request: ", err) + return + end + + ngx.say("request sent") + + local reader = sock:receiveuntil("\r\n0\r\n\r\n") + local data, err = reader() + + if not data then + ngx.say("failed to receive response body: ", err) + return + end + + ngx.say("received response") + local remote_ip = string.match(data, "(bind: %d+%.%d+%.%d+%.%d+)") + ngx.say(remote_ip) + + ngx.say("done") + } + } + + location /foo { + echo bind: $remote_addr; + } +--- request +GET /t +--- response_body +connected: 1 +request sent +received response +bind: 127.0.0.1 +done +--- no_error_log +["[error]", +"bind(127.0.0.1) failed"] +--- error_log eval +"lua tcp socket bind ip: 127.0.0.1" + + + +=== TEST 2: upstream sockets bind server ip, not 127.0.0.1 +--- config + server_tokens off; + location /t { + set $port $TEST_NGINX_SERVER_PORT; + content_by_lua_block { + local ip = "$TEST_NGINX_SERVER_IP" + local port = ngx.var.port + + local sock = ngx.socket.tcp() + local ok, err = sock:bind(ip) + if not ok then + ngx.say("failed to bind", err) + return + end + + local ok, err = sock:connect("127.0.0.1", port) + if not ok then + ngx.say("failed to connect: ", err) + return + end + + ngx.say("connected: ", ok) + + local bytes, err = sock:send("GET /foo HTTP/1.1\r\nHost: localhost\r\nConnection: keepalive\r\n\r\n") + if not bytes then + ngx.say("failed to send request: ", err) + return + end + + ngx.say("request sent") + + local reader = sock:receiveuntil("\r\n0\r\n\r\n") + local data, err = reader() + + if not data then + ngx.say("failed to receive response body: ", err) + return + end + + ngx.say("received response") + local remote_ip = string.match(data, "(bind: %d+%.%d+%.%d+%.%d+)") + if remote_ip == "bind: $TEST_NGINX_SERVER_IP" then + ngx.say("ip matched") + end + + ngx.say("done") + } + } + + location /foo { + echo bind: $remote_addr; + } +--- request +GET /t +--- response_body +connected: 1 +request sent +received response +ip matched +done +--- no_error_log eval +["[error]", +"bind($ENV{TEST_NGINX_SERVER_IP}) failed"] +--- error_log eval +"lua tcp socket bind ip: $ENV{TEST_NGINX_SERVER_IP}" + + + +=== TEST 3: add setkeepalive +--- http_config eval + "lua_package_path '$::HtmlDir/?.lua;./?.lua;;';" +--- config + server_tokens off; + location /t { + set $port $TEST_NGINX_SERVER_PORT; + content_by_lua_block { + local test = require "test" + local t1 = test.go() + local t2 = test.go() + ngx.say("t2 - t1: ", t2 - t1) + } + } +--- user_files +>>> test.lua +local _M = {} + +function _M.go() + local ip = "127.0.0.1" + local port = ngx.var.port + + local sock = ngx.socket.tcp() + local ok, err = sock:bind(ip) + if not ok then + ngx.say("failed to bind", err) + return + end + + ngx.say("bind: ", ip) + + local ok, err = sock:connect("127.0.0.1", port) + if not ok then + ngx.say("failed to connect: ", err) + return + end + + ngx.say("connected: ", ok) + + local reused = sock:getreusedtimes() + + local ok, err = sock:setkeepalive() + if not ok then + ngx.say("failed to set reusable: ", err) + end + + return reused +end + +return _M +--- request +GET /t +--- response_body +bind: 127.0.0.1 +connected: 1 +bind: 127.0.0.1 +connected: 1 +t2 - t1: 1 +--- no_error_log +["[error]", +"bind(127.0.0.1) failed"] +--- error_log eval +"lua tcp socket bind ip: 127.0.0.1" + + + +=== TEST 4: upstream sockets bind not exist ip +--- config + server_tokens off; + location /t { + set $port $TEST_NGINX_SERVER_PORT; + content_by_lua_block { + local ip = "$TEST_NGINX_NOT_EXIST_IP" + local port = ngx.var.port + + local sock = ngx.socket.tcp() + local ok, err = sock:bind(ip) + if not ok then + ngx.say("failed to bind", err) + return + end + + ngx.say("bind: ", ip) + + local ok, err = sock:connect("127.0.0.1", port) + if not ok then + ngx.say("failed to connect: ", err) + return + end + + ngx.say("connected: ", ok) + } + } +--- request +GET /t +--- response_body +bind: 8.8.8.8 +failed to connect: cannot assign requested address +--- error_log eval +["bind(8.8.8.8) failed", +"lua tcp socket bind ip: 8.8.8.8"] + + + +=== TEST 5: upstream sockets bind invalid ip +--- config + server_tokens off; + location /t { + set $port $TEST_NGINX_SERVER_PORT; + content_by_lua_block { + local ip = "$TEST_NGINX_INVALID_IP" + local port = ngx.var.port + + local sock = ngx.socket.tcp() + local ok, err = sock:bind(ip) + if not ok then + ngx.say("failed to bind: ", err) + return + end + + ngx.say("bind: ", ip) + + local ok, err = sock:connect("127.0.0.1", port) + if not ok then + ngx.say("failed to connect: ", err) + return + end + + ngx.say("connected: ", ok) + } + } +--- request +GET /t +--- response_body +failed to bind: bad address +--- no_error_log +[error] + + + +=== TEST 6: tcpsock across request after bind +--- http_config + init_worker_by_lua_block { + -- this is not the recommend way, just for test + local function tcp() + local sock = ngx.socket.tcp() + + local ok, err = sock:bind("127.0.0.1") + if not ok then + ngx.log(ngx.ERR, "failed to bind") + end + + package.loaded.share_sock = sock + end + + local ok, err = ngx.timer.at(0, tcp) + if not ok then + ngx.log(ngx.ERR, "failed to create timer") + end + } +--- config + server_tokens off; + location /t { + set $port $TEST_NGINX_SERVER_PORT; + content_by_lua_block { + local port = ngx.var.port + + -- make sure share_sock is created + ngx.sleep(0.002) + + local sock = package.loaded.share_sock + if sock ~= nil then + package.loaded.share_sock = nil + + local ok, err = sock:connect("127.0.0.1", port) + if not ok then + ngx.say("failed to connect: ", err) + return + end + + ngx.say("connected: ", ok) + + sock:close() + collectgarbage("collect") + else + -- the sock from package.loaded.share_sock is just + -- for the first request after worker init + -- add following code to keep the same result for other request + ngx.say("connected: ", 1) + end + } + } +--- request +GET /t +--- response_body +connected: 1 +--- no_error_log +[error] diff --git a/src/deps/src/lua-nginx-module/t/185-ngx-buf-double-free.t b/src/deps/src/lua-nginx-module/t/185-ngx-buf-double-free.t new file mode 100644 index 000000000..699083db2 --- /dev/null +++ b/src/deps/src/lua-nginx-module/t/185-ngx-buf-double-free.t @@ -0,0 +1,25 @@ +# vim:set ft= ts=4 sw=4 et fdm=marker: + +use Test::Nginx::Socket 'no_plan'; + +repeat_each(2); + +run_tests(); + +__DATA__ + +=== TEST 1: one buf was linked to multiple ngx_chain_t nodes +--- config + location /t { + content_by_lua_block { + local str = string.rep(".", 1300) + ngx.print(str) + ngx.flush() + ngx.print("small chunk") + ngx.flush() + } + body_filter_by_lua_block {local dummy=1} + } +--- request +GET /t +--- response_body_like: small chunk diff --git a/src/deps/src/lua-nginx-module/t/186-cosocket-busy-bufs.t b/src/deps/src/lua-nginx-module/t/186-cosocket-busy-bufs.t new file mode 100644 index 000000000..e50f62d9e --- /dev/null +++ b/src/deps/src/lua-nginx-module/t/186-cosocket-busy-bufs.t @@ -0,0 +1,81 @@ +# vim:set ft= ts=4 sw=4 et fdm=marker: + +use Test::Nginx::Socket 'no_plan'; +use Test::Nginx::Socket::Lua::Stream; + +log_level('warn'); +repeat_each(2); +run_tests(); + +__DATA__ + +=== TEST 1: ngx.say and cosocket +--- stream_server_config + content_by_lua_block { + local sock = assert(ngx.req.socket(true)) + sock:settimeout(1000) + while true do + local data = sock:receive(5) + if not data then + return + end + ngx.print(data) + ngx.flush(true) + end + } +--- config + location /test { + content_by_lua_block { + ngx.say("hello") + --ngx.flush(true) + + local sock = ngx.socket.tcp() + local ok, err = sock:connect("127.0.0.1", ngx.var.server_port + 1) + assert(ok) + + local last_duration = 0 + local cnt = 0 + local t1, t2 + local err_cnt = 0 + local ERR_THRESHOLD_MS = 100 + + for i = 1,100000 do + if cnt == 0 then + ngx.update_time() + t1 = ngx.now() + end + + cnt = cnt + 1 + + local sent = sock:send("hello") + local data = sock:receive(5) + assert(data=="hello") + + if cnt == 1000 then + cnt = 0 + ngx.update_time() + t2 = ngx.now() + local duration = (t2 - t1) * 1000 + if last_duration > 0 and (duration - last_duration) > ERR_THRESHOLD_MS then + if err_cnt >= 3 then + ngx.log(ngx.ERR, + "more than ", err_cnt, " times, duration larger than ", + ERR_THRESHOLD_MS, " ms, ", + "last_duration: ", math.floor(duration), " ms") + return ngx.exit(500) + end + err_cnt = err_cnt + 1 + end + last_duration = duration + end + end + + sock:close() + ngx.exit(200) + } + } +--- no_error_log +[error] +--- timeout: 30 +--- request +GET /test diff --git a/src/deps/src/lua-nginx-module/t/cert/mtls_ca.crt b/src/deps/src/lua-nginx-module/t/cert/mtls_ca.crt new file mode 100644 index 000000000..1fe7e1f98 --- /dev/null +++ b/src/deps/src/lua-nginx-module/t/cert/mtls_ca.crt @@ -0,0 +1,78 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 32:ed:21:56:d8:4e:aa:03:89:a9:4a:a4:e2:85:2d:8a:3b:2b:89:22 + Signature Algorithm: sha256WithRSAEncryption + Issuer: C = US, ST = California, O = OpenResty, CN = OpenResty Testing Root CA + Validity + Not Before: Mar 13 15:49:00 2022 GMT + Not After : Mar 8 15:49:00 2042 GMT + Subject: C = US, ST = California, O = OpenResty, CN = OpenResty Testing Root CA + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public-Key: (2048 bit) + Modulus: + 00:e6:37:d2:c6:17:36:c7:b2:7f:7d:cf:d0:62:87: + 99:d9:21:b8:de:ff:d8:e2:3a:1c:68:90:8f:ce:17: + 68:22:b0:60:30:cc:29:e8:34:ee:ff:b2:25:de:6e: + 1a:d4:df:10:19:11:4b:40:61:d3:a9:4d:80:ed:97: + 81:4e:c5:74:e8:4d:63:e3:5f:21:bc:5a:6e:22:a0: + 17:91:c1:cb:25:53:9b:9d:4e:e1:51:5b:f6:52:e7: + 0a:27:f6:16:c2:31:cb:6c:47:f4:89:51:15:cc:06: + be:31:3e:1c:ea:ee:81:9b:c4:97:96:fd:e5:1c:95: + 9e:c0:65:cd:a9:9a:cb:68:67:f2:62:a0:21:eb:5a: + c5:a1:92:ed:32:41:28:f9:47:34:eb:44:ae:d6:e7: + 76:71:11:98:c9:2e:ce:6c:7c:10:1b:c7:4c:c3:14: + 89:4e:d9:4c:d9:c7:43:e9:3c:29:ca:62:a9:91:b3: + 87:e7:d7:b4:18:ab:65:f9:6b:ed:82:ca:a1:36:35: + 18:05:cb:5c:24:26:13:13:f8:99:ac:99:be:9b:a6: + 73:df:0d:16:95:b1:dc:be:fe:7a:c2:b6:dc:c8:93: + cf:10:e0:29:03:0e:28:78:18:84:ee:14:92:ab:be: + 5a:a0:14:a2:4a:2f:d3:d0:b8:0e:00:d2:5a:cd:e4: + bd:a1 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Key Usage: critical + Certificate Sign, CRL Sign + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Subject Key Identifier: + F0:D7:4B:14:73:E1:67:00:6B:54:B4:19:20:76:12:9F:9D:8E:C8:09 + Signature Algorithm: sha256WithRSAEncryption + 6d:52:21:6d:6e:8c:e5:4a:28:07:65:6d:d8:7c:23:2e:c6:c1: + d0:ec:27:b3:b0:c3:d3:e8:fa:72:b9:de:32:4e:ff:97:8d:86: + a9:6d:b3:a9:b4:2d:77:ca:28:97:6a:3d:7b:a2:15:ed:34:dc: + 72:9f:6f:e7:01:0c:d3:28:6a:80:1b:50:09:fd:d7:2c:d8:92: + d5:10:c4:73:15:20:7d:99:dc:de:30:7b:3c:6e:e9:66:b2:0e: + 4e:1a:c1:51:57:6e:5b:b0:a9:f6:ff:0b:8f:07:67:31:40:5b: + 11:a9:06:d3:d3:76:c5:d2:56:95:9a:9e:4a:16:44:4b:32:e5: + af:dd:4b:4d:5d:57:b8:85:69:36:93:2a:c6:0c:8f:e1:42:35: + be:8e:f3:e7:35:d3:2c:3a:03:31:40:75:8e:e8:dd:57:35:20: + 5e:18:a9:76:ce:85:be:7e:3a:cf:6e:08:58:5b:47:d5:e9:c4: + ec:0e:e9:8e:3c:2d:5c:7b:59:20:5b:24:92:a0:e0:1e:a3:5a: + 67:d8:ff:7f:a5:82:f1:df:db:05:65:79:88:b1:3c:e6:01:d1: + 5a:c7:d2:6e:9a:e6:a2:da:4a:c7:19:78:d9:14:71:6e:1f:70: + f3:41:e5:b3:78:31:d5:22:0e:7c:1a:b2:43:d9:86:ff:53:ea: + 2b:ba:d2:27 +-----BEGIN CERTIFICATE----- +MIIDhDCCAmygAwIBAgIUMu0hVthOqgOJqUqk4oUtijsriSIwDQYJKoZIhvcNAQEL +BQAwWjELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExEjAQBgNVBAoT +CU9wZW5SZXN0eTEiMCAGA1UEAxMZT3BlblJlc3R5IFRlc3RpbmcgUm9vdCBDQTAe +Fw0yMjAzMTMxNTQ5MDBaFw00MjAzMDgxNTQ5MDBaMFoxCzAJBgNVBAYTAlVTMRMw +EQYDVQQIEwpDYWxpZm9ybmlhMRIwEAYDVQQKEwlPcGVuUmVzdHkxIjAgBgNVBAMT +GU9wZW5SZXN0eSBUZXN0aW5nIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQDmN9LGFzbHsn99z9Bih5nZIbje/9jiOhxokI/OF2gisGAwzCno +NO7/siXebhrU3xAZEUtAYdOpTYDtl4FOxXToTWPjXyG8Wm4ioBeRwcslU5udTuFR +W/ZS5won9hbCMctsR/SJURXMBr4xPhzq7oGbxJeW/eUclZ7AZc2pmstoZ/JioCHr +WsWhku0yQSj5RzTrRK7W53ZxEZjJLs5sfBAbx0zDFIlO2UzZx0PpPCnKYqmRs4fn +17QYq2X5a+2CyqE2NRgFy1wkJhMT+Jmsmb6bpnPfDRaVsdy+/nrCttzIk88Q4CkD +Dih4GITuFJKrvlqgFKJKL9PQuA4A0lrN5L2hAgMBAAGjQjBAMA4GA1UdDwEB/wQE +AwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTw10sUc+FnAGtUtBkgdhKf +nY7ICTANBgkqhkiG9w0BAQsFAAOCAQEAbVIhbW6M5UooB2Vt2HwjLsbB0Owns7DD +0+j6crneMk7/l42GqW2zqbQtd8ool2o9e6IV7TTccp9v5wEM0yhqgBtQCf3XLNiS +1RDEcxUgfZnc3jB7PG7pZrIOThrBUVduW7Cp9v8LjwdnMUBbEakG09N2xdJWlZqe +ShZESzLlr91LTV1XuIVpNpMqxgyP4UI1vo7z5zXTLDoDMUB1jujdVzUgXhipds6F +vn46z24IWFtH1enE7A7pjjwtXHtZIFskkqDgHqNaZ9j/f6WC8d/bBWV5iLE85gHR +WsfSbprmotpKxxl42RRxbh9w80Hls3gx1SIOfBqyQ9mG/1PqK7rSJw== +-----END CERTIFICATE----- diff --git a/src/deps/src/lua-nginx-module/t/cert/mtls_ca.key b/src/deps/src/lua-nginx-module/t/cert/mtls_ca.key new file mode 100644 index 000000000..d39b42f9d --- /dev/null +++ b/src/deps/src/lua-nginx-module/t/cert/mtls_ca.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEA5jfSxhc2x7J/fc/QYoeZ2SG43v/Y4jocaJCPzhdoIrBgMMwp +6DTu/7Il3m4a1N8QGRFLQGHTqU2A7ZeBTsV06E1j418hvFpuIqAXkcHLJVObnU7h +UVv2UucKJ/YWwjHLbEf0iVEVzAa+MT4c6u6Bm8SXlv3lHJWewGXNqZrLaGfyYqAh +61rFoZLtMkEo+Uc060Su1ud2cRGYyS7ObHwQG8dMwxSJTtlM2cdD6TwpymKpkbOH +59e0GKtl+WvtgsqhNjUYBctcJCYTE/iZrJm+m6Zz3w0WlbHcvv56wrbcyJPPEOAp +Aw4oeBiE7hSSq75aoBSiSi/T0LgOANJazeS9oQIDAQABAoIBAQDhH9+uNE8uUv/X +MNvvLfklWpOlBf25o+fZ3NuzRjJgEafOsCee2fyI8FWVwIfeeE8OpFm5GLDZk1+r +dwdM10xuSheO5Z1gyfF/TJwfvamA09SNrPArFkm3YhUNZNl2hykMtwSLL06oWEOu +dbXjit4VS9aNIbTlEe7O5/6Ih0W3zmr1yvUua2swmAZMx3GFA4kbjZZ9vDs27sdu +K+VY3DYRbq1HkiNFT0otfke5bObFBCG7Yp8JLyhYaIkGYFoBXuZ6JNY8EuU2+YyP +6r40tJ7StR1Q6eZJh9/1leaYGZLCh5oFyKpilTuxHbRbr5A28RJKjKvPsdDgTtQn +yHGg70FRAoGBAOhC3TQlFcT2WCCZHHql9JEEHnHVBWnL3Jg7VJuL1i6pEIz7qQkW +AtBEIY/nnTcVNfJ6eXznYtutYvvRSgQTUsBNRoj3s1z9wKOo4uw4LoIUXDEmHCr+ +49DiQyIO21SNMHA+dVxvGRDDjLI9Uc+Scb64QOodoX75HLRZG++24mtdAoGBAP2/ +gCjga2p8Jx9UnhIcrEIIGANyxEQeBdhF56Nt9CJy/Iwi3a6qQ/GkbeoDm5FhXnXo +xcBaHyv2lwi4uO/hONY8eRnYxAWMwAKMZe6VnU1hWI2Ytkh+OcMPMh7NIGQf6X1o +JZrBtnTms060TuuDjLeIlaubDR/xDrMWTMKjKbsVAoGAVLuYAZ8J6xpIGlRhbGlA +6OrMxJCHcgpahvsWKc0BLXKmRBjHmTX7fslsSRihZWgKj1SZH7U2fpgpxV6cFxKJ +nPhUJEHhoKo+bjZ92tnANdqBq7iQjCsDJ8Bz52fuIlGD+1795+PsDA6bNKdkQkrV +zlNf80kuEqmFDFJ5+6EHx00CgYAf+jkpbZa71aeMgDpnZ+uhaqm0DYuEVhBAgBa/ +9sRUbw86jc5IC7cCRcmAOzIosQ+ZZls9cV4KSUohVD4iJMzn2rkcM8AIPwOXjp/t +4DbxoHnrZjpaimW3Gjwju5AAbjEbl7tddFoNA2HHYlurvGlIW9MYzDJsOxGyKfZE +dRF2PQKBgQDUKNHgDYEjLJ99S5Fm5zN/64bKzzDtktGdqOxik5pBKcs/BvOdLM0i +eCjGz/3qrEoenFIBwF/IRz3ug90Zr8bWOu6DudReflAKI/N13dZ2gOTAfaX4ljJF +w0ohSi6xs+mu1GmtipGtNxHi/J3na2BeSnSRFSUg6Zd+oh8BZQKmNg== +-----END RSA PRIVATE KEY----- diff --git a/src/deps/src/lua-nginx-module/t/cert/mtls_cert_gen/.gitignore b/src/deps/src/lua-nginx-module/t/cert/mtls_cert_gen/.gitignore new file mode 100644 index 000000000..f375caaef --- /dev/null +++ b/src/deps/src/lua-nginx-module/t/cert/mtls_cert_gen/.gitignore @@ -0,0 +1,4 @@ +*.pem +*.csr +cfssl +cfssljson diff --git a/src/deps/src/lua-nginx-module/t/cert/mtls_cert_gen/generate.sh b/src/deps/src/lua-nginx-module/t/cert/mtls_cert_gen/generate.sh new file mode 100755 index 000000000..46625fdd0 --- /dev/null +++ b/src/deps/src/lua-nginx-module/t/cert/mtls_cert_gen/generate.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +rm *.pem *.csr cfssl cfssljson + +wget -O cfssl https://github.com/cloudflare/cfssl/releases/download/v1.6.1/cfssl_1.6.1_linux_amd64 +wget -O cfssljson https://github.com/cloudflare/cfssl/releases/download/v1.6.1/cfssljson_1.6.1_linux_amd64 +chmod +x cfssl cfssljson + +./cfssl gencert -initca -config profile.json mtls_ca.json | ./cfssljson -bare mtls_ca + +./cfssl gencert -ca mtls_ca.pem -ca-key mtls_ca-key.pem -config profile.json -profile=client mtls_client.json | ./cfssljson -bare mtls_client +./cfssl gencert -ca mtls_ca.pem -ca-key mtls_ca-key.pem -config profile.json -profile=server mtls_server.json | ./cfssljson -bare mtls_server + +openssl x509 -in mtls_ca.pem -text > ../mtls_ca.crt +mv mtls_ca-key.pem ../mtls_ca.key + +openssl x509 -in mtls_client.pem -text > ../mtls_client.crt +mv mtls_client-key.pem ../mtls_client.key + +openssl x509 -in mtls_server.pem -text > ../mtls_server.crt +mv mtls_server-key.pem ../mtls_server.key + +rm *.pem *.csr cfssl cfssljson diff --git a/src/deps/src/lua-nginx-module/t/cert/mtls_cert_gen/mtls_ca.json b/src/deps/src/lua-nginx-module/t/cert/mtls_cert_gen/mtls_ca.json new file mode 100644 index 000000000..0a4a7ab13 --- /dev/null +++ b/src/deps/src/lua-nginx-module/t/cert/mtls_cert_gen/mtls_ca.json @@ -0,0 +1,18 @@ +{ + "CA": { + "expiry": "175200h", + "pathlen": 0 + }, + "CN": "OpenResty Testing Root CA", + "key": { + "algo": "rsa", + "size": 2048 + }, + "names": [ + { + "C": "US", + "O": "OpenResty", + "ST": "California" + } + ] +} diff --git a/src/deps/src/lua-nginx-module/t/cert/mtls_cert_gen/mtls_client.json b/src/deps/src/lua-nginx-module/t/cert/mtls_cert_gen/mtls_client.json new file mode 100644 index 000000000..4d59f47a5 --- /dev/null +++ b/src/deps/src/lua-nginx-module/t/cert/mtls_cert_gen/mtls_client.json @@ -0,0 +1,18 @@ +{ + "CN": "foo@example.com", + "key": { + "algo": "rsa", + "size": 2048 + }, + "names": [ + { + "C": "US", + "O": "OpenResty", + "ST": "California" + } + ], + "hosts": [ + "foo@example.com", + "bar@example.com" + ] +} diff --git a/src/deps/src/lua-nginx-module/t/cert/mtls_cert_gen/mtls_server.json b/src/deps/src/lua-nginx-module/t/cert/mtls_cert_gen/mtls_server.json new file mode 100644 index 000000000..655af54ef --- /dev/null +++ b/src/deps/src/lua-nginx-module/t/cert/mtls_cert_gen/mtls_server.json @@ -0,0 +1,17 @@ +{ + "CN": "example.com", + "key": { + "algo": "rsa", + "size": 2048 + }, + "names": [ + { + "C": "US", + "O": "OpenResty", + "ST": "California" + } + ], + "hosts": [ + "example.com" + ] +} diff --git a/src/deps/src/lua-nginx-module/t/cert/mtls_cert_gen/profile.json b/src/deps/src/lua-nginx-module/t/cert/mtls_cert_gen/profile.json new file mode 100644 index 000000000..d3b6ab16c --- /dev/null +++ b/src/deps/src/lua-nginx-module/t/cert/mtls_cert_gen/profile.json @@ -0,0 +1,27 @@ +{ + "signing": { + "default": { + "expiry": "175200h" + }, + "profiles": { + "server": { + "usages": [ + "signing", + "digital signing", + "key encipherment", + "server auth" + ], + "expiry": "175199h" + }, + "client": { + "usages": [ + "signing", + "digital signature", + "key encipherment", + "client auth" + ], + "expiry": "175199h" + } + } + } +} diff --git a/src/deps/src/lua-nginx-module/t/cert/mtls_client.crt b/src/deps/src/lua-nginx-module/t/cert/mtls_client.crt new file mode 100644 index 000000000..dd0efdf7f --- /dev/null +++ b/src/deps/src/lua-nginx-module/t/cert/mtls_client.crt @@ -0,0 +1,87 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 19:0a:a3:a8:9c:d4:0f:dc:c6:fa:23:7b:f8:fc:bd:f4:73:4e:7e:b1 + Signature Algorithm: sha256WithRSAEncryption + Issuer: C = US, ST = California, O = OpenResty, CN = OpenResty Testing Root CA + Validity + Not Before: Mar 13 15:49:00 2022 GMT + Not After : Mar 8 14:49:00 2042 GMT + Subject: C = US, ST = California, O = OpenResty, CN = foo@example.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public-Key: (2048 bit) + Modulus: + 00:be:5b:09:4c:94:71:d3:82:54:4a:42:6a:76:aa: + 34:5d:28:d9:45:e6:44:9a:74:9f:a6:e6:78:49:9e: + c6:20:75:32:5f:92:3b:ec:6e:4b:7b:b0:75:1c:75: + 09:00:05:77:d6:59:ca:55:5b:13:b6:76:3a:c6:18: + dc:37:6a:20:93:e6:26:56:5d:0b:96:8c:01:f2:96: + 38:08:08:36:a2:64:12:21:a0:8d:48:cd:9a:26:78: + 92:29:b6:63:eb:14:d9:b6:e5:87:f7:d5:55:a4:cc: + 53:1c:a3:7c:b8:bd:ad:7c:a4:d4:86:1f:a7:1c:43: + c5:1a:b5:f1:03:bd:fe:19:98:1d:b7:13:2b:93:a2: + 2a:0e:21:7e:42:a9:bb:28:69:49:59:e7:89:0e:7d: + 5a:ce:fb:d4:0c:20:6a:e1:db:b2:6a:e5:a7:55:e0: + d0:58:4a:e2:08:78:82:b9:06:0c:65:f9:24:06:e6: + 8a:13:b2:9a:ef:1b:4a:b2:3a:b4:98:7f:dd:3c:0e: + 85:0b:a6:c6:47:2f:63:c2:73:52:41:db:7c:06:c3: + 2a:b5:2d:d1:e1:30:d5:c4:79:c9:b9:35:68:46:ad: + c4:45:57:ea:11:88:27:37:ed:ac:49:2d:c4:d6:c6: + a6:74:8d:d3:bc:e0:d9:69:25:0c:0c:b0:e3:b7:cb: + 8d:99 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Key Usage: critical + Digital Signature, Key Encipherment + X509v3 Extended Key Usage: + TLS Web Client Authentication + X509v3 Basic Constraints: critical + CA:FALSE + X509v3 Subject Key Identifier: + 22:70:5E:30:8C:4D:66:39:E7:60:C9:29:A2:ED:95:32:34:63:5C:C0 + X509v3 Authority Key Identifier: + keyid:F0:D7:4B:14:73:E1:67:00:6B:54:B4:19:20:76:12:9F:9D:8E:C8:09 + + X509v3 Subject Alternative Name: + email:foo@example.com, email:bar@example.com + Signature Algorithm: sha256WithRSAEncryption + 96:e7:2a:fc:2a:56:16:80:e2:d3:79:0c:46:db:c3:88:ab:d3: + ef:39:66:4b:a9:ab:6c:0e:30:08:07:7c:fc:03:6c:f7:dd:fb: + 3e:a8:c8:68:28:ab:4e:73:97:80:27:5d:c5:9d:52:00:aa:08: + 25:c8:f9:dc:df:64:73:a4:58:5b:bd:5f:1a:53:a4:33:a3:b1: + 45:38:2d:be:d7:f3:a4:c4:f4:7a:07:71:44:f1:a2:65:02:e4: + 71:84:01:b5:83:4b:de:83:b5:ad:ac:b9:3c:17:42:0c:9a:7d: + eb:7f:ab:26:dd:9b:3a:fd:95:37:55:cc:01:c3:3f:20:df:e5: + ed:49:51:7a:42:ea:f3:8a:3f:da:6e:c1:1a:11:b9:45:4d:6e: + c9:21:f4:e3:4f:31:72:5b:bb:01:92:b6:7f:f1:8a:9e:6c:d0: + 7f:96:d7:eb:29:09:53:38:26:41:00:f2:33:04:77:bd:a9:ee: + 60:9e:06:b7:7d:26:ae:1c:4f:56:bd:a5:b6:50:40:be:be:84: + 2a:54:21:59:47:7d:a5:1e:63:6d:28:36:4d:a6:e4:62:69:9b: + 9b:fa:2b:48:e8:64:d7:14:f4:62:a2:26:17:a5:05:58:4a:38: + d2:44:e7:33:90:b9:c1:8c:85:02:99:b8:03:1a:03:d2:cf:ac: + a5:6b:44:98 +-----BEGIN CERTIFICATE----- +MIID3DCCAsSgAwIBAgIUGQqjqJzUD9zG+iN7+Py99HNOfrEwDQYJKoZIhvcNAQEL +BQAwWjELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExEjAQBgNVBAoT +CU9wZW5SZXN0eTEiMCAGA1UEAxMZT3BlblJlc3R5IFRlc3RpbmcgUm9vdCBDQTAe +Fw0yMjAzMTMxNTQ5MDBaFw00MjAzMDgxNDQ5MDBaMFAxCzAJBgNVBAYTAlVTMRMw +EQYDVQQIEwpDYWxpZm9ybmlhMRIwEAYDVQQKEwlPcGVuUmVzdHkxGDAWBgNVBAMM +D2Zvb0BleGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +AL5bCUyUcdOCVEpCanaqNF0o2UXmRJp0n6bmeEmexiB1Ml+SO+xuS3uwdRx1CQAF +d9ZZylVbE7Z2OsYY3DdqIJPmJlZdC5aMAfKWOAgINqJkEiGgjUjNmiZ4kim2Y+sU +2bblh/fVVaTMUxyjfLi9rXyk1IYfpxxDxRq18QO9/hmYHbcTK5OiKg4hfkKpuyhp +SVnniQ59Ws771AwgauHbsmrlp1Xg0FhK4gh4grkGDGX5JAbmihOymu8bSrI6tJh/ +3TwOhQumxkcvY8JzUkHbfAbDKrUt0eEw1cR5ybk1aEatxEVX6hGIJzftrEktxNbG +pnSN07zg2WklDAyw47fLjZkCAwEAAaOBozCBoDAOBgNVHQ8BAf8EBAMCBaAwEwYD +VR0lBAwwCgYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUInBeMIxN +ZjnnYMkpou2VMjRjXMAwHwYDVR0jBBgwFoAU8NdLFHPhZwBrVLQZIHYSn52OyAkw +KwYDVR0RBCQwIoEPZm9vQGV4YW1wbGUuY29tgQ9iYXJAZXhhbXBsZS5jb20wDQYJ +KoZIhvcNAQELBQADggEBAJbnKvwqVhaA4tN5DEbbw4ir0+85Zkupq2wOMAgHfPwD +bPfd+z6oyGgoq05zl4AnXcWdUgCqCCXI+dzfZHOkWFu9XxpTpDOjsUU4Lb7X86TE +9HoHcUTxomUC5HGEAbWDS96Dta2suTwXQgyafet/qybdmzr9lTdVzAHDPyDf5e1J +UXpC6vOKP9puwRoRuUVNbskh9ONPMXJbuwGStn/xip5s0H+W1+spCVM4JkEA8jME +d72p7mCeBrd9Jq4cT1a9pbZQQL6+hCpUIVlHfaUeY20oNk2m5GJpm5v6K0joZNcU +9GKiJhelBVhKONJE5zOQucGMhQKZuAMaA9LPrKVrRJg= +-----END CERTIFICATE----- diff --git a/src/deps/src/lua-nginx-module/t/cert/mtls_client.key b/src/deps/src/lua-nginx-module/t/cert/mtls_client.key new file mode 100644 index 000000000..7d77e5506 --- /dev/null +++ b/src/deps/src/lua-nginx-module/t/cert/mtls_client.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEAvlsJTJRx04JUSkJqdqo0XSjZReZEmnSfpuZ4SZ7GIHUyX5I7 +7G5Le7B1HHUJAAV31lnKVVsTtnY6xhjcN2ogk+YmVl0LlowB8pY4CAg2omQSIaCN +SM2aJniSKbZj6xTZtuWH99VVpMxTHKN8uL2tfKTUhh+nHEPFGrXxA73+GZgdtxMr +k6IqDiF+Qqm7KGlJWeeJDn1azvvUDCBq4duyauWnVeDQWEriCHiCuQYMZfkkBuaK +E7Ka7xtKsjq0mH/dPA6FC6bGRy9jwnNSQdt8BsMqtS3R4TDVxHnJuTVoRq3ERVfq +EYgnN+2sSS3E1samdI3TvODZaSUMDLDjt8uNmQIDAQABAoIBACqRsUKu78WdH7x7 +ndNrvMoYmH5JQI5KBmoMoFnWZ/haPSmiSkRVZgwDKi1y/tBCaMpGyjjMZVwolHw4 +kwbRdPeeQHSP2keQh974OQ+SxqUKPAPJI89kK1TvIcCySSYJQ6bjLcT+sGhqSSve +Y8XspR96vQxBh92KSknu5jcwBeMy/eG0mmszzP3y2R0BPztuZdE6dq/KxWQ/R4/P +JG9V1rNkIY+1JZvIICIH1Ehn4UKjiE+FJmyDbDlPKEi7W4CpRnShMLOF4cCFnQLW +RQds3Dj9GcVY+8Q/GLZF0ATjekIyEsKZEgrMAUF5ZSGRpjJQEHX7oseAiQGQxtHT +nj5b1AECgYEAwewXbbd1MqRQ6ohfsQ8j5HSMY6ahvUzs1dZUckr2jw8B98tfi/uj +a6Jq1KZe12+4dfwruRSaYdTsSVuvNiSJOxElY0C1p+lXdprFf7XfoQ6UNtg22jcH +9f8cftnlJoV5whh3YKjqnnnAWUQZ61FTNJ258/t+x0ZgpBJvqBoHwDUCgYEA+0qp +FZ5xS4FLJMc+Xf/hUeXo+04e4OD/se3atYqyuh1ghmQZfRRPOC110HG99H+rzq/x +xPMvRFahkAMyi+/3oIcBEuXvoQyqscIsAhkWD/e9t3Qc9OsWe1hlAgWKZxr6oR2U +KKR1FD7UVecOH+FKCKaL5UpEt4yEigc1NtSlTFUCgYBnV5agrIyzQSex5J0CMWxS +Od362PkGdXEc/8we4F4GnNvSnrm7Uo2jNXmy+zo9mtb1YT43sogXLK4C5e44bz4G +kTuYagqkgdBPb2lihpy3KprHo2+P2JXQfXRFEX9xiN37Fqi/hSUK8R0VNRqO8dbi +ik9nexXzwkiMBxsjvUN2JQKBgFy62FpZ9YTfWVNhEuqtGgCWzrqtwUdKwBBwrVyA +qiNz48Kz/ZPigrlATVF2J5qp4kSLOLRs6OxW65exFl39V2utZgALSbosanDeLk83 +4qRRz3h7KJRYjBtIKz3rvX7+va3mtF2rEmk+Jizs7pFlGWTH0Kf0GBeDiwVEU6bA +IZ9hAoGAQTjnRGMjvyhq0aPYP+mRFiMKSkcL1nyXizYInfAnbfbL/uEODH7D+iMf +kak+UgmeD9ce5d/APmZp3/FzYH/M8ivBgG+MnaI+MLVMhmQdLZyMtbSKKaDpiim7 +DdN1wCXYbur0HlO2t+wemMZPpQu7wybgEOLlIG7Yj/0OWDcal1c= +-----END RSA PRIVATE KEY----- diff --git a/src/deps/src/lua-nginx-module/t/cert/mtls_server.crt b/src/deps/src/lua-nginx-module/t/cert/mtls_server.crt new file mode 100644 index 000000000..7cbc2a804 --- /dev/null +++ b/src/deps/src/lua-nginx-module/t/cert/mtls_server.crt @@ -0,0 +1,87 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 2f:d5:41:13:5a:ff:c7:1c:5b:ce:28:cd:a6:f7:a5:5a:0d:c0:e2:d2 + Signature Algorithm: sha256WithRSAEncryption + Issuer: C = US, ST = California, O = OpenResty, CN = OpenResty Testing Root CA + Validity + Not Before: Mar 13 15:49:00 2022 GMT + Not After : Mar 8 14:49:00 2042 GMT + Subject: C = US, ST = California, O = OpenResty, CN = example.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public-Key: (2048 bit) + Modulus: + 00:d7:03:80:a7:42:7d:06:5a:7b:70:d8:11:96:dd: + 63:35:53:07:28:71:52:05:40:55:83:61:a7:14:ac: + cf:4b:9b:ab:b7:4e:9d:79:e9:13:3d:bc:c3:67:8f: + dd:88:d9:8b:c2:31:aa:b8:28:9e:13:70:db:76:b0: + 12:1c:f8:35:c6:2e:33:9c:b9:04:e3:47:e0:f9:e4: + 7f:a5:55:03:0c:2d:b2:54:17:29:12:dd:61:6e:5c: + 33:9f:e5:8f:8a:2b:41:53:dc:e1:98:49:63:df:e3: + 00:30:2d:1b:bb:f0:8f:cb:04:ec:c9:98:c4:09:5b: + b4:ba:a9:a0:0a:77:d2:42:76:7c:ac:64:c3:97:85: + 50:5d:7d:02:61:2a:00:93:d0:69:5e:87:22:f0:c1: + 1e:53:46:02:40:37:c9:55:77:99:7d:9d:3d:35:14: + 74:84:e3:73:ca:e7:4a:ab:33:98:26:aa:41:4b:b5: + e6:63:7c:a4:1e:25:6a:88:f4:56:d9:2c:63:dd:89: + 19:fa:25:41:44:95:87:40:a7:9b:4e:3a:91:29:32: + 79:66:05:f4:2f:68:2c:06:53:df:4d:60:be:ac:09: + 20:61:9c:6f:1a:a6:07:5a:e7:41:91:9d:36:77:38: + 18:3a:69:7b:67:29:9f:1d:e0:c2:d2:8f:16:5b:14: + e8:e1 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Key Usage: critical + Digital Signature, Key Encipherment + X509v3 Extended Key Usage: + TLS Web Server Authentication + X509v3 Basic Constraints: critical + CA:FALSE + X509v3 Subject Key Identifier: + 16:07:B5:C2:4C:B5:2D:4F:B8:E9:D6:FA:2F:3F:C0:1B:B6:4F:20:E6 + X509v3 Authority Key Identifier: + keyid:F0:D7:4B:14:73:E1:67:00:6B:54:B4:19:20:76:12:9F:9D:8E:C8:09 + + X509v3 Subject Alternative Name: + DNS:example.com + Signature Algorithm: sha256WithRSAEncryption + d9:c0:c0:d6:8b:44:04:26:b3:98:24:2c:12:82:6d:15:79:92: + 76:c9:77:94:c1:be:8f:8a:18:78:96:04:68:c9:0a:d1:84:c5: + de:cd:ba:b5:a2:3b:d4:0a:70:be:00:49:19:c0:6e:ca:e9:e5: + 8b:b6:e3:a2:39:0d:d8:ee:55:1a:08:73:39:19:d3:07:07:33: + 8c:d8:1b:0f:1b:73:0e:84:72:cf:e6:c1:a1:da:39:aa:c0:2e: + 3d:b9:a6:8f:ec:98:3a:07:58:34:c2:5e:4c:1a:6b:db:ce:51: + 92:25:1d:ba:78:4b:11:b6:f1:69:02:cb:ac:32:bb:80:f9:15: + 91:bf:4e:6a:ab:51:51:7c:7b:1a:72:80:96:eb:0c:fa:56:0e: + f2:87:3c:16:8a:04:aa:8a:9d:0c:d9:e0:c4:2a:20:42:5a:12: + 41:52:30:50:3d:85:f8:07:31:6b:af:a4:d2:44:38:69:ab:88: + 05:d4:5b:68:34:02:dc:99:5a:6c:b7:ea:fc:79:76:fe:68:29: + df:94:22:58:46:f2:40:cb:e1:92:17:d8:1e:3d:fa:a2:56:4f: + ac:3c:3d:ae:f7:90:12:ac:3b:6c:1e:1f:26:48:08:87:9a:0e: + 8d:9d:75:ef:86:1e:63:ac:e9:14:47:ad:3f:4f:10:57:2a:d1: + 95:ec:6f:24 +-----BEGIN CERTIFICATE----- +MIIDwzCCAqugAwIBAgIUL9VBE1r/xxxbzijNpvelWg3A4tIwDQYJKoZIhvcNAQEL +BQAwWjELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExEjAQBgNVBAoT +CU9wZW5SZXN0eTEiMCAGA1UEAxMZT3BlblJlc3R5IFRlc3RpbmcgUm9vdCBDQTAe +Fw0yMjAzMTMxNTQ5MDBaFw00MjAzMDgxNDQ5MDBaMEwxCzAJBgNVBAYTAlVTMRMw +EQYDVQQIEwpDYWxpZm9ybmlhMRIwEAYDVQQKEwlPcGVuUmVzdHkxFDASBgNVBAMT +C2V4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1wOA +p0J9Blp7cNgRlt1jNVMHKHFSBUBVg2GnFKzPS5urt06deekTPbzDZ4/diNmLwjGq +uCieE3DbdrASHPg1xi4znLkE40fg+eR/pVUDDC2yVBcpEt1hblwzn+WPiitBU9zh +mElj3+MAMC0bu/CPywTsyZjECVu0uqmgCnfSQnZ8rGTDl4VQXX0CYSoAk9BpXoci +8MEeU0YCQDfJVXeZfZ09NRR0hONzyudKqzOYJqpBS7XmY3ykHiVqiPRW2Sxj3YkZ ++iVBRJWHQKebTjqRKTJ5ZgX0L2gsBlPfTWC+rAkgYZxvGqYHWudBkZ02dzgYOml7 +ZymfHeDC0o8WWxTo4QIDAQABo4GOMIGLMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUE +DDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBQWB7XCTLUtT7jp +1vovP8Abtk8g5jAfBgNVHSMEGDAWgBTw10sUc+FnAGtUtBkgdhKfnY7ICTAWBgNV +HREEDzANggtleGFtcGxlLmNvbTANBgkqhkiG9w0BAQsFAAOCAQEA2cDA1otEBCaz +mCQsEoJtFXmSdsl3lMG+j4oYeJYEaMkK0YTF3s26taI71ApwvgBJGcBuyunli7bj +ojkN2O5VGghzORnTBwczjNgbDxtzDoRyz+bBodo5qsAuPbmmj+yYOgdYNMJeTBpr +285RkiUdunhLEbbxaQLLrDK7gPkVkb9OaqtRUXx7GnKAlusM+lYO8oc8FooEqoqd +DNngxCogQloSQVIwUD2F+Acxa6+k0kQ4aauIBdRbaDQC3JlabLfq/Hl2/mgp35Qi +WEbyQMvhkhfYHj36olZPrDw9rveQEqw7bB4fJkgIh5oOjZ1174YeY6zpFEetP08Q +VyrRlexvJA== +-----END CERTIFICATE----- diff --git a/src/deps/src/lua-nginx-module/t/cert/mtls_server.key b/src/deps/src/lua-nginx-module/t/cert/mtls_server.key new file mode 100644 index 000000000..f5b85d18d --- /dev/null +++ b/src/deps/src/lua-nginx-module/t/cert/mtls_server.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEA1wOAp0J9Blp7cNgRlt1jNVMHKHFSBUBVg2GnFKzPS5urt06d +eekTPbzDZ4/diNmLwjGquCieE3DbdrASHPg1xi4znLkE40fg+eR/pVUDDC2yVBcp +Et1hblwzn+WPiitBU9zhmElj3+MAMC0bu/CPywTsyZjECVu0uqmgCnfSQnZ8rGTD +l4VQXX0CYSoAk9BpXoci8MEeU0YCQDfJVXeZfZ09NRR0hONzyudKqzOYJqpBS7Xm +Y3ykHiVqiPRW2Sxj3YkZ+iVBRJWHQKebTjqRKTJ5ZgX0L2gsBlPfTWC+rAkgYZxv +GqYHWudBkZ02dzgYOml7ZymfHeDC0o8WWxTo4QIDAQABAoIBAEnmZUiXnJsbbEPr +r5f3vYptYA9xa2xsoTeHz8JWZuUouwtE1PE6v6c/grXMh6rqgpObOH8VTseFyZhw +ibk1Ql48MPcTzG9FnDinZYvwvRxpdFpcn3xhZIRm4kN5xi0KEuj9CPireM1RmxXz +2w1scC+qIKxlejNxNpvVgzE136mBqEFKJzecP+yZuH/A86MQCgwqqa3jSz5ApNg+ +1aJE34cGFieDbAN+9sdqWA3OkRrHoy8EakUf4JEvwX1AwUN832mj+N/LfmcCGMeD +YhzybzlPBV2q2T1+pHIdNT99JVNPkgdTe1903EjnG5oSDGHt2i9MdnNkMsffDWNt +pJiqSHECgYEA2hL6l8Py4oa5AJ2WXriuHRJykAs90K0akftQt4i4lWCbeRhaGh7h +kPgpDS33RkE4SymVVr0c05abMCKabQBwbu4PNCqetCFtfmIQdQCTUbLbXjL8UuD2 +QnF7nbHiwyGBKRMU/F74oX3z7lXLgRtIiyyo5yYgIAQqpz3oJAaXNTUCgYEA/GhE +Ziez8FXVAg3XwwrE3SexRFKv1JqipYE4mr+ouzfpn9yn8mttxbOORiAAEBl3ZPhd +ZUBzLy19fdFZ8RJ0zPsqoZxsd09/XetaBU56C/g9u0fycj1L2elh9rQAlOW0Grus +l8jBh01TGtlg0xobK0zjwdGPcbYkp1IzIqyD9n0CgYEAicBvVyrJ5FnhxwfEkrTq +FycuAtt3Arg2DnzH8geFQaayzv2Y/OMA7Yg0tkSQ7GoKW0A7O31eFjIOeYuCLNSY +MRpjtDov4e0zsx/S8XWZmYP3mjtutBOyuyngQi655TTm18FcAkcjmy9qxOShFj7b +xj5BuzGUHWVEZDxwxUD8hvkCgYBnrcyqyZQ4HImqllUSYNIMpclC71QaWIqGwVWm ++yMsBAOLDvBNu6MTmnXOiEZ+VnecmgiDFr45ms35aI0xYQtpR6JzT/Wd7KG8ynfn +xhyL3iQ9UYhdNKB7mkoLNFUo1FHuyThUALq+AR0p4jDLheWzG5pSeuoZI2Ba+oDW +tVZfYQKBgC5phtERR5LKU5Wkzm+uY2j+Nzh4kuKkdLosB9pUW8VnrwFDLZ+r1CxG +L6CxOZ0AylCMIlrFeUXMa91kLDJYch0NUPHuGBkdIBDXi2kqN7GflTdV3Z8uev20 +uMjErA93yVOWHTR3Wo8WIHy5mdsNRQgGAPw1RVW7rnYIyXJW/mTs +-----END RSA PRIVATE KEY----- diff --git a/src/deps/src/lua-nginx-module/t/cert/test_passphrase.crt b/src/deps/src/lua-nginx-module/t/cert/test_passphrase.crt new file mode 100644 index 000000000..f4d516ba9 --- /dev/null +++ b/src/deps/src/lua-nginx-module/t/cert/test_passphrase.crt @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICozCCAgwCCQDEutRdSs3vZjANBgkqhkiG9w0BAQUFADCBlDELMAkGA1UEBhMC +Q04xEjAQBgNVBAgMCUd1YW5nZG9uZzERMA8GA1UEBwwIU2hlblpoZW4xEjAQBgNV +BAoMCU9wZW5SZXN0eTESMBAGA1UECwwJT3BlblJlc3R5MREwDwYDVQQDDAh0ZXN0 +LmNvbTEjMCEGCSqGSIb3DQEJARYUZ3VhbmdsaW5sdkBnbWFpbC5jb20wIBcNMTYw +NDI4MTQ0MzI4WhgPMjE1MTAzMjcxNDQzMjhaMIGUMQswCQYDVQQGEwJDTjESMBAG +A1UECAwJR3Vhbmdkb25nMREwDwYDVQQHDAhTaGVuWmhlbjESMBAGA1UECgwJT3Bl +blJlc3R5MRIwEAYDVQQLDAlPcGVuUmVzdHkxETAPBgNVBAMMCHRlc3QuY29tMSMw +IQYJKoZIhvcNAQkBFhRndWFuZ2xpbmx2QGdtYWlsLmNvbTCBnzANBgkqhkiG9w0B +AQEFAAOBjQAwgYkCgYEA2KZ+HdH9R2tarxD8PKqu5EYq2BNGlFRg1xJmrw0XZBRM +UP/VPb+sIeioooz36uhiXfQjExlpBCA/0zNAN+HbFyqpPPTf1qLGrj/dqeE4MJaN +Bwzxiv3fZnENT65u2qbiFWIY+ATNHgA20d50nxNNjPTzLbkx/nYXL92r4kuAGk0C +AwEAATANBgkqhkiG9w0BAQUFAAOBgQCfMo0qbcs3kwl1tcNBO5hCcUUJRzyv041V +ff/nZ/JPIMo/LSZd12K82G/dLRN7uRT9nzqtm+JRkHALHWWWFKi6bdg1vcdOTWqC +08bCkJHQoXJQQLvvA6gNvnR+0b7L4CrCmrcyYgKDLXVGNP9Wv/PqSWWbxsmqngkA +Mvy6CVytFw== +-----END CERTIFICATE----- diff --git a/src/deps/src/lua-nginx-module/t/cert/test_passphrase.key b/src/deps/src/lua-nginx-module/t/cert/test_passphrase.key new file mode 100644 index 000000000..b8fc97634 --- /dev/null +++ b/src/deps/src/lua-nginx-module/t/cert/test_passphrase.key @@ -0,0 +1,18 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,679ACC8E69ACAA92 + +Ssrjp3VU4somCNPiXkWqcudDnvnwbyj/Q0pS07at3lXKbhQSgI1Tzhg9Pm3BXXj5 +mkLdeGG5ocrj1Q9dhtmZgZeHHQIiynZBhjBu1Y+HPef8jXOWLrCOi8EKiWkJ2qG3 +V1KFM/95CcDt0mRLykUXEL3IpUst05SFb9XwiLokB7ypeu3NhgNUHjL6G+ubB4ri +TOUjCW4pEoNHjdC22IiqSncwCVhluYSGhr6ktHKehZMhYIXmL1wmSLdhTlsPXCQl +xvYILQ2vJcKIR1BkeYYPD/OQC6zCZlXIErzfgeZiz2+NTudKYpb9VmsQKsO+R8L7 +tZ/fNaR0vk8bbimMHgStAV4acVsC/7WxsqOjMJ8VTq1iqhYPl6N7kRdR3H3kSSOm +cN9T3SrOHDVaHbnWgToaOE4mKFjvFSLIOcWgus0iOHWXmY+SLG+Ndag3oVB6R9oB +cAHX19mq99+GhzA8IV4I0En2UCKQhnGPvkM+9mcCDxhRETlwncDjlMGOHpQ65J9r +eReVPIpnDkvHxPGTtsR3ZHTdWTZb+C0W2N3QIlJKrOzxFmfoj++yG3tMX42aDY0g +DVkrXgcKobiWN0AVrJNAwfG7uObKSCFYgz/0RRMCO4cjXRW99nxdjVDZhyc6R0Te +jzuF04okkOLNb25n2hP+yIULrn+6Nv/uHtFI0j0n3hOzcKh//dNbACSAKgkHni9g +JKDFJXgLJxf+Wc3So0DF9gYMKJJ+WbcdVT9gkC7RyQHlC90Pn7kNXzHr0ZawUsNI +ZxSkL4dMhYAfA4lUBJbOkwbSurv97LinOSRffpM0Nmf7VNw/Ue15eg== +-----END RSA PRIVATE KEY----- diff --git a/src/deps/src/lua-nginx-module/util/build-with-dd.sh b/src/deps/src/lua-nginx-module/util/build-with-dd.sh new file mode 100755 index 000000000..41ecc7268 --- /dev/null +++ b/src/deps/src/lua-nginx-module/util/build-with-dd.sh @@ -0,0 +1,57 @@ +#!/usr/bin/env bash + +# this script is for developers only. +# dependent on the ngx-build script from the nginx-devel-utils repository: +# https://github.com/openresty/nginx-devel-utils/blob/master/ngx-build +# the resulting nginx is located at ./work/nginx/sbin/nginx + +root=`pwd` +version=${1:-1.4.1} +home=~ +force=$2 + +add_fake_shm_module="--add-module=$root/t/data/fake-shm-module" + +time ngx-build $force $version \ + --with-threads \ + --with-pcre-jit \ + --with-ipv6 \ + --with-cc-opt="-DNGX_LUA_USE_ASSERT -I$PCRE_INC -I$OPENSSL_INC -DDDEBUG=1" \ + --with-http_v2_module \ + --with-http_realip_module \ + --with-http_ssl_module \ + --add-module=$root/../ndk-nginx-module \ + --add-module=$root/../set-misc-nginx-module \ + --with-ld-opt="-L$PCRE_LIB -L$OPENSSL_LIB -Wl,-rpath,$PCRE_LIB:$LIBDRIZZLE_LIB:$OPENSSL_LIB" \ + --without-mail_pop3_module \ + --without-mail_imap_module \ + --with-http_image_filter_module \ + --without-mail_smtp_module \ + --with-stream \ + --with-stream_ssl_module \ + --without-http_upstream_ip_hash_module \ + --without-http_memcached_module \ + --without-http_auth_basic_module \ + --without-http_userid_module \ + --with-http_auth_request_module \ + --add-module=$root/../echo-nginx-module \ + --add-module=$root/../memc-nginx-module \ + --add-module=$root/../srcache-nginx-module \ + --add-module=$root \ + --add-module=$root/../lua-upstream-nginx-module \ + --add-module=$root/../headers-more-nginx-module \ + --add-module=$root/../drizzle-nginx-module \ + --add-module=$root/../rds-json-nginx-module \ + --add-module=$root/../coolkit-nginx-module \ + --add-module=$root/../redis2-nginx-module \ + --add-module=$root/../stream-lua-nginx-module \ + --add-module=$root/t/data/fake-module \ + $add_fake_shm_module \ + --add-module=$root/t/data/fake-delayed-load-module \ + --with-http_gunzip_module \ + --with-http_dav_module \ + --with-select_module \ + --with-poll_module \ + $opts \ + --with-debug + diff --git a/src/deps/src/lua-nginx-module/util/build-without-ssl.sh b/src/deps/src/lua-nginx-module/util/build-without-ssl.sh new file mode 100755 index 000000000..906be7570 --- /dev/null +++ b/src/deps/src/lua-nginx-module/util/build-without-ssl.sh @@ -0,0 +1,67 @@ +#!/usr/bin/env bash + +# this script is for developers only. +# dependent on the ngx-build script from the nginx-devel-utils repository: +# https://github.com/openresty/nginx-devel-utils/blob/master/ngx-build +# the resulting nginx is located at ./work/nginx/sbin/nginx + +root=`pwd` +version=${1:-1.4.1} +home=~ +force=$2 + +# the ngx-build script is from https://github.com/agentzh/nginx-devel-utils + + #--add-module=$home/work/nginx_upload_module-2.2.0 \ + + #--without-pcre \ + #--without-http_rewrite_module \ + #--without-http_autoindex_module \ + #--with-cc=gcc46 \ + #--with-cc=clang \ + #--without-http_referer_module \ + #--with-http_spdy_module \ + +add_fake_shm_module="--add-module=$root/t/data/fake-shm-module" + +time ngx-build $force $version \ + --with-threads \ + --with-pcre-jit \ + --with-ipv6 \ + --with-cc-opt="-DNGX_LUA_USE_ASSERT -I$PCRE_INC" \ + --with-http_v2_module \ + --with-http_realip_module \ + --add-module=$root/../ndk-nginx-module \ + --add-module=$root/../set-misc-nginx-module \ + --with-ld-opt="-L$PCRE_LIB -Wl,-rpath,$PCRE_LIB:$LIBDRIZZLE_LIB" \ + --without-mail_pop3_module \ + --without-mail_imap_module \ + --with-http_image_filter_module \ + --without-mail_smtp_module \ + --with-stream \ + --without-http_upstream_ip_hash_module \ + --without-http_memcached_module \ + --without-http_auth_basic_module \ + --without-http_userid_module \ + --with-http_auth_request_module \ + --add-module=$root/../echo-nginx-module \ + --add-module=$root/../memc-nginx-module \ + --add-module=$root/../srcache-nginx-module \ + --add-module=$root \ + --add-module=$root/../lua-upstream-nginx-module \ + --add-module=$root/../headers-more-nginx-module \ + --add-module=$root/../drizzle-nginx-module \ + --add-module=$root/../rds-json-nginx-module \ + --add-module=$root/../coolkit-nginx-module \ + --add-module=$root/../redis2-nginx-module \ + --add-module=$root/../stream-lua-nginx-module \ + --add-module=$root/t/data/fake-module \ + $add_fake_shm_module \ + --add-module=$root/t/data/fake-delayed-load-module \ + --with-http_gunzip_module \ + --with-http_dav_module \ + --with-select_module \ + --with-poll_module \ + $opts \ + --with-debug + diff --git a/src/deps/src/lua-nginx-module/util/nc_server.py b/src/deps/src/lua-nginx-module/util/nc_server.py new file mode 100644 index 000000000..48c6f4bf1 --- /dev/null +++ b/src/deps/src/lua-nginx-module/util/nc_server.py @@ -0,0 +1,25 @@ +import select, socket +server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +server.setblocking(0) +server.bind(('localhost', 65110)) +server.listen(5) +inputs = [server] + +while inputs: + outputs = [] + readable, writable, exceptional = select.select( + inputs, outputs, inputs) + for s in readable: + if s is server: + connection, client_address = s.accept() + connection.setblocking(0) + inputs.append(connection) + else: + data = s.recv(1024) + if not data: + inputs.remove(s) + s.close() + + for s in exceptional: + inputs.remove(s) + s.close() diff --git a/src/deps/src/lua-resty-core/.github/workflows/semantic-pull-request.yml b/src/deps/src/lua-resty-core/.github/workflows/semantic-pull-request.yml new file mode 100644 index 000000000..12b87cb3c --- /dev/null +++ b/src/deps/src/lua-resty-core/.github/workflows/semantic-pull-request.yml @@ -0,0 +1,30 @@ +name: "Lint PR" + +on: + pull_request_target: + types: + - opened + - edited + - synchronize + +jobs: + main: + name: Validate PR title + runs-on: ubuntu-latest + steps: + - uses: amannn/action-semantic-pull-request@v4 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + # Configure which types are allowed. + # Default: https://github.com/commitizen/conventional-commit-types + types: | + bugfix # bug fixes + change # backward incompatible changes + doc # documentation changes including code comments + editor # code editor related configurations + feature # implementing a new feature + optimize # performance optimizations + refactor # code refactoring and other code rearrangement + style # coding style changes + tests # test suite changes diff --git a/src/deps/src/lua-resty-core/.travis.yml b/src/deps/src/lua-resty-core/.travis.yml index 2d1a3b91a..b8b48456c 100644 --- a/src/deps/src/lua-resty-core/.travis.yml +++ b/src/deps/src/lua-resty-core/.travis.yml @@ -1,3 +1,4 @@ +--- sudo: required dist: bionic @@ -18,6 +19,7 @@ addons: - cpanminus - axel - luarocks + - daemonize cache: directories: @@ -32,7 +34,7 @@ env: - LUAJIT_INC=$LUAJIT_PREFIX/include/luajit-2.1 - LUA_INCLUDE_DIR=$LUAJIT_INC - LUA_CMODULE_DIR=/lib - - PCRE_VER=8.40 + - PCRE_VER=8.45 - PCRE_PREFIX=/opt/pcre - PCRE_LIB=$PCRE_PREFIX/lib - PCRE_INC=$PCRE_PREFIX/include @@ -44,14 +46,14 @@ env: - TEST_NGINX_RANDOMIZE=1 - LUACHECK_VER=0.21.1 matrix: - - NGINX_VERSION=1.21.4 OPENSSL_VER=1.1.1l OPENSSL_PATCH_VER=1.1.1f + - NGINX_VERSION=1.21.4 OPENSSL_VER=1.1.1s OPENSSL_PATCH_VER=1.1.1f services: - memcache before_install: - sudo luarocks install luacheck $LUACHECK_VER - - luacheck -q . + - luacheck --globals coroutine -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 IPC::Run > build.log 2>&1 || (cat build.log && exit 1) diff --git a/src/deps/src/lua-resty-core/README.markdown b/src/deps/src/lua-resty-core/README.markdown index acc0c761b..ea5212d8f 100644 --- a/src/deps/src/lua-resty-core/README.markdown +++ b/src/deps/src/lua-resty-core/README.markdown @@ -29,9 +29,11 @@ Table of Contents * [resty.core.phase](#restycorephase) * [resty.core.ndk](#restycorendk) * [resty.core.socket](#restycoresocket) + * [resty.core.param](#restycoreparam) * [ngx.semaphore](#ngxsemaphore) * [ngx.balancer](#ngxbalancer) * [ngx.ssl](#ngxssl) + * [ngx.ssl.clienthello](#ngxsslclienthello) * [ngx.ssl.session](#ngxsslsession) * [ngx.re](#ngxre) * [ngx.resp](#ngxresp) @@ -228,6 +230,7 @@ in the current request before you reusing the `ctx` table in some other place. * [ngx.status](https://github.com/openresty/lua-nginx-module#ngxstatus) * [ngx.is_subrequest](https://github.com/openresty/lua-nginx-module#ngxis_subrequest) * [ngx.headers_sent](https://github.com/openresty/lua-nginx-module#ngxheaders_sent) +* [ngx.req.is_internal](https://github.com/openresty/lua-nginx-module#ngxreqis_internal) [Back to TOC](#table-of-contents) @@ -241,6 +244,8 @@ in the current request before you reusing the `ctx` table in some other place. * [ngx.cookie_time](https://github.com/openresty/lua-nginx-module#ngxcookie_time) * [ngx.http_time](https://github.com/openresty/lua-nginx-module#ngxhttp_time) * [ngx.parse_http_time](https://github.com/openresty/lua-nginx-module#ngxparse_http_time) +* [monotonic_msec](./lib/resty/core/time.md#monotonic_msec) +* [monotonic_time](./lib/resty/core/time.md#monotonic_time) [Back to TOC](#table-of-contents) @@ -268,6 +273,14 @@ in the current request before you reusing the `ctx` table in some other place. ## resty.core.socket * [socket.setoption](https://github.com/openresty/lua-nginx-module#tcpsocksetoption) +* [socket.setclientcert](https://github.com/openresty/lua-nginx-module#tcpsocksetclientcert) +* [socket.sslhandshake](https://github.com/openresty/lua-nginx-module#tcpsocksslhandshake) + +[Back to TOC](#table-of-contents) + +## resty.core.param + +* [ngx.arg](https://github.com/openresty/lua-nginx-module#ngxarg) (getter only) [Back to TOC](#table-of-contents) @@ -297,6 +310,15 @@ See the [documentation](./lib/ngx/ssl.md) for this Lua module for more details. [Back to TOC](#table-of-contents) +## ngx.ssl.clienthello + +This Lua module provides a Lua API for post-processing SSL client hello message +for NGINX downstream SSL connections. + +See the [documentation](./lib/ngx/ssl/clienthello.md) for this Lua module for more details. + +[Back to TOC](#table-of-contents) + ## ngx.ssl.session This Lua module provides a Lua API for manipulating SSL session data and IDs diff --git a/src/deps/src/lua-resty-core/lib/ngx/pipe.lua b/src/deps/src/lua-resty-core/lib/ngx/pipe.lua index 413a10efb..3757ab7c5 100644 --- a/src/deps/src/lua-resty-core/lib/ngx/pipe.lua +++ b/src/deps/src/lua-resty-core/lib/ngx/pipe.lua @@ -47,7 +47,8 @@ typedef struct { ngx_http_lua_pipe_t *pipe; } ngx_http_lua_ffi_pipe_proc_t; -int ngx_http_lua_ffi_pipe_spawn(ngx_http_lua_ffi_pipe_proc_t *proc, +int ngx_http_lua_ffi_pipe_spawn(ngx_http_request_t *r, + ngx_http_lua_ffi_pipe_proc_t *proc, const char *file, const char **argv, int merge_stderr, size_t buffer_size, const char **environ, u_char *errbuf, size_t *errbuf_size); @@ -624,8 +625,9 @@ do local errbuf = get_string_buf(ERR_BUF_SIZE) local errbuf_size = get_size_ptr() + local r = get_request() errbuf_size[0] = ERR_BUF_SIZE - local rc = C.ngx_http_lua_ffi_pipe_spawn(proc, exe, proc_args, + local rc = C.ngx_http_lua_ffi_pipe_spawn(r, proc, exe, proc_args, merge_stderr, buffer_size, proc_envs, errbuf, errbuf_size) if rc == FFI_ERROR then diff --git a/src/deps/src/lua-resty-core/lib/ngx/ssl.lua b/src/deps/src/lua-resty-core/lib/ngx/ssl.lua index b769fd820..8792be0f0 100644 --- a/src/deps/src/lua-resty-core/lib/ngx/ssl.lua +++ b/src/deps/src/lua-resty-core/lib/ngx/ssl.lua @@ -65,7 +65,8 @@ if subsystem == 'http' then size_t pem_len, unsigned char *der, char **err); int ngx_http_lua_ffi_priv_key_pem_to_der(const unsigned char *pem, - size_t pem_len, unsigned char *der, char **err); + size_t pem_len, const unsigned char *passphrase, + unsigned char *der, char **err); int ngx_http_lua_ffi_ssl_get_tls1_version(ngx_http_request_t *r, char **err); @@ -135,7 +136,8 @@ elseif subsystem == 'stream' then size_t pem_len, unsigned char *der, char **err); int ngx_stream_lua_ffi_priv_key_pem_to_der(const unsigned char *pem, - size_t pem_len, unsigned char *der, char **err); + size_t pem_len, const unsigned char *passphrase, + unsigned char *der, char **err); int ngx_stream_lua_ffi_ssl_get_tls1_version(ngx_stream_lua_request_t *r, char **err); @@ -330,10 +332,11 @@ function _M.cert_pem_to_der(pem) end -function _M.priv_key_pem_to_der(pem) +function _M.priv_key_pem_to_der(pem, passphrase) local outbuf = get_string_buf(#pem) - local sz = ngx_lua_ffi_priv_key_pem_to_der(pem, #pem, outbuf, errmsg) + local sz = ngx_lua_ffi_priv_key_pem_to_der(pem, #pem, + passphrase, outbuf, errmsg) if sz > 0 then return ffi_str(outbuf, sz) end diff --git a/src/deps/src/lua-resty-core/lib/ngx/ssl.md b/src/deps/src/lua-resty-core/lib/ngx/ssl.md index 3ab805987..b71ed5733 100644 --- a/src/deps/src/lua-resty-core/lib/ngx/ssl.md +++ b/src/deps/src/lua-resty-core/lib/ngx/ssl.md @@ -89,8 +89,9 @@ server { -- assuming the user already defines the my_load_private_key() -- function herself. local pem_pkey = assert(my_load_private_key()) + local passphrase = "password" -- or nil - local der_pkey, err = ssl.priv_key_pem_to_der(pem_pkey) + local der_pkey, err = ssl.priv_key_pem_to_der(pem_pkey, passphrase) if not der_pkey then ngx.log(ngx.ERR, "failed to convert private key ", "from PEM to DER: ", err) @@ -188,7 +189,7 @@ function to do the conversion first. priv_key_pem_to_der ------------------- -**syntax:** *der_priv_key, err = ssl.priv_key_pem_to_der(pem_priv_key)* +**syntax:** *der_priv_key, err = ssl.priv_key_pem_to_der(pem_priv_key, passphrase)* **context:** *any* @@ -196,6 +197,8 @@ Converts the PEM-formatted SSL private key data into the DER format (for later u in the [set_der_priv_key](#set_der_priv_key) function, for example). +The `passphrase` is the passphrase for `pem_priv_key` if the private key is password protected. + In case of failures, returns `nil` and a string describing the error. Alternatively, you can do the PEM to DER conversion *offline* with the `openssl` command-line utility, like below diff --git a/src/deps/src/lua-resty-core/lib/ngx/ssl/clienthello.lua b/src/deps/src/lua-resty-core/lib/ngx/ssl/clienthello.lua index ed68f9b61..b08351813 100644 --- a/src/deps/src/lua-resty-core/lib/ngx/ssl/clienthello.lua +++ b/src/deps/src/lua-resty-core/lib/ngx/ssl/clienthello.lua @@ -7,6 +7,7 @@ base.allows_subsystem('http', 'stream') local ffi = require "ffi" local bit = require "bit" +local bor = bit.bor local C = ffi.C local ffi_str = ffi.string local get_request = base.get_request @@ -16,6 +17,9 @@ local get_size_ptr = base.get_size_ptr local FFI_OK = base.FFI_OK local subsystem = ngx.config.subsystem local ngx_phase = ngx.get_phase +local byte = string.byte +local lshift = bit.lshift +local table_insert = table.insert local ngx_lua_ffi_ssl_get_client_hello_server_name @@ -79,7 +83,7 @@ function _M.get_client_hello_server_name() end if ngx_phase() ~= "ssl_client_hello" then - error("API disabled in the current context", 2) + error("API disabled in the current context") end local sizep = get_size_ptr() @@ -107,7 +111,7 @@ function _M.get_client_hello_ext(ext_type) end if ngx_phase() ~= "ssl_client_hello" then - error("API disabled in the current context", 2) + error("API disabled in the current context") end local sizep = get_size_ptr() @@ -126,6 +130,67 @@ function _M.get_client_hello_ext(ext_type) return nil, ffi_str(errmsg[0]) end +-- tls.handshake.extension.type supported_version +local supported_versions_type = 43 +local versions_map = { + [0x002] = "SSLv2", + [0x300] = "SSLv3", + [0x301] = "TLSv1", + [0x302] = "TLSv1.1", + [0x303] = "TLSv1.2", + [0x304] = "TLSv1.3", +} + +-- return types, err +function _M.get_supported_versions() + local r = get_request() + if not r then + error("no request found") + end + + if ngx_phase() ~= "ssl_client_hello" then + error("API disabled in the current context") + end + + local sizep = get_size_ptr() + + local rc = ngx_lua_ffi_ssl_get_client_hello_ext(r, supported_versions_type, + cucharpp, sizep, errmsg) + + if rc ~= FFI_OK then + -- NGX_DECLINED: no extension + if rc == -5 then + return nil + end + + return nil, ffi_str(errmsg[0]) + end + + local supported_versions_str = ffi_str(cucharpp[0], sizep[0]) + local remain_len = #supported_versions_str + if remain_len == 0 then + return nil + end + + local supported_versions_len = byte(supported_versions_str, 1) + remain_len = remain_len - 1 + + if remain_len ~= supported_versions_len then + return nil + end + local types = {} + while remain_len >= 2 do + local type_hi = byte(supported_versions_str, remain_len) + local type_lo = byte(supported_versions_str, remain_len + 1) + local type_id = lshift(type_hi, 8) + type_lo + if versions_map[type_id] ~= nil then + table_insert(types, versions_map[type_id]) + end + remain_len = remain_len - 2 + end + return types +end + local prot_map = { ["SSLv2"] = 0x0002, @@ -145,7 +210,7 @@ function _M.set_protocols(protocols) end if ngx_phase() ~= "ssl_client_hello" then - error("API disabled in the current context" .. ngx_phase(), 2) + error("API disabled in the current context") end local prots = 0 @@ -153,7 +218,7 @@ function _M.set_protocols(protocols) if not prot_map[v] then return nil, "invalid protocols failed" end - prots = bit.bor(prots, prot_map[v]) + prots = bor(prots, prot_map[v]) end local rc = ngx_lua_ffi_ssl_set_protocols(r, prots, errmsg) diff --git a/src/deps/src/lua-resty-core/lib/ngx/ssl/clienthello.md b/src/deps/src/lua-resty-core/lib/ngx/ssl/clienthello.md index bc70b4cf9..be4a6782a 100644 --- a/src/deps/src/lua-resty-core/lib/ngx/ssl/clienthello.md +++ b/src/deps/src/lua-resty-core/lib/ngx/ssl/clienthello.md @@ -106,6 +106,24 @@ So this function can only be called in the context of [ssl_client_hello_by_lua*] [Back to TOC](#table-of-contents) +get_supported_versions +-------------- +**syntax:** *types, err = ssl_clt.get_supported_versions()* + +**context:** *ssl_client_hello_by_lua** + +Returns the table of ssl hello supported versions set by the client. + +Return `nil` when then the extension does not exist. + +In case of errors, it returns `nil` and a string describing the error. + +Note that the types is gotten from the raw extensions of the client hello message associated with the current downstream SSL connection. + +So this function can only be called in the context of [ssl_client_hello_by_lua*](https://github.com/openresty/lua-nginx-module/#ssl_client_hello_by_lua_block). + +[Back to TOC](#table-of-contents) + get_client_hello_ext ---------------------- **syntax:** *ext, err = ssl_clt.get_client_hello_ext(ext_type)* diff --git a/src/deps/src/lua-resty-core/lib/resty/core.lua b/src/deps/src/lua-resty-core/lib/resty/core.lua index 54722302a..e92084c09 100644 --- a/src/deps/src/lua-resty-core/lib/resty/core.lua +++ b/src/deps/src/lua-resty-core/lib/resty/core.lua @@ -20,6 +20,8 @@ if subsystem == 'http' then require "resty.core.phase" require "resty.core.ndk" require "resty.core.socket" + require "resty.core.coroutine" + require "resty.core.param" end diff --git a/src/deps/src/lua-resty-core/lib/resty/core/base.lua b/src/deps/src/lua-resty-core/lib/resty/core/base.lua index d1dff96a4..bc50c3b30 100644 --- a/src/deps/src/lua-resty-core/lib/resty/core/base.lua +++ b/src/deps/src/lua-resty-core/lib/resty/core/base.lua @@ -3,6 +3,7 @@ local ffi = require 'ffi' local ffi_new = ffi.new +local pcall = pcall local error = error local select = select local ceil = math.ceil @@ -18,22 +19,22 @@ local FREE_LIST_REF = 0 if subsystem == 'http' then if not ngx.config or not ngx.config.ngx_lua_version - or ngx.config.ngx_lua_version ~= 10022 + or ngx.config.ngx_lua_version ~= 10023 then - error("ngx_http_lua_module 0.10.22 required") + error("ngx_http_lua_module 0.10.23 required") end elseif subsystem == 'stream' then if not ngx.config or not ngx.config.ngx_lua_version - or ngx.config.ngx_lua_version ~= 11 + or ngx.config.ngx_lua_version ~= 12 then - error("ngx_stream_lua_module 0.0.11 required") + error("ngx_stream_lua_module 0.0.12 required") end else - error("ngx_http_lua_module 0.10.22 or " - .. "ngx_stream_lua_module 0.0.11 required") + error("ngx_http_lua_module 0.10.23 or " + .. "ngx_stream_lua_module 0.0.12 required") end @@ -68,9 +69,17 @@ end do local orig_require = require local pkg_loaded = package.loaded + -- the key_sentinel is inserted into package.loaded before + -- the chunk is executed and replaced if the chunk completes normally. + local key_sentinel = pkg_loaded[...] + local function my_require(name) local mod = pkg_loaded[name] if mod then + if mod == key_sentinel then + error("loop or previous error loading module '" .. name .. "'") + end + return mod end return orig_require(name) @@ -132,7 +141,7 @@ local c_buf_type = ffi.typeof("char[?]") local _M = new_tab(0, 18) -_M.version = "0.1.24" +_M.version = "0.1.25" _M.new_tab = new_tab _M.clear_tab = clear_tab @@ -181,7 +190,8 @@ end function _M.get_string_buf(size, must_alloc) -- ngx.log(ngx.ERR, "str buf size: ", str_buf_size) if size > str_buf_size or must_alloc then - return ffi_new(c_buf_type, size) + local buf = ffi_new(c_buf_type, size) + return buf end if not str_buf then diff --git a/src/deps/src/lua-resty-core/lib/resty/core/coroutine.lua b/src/deps/src/lua-resty-core/lib/resty/core/coroutine.lua new file mode 100644 index 000000000..9c95b163e --- /dev/null +++ b/src/deps/src/lua-resty-core/lib/resty/core/coroutine.lua @@ -0,0 +1,29 @@ +local base = require "resty.core.base" +local get_request = base.get_request + +do + local keys = {'create', 'yield', 'resume', 'status', 'wrap'} + local errmsg = base.get_errmsg_ptr() + local get_raw_phase = ngx.get_raw_phase + + for _, key in ipairs(keys) do + local std = coroutine['_' .. key] + local ours = coroutine['__' .. key] + coroutine[key] = function (...) + local r = get_request() + if r ~= nil then + local ctx = get_raw_phase(r, errmsg) + if ctx ~= 0x020 and ctx ~= 0x040 then + return ours(...) + end + end + return std(...) + end + end + + package.loaded.coroutine = coroutine +end + +return { + version = base.version +} diff --git a/src/deps/src/lua-resty-core/lib/resty/core/misc.lua b/src/deps/src/lua-resty-core/lib/resty/core/misc.lua index ff7954a2b..4f4151d7b 100644 --- a/src/deps/src/lua-resty-core/lib/resty/core/misc.lua +++ b/src/deps/src/lua-resty-core/lib/resty/core/misc.lua @@ -89,6 +89,7 @@ if subsystem == "http" then int ngx_http_lua_ffi_get_conf_env(const unsigned char *name, unsigned char **env_buf, size_t *name_len); + int ngx_http_lua_ffi_req_is_internal(ngx_http_request_t *r); ]] @@ -115,8 +116,6 @@ if subsystem == "http" then if rc == FFI_BAD_CONTEXT then error("API disabled in the current context", 2) end - - return end register_setter("status", set_status) @@ -166,6 +165,25 @@ if subsystem == "http" then end register_getter("headers_sent", headers_sent) + + -- ngx.req.is_internal + + + function ngx.req.is_internal() + local r = get_request() + if not r then + error("no request found") + end + + local rc = C.ngx_http_lua_ffi_req_is_internal(r) + + if rc == FFI_BAD_CONTEXT then + error("API disabled in the current context") + end + + return rc == 1 + end + elseif subsystem == "stream" then ffi.cdef[[ int ngx_stream_lua_ffi_get_resp_status(ngx_stream_lua_request_t *r); diff --git a/src/deps/src/lua-resty-core/lib/resty/core/param.lua b/src/deps/src/lua-resty-core/lib/resty/core/param.lua new file mode 100644 index 000000000..ef571372a --- /dev/null +++ b/src/deps/src/lua-resty-core/lib/resty/core/param.lua @@ -0,0 +1,103 @@ +-- Copyright (C) Yichun Zhang (agentzh) + + +local ffi = require 'ffi' +local base = require "resty.core.base" +require "resty.core.phase" -- for ngx.get_phase + + +local C = ffi.C +local ffi_str = ffi.string +local FFI_AGAIN = base.FFI_AGAIN +local FFI_OK = base.FFI_OK +local get_request = base.get_request +local get_string_buf = base.get_string_buf +local getmetatable = getmetatable +local ngx = ngx +local ngx_phase = ngx.get_phase + + +local _M = { + version = base.version +} + + +ffi.cdef[[ + typedef unsigned char u_char; + + void ngx_http_lua_ffi_get_setby_param(ngx_http_request_t *r, int idx, + u_char **data, size_t *len); + int ngx_http_lua_ffi_get_body_filter_param_eof(ngx_http_request_t *r); + int ngx_http_lua_ffi_get_body_filter_param_body(ngx_http_request_t *r, + u_char **data_p, size_t *len_p); + int ngx_http_lua_ffi_copy_body_filter_param_body(ngx_http_request_t *r, + u_char *data); +]] +local data_p = ffi.new("unsigned char*[1]") +local len_p = ffi.new("size_t[1]") + + +local function get_setby_param(r, idx) + C.ngx_http_lua_ffi_get_setby_param(r, idx, data_p, len_p) + if len_p[0] == 0 then + return nil + end + + return ffi_str(data_p[0], len_p[0]) +end + + +local function get_body_filter_param(r, idx) + if idx == 1 then + data_p[0] = nil + local rc = C.ngx_http_lua_ffi_get_body_filter_param_body(r, data_p, + len_p) + if rc == FFI_AGAIN then + local buf = get_string_buf(len_p[0]) + assert(C.ngx_http_lua_ffi_copy_body_filter_param_body(r, buf) + == FFI_OK) + return ffi_str(buf, len_p[0]) + end + + if len_p[0] == 0 then + return "" + end + + return ffi_str(data_p[0], len_p[0]) + + elseif idx == 2 then + local rc = C.ngx_http_lua_ffi_get_body_filter_param_eof(r) + return rc == 1 + + else + return nil + end +end + + +local function get_param(tb, idx) + local r = get_request() + if not r then + error("no request found") + end + + local phase = ngx_phase() + if phase == "set" then + return get_setby_param(r, idx) + end + + if phase == "body_filter" then + return get_body_filter_param(r, idx) + end + + error("API disabled in the current context") +end + + +do + local mt = getmetatable(ngx.arg) + mt.__index = get_param +end + + +return _M diff --git a/src/deps/src/lua-resty-core/lib/resty/core/phase.lua b/src/deps/src/lua-resty-core/lib/resty/core/phase.lua index 6eaad4c8b..8bd2ce827 100644 --- a/src/deps/src/lua-resty-core/lib/resty/core/phase.lua +++ b/src/deps/src/lua-resty-core/lib/resty/core/phase.lua @@ -30,6 +30,7 @@ local context_names = { [0x1000] = "ssl_session_fetch", [0x2000] = "exit_worker", [0x4000] = "ssl_client_hello", + [0x8000] = "server_rewrite", } @@ -55,6 +56,16 @@ function ngx.get_phase() end +function ngx.get_raw_phase(r) + local context = C.ngx_http_lua_ffi_get_phase(r, errmsg) + if context == FFI_ERROR then -- NGX_ERROR + error(errmsg, 2) + end + + return context +end + + return { version = base.version } diff --git a/src/deps/src/lua-resty-core/lib/resty/core/request.lua b/src/deps/src/lua-resty-core/lib/resty/core/request.lua index 747b8c256..524338d6a 100644 --- a/src/deps/src/lua-resty-core/lib/resty/core/request.lua +++ b/src/deps/src/lua-resty-core/lib/resty/core/request.lua @@ -10,6 +10,7 @@ local subsystem = ngx.config.subsystem local FFI_BAD_CONTEXT = base.FFI_BAD_CONTEXT local FFI_DECLINED = base.FFI_DECLINED local FFI_OK = base.FFI_OK +local clear_tab = base.clear_tab local new_tab = base.new_tab local C = ffi.C local ffi_cast = ffi.cast @@ -192,7 +193,7 @@ function ngx.req.get_headers(max_headers, raw) end -function ngx.req.get_uri_args(max_args) +function ngx.req.get_uri_args(max_args, tab) local r = get_request() if not r then error("no request found") @@ -202,13 +203,17 @@ function ngx.req.get_uri_args(max_args) max_args = -1 end + if tab then + clear_tab(tab) + end + local n = C.ngx_http_lua_ffi_req_get_uri_args_count(r, max_args, truncated) if n == FFI_BAD_CONTEXT then error("API disabled in the current context", 2) end if n == 0 then - return {} + return tab or {} end local args_len = C.ngx_http_lua_ffi_req_get_querystring_len(r) @@ -218,7 +223,7 @@ function ngx.req.get_uri_args(max_args) local nargs = C.ngx_http_lua_ffi_req_get_uri_args(r, strbuf, kvbuf, n) - local args = new_tab(0, nargs) + local args = tab or new_tab(0, nargs) for i = 0, nargs - 1 do local arg = kvbuf[i] diff --git a/src/deps/src/lua-resty-core/lib/resty/core/response.lua b/src/deps/src/lua-resty-core/lib/resty/core/response.lua index 891a07edc..986de7461 100644 --- a/src/deps/src/lua-resty-core/lib/resty/core/response.lua +++ b/src/deps/src/lua-resty-core/lib/resty/core/response.lua @@ -45,6 +45,61 @@ ffi.cdef[[ ]] +local ngx_lua_ffi_set_resp_header + +local MACOS = jit and jit.os == "OSX" + +if MACOS then + ffi.cdef[[ + typedef struct { + ngx_http_request_t *r; + const char *key_data; + size_t key_len; + int is_nil; + const char *sval; + size_t sval_len; + void *mvals; + size_t mvals_len; + int override; + char **errmsg; + } ngx_http_lua_set_resp_header_params_t; + + int ngx_http_lua_ffi_set_resp_header_macos( + ngx_http_lua_set_resp_header_params_t *p); + ]] + + local set_params = ffi.new("ngx_http_lua_set_resp_header_params_t") + + ngx_lua_ffi_set_resp_header = function(r, key, key_len, is_nil, + sval, sval_len, mvals, + mvals_len, override, err) + + set_params.r = r + set_params.key_data = key + set_params.key_len = key_len + set_params.is_nil = is_nil + set_params.sval = sval + set_params.sval_len = sval_len + set_params.mvals = mvals + set_params.mvals_len = mvals_len + set_params.override = override + set_params.errmsg = err + + return C.ngx_http_lua_ffi_set_resp_header_macos(set_params) + end + +else + ngx_lua_ffi_set_resp_header = function(r, key, key_len, is_nil, + sval, sval_len, mvals, + mvals_len, override, err) + + return C.ngx_http_lua_ffi_set_resp_header(r, key, key_len, is_nil, + sval, sval_len, mvals, + mvals_len, override, err) + end +end + + local function set_resp_header(tb, key, value, no_override) local r = get_request() if not r then @@ -61,8 +116,8 @@ local function set_resp_header(tb, key, value, no_override) error("invalid header value", 3) end - rc = C.ngx_http_lua_ffi_set_resp_header(r, key, #key, true, nil, 0, nil, - 0, 1, errmsg) + rc = ngx_lua_ffi_set_resp_header(r, key, #key, true, nil, 0, nil, + 0, 1, errmsg) else local sval, sval_len, mvals, mvals_len, buf @@ -99,9 +154,9 @@ local function set_resp_header(tb, key, value, no_override) end local override_int = no_override and 0 or 1 - rc = C.ngx_http_lua_ffi_set_resp_header(r, key, #key, false, sval, - sval_len, mvals, mvals_len, - override_int, errmsg) + rc = ngx_lua_ffi_set_resp_header(r, key, #key, false, sval, + sval_len, mvals, mvals_len, + override_int, errmsg) end if rc == 0 or rc == FFI_DECLINED then diff --git a/src/deps/src/lua-resty-core/lib/resty/core/shdict.lua b/src/deps/src/lua-resty-core/lib/resty/core/shdict.lua index dedf12c44..8d60d160e 100644 --- a/src/deps/src/lua-resty-core/lib/resty/core/shdict.lua +++ b/src/deps/src/lua-resty-core/lib/resty/core/shdict.lua @@ -72,9 +72,39 @@ size_t ngx_http_lua_ffi_shdict_capacity(void *zone); void *ngx_http_lua_ffi_shdict_udata_to_zone(void *zone_udata); ]] - ngx_lua_ffi_shdict_get = C.ngx_http_lua_ffi_shdict_get - ngx_lua_ffi_shdict_incr = C.ngx_http_lua_ffi_shdict_incr - ngx_lua_ffi_shdict_store = C.ngx_http_lua_ffi_shdict_store + ngx_lua_ffi_shdict_get = function(zone, key, key_len, value_type, + str_value_buf, value_len, + num_value, user_flags, + get_stale, is_stale, errmsg) + + return C.ngx_http_lua_ffi_shdict_get(zone, key, key_len, value_type, + str_value_buf, value_len, + num_value, user_flags, + get_stale, is_stale, errmsg) + end + + ngx_lua_ffi_shdict_incr = function(zone, key, + key_len, value, err, has_init, + init, init_ttl, forcible) + + return C.ngx_http_lua_ffi_shdict_incr(zone, key, + key_len, value, err, has_init, + init, init_ttl, forcible) + end + + ngx_lua_ffi_shdict_store = function(zone, op, + key, key_len, value_type, + str_value_buf, str_value_len, + num_value, exptime, user_flags, + errmsg, forcible) + + return C.ngx_http_lua_ffi_shdict_store(zone, op, + key, key_len, value_type, + str_value_buf, str_value_len, + num_value, exptime, user_flags, + errmsg, forcible) + end + ngx_lua_ffi_shdict_flush_all = C.ngx_http_lua_ffi_shdict_flush_all ngx_lua_ffi_shdict_get_ttl = C.ngx_http_lua_ffi_shdict_get_ttl ngx_lua_ffi_shdict_set_expire = C.ngx_http_lua_ffi_shdict_set_expire @@ -126,9 +156,39 @@ size_t ngx_stream_lua_ffi_shdict_capacity(void *zone); void *ngx_stream_lua_ffi_shdict_udata_to_zone(void *zone_udata); ]] - ngx_lua_ffi_shdict_get = C.ngx_stream_lua_ffi_shdict_get - ngx_lua_ffi_shdict_incr = C.ngx_stream_lua_ffi_shdict_incr - ngx_lua_ffi_shdict_store = C.ngx_stream_lua_ffi_shdict_store + ngx_lua_ffi_shdict_get = function(zone, key, key_len, value_type, + str_value_buf, value_len, + num_value, user_flags, + get_stale, is_stale, errmsg) + + return C.ngx_stream_lua_ffi_shdict_get(zone, key, key_len, value_type, + str_value_buf, value_len, + num_value, user_flags, + get_stale, is_stale, errmsg) + end + + ngx_lua_ffi_shdict_incr = function(zone, key, + key_len, value, err, has_init, + init, init_ttl, forcible) + + return C.ngx_stream_lua_ffi_shdict_incr(zone, key, + key_len, value, err, has_init, + init, init_ttl, forcible) + end + + ngx_lua_ffi_shdict_store = function(zone, op, + key, key_len, value_type, + str_value_buf, str_value_len, + num_value, exptime, user_flags, + errmsg, forcible) + + return C.ngx_stream_lua_ffi_shdict_store(zone, op, + key, key_len, value_type, + str_value_buf, str_value_len, + num_value, exptime, user_flags, + errmsg, forcible) + end + ngx_lua_ffi_shdict_flush_all = C.ngx_stream_lua_ffi_shdict_flush_all ngx_lua_ffi_shdict_get_ttl = C.ngx_stream_lua_ffi_shdict_get_ttl ngx_lua_ffi_shdict_set_expire = C.ngx_stream_lua_ffi_shdict_set_expire @@ -153,6 +213,240 @@ else error("unknown subsystem: " .. subsystem) end + +local MACOS = jit and jit.os == "OSX" + +if MACOS and subsystem == 'http' then + ffi.cdef[[ +typedef struct { + void *zone; + const unsigned char *key; + size_t key_len; + int *value_type; + unsigned char **str_value_buf; + size_t *str_value_len; + double *num_value; + int *user_flags; + int get_stale; + int *is_stale; + char **errmsg; +} ngx_http_lua_shdict_get_params_t; + +typedef struct { + void *zone; + int op; + const unsigned char *key; + size_t key_len; + int value_type; + const unsigned char *str_value_buf; + size_t str_value_len; + double num_value; + long exptime; + int user_flags; + char **errmsg; + int *forcible; +} ngx_http_lua_shdict_store_params_t; + +typedef struct { + void *zone; + const unsigned char *key; + size_t key_len; + double *num_value; + char **errmsg; + int has_init; + double init; + long init_ttl; + int *forcible; +} ngx_http_lua_shdict_incr_params_t; + +int ngx_http_lua_ffi_shdict_get_macos( + ngx_http_lua_shdict_get_params_t *p); +int ngx_http_lua_ffi_shdict_store_macos( + ngx_http_lua_shdict_store_params_t *p); +int ngx_http_lua_ffi_shdict_incr_macos( + ngx_http_lua_shdict_incr_params_t *p); + ]] + + local get_params = ffi_new("ngx_http_lua_shdict_get_params_t") + local incr_params = ffi_new("ngx_http_lua_shdict_incr_params_t") + local store_params = ffi_new("ngx_http_lua_shdict_store_params_t") + + ngx_lua_ffi_shdict_get = function(zone, key, key_len, value_type, + str_value_buf, value_len, + num_value, user_flags, + get_stale, is_stale, errmsg) + + get_params.zone = zone + get_params.key = key + get_params.key_len = key_len + get_params.value_type = value_type + get_params.str_value_buf = str_value_buf + get_params.str_value_len = value_len + get_params.num_value = num_value + get_params.user_flags = user_flags + get_params.get_stale = get_stale + get_params.is_stale = is_stale + get_params.errmsg = errmsg + + return C.ngx_http_lua_ffi_shdict_get_macos(get_params) + end + + ngx_lua_ffi_shdict_incr = function(zone, key, + key_len, value, err, has_init, + init, init_ttl, forcible) + + incr_params.zone = zone + incr_params.key = key + incr_params.key_len = key_len + incr_params.num_value = value + incr_params.errmsg = err + incr_params.has_init = has_init + incr_params.init = init + incr_params.init_ttl = init_ttl + incr_params.forcible = forcible + + return C.ngx_http_lua_ffi_shdict_incr_macos(incr_params) + end + + ngx_lua_ffi_shdict_store = function(zone, op, + key, key_len, value_type, + str_value_buf, str_value_len, + num_value, exptime, user_flags, + errmsg, forcible) + + store_params.zone = zone + store_params.op = op + store_params.key = key + store_params.key_len = key_len + store_params.value_type = value_type + store_params.str_value_buf = str_value_buf + store_params.str_value_len = str_value_len + store_params.num_value = num_value + store_params.exptime = exptime + store_params.user_flags = user_flags + store_params.errmsg = errmsg + store_params.forcible = forcible + + return C.ngx_http_lua_ffi_shdict_store_macos(store_params) + end +end + +if MACOS and subsystem == 'stream' then + ffi.cdef[[ +typedef struct { + void *zone; + const unsigned char *key; + size_t key_len; + int *value_type; + unsigned char **str_value_buf; + size_t *str_value_len; + double *num_value; + int *user_flags; + int get_stale; + int *is_stale; + char **errmsg; +} ngx_stream_lua_shdict_get_params_t; + +typedef struct { + void *zone; + int op; + const unsigned char *key; + size_t key_len; + int value_type; + const unsigned char *str_value_buf; + size_t str_value_len; + double num_value; + long exptime; + int user_flags; + char **errmsg; + int *forcible; +} ngx_stream_lua_shdict_store_params_t; + +typedef struct { + void *zone; + const unsigned char *key; + size_t key_len; + double *num_value; + char **errmsg; + int has_init; + double init; + long init_ttl; + int *forcible; +} ngx_stream_lua_shdict_incr_params_t; + +int ngx_stream_lua_ffi_shdict_get_macos( + ngx_stream_lua_shdict_get_params_t *p); +int ngx_stream_lua_ffi_shdict_store_macos( + ngx_stream_lua_shdict_store_params_t *p); +int ngx_stream_lua_ffi_shdict_incr_macos( + ngx_stream_lua_shdict_incr_params_t *p); + ]] + + local get_params = ffi_new("ngx_stream_lua_shdict_get_params_t") + local store_params = ffi_new("ngx_stream_lua_shdict_store_params_t") + local incr_params = ffi_new("ngx_stream_lua_shdict_incr_params_t") + + ngx_lua_ffi_shdict_get = function(zone, key, key_len, value_type, + str_value_buf, value_len, + num_value, user_flags, + get_stale, is_stale, errmsg) + + get_params.zone = zone + get_params.key = key + get_params.key_len = key_len + get_params.value_type = value_type + get_params.str_value_buf = str_value_buf + get_params.str_value_len = value_len + get_params.num_value = num_value + get_params.user_flags = user_flags + get_params.get_stale = get_stale + get_params.is_stale = is_stale + get_params.errmsg = errmsg + + return C.ngx_stream_lua_ffi_shdict_get_macos(get_params) + end + + ngx_lua_ffi_shdict_incr = function(zone, key, + key_len, value, err, has_init, + init, init_ttl, forcible) + + incr_params.zone = zone + incr_params.key = key + incr_params.key_len = key_len + incr_params.num_value = value + incr_params.errmsg = err + incr_params.has_init = has_init + incr_params.init = init + incr_params.init_ttl = init_ttl + incr_params.forcible = forcible + + return C.ngx_stream_lua_ffi_shdict_incr_macos(incr_params) + end + + ngx_lua_ffi_shdict_store = function(zone, op, + key, key_len, value_type, + str_value_buf, str_value_len, + num_value, exptime, user_flags, + errmsg, forcible) + + store_params.zone = zone + store_params.op = op + store_params.key = key + store_params.key_len = key_len + store_params.value_type = value_type + store_params.str_value_buf = str_value_buf + store_params.str_value_len = str_value_len + store_params.num_value = num_value + store_params.exptime = exptime + store_params.user_flags = user_flags + store_params.errmsg = errmsg + store_params.forcible = forcible + + return C.ngx_stream_lua_ffi_shdict_store_macos(store_params) + end +end + + if not pcall(function () return C.free end) then ffi.cdef[[ void free(void *ptr); diff --git a/src/deps/src/lua-resty-core/lib/resty/core/socket.lua b/src/deps/src/lua-resty-core/lib/resty/core/socket.lua index 1a504ecfc..ede5b663f 100644 --- a/src/deps/src/lua-resty-core/lib/resty/core/socket.lua +++ b/src/deps/src/lua-resty-core/lib/resty/core/socket.lua @@ -1,18 +1,27 @@ local base = require "resty.core.base" -base.allows_subsystem('http') -local debug = require 'debug' -local ffi = require 'ffi' +base.allows_subsystem("http") +local debug = require "debug" +local ffi = require "ffi" -local error = error +local error = error +local assert = assert local tonumber = tonumber -local registry = debug.getregistry() -local ffi_new = ffi.new -local ffi_string = ffi.string -local C = ffi.C -local get_string_buf = base.get_string_buf -local get_size_ptr = base.get_size_ptr local tostring = tostring +local type = type +local select = select +local registry = debug.getregistry() + +local C = ffi.C +local ffi_new = ffi.new +local ffi_str = ffi.string +local ffi_gc = ffi.gc + +local get_string_buf = base.get_string_buf +local get_size_ptr = base.get_size_ptr +local get_request = base.get_request + +local co_yield = coroutine._yield local option_index = { @@ -35,14 +44,36 @@ ngx_http_lua_ffi_socket_tcp_getoption(ngx_http_lua_socket_tcp_upstream_t *u, int ngx_http_lua_ffi_socket_tcp_setoption(ngx_http_lua_socket_tcp_upstream_t *u, int opt, int val, unsigned char *err, size_t *errlen); + +int +ngx_http_lua_ffi_socket_tcp_sslhandshake(ngx_http_request_t *r, + ngx_http_lua_socket_tcp_upstream_t *u, void *sess, + int enable_session_reuse, ngx_str_t *server_name, int verify, + int ocsp_status_req, void *chain, void *pkey, char **errmsg); + +int +ngx_http_lua_ffi_socket_tcp_get_sslhandshake_result(ngx_http_request_t *r, + ngx_http_lua_socket_tcp_upstream_t *u, void **sess, char **errmsg, + int *openssl_error_code); + +void +ngx_http_lua_ffi_ssl_free_session(void *sess); ]] local output_value_buf = ffi_new("int[1]") -local FFI_OK = base.FFI_OK -local SOCKET_CTX_INDEX = 1 local ERR_BUF_SIZE = 4096 +local FFI_OK = base.FFI_OK +local FFI_ERROR = base.FFI_ERROR +local FFI_DONE = base.FFI_DONE +local FFI_AGAIN = base.FFI_AGAIN +local FFI_NO_REQ_CTX = base.FFI_NO_REQ_CTX + +local SOCKET_CTX_INDEX = 1 +local SOCKET_CLIENT_CERT_INDEX = 6 +local SOCKET_CLIENT_PKEY_INDEX = 7 + local function get_tcp_socket(cosocket) local tcp_socket = cosocket[SOCKET_CTX_INDEX] @@ -75,7 +106,7 @@ local function getoption(cosocket, option) err, errlen) if rc ~= FFI_OK then - return nil, ffi_string(err, errlen[0]) + return nil, ffi_str(err, errlen[0]) end return tonumber(output_value_buf[0]) @@ -107,17 +138,134 @@ local function setoption(cosocket, option, value) err, errlen) if rc ~= FFI_OK then - return nil, ffi_string(err, errlen[0]) + return nil, ffi_str(err, errlen[0]) end return true end +local errmsg = base.get_errmsg_ptr() +local session_ptr = ffi_new("void *[1]") +local server_name_str = ffi_new("ngx_str_t[1]") +local openssl_error_code = ffi_new("int[1]") + + +local function setclientcert(cosocket, cert, pkey) + if not cert and not pkey then + cosocket[SOCKET_CLIENT_CERT_INDEX] = nil + cosocket[SOCKET_CLIENT_PKEY_INDEX] = nil + return true + end + + if not cert or not pkey then + return nil, + "client certificate must be supplied with corresponding " .. + "private key" + end + + if type(cert) ~= "cdata" then + return nil, "bad cert arg: cdata expected, got " .. type(cert) + end + + if type(pkey) ~= "cdata" then + return nil, "bad pkey arg: cdata expected, got " .. type(pkey) + end + + cosocket[SOCKET_CLIENT_CERT_INDEX] = cert + cosocket[SOCKET_CLIENT_PKEY_INDEX] = pkey + + return true +end + + +local function sslhandshake(cosocket, reused_session, server_name, ssl_verify, + send_status_req, ...) + + local n = select("#", ...) + if not cosocket or n > 0 then + error("ngx.socket sslhandshake: expecting 1 ~ 5 arguments " .. + "(including the object), but seen " .. (cosocket and 5 + n or 0)) + end + + local r = get_request() + if not r then + error("no request found", 2) + end + + session_ptr[0] = type(reused_session) == "cdata" and reused_session or nil + + if server_name then + server_name_str[0].data = server_name + server_name_str[0].len = #server_name + + else + server_name_str[0].data = nil + server_name_str[0].len = 0 + end + + local u = get_tcp_socket(cosocket) + + local rc = C.ngx_http_lua_ffi_socket_tcp_sslhandshake(r, u, + session_ptr[0], + reused_session ~= false, + server_name_str, + ssl_verify and 1 or 0, + send_status_req and 1 or 0, + cosocket[SOCKET_CLIENT_CERT_INDEX], + cosocket[SOCKET_CLIENT_PKEY_INDEX], + errmsg) + + if rc == FFI_NO_REQ_CTX then + error("no request ctx found", 2) + end + + while true do + if rc == FFI_ERROR then + if openssl_error_code[0] ~= 0 then + return nil, openssl_error_code[0] .. ": " .. ffi_str(errmsg[0]) + end + + return nil, ffi_str(errmsg[0]) + end + + if rc == FFI_DONE then + return reused_session + end + + if rc == FFI_OK then + if reused_session == false then + return true + end + + rc = C.ngx_http_lua_ffi_socket_tcp_get_sslhandshake_result(r, u, + session_ptr, errmsg, openssl_error_code) + + assert(rc == FFI_OK) + + if session_ptr[0] == nil then + return session_ptr[0] + end + + return ffi_gc(session_ptr[0], C.ngx_http_lua_ffi_ssl_free_session) + end + + assert(rc == FFI_AGAIN) + + co_yield() + + rc = C.ngx_http_lua_ffi_socket_tcp_get_sslhandshake_result(r, u, + session_ptr, errmsg, openssl_error_code) + end +end + + do local method_table = registry.__tcp_cosocket_mt method_table.getoption = getoption method_table.setoption = setoption + method_table.setclientcert = setclientcert + method_table.sslhandshake = sslhandshake end diff --git a/src/deps/src/lua-resty-core/lib/resty/core/time.lua b/src/deps/src/lua-resty-core/lib/resty/core/time.lua index 10ae72e5f..cf8f72eb3 100644 --- a/src/deps/src/lua-resty-core/lib/resty/core/time.lua +++ b/src/deps/src/lua-resty-core/lib/resty/core/time.lua @@ -20,6 +20,7 @@ local subsystem = ngx.config.subsystem local ngx_lua_ffi_now local ngx_lua_ffi_time +local ngx_lua_ffi_monotonic_msec local ngx_lua_ffi_today local ngx_lua_ffi_localtime local ngx_lua_ffi_utctime @@ -30,6 +31,7 @@ if subsystem == 'http' then ffi.cdef[[ double ngx_http_lua_ffi_now(void); long ngx_http_lua_ffi_time(void); +long ngx_http_lua_ffi_monotonic_msec(void); void ngx_http_lua_ffi_today(unsigned char *buf); void ngx_http_lua_ffi_localtime(unsigned char *buf); void ngx_http_lua_ffi_utctime(unsigned char *buf); @@ -42,6 +44,7 @@ void ngx_http_lua_ffi_parse_http_time(const unsigned char *str, size_t len, ngx_lua_ffi_now = C.ngx_http_lua_ffi_now ngx_lua_ffi_time = C.ngx_http_lua_ffi_time + ngx_lua_ffi_monotonic_msec = C.ngx_http_lua_ffi_monotonic_msec ngx_lua_ffi_today = C.ngx_http_lua_ffi_today ngx_lua_ffi_localtime = C.ngx_http_lua_ffi_localtime ngx_lua_ffi_utctime = C.ngx_http_lua_ffi_utctime @@ -51,6 +54,7 @@ elseif subsystem == 'stream' then ffi.cdef[[ double ngx_stream_lua_ffi_now(void); long ngx_stream_lua_ffi_time(void); +long ngx_stream_lua_ffi_monotonic_msec(void); void ngx_stream_lua_ffi_today(unsigned char *buf); void ngx_stream_lua_ffi_localtime(unsigned char *buf); void ngx_stream_lua_ffi_utctime(unsigned char *buf); @@ -59,6 +63,7 @@ void ngx_stream_lua_ffi_update_time(void); ngx_lua_ffi_now = C.ngx_stream_lua_ffi_now ngx_lua_ffi_time = C.ngx_stream_lua_ffi_time + ngx_lua_ffi_monotonic_msec = C.ngx_stream_lua_ffi_monotonic_msec ngx_lua_ffi_today = C.ngx_stream_lua_ffi_today ngx_lua_ffi_localtime = C.ngx_stream_lua_ffi_localtime ngx_lua_ffi_utctime = C.ngx_stream_lua_ffi_utctime @@ -76,6 +81,20 @@ function ngx.time() end +local function monotonic_msec() + local msec = tonumber(ngx_lua_ffi_monotonic_msec()) + return msec +end + + +local function monotonic_time() + local msec = tonumber(ngx_lua_ffi_monotonic_msec()) + local time = msec / 1000 + + return time +end + + function ngx.update_time() ngx_lua_ffi_update_time() end @@ -155,5 +174,7 @@ end end return { - version = base.version + version = base.version, + monotonic_msec = monotonic_msec, + monotonic_time = monotonic_time } diff --git a/src/deps/src/lua-resty-core/lib/resty/core/time.md b/src/deps/src/lua-resty-core/lib/resty/core/time.md new file mode 100644 index 000000000..7fa6191f9 --- /dev/null +++ b/src/deps/src/lua-resty-core/lib/resty/core/time.md @@ -0,0 +1,145 @@ +Name +==== + +`resty.core.time` - utility functions for time operations. + +Table of Contents +================= + +* [Name](#name) +* [Status](#status) +* [Synopsis](#synopsis) +* [Description](#description) +* [Methods](#methods) + * [monotonic_msec](#monotonic_msec) + * [monotonic_time](#monotonic_time) +* [Community](#community) + * [English Mailing List](#english-mailing-list) + * [Chinese Mailing List](#chinese-mailing-list) +* [Bugs and Patches](#bugs-and-patches) +* [Copyright and License](#copyright-and-license) +* [See Also](#see-also) + +Status +====== + +This Lua module is currently considered production ready. + +Synopsis +======== + +```nginx +location = /t { + content_by_lua_block { + local time = require "resty.core.time" + ngx.say(time.monotonic_time()) + ngx.say(time.monotonic_msec()) + } +} +``` + +The value get by `"resty.core.time".monotonic_time` should equal to the value from /proc/uptime. + +[Back to TOC](#table-of-contents) + +Description +=========== + +This module provides utility functions for the time operations. + +[Back to TOC](#table-of-contents) + +Methods +======= + +monotonic_msec +-------------- + +**syntax:** *monotonic_msec()* + +Returns the elapsed time in microseconds from the machine boot for the current time stamp from the Nginx cached time (no syscall involved unlike Lua's date library). + +```lua +local cur_msec = require "resty.core.time".monotonic_msec +ngx.say(cur_msec()) + +``` + +This api was first introduced in lua-resty-core v0.1.25. + +[Back to TOC](#table-of-contents) + +monotonic_time +-------------- + +**syntax:** *monotonic_time()* + +Returns a floating-point number for the elapsed time in seconds (including milliseconds as the decimal part) from the machine boot for the current time stamp from the Nginx cached time (no syscall involved unlike Lua's date library). + +```lua +local cur_time = require "resty.core.time".monotonic_time +ngx.say(cur_time()) + +``` + +This api was first introduced in lua-resty-core v0.1.25. + +[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) + +Copyright and License +===================== + +This module is licensed under the BSD license. + +Copyright (C) 2018, by 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 +======== +* the [lua-resty-core](https://github.com/openresty/lua-resty-core) library. +* the ngx_lua module: https://github.com/openresty/lua-nginx-module +* OpenResty: https://openresty.org + +[Back to TOC](#table-of-contents) diff --git a/src/deps/src/lua-resty-core/lib/resty/core/worker.lua b/src/deps/src/lua-resty-core/lib/resty/core/worker.lua index c336debdb..187289786 100644 --- a/src/deps/src/lua-resty-core/lib/resty/core/worker.lua +++ b/src/deps/src/lua-resty-core/lib/resty/core/worker.lua @@ -6,12 +6,14 @@ local base = require "resty.core.base" local C = ffi.C +local ffi_new = ffi.new local new_tab = base.new_tab local subsystem = ngx.config.subsystem local ngx_lua_ffi_worker_id local ngx_lua_ffi_worker_pid +local ngx_lua_ffi_worker_pids local ngx_lua_ffi_worker_count local ngx_lua_ffi_worker_exiting @@ -23,12 +25,14 @@ if subsystem == "http" then ffi.cdef[[ int ngx_http_lua_ffi_worker_id(void); int ngx_http_lua_ffi_worker_pid(void); + int ngx_http_lua_ffi_worker_pids(int *pids, size_t *pids_len); int ngx_http_lua_ffi_worker_count(void); int ngx_http_lua_ffi_worker_exiting(void); ]] ngx_lua_ffi_worker_id = C.ngx_http_lua_ffi_worker_id ngx_lua_ffi_worker_pid = C.ngx_http_lua_ffi_worker_pid + ngx_lua_ffi_worker_pids = C.ngx_http_lua_ffi_worker_pids ngx_lua_ffi_worker_count = C.ngx_http_lua_ffi_worker_count ngx_lua_ffi_worker_exiting = C.ngx_http_lua_ffi_worker_exiting @@ -36,12 +40,14 @@ elseif subsystem == "stream" then ffi.cdef[[ int ngx_stream_lua_ffi_worker_id(void); int ngx_stream_lua_ffi_worker_pid(void); + int ngx_stream_lua_ffi_worker_pids(int *pids, size_t *pids_len); int ngx_stream_lua_ffi_worker_count(void); int ngx_stream_lua_ffi_worker_exiting(void); ]] ngx_lua_ffi_worker_id = C.ngx_stream_lua_ffi_worker_id ngx_lua_ffi_worker_pid = C.ngx_stream_lua_ffi_worker_pid + ngx_lua_ffi_worker_pids = C.ngx_stream_lua_ffi_worker_pids ngx_lua_ffi_worker_count = C.ngx_stream_lua_ffi_worker_count ngx_lua_ffi_worker_exiting = C.ngx_stream_lua_ffi_worker_exiting end @@ -56,6 +62,24 @@ function ngx.worker.pid() return ngx_lua_ffi_worker_pid() end +local size_ptr = ffi_new("size_t[1]") +local pids_ptr = ffi_new("int[1024]") -- using NGX_MAX_PROCESSES + +function ngx.worker.pids() + if ngx.get_phase() == "init" or ngx.get_phase() == "init_worker" then + return nil, "API disabled in the current context" + end + + local res = ngx_lua_ffi_worker_pids(pids_ptr, size_ptr) + + local pids = {} + if res == 0 then + for i = 1, tonumber(size_ptr[0]) do + pids[i] = pids_ptr[i-1] + end + end + return pids +end function ngx.worker.id() local id = ngx_lua_ffi_worker_id() diff --git a/src/deps/src/lua-resty-core/t/balancer-timeout.t b/src/deps/src/lua-resty-core/t/balancer-timeout.t index b6ca8d2f2..d5cdfe11b 100644 --- a/src/deps/src/lua-resty-core/t/balancer-timeout.t +++ b/src/deps/src/lua-resty-core/t/balancer-timeout.t @@ -205,7 +205,7 @@ event timer add: \d+: 7689: --- response_body_like: 500 Internal Server Error --- error_code: 500 --- error_log eval -qr/\[error\] .*? balancer_by_lua:4: bad connect timeout/ +qr/\[error\] .*? balancer_by_lua\(nginx.conf:\d+\):4: bad connect timeout/ --- no_error_log [warn] @@ -236,7 +236,7 @@ qr/\[error\] .*? balancer_by_lua:4: bad connect timeout/ --- response_body_like: 500 Internal Server Error --- error_code: 500 --- error_log eval -qr/\[error\] .*? balancer_by_lua:4: bad connect timeout/ +qr/\[error\] .*? balancer_by_lua\(nginx.conf:\d+\):4: bad connect timeout/ --- no_error_log [warn] @@ -267,7 +267,7 @@ qr/\[error\] .*? balancer_by_lua:4: bad connect timeout/ --- response_body_like: 500 Internal Server Error --- error_code: 500 --- error_log eval -qr/\[error\] .*? balancer_by_lua:4: bad send timeout/ +qr/\[error\] .*? balancer_by_lua\(nginx.conf:\d+\):4: bad send timeout/ --- no_error_log [warn] @@ -298,7 +298,7 @@ qr/\[error\] .*? balancer_by_lua:4: bad send timeout/ --- response_body_like: 500 Internal Server Error --- error_code: 500 --- error_log eval -qr/\[error\] .*? balancer_by_lua:4: bad send timeout/ +qr/\[error\] .*? balancer_by_lua\(nginx.conf:\d+\):4: bad send timeout/ --- no_error_log [warn] @@ -329,7 +329,7 @@ qr/\[error\] .*? balancer_by_lua:4: bad send timeout/ --- response_body_like: 500 Internal Server Error --- error_code: 500 --- error_log eval -qr/\[error\] .*? balancer_by_lua:4: bad read timeout/ +qr/\[error\] .*? balancer_by_lua\(nginx.conf:\d+\):4: bad read timeout/ --- no_error_log [warn] diff --git a/src/deps/src/lua-resty-core/t/balancer.t b/src/deps/src/lua-resty-core/t/balancer.t index 8c97227ce..3e9fb2f73 100644 --- a/src/deps/src/lua-resty-core/t/balancer.t +++ b/src/deps/src/lua-resty-core/t/balancer.t @@ -42,7 +42,7 @@ __DATA__ --- error_code: 502 --- error_log eval [ -'[lua] balancer_by_lua:2: hello from balancer by lua! while connecting to upstream,', +'[lua] balancer_by_lua(nginx.conf:29):2: hello from balancer by lua! while connecting to upstream,', qr{connect\(\) failed .*?, upstream: "http://127\.0\.0\.3:12345/t"}, ] --- no_error_log @@ -419,7 +419,7 @@ last peer failure: failed 502 --- error_code: 502 --- error_log eval [ -'[lua] balancer_by_lua:2: hello from balancer by lua! while connecting to upstream,', +'[lua] balancer_by_lua(nginx.conf:29):2: hello from balancer by lua! while connecting to upstream,', qr{connect\(\) failed .*?, upstream: "http://127\.0\.0\.3:12345/t"}, ] --- no_error_log @@ -457,7 +457,7 @@ qr{connect\(\) failed .*?, upstream: "http://127\.0\.0\.3:12345/t"}, --- error_code: 502 --- error_log eval [ -'[lua] balancer_by_lua:2: hello from balancer by lua! while connecting to upstream,', +'[lua] balancer_by_lua(nginx.conf:30):2: hello from balancer by lua! while connecting to upstream,', qr{connect\(\) failed .*?, upstream: "http://127\.0\.0\.3:12345/t"}, ] --- no_error_log @@ -716,13 +716,13 @@ qr/\[error] .*? upstream prematurely closed connection while reading response he balancer_by_lua_block { local b = require "ngx.balancer" print("hello from balancer by lua!") - assert(b.set_current_peer("127.0.0.1", 1234)) + assert(b.set_current_peer("127.0.0.1", $TEST_NGINX_RAND_PORT_1)) } keepalive 1; } server { - listen 1234 ssl; + listen $TEST_NGINX_RAND_PORT_1 ssl; ssl_certificate ../../cert/test.crt; ssl_certificate_key ../../cert/test.key; @@ -762,12 +762,12 @@ hello from balancer by lua! balancer_by_lua_block { local b = require "ngx.balancer" print("hello from balancer by lua!") - assert(b.set_current_peer("127.0.0.1", 12347)) + assert(b.set_current_peer("127.0.0.1", $TEST_NGINX_RAND_PORT_2)) } } server { - listen 12347 ssl; + listen $TEST_NGINX_RAND_PORT_2 ssl; ssl_certificate ../../cert/test.crt; ssl_certificate_key ../../cert/test.key; diff --git a/src/deps/src/lua-resty-core/t/cert/test.crt b/src/deps/src/lua-resty-core/t/cert/test.crt index a69a01141..bfcc567ce 100644 --- a/src/deps/src/lua-resty-core/t/cert/test.crt +++ b/src/deps/src/lua-resty-core/t/cert/test.crt @@ -1,17 +1,35 @@ -----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== +MIIGETCCA/mgAwIBAgIUE3pqyVuRQL+qGuSFAUCLq4g7pt4wDQYJKoZIhvcNAQEL +BQAwgZcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQH +DA1TYW4gRnJhbmNpc2NvMRIwEAYDVQQKDAlPcGVuUmVzdHkxEjAQBgNVBAsMCU9w +ZW5SZXN0eTERMA8GA1UEAwwIdGVzdC5jb20xIDAeBgkqhkiG9w0BCQEWEWFnZW50 +emhAZ21haWwuY29tMB4XDTIyMDUyOTA2MTk1N1oXDTMyMDUyNjA2MTk1N1owgZcx +CzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQHDA1TYW4g +RnJhbmNpc2NvMRIwEAYDVQQKDAlPcGVuUmVzdHkxEjAQBgNVBAsMCU9wZW5SZXN0 +eTERMA8GA1UEAwwIdGVzdC5jb20xIDAeBgkqhkiG9w0BCQEWEWFnZW50emhAZ21h +aWwuY29tMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAyLzMbnMBcxYB +2W0uEqPKo2lOJdUQTnakipVLqRvZIJv7NkZgU76pxdFwoSxPpvJcpJ4rsosBZvhV +dkGoKmuVfIFU0lYcdaccq88aT7E9XfTXiiyB2tkT6jS6wr+QxDj7KW47zdUBUT9O +6ClNyY2o1gZldElTG0Bwk4j2sAkXuWGmyncTOJ4ge3mWVksAQYbL5pwfdfyqgDmK +B4nLJHBkorLbF7nm7pK2HzQCtaEUJpQKpJdCULcOHrydjVAwHUQsZAb9XXjQWPTb +A0BSplbgMSI6saT9uA2RjLBzpYKj8J1rWGadWteSyQAf6XooQrquTPuR+OWF6t/m +2vkTcJlh1ukPPAPZBvlAQX9VSLWk5fmAQZA5BxYXNVWcMGVNO7UtilRmjqK1nCmv +oyDXHzpE5RZPBZH4ecOqTscUgmS72ItPGWMtEtCQYbzWyMAa1cpCvK40YRa4814r +XgffWgWJQfqyVvRjzpWIUiqwjUX3/p3W3pxX/GNHOv2ZH/pebcODOl7EFxzv5eQc +z9vW5+RfiCSzs5bGG7qw58dMFROeAJbwR6t2o6GRd0HfgTTwSDcrrpcdLP/PaL+v +twnrNa9r7rIwXnDWxYo3KiGpqEfG2WwW+lJsUzZOi9eI9kYPyvFmNFLugZbHMi+h +ICCb8AQB2thON5X4N7FtP5GVfMR9vIkCAwEAAaNTMFEwHQYDVR0OBBYEFDEy866N +WPHPTJKeL/96VYoczkINMB8GA1UdIwQYMBaAFDEy866NWPHPTJKeL/96VYoczkIN +MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIBAHJgyS6/OyRqzqwd ++6DnntGV+MTo9WBNvNs/fekJghnrr85oG330GasYENQLi0wF20to7FMan2U9kwgV +cbhDwe70JD0jg8htYof/uXOMBVWT4iZ+eXn60mP3iLsSutwt/drXBBzbxMYbUC12 +CIiadkV8aMPIN6oGnF7TLF4AvBqYYp2qAVGXr/ZQm3L7NPB0jkSktSe6obnaq1tO +ug18ImhzAqkn1UGnLRiTADOba5HuKtovwWtLblNBODdnv1E7IK1A6jpqwiYjlbU5 +4v9ZzFzEJw+GqYHkTRmJGCA2Uw7HNEUFeno1BTp19Ce9fvrkofTWYmLp/NAvEp6E +aFnBdCjY4tWzI2Iig7IjDIM7F6igGODybeN9ijD7oSyEDtNE7ECLSuXhgekiQJ8c +NYALgbbNPxWx8zJcNiYy1NDYdIjO5vYFOpbn+rQObKVCX/X+Al9fT126ciTT1xAF +fZtkGPpp3Wjgws9UDSzetvWHYt0Rs70m351LFPHyR4tQLHoDFqnA2buG/mSvKZ9U +to0JQ/8QPRIYv0FUJcF0+/xQRYrIqvmjiCpfL2hwJyRViq7f8z0/tmMoLxFlPo/k +GC+gvh3WwTB622h9JEqS48lllcYZIQWOX2mbFtUtNFdzUtSRmZMa8RmcYr5So2OH +9QLIIjC6ntPFjWq+uLJAJ8uazRt7 -----END CERTIFICATE----- diff --git a/src/deps/src/lua-resty-core/t/cert/test.crt.der b/src/deps/src/lua-resty-core/t/cert/test.crt.der index 0b6ef6344..936635fd6 100644 Binary files a/src/deps/src/lua-resty-core/t/cert/test.crt.der and b/src/deps/src/lua-resty-core/t/cert/test.crt.der differ diff --git a/src/deps/src/lua-resty-core/t/cert/test.key b/src/deps/src/lua-resty-core/t/cert/test.key index 6c1352711..0c07e066f 100644 --- a/src/deps/src/lua-resty-core/t/cert/test.key +++ b/src/deps/src/lua-resty-core/t/cert/test.key @@ -1,15 +1,52 @@ ------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----- +MIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQDIvMxucwFzFgHZ +bS4So8qjaU4l1RBOdqSKlUupG9kgm/s2RmBTvqnF0XChLE+m8lykniuyiwFm+FV2 +Qagqa5V8gVTSVhx1pxyrzxpPsT1d9NeKLIHa2RPqNLrCv5DEOPspbjvN1QFRP07o +KU3JjajWBmV0SVMbQHCTiPawCRe5YabKdxM4niB7eZZWSwBBhsvmnB91/KqAOYoH +icskcGSistsXuebukrYfNAK1oRQmlAqkl0JQtw4evJ2NUDAdRCxkBv1deNBY9NsD +QFKmVuAxIjqxpP24DZGMsHOlgqPwnWtYZp1a15LJAB/peihCuq5M+5H45YXq3+ba ++RNwmWHW6Q88A9kG+UBBf1VItaTl+YBBkDkHFhc1VZwwZU07tS2KVGaOorWcKa+j +INcfOkTlFk8Fkfh5w6pOxxSCZLvYi08ZYy0S0JBhvNbIwBrVykK8rjRhFrjzXite +B99aBYlB+rJW9GPOlYhSKrCNRff+ndbenFf8Y0c6/Zkf+l5tw4M6XsQXHO/l5BzP +29bn5F+IJLOzlsYburDnx0wVE54AlvBHq3ajoZF3Qd+BNPBINyuulx0s/89ov6+3 +Ces1r2vusjBecNbFijcqIamoR8bZbBb6UmxTNk6L14j2Rg/K8WY0Uu6BlscyL6Eg +IJvwBAHa2E43lfg3sW0/kZV8xH28iQIDAQABAoICABwZgax8YNmRXRTomah2USlq +1kupdazmIsZbe8niYhSUgSfp1hYi/HT6in+lSkkeaCWLFqbZmoqlfKEfM8EsajKR +kCQZdcZqbDMIvLAnKWX7nihzboIKHSWN2A7m7gbpyw7TpX98r8CF0i/hiEgMknPT +VWRf10hbTub4J0AhJbcHmmeBH6mvSPC/5nGR8ik6C1TuyeCkS+HDLDU97rfdG9lC +nDTICzGeS+w2RaLTN5Tm6E599gSCe3GGCa/8Z5/RKT2fVNw+yzuImxfrayZpxtxZ +5El1xSZ8j8FX+fhTP0uxXZN0WdabkqqcX9s5BGXC6B9Sn+5tgr+MNC626ye58N36 +vhASbLhnZxZ1MxbVNdvQjl9A5mj/Tv/TM/syjFkElFwXBFz5MXgYRTu5TnoJpDyp +wMqNodTSbe8UuULtBIHYyuLEsrPWjne/ape8CqSQKgfnI91tveAMlAQA+yGRufSw +fx1gDrBIk3EtDGuelAIiW1ZimZoTj51HW7Mpfq9PXbuVO7i+zzSDFP/zyto2hITq +UeiTwKYpj8AgF39HiudAyJVYKDjKgATeSN1ziTvXBvBxe4JJ+7wovjl+R5ClBUEk +cNrn3FNVrgPjmJ6X7+42U2upQ2WIo8dT6PuE408nh2FR/VuabEqqwmmDEUW19+U+ +yZWfhDMv6Y/l6f75UBHhAoIBAQD++61+BBEwqTPfGH5EUxxeeaXXto8zW/N3aBql +f77iI3/XuOhve4WfL8v5xAXPfPIBGGBlG5RQ0Quxoo5fE6RPKt+5vaaOpMhLVf4L +sAQfLM9M9JK84BbWI+Z1o2s1knxlTlK0GZ/pbqg6J1YFfFAL/3PKi98EAGw9Dpj9 +u3GnSjF/dbtwwUiTS0Rv/8FV4bFxsSoul+N3xeyi26UWG9WIvuAzuLJfvqV2fb/l +o3LKpeXyD+SFatRmPe0JWIi2o0ZQpF8hhJXg1UYo2RGWf/bbl3SnivIMb/hNs8LB +17DNKu1DvgZoJSyocFmKAShZvbbirQYRtHo7SI2hAaOt6T81AoIBAQDJib1HIp/V +N59IIFOru6+kc9Vkhm8FDf3iyQfIL9Y0uVI4WrdKUeIH+pEKU7CMCT0WSgCxENe2 +TT+pOF3/T398eEmGAr79CtgtSzzuDvBlpD2aEfhjBPUE7g6tNuUFjgFJmzdXHT7u +99mWag4l30hfIAFXLu9ofm05nw0CRxlotYUiTCBU892ZxpO2/nDNJUjAU1MOvSa7 +MM7VbETui9teHgjZa+AadHZs2OqnWVo+g3RcKl3PyAdcOWobVQknRrpN9SlQkf/V +GYRhY2tQCpstKrEDQPWsNGmwjmT3uPdK8t5SXZZBji282XtCa+C+tB34AZ8YuU/Z +BH+Akez5zw6FAoIBAQCLK17kGuAvCQsQx1OTgzFGt2q3NCMwyw01rRJuJi1PTETo +vznOL0MdQX85Ua5CM1X7Fwz14nmvKooRaEIAzr2toB8AR+zyiinwRH0mb+mwAksb +G5pDkKOmOW394zYOxWcz++3T8vB+/jC/nNysnc8q3UCb2n/ctUZehOsoAfjkb/BY +OzAVOMmd60TtRFCHyWmKPkJhr/EtXE/uC6gtSv/fZR8F29cvvuScqcHlWrK6vJWm +6tm1oDtRmpcXtMTZuoAUX8K0jqMnVgC3JtMcq7dW33GCSKoX870429Z+6nTLZpSd +lsf0a+XWAYw9cKhPYubBDeL0IudcGBuFN1nZACfJAoIBABpg/vdKnuUHjL+iC5GU +1V6PEsU/m1RsCmkeqvgW2tC32P0rUoZVxWIJ9+YEIj2SD/7U3NZQQAvKfKSnjhYW +z7b4/5ac0WbJfpYfHPCD4A9Nugpqg7piMbfdeOpPHxblCWIbANlUKKKaqk43v3ZR +jWV2CPbiW8+vjJhYKxm7OKYt7CkbEbhM2xp/lWIEV7tiP+18eoiZVXJ25vukWjlm +8OWWxM3Aguqzh7Sjh8MzvM4l4psVqIXDxsLZePvu223aohQGHMxA791yo5Mjsi4d +1UXKKrUkUYOisJq9aJXMDgIvW84oFbyq4W2wgaOl/xq29J07iRlxV/Qt1Ip9jyj7 +YwkCggEBANFod5wwlOzTyAlRdZAPvyBWa0i+SLWecwr93rGQF3UuZwzaviY7U0tp +BoeFZAxiwns3SM6SJYIhce8Ku0PO1rp4FXvOopnIVO9BFXk1E5YUholQHHbERsse +pQahtlZ26ZAyRQjMQI9KKmU6pNFiF87MCnsz70BQajKo2+5NfZpnjaQzT6uyJeRQ +Iy38QlOk0221UsUU/bjahDlxmuHVdcnl6gi+4SYrI45wJSiBTiCJrVmxScg2D3IA +EZ3pVKOam0a3Mroqe0uMdY892cIYSAKOrZcxg5ZXWKDwlcsXgVuGDSvrU8LUPqn1 +jxLWsmKbkVA5hFln8GPxs6EqfqOJhkM= +-----END PRIVATE KEY----- diff --git a/src/deps/src/lua-resty-core/t/cert/test.key.der b/src/deps/src/lua-resty-core/t/cert/test.key.der index 537a4f1b3..76df7016b 100644 Binary files a/src/deps/src/lua-resty-core/t/cert/test.key.der and b/src/deps/src/lua-resty-core/t/cert/test.key.der differ diff --git a/src/deps/src/lua-resty-core/t/cert/test2.crt b/src/deps/src/lua-resty-core/t/cert/test2.crt index edc3b0df3..b75e130ee 100644 --- a/src/deps/src/lua-resty-core/t/cert/test2.crt +++ b/src/deps/src/lua-resty-core/t/cert/test2.crt @@ -1,16 +1,34 @@ -----BEGIN CERTIFICATE----- -MIIChzCCAfACCQDjCkJpJUtZmjANBgkqhkiG9w0BAQUFADCBhjELMAkGA1UEBhMC -VVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDVNhbiBGcmFuY2lzY28x -EjAQBgNVBAoMCU9wZW5SZXN0eTESMBAGA1UEAwwJdGVzdDIuY29tMSIwIAYJKoZI -hvcNAQkBFhNvcGVucmVzdHlAZ21haWwuY29tMCAXDTE0MDkxMzAwMTgxMFoYDzIx -MTQwODIwMDAxODEwWjCBhjELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3Ju -aWExFjAUBgNVBAcMDVNhbiBGcmFuY2lzY28xEjAQBgNVBAoMCU9wZW5SZXN0eTES -MBAGA1UEAwwJdGVzdDIuY29tMSIwIAYJKoZIhvcNAQkBFhNvcGVucmVzdHlAZ21h -aWwuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDy+OVI2u5NBOeB2Cyz -Gnwy9b7Ao4CSi05XtUxh2IoVdzYZz6c4PFb9C1ad52LDdRStiQT5A7+RKLj6Kr7f -JrKFziJxMy4g4Kdn9G659vE7CWu/UAVjRUtc+mTBAEfjdbumizmHLG7DmnNhGl3R -NGiVNLsUInSMGfUlJRzZJXhI4QIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAEMmRvyN -N7uE24Tc6TR19JadNHK8g3YGktRoXWiqd/y0HY4NRPgvnK/nX7CY/wXa1j+uDO8K -e6/Ldm5RZrjtvfHJmTSAu8zkqTJz8bqRDH7kzL5Ni2Ky2x8r9dtB0ImpOiSlwvZN -snMvbrxEdwBiqlC9prV2f9aG+ACo1KnPL0j6 +MIIF7zCCA9egAwIBAgIUBwRM0hlOTRGtIMvLy56P3TZc6jIwDQYJKoZIhvcNAQEL +BQAwgYYxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRYwFAYDVQQH +DA1TYW4gRnJhbmNpc2NvMRIwEAYDVQQKDAlPcGVuUmVzdHkxEjAQBgNVBAMMCXRl +c3QyLmNvbTEiMCAGCSqGSIb3DQEJARYTb3BlbnJlc3R5QGdtYWlsLmNvbTAeFw0y +MjA1MjkwNjEzMjVaFw0zMjA1MjYwNjEzMjVaMIGGMQswCQYDVQQGEwJVUzETMBEG +A1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzESMBAGA1UE +CgwJT3BlblJlc3R5MRIwEAYDVQQDDAl0ZXN0Mi5jb20xIjAgBgkqhkiG9w0BCQEW +E29wZW5yZXN0eUBnbWFpbC5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK +AoICAQDCOlzMo5qPtb5wjXHqy1mjm2rMAPeiz0wrDRXC0+9l/f/6KYBfJoaAuLau +P6kCojDNLOOHAjmbjeoG+bVGoLVNAGhFaThKQepmBPFhjtT0+7syGq6H12Wb9mmn +hMy65gS+7dsUU74HUjlHuYyOnXHmrJH/7sGzG6DXX6t2x0Ts49gVWzFr1TINMjP0 +opupvpokbr+EEzIP4NE5isPQnMeIt2HhzTMN+wHBalnHIVq0v03M911l4XpzHtP+ +MetDMraHJdv8Hlh5qeyrDkn7N5zE05cnSu6AK3vMaxsDbRJ92Akv6bLMqTqSnR3j +16Qwqs369cU+zl7wQJ7+J1Gh5DhOe9Vns+bLbBJC5XZz3qcFxUXXRResuBYPQNht +JwgT7wq+XNMkd7TzDQzfWx4G7zz+3ogiNK6k02e0Uafuizi4nyMpwuu9SwvfYan3 +QBL7ddjuMGUHG9oOepLmiKt8ST/plduc+67oXu1oeGnaEthpQ9Aong0/JhDvvnsX +Pe4tZQwzFK1m/fxF034l3fy+gmGfnRC4k2thUotfp+BReDAZ5Wwg6FO7eaowuQbH +Qk8Pt36yd0fWwAgX3kmhxC91QOYt29Aya4gTuJT4ajueDVRzB3bCxX0t7Awz/Ohh +36XiLHZp7Zo1eJtG7oOXRJdiKCglxOk9WiXTIaDXunXDGRl+DQIDAQABo1MwUTAd +BgNVHQ4EFgQUwIug2OC092u/dZFClmac5Sbo4ukwHwYDVR0jBBgwFoAUwIug2OC0 +92u/dZFClmac5Sbo4ukwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOC +AgEAhnWpbQ31DbMzbSiY7iKM8OsUAqPzjvGObB6hzF+i8/q0GfQm11V+aKFTWu3p +5aJua0hCPxq3F6q3Wj+F42pcRkoOmcGMMkGVOFeT1TRaC1WwTvhYjwFke4jqOi+5 +kcfLWO3bkADm73AuW/PJ6WgQzrfOvd+uvVX6B0NKumgNYrhyDfwb4tZ/fOLHSA9W +NNd/93yo2OhH0vOMbAcDGdOpBR7Sx7c+BeI57kORIlSwCQmaSeIIOLs69VsMH/Yo +DiNWfbj7pPRhdCSEmd59wyPKUcBJHfEE9z54NIb6ETTKrmtwYLPNKdgW6dqHe8UK +bsjXiiw0Y3nHhrv7Fh+aqy470mn890K0+CPTh9Gi+Qwkfyt7tJr4uCdDzLPoP6up +FlQaobMtOFuCMNZs+B1UZm2jcj5j/PjY19PZu8XAHOFJmY66oqK6FvZHrq/26K29 +p6BXPMUVhxFoXUX2EmAtey919+GY9KncMuhobn+5If/6mug3QRNNt/csw30NvBOZ +6Lqc920e/lgoFPQ7RnxI5PLNdTFLTqM8c9lMt6rqcff7cK9aonfWPd3s1pyWTFhx +tSBH95qNcu+kgu+iVLeFZjqyTW5lLyqZLPjnx8cS4HZtAUeM73RjFcDVokqGxAgc +qzatPoPNGjLtG1JoMsXjaMuc0ed3BkjXpXH24z8o0g7ppgQ= -----END CERTIFICATE----- diff --git a/src/deps/src/lua-resty-core/t/cert/test2.key b/src/deps/src/lua-resty-core/t/cert/test2.key index 82ce6ce91..029d02e42 100644 --- a/src/deps/src/lua-resty-core/t/cert/test2.key +++ b/src/deps/src/lua-resty-core/t/cert/test2.key @@ -1,15 +1,52 @@ ------BEGIN RSA PRIVATE KEY----- -MIICXAIBAAKBgQDy+OVI2u5NBOeB2CyzGnwy9b7Ao4CSi05XtUxh2IoVdzYZz6c4 -PFb9C1ad52LDdRStiQT5A7+RKLj6Kr7fJrKFziJxMy4g4Kdn9G659vE7CWu/UAVj -RUtc+mTBAEfjdbumizmHLG7DmnNhGl3RNGiVNLsUInSMGfUlJRzZJXhI4QIDAQAB -AoGAEqBB83PVENJvbOTFiHVfUAjGtr3R/Wnwd4jOcjHHZB3fZ9sjVoxJntxfp3s1 -dwZir2rxlqVS6i3VAFiGiVTOGo2Vvzhw2J7f58twCECmnLb2f863AkGEYe4dAndD -GHGD0WI0CBMD1sT18YCj561o0Wol5deWH0gM9pr2N3HkeIECQQD6hUKFlFhrpaHP -WNJsl6BxgE6pB5kxLcMcpIQ7P+kHUvtyvCJl5QZJqPrpPGjRsAI5Ph92rpsp/zDp -/IZNWGVjAkEA+Ele31Rt+XbV32MrLKZgBDBk+Pzss5LTn9fZ5v1k/7hrMk2VVWvk -AD6n5QiGe/g59woANpPb1T9l956SBf0d6wJABTXOS17pc9uvANP1FGMW6CVl/Wf2 -DKrJ+weE5IKQwyE7r4gwIvRfbBrClSU3fNzvPueG2f4JphbzmnoxBNzIxwJAYivY -mGNwzHehXx99/byXMHDWK+EN0n8WsBgP75Z3rekEcbJdfpYXY8Via1vwmOnwOW65 -4NqbzHix37PSNw37GwJBALxaGNpREO2Tk+oWOvsD2QyviMVae3mXAJHc6nLVdKDM -q0YvDT6VdeNYYFTkAuzJacsVXOpn6AnUMFj0OBedMhc= ------END RSA PRIVATE KEY----- +-----BEGIN PRIVATE KEY----- +MIIJQQIBADANBgkqhkiG9w0BAQEFAASCCSswggknAgEAAoICAQDCOlzMo5qPtb5w +jXHqy1mjm2rMAPeiz0wrDRXC0+9l/f/6KYBfJoaAuLauP6kCojDNLOOHAjmbjeoG ++bVGoLVNAGhFaThKQepmBPFhjtT0+7syGq6H12Wb9mmnhMy65gS+7dsUU74HUjlH +uYyOnXHmrJH/7sGzG6DXX6t2x0Ts49gVWzFr1TINMjP0opupvpokbr+EEzIP4NE5 +isPQnMeIt2HhzTMN+wHBalnHIVq0v03M911l4XpzHtP+MetDMraHJdv8Hlh5qeyr +Dkn7N5zE05cnSu6AK3vMaxsDbRJ92Akv6bLMqTqSnR3j16Qwqs369cU+zl7wQJ7+ +J1Gh5DhOe9Vns+bLbBJC5XZz3qcFxUXXRResuBYPQNhtJwgT7wq+XNMkd7TzDQzf +Wx4G7zz+3ogiNK6k02e0Uafuizi4nyMpwuu9SwvfYan3QBL7ddjuMGUHG9oOepLm +iKt8ST/plduc+67oXu1oeGnaEthpQ9Aong0/JhDvvnsXPe4tZQwzFK1m/fxF034l +3fy+gmGfnRC4k2thUotfp+BReDAZ5Wwg6FO7eaowuQbHQk8Pt36yd0fWwAgX3kmh +xC91QOYt29Aya4gTuJT4ajueDVRzB3bCxX0t7Awz/Ohh36XiLHZp7Zo1eJtG7oOX +RJdiKCglxOk9WiXTIaDXunXDGRl+DQIDAQABAoICAF1s/V5iA+LEpUo2f2lVT1Tn +WUOv424pEJZUwPbqQuloeEy40crzGRepwhWnAYEGyzqmMPusElHEvaGFU7EZdJwJ +ah6ZMj5l3n4cOo+WyNDelXjQZMtqzLFsof22X1Q3eGjuuMbaUTnsTyk1E2s2SKeQ +stnM2tdwnrl6h1unFnxsTHBZYThhYKYAVAWEgiPwTuzfaLf7E8WXeoyXNwGNqF0W ++LpInhpHdty2b2Ddpmfy7VV+Vyq+fswJNCe9k1DLgAkaKOrpHd3H4tOVF/kDEyGK +NdbssDRutinqCyBmwtJNrH2jiCHx9P65HLuP6qaOQm5I8gv38KrYKqJN/3JD+ODQ +dn8yVXjcCRzq8vylFLJfVEY0hB3ZWJAgDxY8GFax7foyaJ6889qgMOU4xBdotF7c +hKNsH+ClHSuJ5h4SNAV7/mRcJrYDFJ9imuY4PGFMZMQYSZig5dLawTe52+wsSuZ4 +kYxDXk76ZLr/MsbijrNOdze3Mny6EPxJGlv04XNNfIrsN9PXQGLpUwaJSJMGnFTI +TgAlcLATVMLusU2xf/Ra8eCk8Xydk0ExdB4TnMD0TTM/6bPJYIwwqrjee1ao4V0E +eISaoC8QHDi1XIFav2amzeyfHQI8uV4OQwV1rVLgeBY8TtQ0Mk6oU3AZ9z8Hvb1V +szdpOicXdI2lC9qpFiIBAoIBAQDxYMCvRDTkYcebG2sSi7ViUd3NWuBYFjlNfHED +/Rz6mUDud9r6TC3nqCPuugGt9P7fz3KktCoSh/x6iYsUP7iSK2V6Gg/kD1wtjIdY +9OW8u2cHyyGPshgZBgFJ4jE1wvzHQApQYrbdLdSmlwnvXT+tEG57vEa1ep2DSNaJ +hXlvpPMJAghNtc0wvcTZ8Aas8HfuEthKrb22O2zo0J2QObBZv2gcA0djW0ZbEEGg +BVNzmfaZFrLqSIP+7SD9KTgyRz1pAmeIgv//szYweHNVGeVbPgG2W4HiaV7c4+aF +3dmaikSZgz6Qily74HcVMrTzcgw2v2uM3IkTvWEX1PrixPdhAoIBAQDN/mqXtqtO +mbQBbn6+QgnVNRc/lnLv2QnzfuK93omZGFrl+COaCdM+T93PQkTiEydCjOYgwv3x +6KVMyrZLVKuYIHcdwP7z+Xi3wDQkCO0D8JmJGFBU+tAUJHEgF7DxEDa+PGxEPXWe +Ta4ZXpqQH96bssfzyFB2+PQcSIcRyWdnhJyVgXdRfMxMbYxH6g5X1bIGOAzCF1hp +b9QN3Rc/2UKCfw3IoFl1Yzo8yXi9hLhkIb2tjpBmt9V6itgVHL12HLLgvzs4egkI +aBHtMIxWcrzq+XtG3ARgugkRlhLhDR7nZOV2nFYXFNJ2tHfg2q4PBkrFm5EPLpXj +shzOZzlok0ItAoIBAGVo7ssz7rzcz828sTlzdNs/5d33BjY78As78wdn+hrW9E68 +EEYEZ2ziWWZcw4PgYIyLTXEhOGPcuhiJXOM++j5++P1Zob+BLIr+dYbMLREj8t91 +Wj5S5ojs2vG9lEswBp93ql2ne4hlTuhGoKfuF2iQdLqLmXF5eF/F5EyWxTRAqtLo +BbEQZorJz8B4dXWG+fwN8s09PW0oflM6AlirxAmQvx61yfJWULLFm6ytUChLUS10 +OerwWHRsD+YMwU1uXMCXgAP8da1qD6RBlsL0REYXQQTqYSFMf8xx+1HWqSuiV7vf +RhPX7aoJXj6LtTZqffMqbPcbWIPwlrA6jMVlV0ECggEAHqfDAyrrGXpkQGZKNFQt +lG4fNJZWKn15LqRuZ+UrQv5N4LVpzu2xYy+Nid+J0r8Y8512Td/W3N5LYz8zm8hQ +9QW31FS5XGN+5JGU8NvnMdPndXCJ2+urdaPqteTwrx9DllH1pr4it9lFlH7wr4we +m7siaJQh7WKlKWRdvXbkjZI9nz4yHI1e9ezDmJwrYETsBmLm+ydwP9iljR6e7CCP +9k2kJnw+c+q9avhsoH+U1Un0KVTzBmZLPb5V4+ZwB5jDwhCTZpc6quaZ7FtyNxdC +KBHSl7v8ZsyottZHnvhN5g+s2lbvtOWjYIkA4hSJHLFKBVheYQ0Ev2rtQIY6E+b+ +TQKCAQA+jl6f5wFSGBFjnrQu5V6E3tcI6fhkk2b4KGRBLyp27gIdqnw6FCZLsJ+g +qUmJd8lz3E4UR/VXy2lSWcKbmDmO1l+v2fZZu227hbZp8YTsPqt1JhnrroBP3Pdj +d+Zj+ZJpw5MbLb+8Wsx41fsAy8k1kZX82Vigbj2HEE/O7keflwBfa455ue9IGIFY +1SRNNJPB4RZ/9T/NM+MsTJZapsp6Si/nkncluSKeBnE1LfHoJi2eVW77qPIOGOPy +L3iaDoc8MmhMx2EFzSDlzwdB9Jg8cXxF4XxjadYc6JOtzUEkCqR0XS8KOgO2eMU0 +uWdAG+HmOwioRij8CIrb/9veL2jl +-----END PRIVATE KEY----- diff --git a/src/deps/src/lua-resty-core/t/cert/test_passphrase.crt b/src/deps/src/lua-resty-core/t/cert/test_passphrase.crt new file mode 100644 index 000000000..f4d516ba9 --- /dev/null +++ b/src/deps/src/lua-resty-core/t/cert/test_passphrase.crt @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICozCCAgwCCQDEutRdSs3vZjANBgkqhkiG9w0BAQUFADCBlDELMAkGA1UEBhMC +Q04xEjAQBgNVBAgMCUd1YW5nZG9uZzERMA8GA1UEBwwIU2hlblpoZW4xEjAQBgNV +BAoMCU9wZW5SZXN0eTESMBAGA1UECwwJT3BlblJlc3R5MREwDwYDVQQDDAh0ZXN0 +LmNvbTEjMCEGCSqGSIb3DQEJARYUZ3VhbmdsaW5sdkBnbWFpbC5jb20wIBcNMTYw +NDI4MTQ0MzI4WhgPMjE1MTAzMjcxNDQzMjhaMIGUMQswCQYDVQQGEwJDTjESMBAG +A1UECAwJR3Vhbmdkb25nMREwDwYDVQQHDAhTaGVuWmhlbjESMBAGA1UECgwJT3Bl +blJlc3R5MRIwEAYDVQQLDAlPcGVuUmVzdHkxETAPBgNVBAMMCHRlc3QuY29tMSMw +IQYJKoZIhvcNAQkBFhRndWFuZ2xpbmx2QGdtYWlsLmNvbTCBnzANBgkqhkiG9w0B +AQEFAAOBjQAwgYkCgYEA2KZ+HdH9R2tarxD8PKqu5EYq2BNGlFRg1xJmrw0XZBRM +UP/VPb+sIeioooz36uhiXfQjExlpBCA/0zNAN+HbFyqpPPTf1qLGrj/dqeE4MJaN +Bwzxiv3fZnENT65u2qbiFWIY+ATNHgA20d50nxNNjPTzLbkx/nYXL92r4kuAGk0C +AwEAATANBgkqhkiG9w0BAQUFAAOBgQCfMo0qbcs3kwl1tcNBO5hCcUUJRzyv041V +ff/nZ/JPIMo/LSZd12K82G/dLRN7uRT9nzqtm+JRkHALHWWWFKi6bdg1vcdOTWqC +08bCkJHQoXJQQLvvA6gNvnR+0b7L4CrCmrcyYgKDLXVGNP9Wv/PqSWWbxsmqngkA +Mvy6CVytFw== +-----END CERTIFICATE----- diff --git a/src/deps/src/lua-resty-core/t/cert/test_passphrase.key b/src/deps/src/lua-resty-core/t/cert/test_passphrase.key new file mode 100644 index 000000000..b8fc97634 --- /dev/null +++ b/src/deps/src/lua-resty-core/t/cert/test_passphrase.key @@ -0,0 +1,18 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,679ACC8E69ACAA92 + +Ssrjp3VU4somCNPiXkWqcudDnvnwbyj/Q0pS07at3lXKbhQSgI1Tzhg9Pm3BXXj5 +mkLdeGG5ocrj1Q9dhtmZgZeHHQIiynZBhjBu1Y+HPef8jXOWLrCOi8EKiWkJ2qG3 +V1KFM/95CcDt0mRLykUXEL3IpUst05SFb9XwiLokB7ypeu3NhgNUHjL6G+ubB4ri +TOUjCW4pEoNHjdC22IiqSncwCVhluYSGhr6ktHKehZMhYIXmL1wmSLdhTlsPXCQl +xvYILQ2vJcKIR1BkeYYPD/OQC6zCZlXIErzfgeZiz2+NTudKYpb9VmsQKsO+R8L7 +tZ/fNaR0vk8bbimMHgStAV4acVsC/7WxsqOjMJ8VTq1iqhYPl6N7kRdR3H3kSSOm +cN9T3SrOHDVaHbnWgToaOE4mKFjvFSLIOcWgus0iOHWXmY+SLG+Ndag3oVB6R9oB +cAHX19mq99+GhzA8IV4I0En2UCKQhnGPvkM+9mcCDxhRETlwncDjlMGOHpQ65J9r +eReVPIpnDkvHxPGTtsR3ZHTdWTZb+C0W2N3QIlJKrOzxFmfoj++yG3tMX42aDY0g +DVkrXgcKobiWN0AVrJNAwfG7uObKSCFYgz/0RRMCO4cjXRW99nxdjVDZhyc6R0Te +jzuF04okkOLNb25n2hP+yIULrn+6Nv/uHtFI0j0n3hOzcKh//dNbACSAKgkHni9g +JKDFJXgLJxf+Wc3So0DF9gYMKJJ+WbcdVT9gkC7RyQHlC90Pn7kNXzHr0ZawUsNI +ZxSkL4dMhYAfA4lUBJbOkwbSurv97LinOSRffpM0Nmf7VNw/Ue15eg== +-----END RSA PRIVATE KEY----- diff --git a/src/deps/src/lua-resty-core/t/exit.t b/src/deps/src/lua-resty-core/t/exit.t index 8a918b11f..fc8d77927 100644 --- a/src/deps/src/lua-resty-core/t/exit.t +++ b/src/deps/src/lua-resty-core/t/exit.t @@ -78,3 +78,94 @@ GET /t ["[error]", qr/ -- NYI: (?!FastFunc coroutine.yield)/, " bad argument"] + + + +=== TEST 3: accepts NGX_OK +--- config + location = /t { + content_by_lua_block { + ngx.exit(ngx.OK) + } + } +--- request +GET /t +--- response_body +--- no_error_log eval +["[error]", +qr/ -- NYI: (?!FastFunc coroutine.yield)/, +" bad argument"] + + + +=== TEST 4: accepts NGX_ERROR +--- config + location = /t { + content_by_lua_block { + ngx.exit(ngx.ERROR) + } + } +--- request +GET /t +--- error_code: +--- response_body +--- no_error_log eval +["[error]", +qr/ -- NYI: (?!FastFunc coroutine.yield)/, +" bad argument"] + + + +=== TEST 5: accepts NGX_DECLINED +--- config + location = /t { + content_by_lua_block { + ngx.exit(ngx.DECLINED) + } + } +--- request +GET /t +--- error_code: +--- response_body +--- no_error_log eval +["[error]", +qr/ -- NYI: (?!FastFunc coroutine.yield)/, +" bad argument"] + + + +=== TEST 6: refuses NGX_AGAIN +--- config + location = /t { + content_by_lua_block { + ngx.exit(ngx.AGAIN) + } + } +--- request +GET /t +--- response_body_like: 500 Internal Server Error +--- error_code: 500 +--- error_log eval +qr/\[error\] .*? bad argument to 'ngx.exit': does not accept NGX_AGAIN or NGX_DONE/ +--- no_error_log eval +qr/ -- NYI: (?!FastFunc coroutine.yield)/ +[crit] + + + +=== TEST 7: refuses NGX_DONE +--- config + location = /t { + content_by_lua_block { + ngx.exit(ngx.DONE) + } + } +--- request +GET /t +--- response_body_like: 500 Internal Server Error +--- error_code: 500 +--- error_log eval +qr/\[error\] .*? bad argument to 'ngx.exit': does not accept NGX_AGAIN or NGX_DONE/ +--- no_error_log eval +qr/ -- NYI: (?!FastFunc coroutine.yield)/ +[crit] diff --git a/src/deps/src/lua-resty-core/t/misc.t b/src/deps/src/lua-resty-core/t/misc.t index 4f6b25304..f45436240 100644 --- a/src/deps/src/lua-resty-core/t/misc.t +++ b/src/deps/src/lua-resty-core/t/misc.t @@ -9,7 +9,7 @@ log_level('warn'); #repeat_each(120); repeat_each(2); -plan tests => repeat_each() * (blocks() * 6 - 2); +plan tests => repeat_each() * (blocks() * 6); #no_diff(); #no_long_string(); @@ -36,11 +36,10 @@ GET /t --- error_code: 201 --- no_error_log [error] - -- NYI: bad argument --- error_log eval ["is subrequest: false,", -qr/\[TRACE\s+\d+\s+header_filter_by_lua:3 loop\]/ +qr/\[TRACE\s+\d+\s+header_filter_by_lua\(nginx.conf:58\):3 loop\]/ ] @@ -111,6 +110,7 @@ GET /t ok --- no_error_log [error] +[crit] -- NYI: bad argument @@ -130,7 +130,95 @@ ok GET /t --- error_code: 500 --- no_error_log +[alert] +[crit] -- NYI: bad argument --- error_log unsupported subsystem: http + + + +=== TEST 6: not internal request +--- http_config eval: $::HttpConfig +--- config + location /test { + rewrite ^/test$ /lua last; + } + location /lua { + content_by_lua_block { + if ngx.req.is_internal() then + ngx.say("internal") + else + ngx.say("not internal") + end + } + } +--- request +GET /lua +--- response_body +not internal +--- no_error_log +[error] +[alert] +[crit] + -- NYI: + + + +=== TEST 7: internal request +--- http_config eval: $::HttpConfig +--- config + location /test { + rewrite ^/test$ /lua last; + } + location /lua { + content_by_lua_block { + if ngx.req.is_internal() then + ngx.say("internal") + else + ngx.say("not internal") + end + } + } +--- request +GET /test +--- response_body +internal +--- no_error_log +[error] +[alert] +[crit] + -- NYI: + + + +=== TEST 8: bad context +--- http_config eval: $::HttpConfig +--- config + location /lua { + content_by_lua_block { + local function test() + local ok, err = pcall(ngx.req.is_internal) + package.loaded.bad_context = {ok, err} + end + + ngx.timer.at(0, test) + ngx.sleep(0.02) + + local ctx = package.loaded.bad_context + ngx.say(ctx[1]) + local i = string.find(ctx[2], "API disabled in the current context") + ngx.say(i > 1) + } + } +--- request +GET /lua +--- response_body +false +true +--- no_error_log +[error] +[alert] +[crit] + -- NYI: diff --git a/src/deps/src/lua-resty-core/t/ocsp.t b/src/deps/src/lua-resty-core/t/ocsp.t index 36af8b7c7..23a51017c 100644 --- a/src/deps/src/lua-resty-core/t/ocsp.t +++ b/src/deps/src/lua-resty-core/t/ocsp.t @@ -97,7 +97,7 @@ __DATA__ GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata --- error_log lua ssl server name: "test.com" @@ -189,7 +189,7 @@ OCSP url found: http://127.0.0.1:8888/ocsp?foo=1, GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata --- error_log lua ssl server name: "test.com" @@ -281,7 +281,7 @@ OCSP responder not found GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata --- error_log lua ssl server name: "test.com" @@ -372,7 +372,7 @@ failed to get OCSP responder: no issuer certificate in chain GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata --- error_log lua ssl server name: "test.com" @@ -467,7 +467,7 @@ failed to get OCSP responder: issuer certificate not next to leaf GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata --- error_log lua ssl server name: "test.com" @@ -564,7 +564,7 @@ still get an error: truncated GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata --- error_log lua ssl server name: "test.com" @@ -657,7 +657,7 @@ OCSP request created with length 68 GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata --- error_log lua ssl server name: "test.com" @@ -831,7 +831,7 @@ failed to create OCSP request: d2i_X509_bio() failed GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata --- error_log lua ssl server name: "test.com" @@ -922,7 +922,7 @@ failed to create OCSP request: no issuer certificate in chain GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata --- error_log lua ssl server name: "test.com" @@ -1015,7 +1015,7 @@ OCSP response validation ok GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata --- error_log lua ssl server name: "test.com" @@ -1107,7 +1107,7 @@ OCSP response validation ok GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata --- error_log lua ssl server name: "test.com" @@ -1202,7 +1202,7 @@ FIXME: we should complain in this case. GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata --- error_log lua ssl server name: "test.com" @@ -1296,7 +1296,7 @@ OCSP response validation ok GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata --- error_log lua ssl server name: "test.com" @@ -1472,7 +1472,7 @@ FIXME: check the OCSP staple actually received by the ssl client GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata --- error_log lua ssl server name: "test.com" @@ -1554,7 +1554,7 @@ ocsp status resp set ok: nil, GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata --- error_log lua ssl server name: "test.com" diff --git a/src/deps/src/lua-resty-core/t/param.t b/src/deps/src/lua-resty-core/t/param.t new file mode 100644 index 000000000..75266631e --- /dev/null +++ b/src/deps/src/lua-resty-core/t/param.t @@ -0,0 +1,66 @@ +# vim:set ft= ts=4 sw=4 et fdm=marker: +use lib '.'; +use t::TestCore; + +#worker_connections(1014); +#master_process_enabled(1); +#log_level('warn'); + +repeat_each(2); + +plan tests => repeat_each() * (blocks() * 4 + 1); + +#no_diff(); +#no_long_string(); +check_accum_error_log(); +run_tests(); + +__DATA__ + +=== TEST 1: ngx.arg getter in set_by_lua +--- config + location = /t { + # set_by_lua_block doesn't support arguments + set_by_lua $res ' + local arg = ngx.arg + local val + for i = 1, 30 do + val = arg[1] + arg[2] + end + return val + ' $arg_a $arg_b; + echo $res; + } +--- request +GET /t?a=1&b=2 +--- response_body +3 +--- error_log eval +qr/\[TRACE\s+\d+ set_by_lua\(nginx\.conf:\d+\):4 loop\]/ +--- no_error_log +[error] + -- NYI: (?!return to lower frame) + + + +=== TEST 2: ngx.arg getter in body_filter_by_lua +--- config + location = /t { + echo hello; + body_filter_by_lua_block { + local arg = ngx.arg + local eof + local body = "" + for i = 1, 30 do + body = body .. arg[1] + eof = arg[2] + end + } + } +--- request +GET /t +--- error_log eval +qr/\[TRACE\s+\d+ body_filter_by_lua\(nginx\.conf:\d+\):5 loop\]/ +--- no_error_log +[error] + -- NYI: (?!return to lower frame) diff --git a/src/deps/src/lua-resty-core/t/pipe-stdout.t b/src/deps/src/lua-resty-core/t/pipe-stdout.t index 863868664..4d140b67a 100644 --- a/src/deps/src/lua-resty-core/t/pipe-stdout.t +++ b/src/deps/src/lua-resty-core/t/pipe-stdout.t @@ -920,12 +920,12 @@ exit else -- so just return the expected data in repeated tests. - ngx.say("hello world") + ngx.say("closed") end } } --- response_body -hello world +closed @@ -1005,3 +1005,25 @@ stdout err: timeout lua pipe add timer for reading: 100(ms) --- no_error_log [error] + + + +=== TEST 35: start a daemon process +--- config + location = /t { + content_by_lua_block { + local ngx_pipe = require "ngx.pipe" + local proc = ngx_pipe.spawn({"sh", "-c", "daemonize /usr/bin/sleep 30 >/dev/null 2>&1"}) + + local data, err = proc:stdout_read_all() + if not data then + ngx.say(err) + end + + ngx.say("OK") + } + } +--- response_body +OK +--- no_error_log +[error] diff --git a/src/deps/src/lua-resty-core/t/pipe.t b/src/deps/src/lua-resty-core/t/pipe.t index 6df1a9a05..03ef9a7cf 100644 --- a/src/deps/src/lua-resty-core/t/pipe.t +++ b/src/deps/src/lua-resty-core/t/pipe.t @@ -1361,7 +1361,10 @@ lua pipe kill process: } --- response_body ok ---- shutdown_error_log +--- error_log +lua pipe destroy process: +lua pipe kill process: +--- no_shutdown_error_log lua pipe destroy process: lua pipe kill process: diff --git a/src/deps/src/lua-resty-core/t/process-type-cache.t b/src/deps/src/lua-resty-core/t/process-type-cache.t index facadd218..1e3067385 100644 --- a/src/deps/src/lua-resty-core/t/process-type-cache.t +++ b/src/deps/src/lua-resty-core/t/process-type-cache.t @@ -60,13 +60,13 @@ GET /t --- response_body type: worker --- grep_error_log eval -qr/\[TRACE\s+\d+ init_worker_by_lua:\d+ loop\]|\[TRACE\s+\d+ content_by_lua\(nginx\.conf:\d+\):\d loop\]/ +qr/\[TRACE\s+\d+ init_worker_by_lua\(nginx.conf:\d+\):\d+ loop\]|\[TRACE\s+\d+ content_by_lua\(nginx\.conf:\d+\):\d loop\]/ --- grep_error_log_out eval [ -qr/\[TRACE\s+\d+ init_worker_by_lua:\d+ loop\] +qr/\[TRACE\s+\d+ init_worker_by_lua\(nginx.conf:\d+\):\d+ loop\] \[TRACE\s+\d+ content_by_lua\(nginx.conf:\d+\):\d+ loop\] /, -qr/\[TRACE\s+\d+ init_worker_by_lua:\d+ loop\] +qr/\[TRACE\s+\d+ init_worker_by_lua\(nginx.conf:\d+\):\d+ loop\] \[TRACE\s+\d+ content_by_lua\(nginx.conf:\d+\):\d+ loop\] / ] diff --git a/src/deps/src/lua-resty-core/t/process-type-hup.t b/src/deps/src/lua-resty-core/t/process-type-hup.t index 4ee92d88f..f8203942b 100644 --- a/src/deps/src/lua-resty-core/t/process-type-hup.t +++ b/src/deps/src/lua-resty-core/t/process-type-hup.t @@ -82,8 +82,7 @@ GET /t --- response_body type: worker --- error_log -init_worker_by_lua:6: process type: privileged +init_worker_by_lua(nginx.conf:48):6: process type: privileged --- no_error_log [error] --- skip_nginx: 4: < 1.11.2 ---- wait: 0.1 diff --git a/src/deps/src/lua-resty-core/t/process-type-master.t b/src/deps/src/lua-resty-core/t/process-type-master.t index aafc96742..82af5b862 100644 --- a/src/deps/src/lua-resty-core/t/process-type-master.t +++ b/src/deps/src/lua-resty-core/t/process-type-master.t @@ -53,12 +53,12 @@ GET /t --- response_body process type: master --- grep_error_log eval -qr/\[TRACE\s+\d+ init_by_lua:\d+ loop\]/ +qr/\[TRACE\s+\d+ init_by_lua\(nginx.conf:\d+\):\d+ loop\]/ --- grep_error_log_out eval [ -qr/\A\[TRACE\s+\d+ init_by_lua:\d+ loop\] +qr/\A\[TRACE\s+\d+ init_by_lua\(nginx.conf:\d+\):\d+ loop\] \z/, -qr/\A\[TRACE\s+\d+ init_by_lua:\d+ loop\] +qr/\A\[TRACE\s+\d+ init_by_lua\(nginx.conf:\d+\):\d+ loop\] \z/ ] --- no_error_log diff --git a/src/deps/src/lua-resty-core/t/process-type-privileged-agent.t b/src/deps/src/lua-resty-core/t/process-type-privileged-agent.t index 52f4d21bd..bd6a55d7a 100644 --- a/src/deps/src/lua-resty-core/t/process-type-privileged-agent.t +++ b/src/deps/src/lua-resty-core/t/process-type-privileged-agent.t @@ -91,18 +91,18 @@ GET /t --- response_body type: worker --- grep_error_log eval -qr/\[TRACE\s+\d+ init_worker_by_lua:\d+ loop\]|\[TRACE\s+\d+ content_by_lua\(nginx\.conf:\d+\):\d+ loop\]|init_worker_by_lua:\d+: process type: \w+/ +qr/\[TRACE\s+\d+ init_worker_by_lua\(nginx.conf:\d+\):\d+ loop\]|\[TRACE\s+\d+ content_by_lua\(nginx\.conf:\d+\):\d+ loop\]|init_worker_by_lua\(nginx.conf:\d+\):\d+: process type: \w+/ --- grep_error_log_out eval [ -qr/\[TRACE\s+\d+ init_worker_by_lua:\d+ loop\] -(?:\[TRACE\s+\d+ init_worker_by_lua:\d+ loop\] +qr/\[TRACE\s+\d+ init_worker_by_lua\(nginx.conf:\d+\):\d+ loop\] +(?:\[TRACE\s+\d+ init_worker_by_lua\(nginx.conf:\d+\):\d+ loop\] )?\[TRACE\s+\d+ content_by_lua\(nginx.conf:\d+\):\d+ loop\] -init_worker_by_lua:10: process type: privileged +init_worker_by_lua\(nginx.conf:\d+\):10: process type: privileged /, -qr/\[TRACE\s+\d+ init_worker_by_lua:\d+ loop\] -(?:\[TRACE\s+\d+ init_worker_by_lua:\d+ loop\] +qr/\[TRACE\s+\d+ init_worker_by_lua\(nginx.conf:\d+\):\d+ loop\] +(?:\[TRACE\s+\d+ init_worker_by_lua\(nginx.conf:\d+\):\d+ loop\] )?\[TRACE\s+\d+ content_by_lua\(nginx.conf:\d+\):\d+ loop\] -init_worker_by_lua:10: process type: privileged +init_worker_by_lua\(nginx.conf:\d+\):10: process type: privileged / ] --- no_error_log diff --git a/src/deps/src/lua-resty-core/t/process-type-single.t b/src/deps/src/lua-resty-core/t/process-type-single.t index a3c490375..f1d1f2686 100644 --- a/src/deps/src/lua-resty-core/t/process-type-single.t +++ b/src/deps/src/lua-resty-core/t/process-type-single.t @@ -67,20 +67,20 @@ GET /t --- response_body process type: single --- grep_error_log eval -qr/\[TRACE\s+\d+ init_by_lua:\d+ loop\]|\[TRACE\s+\d+ init_worker_by_lua:\d loop\]|\[TRACE\s+\d+ content_by_lua\(nginx\.conf:\d+\):\d loop\]|process type in init_by_lua\*: \w+|init_worker_by_lua:\d+: process type: \w+/ +qr/\[TRACE\s+\d+ init_by_lua\(nginx.conf:\d+\):\d+ loop\]|\[TRACE\s+\d+ init_worker_by_lua\(nginx.conf:\d+\):\d loop\]|\[TRACE\s+\d+ content_by_lua\(nginx\.conf:\d+\):\d loop\]|process type in init_by_lua\*: \w+|init_worker_by_lua\(nginx.conf:\d+\):\d+: process type: \w+/ --- grep_error_log_out eval [ -qr/\[TRACE\s+\d+ init_by_lua:\d+ loop\] -\[TRACE\s+\d+ init_worker_by_lua:\d+ loop\] +qr/\[TRACE\s+\d+ init_by_lua\(nginx.conf:\d+\):\d+ loop\] +\[TRACE\s+\d+ init_worker_by_lua\(nginx.conf:\d+\):\d+ loop\] \[TRACE\s+\d+ content_by_lua\(nginx.conf:\d+\):4 loop\] process type in init_by_lua\*: single -init_worker_by_lua:10: process type: single +init_worker_by_lua\(nginx.conf:\d+\):10: process type: single /, -qr/\[TRACE\s+\d+ init_by_lua:\d+ loop\] -\[TRACE\s+\d+ init_worker_by_lua:\d+ loop\] +qr/\[TRACE\s+\d+ init_by_lua\(nginx.conf:\d+\):\d+ loop\] +\[TRACE\s+\d+ init_worker_by_lua\(nginx.conf:\d+\):\d+ loop\] \[TRACE\s+\d+ content_by_lua\(nginx.conf:\d+\):4 loop\] process type in init_by_lua\*: single -init_worker_by_lua:10: process type: single +init_worker_by_lua\(nginx.conf:\d+\):10: process type: single / ] --- no_error_log diff --git a/src/deps/src/lua-resty-core/t/process-type-worker.t b/src/deps/src/lua-resty-core/t/process-type-worker.t index e94ec4459..e6ba764d8 100644 --- a/src/deps/src/lua-resty-core/t/process-type-worker.t +++ b/src/deps/src/lua-resty-core/t/process-type-worker.t @@ -55,16 +55,16 @@ GET /t --- response_body process type: worker --- grep_error_log eval -qr/\[TRACE\s+\d+ init_worker_by_lua:\d loop\]|\[TRACE\s+\d+ content_by_lua\(nginx\.conf:\d+\):\d loop\]|init_worker_by_lua:\d: process type: \w+/ +qr/\[TRACE\s+\d+ init_worker_by_lua\(nginx.conf:\d+\):\d loop\]|\[TRACE\s+\d+ content_by_lua\(nginx\.conf:\d+\):\d loop\]|init_worker_by_lua\(nginx.conf:\d+\):\d: process type: \w+/ --- grep_error_log_out eval [ -qr/\[TRACE\s+\d+ init_worker_by_lua:4 loop\] +qr/\[TRACE\s+\d+ init_worker_by_lua\(nginx.conf:\d+\):4 loop\] \[TRACE\s+\d+ content_by_lua\(nginx.conf:\d+\):4 loop\] -init_worker_by_lua:8: process type: worker +init_worker_by_lua\(nginx.conf:\d+\):8: process type: worker /, -qr/\[TRACE\s+\d+ init_worker_by_lua:4 loop\] +qr/\[TRACE\s+\d+ init_worker_by_lua\(nginx.conf:\d+\):4 loop\] \[TRACE\s+\d+ content_by_lua\(nginx.conf:\d+\):4 loop\] -init_worker_by_lua:8: process type: worker +init_worker_by_lua\(nginx.conf:\d+\):8: process type: worker / ] --- no_error_log diff --git a/src/deps/src/lua-resty-core/t/request.t b/src/deps/src/lua-resty-core/t/request.t index 80e866b2f..2764d7c3d 100644 --- a/src/deps/src/lua-resty-core/t/request.t +++ b/src/deps/src/lua-resty-core/t/request.t @@ -8,7 +8,7 @@ use t::TestCore; repeat_each(2); -plan tests => repeat_each() * (blocks() * 5 + 2); +plan tests => repeat_each() * (blocks() * 4 + 19); #no_diff(); #no_long_string(); @@ -612,3 +612,70 @@ hello [error] --- skip_nginx 2: < 1.21.1 + + + +=== TEST 20: get_uri_args allows to reuse table +--- config + location = /t { + set $foo hello; + content_by_lua_block { + local base = require "resty.core.base" + local args = base.new_tab(0, 3) + local id = tostring(args) + for i = 1, 5 do + base.clear_tab(args) + args = ngx.req.get_uri_args(-1, args) + assert(tostring(args) == id) + end + local keys = {} + for k, _ in pairs(args) do + keys[#keys + 1] = k + end + table.sort(keys) + for _, k in ipairs(keys) do + local v = args[k] + if type(v) == "table" then + ngx.say(k, ": ", table.concat(v, ", ")) + else + ngx.say(k, ": ", v) + end + end + } + } +--- request +GET /t?a=3%200&foo%20bar=&a=hello&blah +--- response_body +a: 3 0, hello +blah: true +foo bar: +--- no_error_log +[error] + + + +=== TEST 21: get_uri_args allows to reuse table (empty) +--- config + location = /t { + set $foo hello; + content_by_lua_block { + local base = require "resty.core.base" + local args = base.new_tab(0, 3) + local id = tostring(args) + for i = 1, 5 do + args = ngx.req.get_uri_args(-1, args) + assert(tostring(args) == id) + end + local n_key = 0 + for k, _ in pairs(args) do + n_key = n_key + 1 + end + ngx.say(n_key) + } + } +--- request +GET /t +--- response_body +0 +--- no_error_log +[error] diff --git a/src/deps/src/lua-resty-core/t/require.t b/src/deps/src/lua-resty-core/t/require.t new file mode 100644 index 000000000..68e98d721 --- /dev/null +++ b/src/deps/src/lua-resty-core/t/require.t @@ -0,0 +1,74 @@ +# vim:set ft= ts=4 sw=4 et fdm=marker: +use lib '.'; +use t::TestCore; + +plan tests => repeat_each() * blocks() * 3; + +add_block_preprocessor(sub { + my $block = shift; + + my $http_config = $block->http_config || ''; + my $init_by_lua_block = $block->init_by_lua_block || ''; + + $http_config .= <<_EOC_; + lua_package_path '\$prefix/html/?.lua;$t::TestCore::lua_package_path'; + init_by_lua_block { + $t::TestCore::init_by_lua_block + $init_by_lua_block + } +_EOC_ + + $block->set_value("http_config", $http_config); +}); + +no_diff(); +no_long_string(); +run_tests(); + +__DATA__ + +=== TEST 1: utils.str_replace_char() sanity (replaces a single character) +--- config + location /t { + content_by_lua_block { + local has_foo, foo + has_foo, foo= pcall(require, "foo") + if not has_foo then + ngx.say("failed to load foo: ", foo) + end + + has_foo, foo = pcall(require, "foo") + if not has_foo then + ngx.say("failed to load foo again: ", foo) + else + ngx.say("type(a)=", type(a), " foo=", foo) + end + } + } +--- user_files +>>> foo.lua +local ffi = require("ffi") + +local _M = {} + +ffi.cdef[[ +int xxxx(); +]] + +local function get_caches_array() + return tonumber(ffi.C.xxxx()) +end + +local a = get_caches_array() + +_M.a = a +_M.get_caches_array = get_caches_array + +return _M +--- request +GET /t +--- response_body eval +qr|failed to load foo: .*/html/foo.lua:10: .*/lib/libluajit-5.1.so.2: undefined symbol: xxxx +failed to load foo again: ./lib/resty/core/base.lua:\d+: loop or previous error loading module 'foo'|ms +--- no_error_log +[error] diff --git a/src/deps/src/lua-resty-core/t/semaphore.t b/src/deps/src/lua-resty-core/t/semaphore.t index c91ed4825..064831e38 100644 --- a/src/deps/src/lua-resty-core/t/semaphore.t +++ b/src/deps/src/lua-resty-core/t/semaphore.t @@ -304,10 +304,10 @@ GET /test sem count: [12] waited successfully. --- grep_error_log eval -qr/\[lua\] init_by_lua:\d+: sema created: table: 0x[a-f0-9]+/ +qr/\[lua\] init_by_lua\(nginx.conf:\d+\):\d+: sema created: table: 0x[a-f0-9]+/ --- grep_error_log_out eval [ -qr/\[lua\] init_by_lua:\d+: sema created: table: 0x[a-f0-9]+/, +qr/\[lua\] init_by_lua\(nginx.conf:\d+\):\d+: sema created: table: 0x[a-f0-9]+/, "", ] @@ -348,10 +348,10 @@ GET /test sem count: [12] waited successfully. --- grep_error_log eval -qr/\[lua\] init_by_lua:\d+: sema created: table: 0x[a-f0-9]+/ +qr/\[lua\] init_by_lua\(nginx.conf:\d+\):\d+: sema created: table: 0x[a-f0-9]+/ --- grep_error_log_out eval [ -qr/\[lua\] init_by_lua:\d+: sema created: table: 0x[a-f0-9]+/, +qr/\[lua\] init_by_lua\(nginx.conf:\d+\):\d+: sema created: table: 0x[a-f0-9]+/, "", ] diff --git a/src/deps/src/lua-resty-core/t/ssl-client-hello.t b/src/deps/src/lua-resty-core/t/ssl-client-hello.t index 7dcf9e74c..4e798e3b8 100644 --- a/src/deps/src/lua-resty-core/t/ssl-client-hello.t +++ b/src/deps/src/lua-resty-core/t/ssl-client-hello.t @@ -15,7 +15,7 @@ my $openssl_version = eval { `$NginxBinary -V 2>&1` }; if ($openssl_version =~ m/built with OpenSSL (0\S*|1\.0\S*|1\.1\.0\S*)/) { plan(skip_all => "too old OpenSSL, need 1.1.1, was $1"); } else { - plan tests => repeat_each() * (blocks() * 6 - 2); + plan tests => repeat_each() * (blocks() * 6 - 2) - 4; } no_long_string(); @@ -108,7 +108,7 @@ __DATA__ GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 56 bytes. received: HTTP/1.1 201 Created received: Server: nginx @@ -209,7 +209,7 @@ read SNI name from Lua: test.com GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 56 bytes. received: HTTP/1.1 201 Created received: Server: nginx @@ -340,7 +340,7 @@ read SNI name from Lua: nil, type: nil GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 56 bytes. received: HTTP/1.1 201 Created received: Server: nginx @@ -442,7 +442,7 @@ read SNI name from Lua: test.com GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 56 bytes. received: HTTP/1.1 201 Created received: Server: nginx @@ -548,7 +548,7 @@ read SNI name from Lua: nil, type: nil GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 56 bytes. received: HTTP/1.1 201 Created received: Server: nginx @@ -654,7 +654,7 @@ close: 1 nil GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 56 bytes. received: HTTP/1.1 201 Created received: Server: nginx @@ -864,3 +864,103 @@ failed to do SSL handshake: handshake failed --- no_error_log [alert] [emerg] + + + +=== TEST 9: get client hello supported versions - allow TLSv1.2 +--- skip_nginx: 4: < 1.19.9 +--- http_config + lua_package_path "$TEST_NGINX_LUA_PACKAGE_PATH"; + + server { + listen 127.0.0.2:$TEST_NGINX_RAND_PORT_1 ssl; + server_name test.com; + ssl_client_hello_by_lua_block { + local ssl_clt = require "ngx.ssl.clienthello" + local types, err = ssl_clt.get_supported_versions() + if not err and types then + for _, ssl_type in pairs(types) do + if ssl_type == "TLSv1.2" then + ngx.exit(ngx.OK) + end + end + end + ngx.log(ngx.ERR, "failed to get_supported_versions") + ngx.exit(ngx.ERROR) + } + ssl_protocols TLSv1 TLSv1.1 TLSv1.2; + ssl_certificate ../../cert/test.crt; + ssl_certificate_key ../../cert/test.key; + + server_tokens off; + location /foo { + default_type 'text/plain'; + content_by_lua_block {ngx.status = 201 ngx.say("foo") ngx.exit(201)} + more_clear_headers Date; + } + } +--- config + server_tokens off; + lua_ssl_trusted_certificate ../../cert/test.crt; + lua_ssl_protocols TLSv1 TLSv1.1 ; + + location /t { + content_by_lua_block { + do + local sock = ngx.socket.tcp() + + sock:settimeout(3000) + + local ok, err = sock:connect("127.0.0.2", $TEST_NGINX_RAND_PORT_1) + if not ok then + ngx.say("failed to connect: ", err) + return + end + + ngx.say("connected: ", ok) + + local sess, err = sock:sslhandshake(nil, nil, true) + if not sess then + ngx.say("failed to do SSL handshake: ", err) + return + end + + ngx.say("ssl handshake: ", type(sess)) + + local req = "GET /foo HTTP/1.0\r\nHost: test.com\r\nConnection: close\r\n\r\n" + local bytes, err = sock:send(req) + if not bytes then + ngx.say("failed to send http request: ", err) + return + end + + ngx.say("sent http request: ", bytes, " bytes.") + + while true do + local line, err = sock:receive() + if not line then + -- ngx.say("failed to receive response status line: ", err) + break + end + + ngx.say("received: ", line) + end + + local ok, err = sock:close() + ngx.say("close: ", ok, " ", err) + end -- do + -- collectgarbage() + } + } + +--- request +GET /t +--- response_body +connected: 1 +failed to do SSL handshake: handshake failed + +--- error_log +failed to get_supported_versions + +--- no_error_log +[alert] diff --git a/src/deps/src/lua-resty-core/t/ssl-session-fetch.t b/src/deps/src/lua-resty-core/t/ssl-session-fetch.t index 515b151a3..879f464d9 100644 --- a/src/deps/src/lua-resty-core/t/ssl-session-fetch.t +++ b/src/deps/src/lua-resty-core/t/ssl-session-fetch.t @@ -89,17 +89,17 @@ __DATA__ GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata close: 1 nil --- grep_error_log eval -qr/ssl_session_fetch_by_lua_block:\d+: session id: [a-fA-f\d]+/s +qr/ssl_session_fetch_by_lua\(nginx.conf:\d+\):\d+: session id: [a-fA-f\d]+/s --- grep_error_log_out eval [ '', -qr/ssl_session_fetch_by_lua_block:4: session id: [a-fA-f\d]+/s, -qr/ssl_session_fetch_by_lua_block:4: session id: [a-fA-f\d]+/s, +qr/ssl_session_fetch_by_lua\(nginx.conf:\d+\):4: session id: [a-fA-f\d]+/s, +qr/ssl_session_fetch_by_lua\(nginx.conf:\d+\):4: session id: [a-fA-f\d]+/s, ] --- no_error_log @@ -176,7 +176,7 @@ qr/ssl_session_fetch_by_lua_block:4: session id: [a-fA-f\d]+/s, GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata close: 1 nil --- grep_error_log eval @@ -279,17 +279,17 @@ In practice, never store session in plaintext on persistent storage. GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata close: 1 nil --- grep_error_log eval -qr/ssl_session_(fetch|store)_by_lua_block:\d+: session id: [a-fA-F\d]+/s +qr/ssl_session_(fetch|store)_by_lua\(nginx.conf:\d+\):\d+: session id: [a-fA-F\d]+/s --- grep_error_log_out eval [ -qr/ssl_session_store_by_lua_block:5: session id: [a-fA-F\d]+/s, -qr/ssl_session_fetch_by_lua_block:4: session id: [a-fA-F\d]+/s, -qr/ssl_session_fetch_by_lua_block:4: session id: [a-fA-F\d]+/s, +qr/ssl_session_store_by_lua\(nginx.conf:\d+\):5: session id: [a-fA-F\d]+/s, +qr/ssl_session_fetch_by_lua\(nginx.conf:\d+\):4: session id: [a-fA-F\d]+/s, +qr/ssl_session_fetch_by_lua\(nginx.conf:\d+\):4: session id: [a-fA-F\d]+/s, ] --- no_error_log @@ -375,22 +375,22 @@ able to carry on and negotiate a new session. GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata close: 1 nil --- grep_error_log eval -qr/failed to resume session: failed to de-serialize session|ssl_session_(fetch|store)_by_lua_block:\d+: session id: [a-fA-F\d]+/s +qr/failed to resume session: failed to de-serialize session|ssl_session_(fetch|store)_by_lua\(nginx.conf:\d+\):\d+: session id: [a-fA-F\d]+/s --- grep_error_log_out eval [ -qr/^ssl_session_store_by_lua_block:5: session id: [a-fA-F\d]+$/s, -qr/^ssl_session_fetch_by_lua_block:4: session id: [a-fA-F\d]+ +qr/^ssl_session_store_by_lua\(nginx.conf:\d+\):5: session id: [a-fA-F\d]+$/s, +qr/^ssl_session_fetch_by_lua\(nginx.conf:\d+\):4: session id: [a-fA-F\d]+ failed to resume session: failed to de-serialize session -ssl_session_store_by_lua_block:5: session id: [a-fA-F\d]+ +ssl_session_store_by_lua\(nginx.conf:\d+\):5: session id: [a-fA-F\d]+ $/s, -qr/ssl_session_fetch_by_lua_block:4: session id: [a-fA-F\d]+ +qr/ssl_session_fetch_by_lua:4: session id: [a-fA-F\d]+ failed to resume session: failed to de-serialize session -ssl_session_store_by_lua_block:5: session id: [a-fA-F\d]+ +ssl_session_store_by_lua\(nginx.conf:\d+\):5: session id: [a-fA-F\d]+ $/s, ] @@ -489,20 +489,20 @@ ok --- error_log eval qr/content_by_lua\(nginx\.conf:\d+\):\d+: CONNECTED/ --- grep_error_log eval -qr/failed to resume session: failed to de-serialize session|ssl_session_(fetch|store)_by_lua_block:\d+: session id: [a-fA-F\d]+/s +qr/failed to resume session: failed to de-serialize session|ssl_session_(fetch|store)_by_lua\(nginx.conf:\d+\):\d+: session id: [a-fA-F\d]+/s --- grep_error_log_out eval [ -qr/^ssl_session_fetch_by_lua_block:\d+: session id: [a-fA-F\d]+ +qr/^ssl_session_fetch_by_lua\(nginx.conf:\d+\):\d+: session id: [a-fA-F\d]+ failed to resume session: failed to de-serialize session -ssl_session_store_by_lua_block:\d+: session id: [a-fA-F\d]+ +ssl_session_store_by_lua\(nginx.conf:\d+\):\d+: session id: [a-fA-F\d]+ $/s, -qr/^ssl_session_fetch_by_lua_block:\d+: session id: [a-fA-F\d]+ +qr/^ssl_session_fetch_by_lua\(nginx.conf:\d+\):\d+: session id: [a-fA-F\d]+ failed to resume session: failed to de-serialize session -ssl_session_store_by_lua_block:\d+: session id: [a-fA-F\d]+ +ssl_session_store_by_lua\(nginx.conf:\d+\):\d+: session id: [a-fA-F\d]+ $/s, -qr/^ssl_session_fetch_by_lua_block:\d+: session id: [a-fA-F\d]+ +qr/^ssl_session_fetch_by_lua\(nginx.conf:\d+\):\d+: session id: [a-fA-F\d]+ failed to resume session: failed to de-serialize session -ssl_session_store_by_lua_block:\d+: session id: [a-fA-F\d]+ +ssl_session_store_by_lua\(nginx.conf:\d+\):\d+: session id: [a-fA-F\d]+ $/s, ] @@ -582,7 +582,7 @@ $/s, GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata close: 1 nil --- no_error_log [alert] diff --git a/src/deps/src/lua-resty-core/t/ssl-session-store.t b/src/deps/src/lua-resty-core/t/ssl-session-store.t index d4ba33ebc..04b9c49ba 100644 --- a/src/deps/src/lua-resty-core/t/ssl-session-store.t +++ b/src/deps/src/lua-resty-core/t/ssl-session-store.t @@ -85,11 +85,11 @@ __DATA__ GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata close: 1 nil --- error_log eval -qr/ssl_session_store_by_lua_block:4: session size: \d+/s +qr/ssl_session_store_by_lua\(nginx.conf:\d+\):4: session size: \d+/s --- no_error_log [alert] @@ -157,11 +157,11 @@ qr/ssl_session_store_by_lua_block:4: session size: \d+/s GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata close: 1 nil --- error_log eval -qr/ssl_session_store_by_lua_block:4: session id: [a-fA-f\d]+/s +qr/ssl_session_store_by_lua\(nginx.conf:\d+\):4: session id: [a-fA-f\d]+/s --- no_error_log [alert] @@ -265,13 +265,13 @@ qr/ssl_session_store_by_lua_block:4: session id: [a-fA-f\d]+/s GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata close: 1 nil --- error_log eval [ -qr/ssl_session_store_by_lua_block:32: session id: [a-fA-f\d]+/s, -qr/ssl_session_store_by_lua_block:34: session size: \d+/s, +qr/ssl_session_store_by_lua\(nginx.conf:\d+\):32: session id: [a-fA-f\d]+/s, +qr/ssl_session_store_by_lua\(nginx.conf:\d+\):34: session size: \d+/s, qr/received memc reply: STORED/s, ] diff --git a/src/deps/src/lua-resty-core/t/ssl.t b/src/deps/src/lua-resty-core/t/ssl.t index e7e612e21..139e164ff 100644 --- a/src/deps/src/lua-resty-core/t/ssl.t +++ b/src/deps/src/lua-resty-core/t/ssl.t @@ -210,7 +210,7 @@ sslv3 alert handshake failure GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 56 bytes. received: HTTP/1.1 201 Created received: Server: nginx @@ -309,7 +309,7 @@ lua ssl server name: "test.com" GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 56 bytes. received: HTTP/1.1 201 Created received: Server: nginx @@ -409,7 +409,7 @@ read SNI name from Lua: test.com GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 56 bytes. received: HTTP/1.1 201 Created received: Server: nginx @@ -525,7 +525,7 @@ read SNI name from Lua: nil, type: nil GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 56 bytes. received: HTTP/1.1 201 Created received: Server: nginx @@ -646,7 +646,7 @@ qr/Using unix socket file .*?nginx\.sock/ GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 56 bytes. received: HTTP/1.1 201 Created received: Server: nginx @@ -765,7 +765,7 @@ Using IPv4 address: 127.0.0.1 GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 56 bytes. received: HTTP/1.1 201 Created received: Server: nginx @@ -888,7 +888,7 @@ Using IPv6 address: 0.0.0.1 GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 56 bytes. received: HTTP/1.1 201 Created received: Server: nginx @@ -1015,7 +1015,7 @@ lua ssl server name: "test.com" GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 56 bytes. received: HTTP/1.1 201 Created received: Server: nginx @@ -1540,7 +1540,7 @@ ssl cert by lua done GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 56 bytes. received: HTTP/1.1 201 Created received: Server: nginx @@ -1673,7 +1673,7 @@ lua ssl server name: "test.com" GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 56 bytes. received: HTTP/1.1 201 Created received: Server: nginx @@ -2148,7 +2148,7 @@ qr/\[error\] .*? failed to parse pem key: PEM_read_bio_PrivateKey\(\) failed/ GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 56 bytes. received: HTTP/1.1 201 Created received: Server: nginx @@ -2513,7 +2513,7 @@ client certificate subject: nil lua_package_path "$TEST_NGINX_LUA_PACKAGE_PATH"; server { - listen 127.0.0.1:12345 ssl; + listen 127.0.0.1:$TEST_NGINX_RAND_PORT_2 ssl; server_name test.com; ssl_certificate_by_lua_block { local ssl = require "ngx.ssl" @@ -2541,7 +2541,7 @@ client certificate subject: nil sock:settimeout(3000) - local ok, err = sock:connect("127.0.0.1", 12345) + local ok, err = sock:connect("127.0.0.1", $TEST_NGINX_RAND_PORT_2) if not ok then ngx.say("failed to connect: ", err) return @@ -2587,7 +2587,7 @@ client certificate subject: nil GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 56 bytes. received: HTTP/1.1 201 Created received: Server: nginx @@ -2598,8 +2598,8 @@ received: received: foo close: 1 nil ---- error_log -read server port from Lua: 12345 +--- error_log eval +qr/read server port from Lua: \d+/ --- no_error_log [error] @@ -2687,7 +2687,7 @@ read server port from Lua: 12345 GET /t --- response_body connected: 1 -ssl handshake: userdata +ssl handshake: cdata sent http request: 56 bytes. received: HTTP/1.1 201 Created received: Server: nginx @@ -2705,3 +2705,135 @@ read server port from Lua: nilunix domain has no port [error] [alert] [emerg] + + + +=== TEST 28: PEM key protected by passphrase +--- http_config + lua_package_path "$TEST_NGINX_LUA_PACKAGE_PATH"; + + server { + listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl; + server_name test.com; + ssl_certificate_by_lua_block { + local ssl = require "ngx.ssl" + + ssl.clear_certs() + + local f = assert(io.open("t/cert/test_passphrase.crt")) + local cert_data = f:read("*a") + f:close() + + local cert, err = ssl.cert_pem_to_der(cert_data) + if not cert then + ngx.log(ngx.ERR, "failed to convert pem cert to der cert: ", err) + return + end + + local ok, err = ssl.set_der_cert(cert) + if not ok then + ngx.log(ngx.ERR, "failed to set DER cert: ", err) + return + end + + local f = assert(io.open("t/cert/test_passphrase.key")) + local pkey_data = f:read("*a") + f:close() + + pkey_data, err = ssl.priv_key_pem_to_der(pkey_data, "123456") + if not pkey_data then + ngx.log(ngx.ERR, "failed to convert pem key to der key: ", err) + return + end + local ok, err = ssl.set_der_priv_key(pkey_data) + if not ok then + ngx.log(ngx.ERR, "failed to set private key: ", err) + return + end + } + ssl_certificate ../../cert/test2.crt; + ssl_certificate_key ../../cert/test2.key; + + server_tokens off; + location /foo { + default_type 'text/plain'; + content_by_lua_block { ngx.status = 201 ngx.say("foo") ngx.exit(201) } + more_clear_headers Date; + } + } +--- config + server_tokens off; + lua_ssl_trusted_certificate ../../cert/chain/root-ca.crt; + lua_ssl_verify_depth 3; + + location /t { + content_by_lua_block { + do + local sock = ngx.socket.tcp() + + sock:settimeout(3000) + + local ok, err = sock:connect("unix:$TEST_NGINX_HTML_DIR/nginx.sock") + if not ok then + ngx.say("failed to connect: ", err) + return + end + + ngx.say("connected: ", ok) + + local sess, err = sock:sslhandshake(nil, "test.com", false) + if not sess then + ngx.say("failed to do SSL handshake: ", err) + return + end + + ngx.say("ssl handshake: ", type(sess)) + + local req = "GET /foo HTTP/1.0\r\nHost: test.com\r\nConnection: close\r\n\r\n" + local bytes, err = sock:send(req) + if not bytes then + ngx.say("failed to send http request: ", err) + return + end + + ngx.say("sent http request: ", bytes, " bytes.") + + while true do + local line, err = sock:receive() + if not line then + -- ngx.say("failed to receive response status line: ", err) + break + end + + ngx.say("received: ", line) + end + + local ok, err = sock:close() + ngx.say("close: ", ok, " ", err) + end -- do + -- collectgarbage() + } + } + +--- request +GET /t +--- response_body +connected: 1 +ssl handshake: cdata +sent http request: 56 bytes. +received: HTTP/1.1 201 Created +received: Server: nginx +received: Content-Type: text/plain +received: Content-Length: 4 +received: Connection: close +received: +received: foo +close: 1 nil + +--- error_log +lua ssl server name: "test.com" + +--- no_error_log +[error] +[alert] +[emerg] diff --git a/src/deps/src/lua-resty-core/t/status.t b/src/deps/src/lua-resty-core/t/status.t index 37725c38d..41990cafe 100644 --- a/src/deps/src/lua-resty-core/t/status.t +++ b/src/deps/src/lua-resty-core/t/status.t @@ -40,7 +40,7 @@ GET /t bad argument --- error_log eval ["sum: 6030,", -qr/\[TRACE\s+\d+\s+header_filter_by_lua:3 loop\]/ +qr/\[TRACE\s+\d+\s+header_filter_by_lua\(nginx.conf:\d+\):3 loop\]/ ] @@ -65,5 +65,5 @@ GET /t bad argument --- error_log eval ["status: 200,", -qr/\[TRACE\s+\d+\s+header_filter_by_lua:2 loop\]/ +qr/\[TRACE\s+\d+\s+header_filter_by_lua\(nginx.conf:\d+\):2 loop\]/ ] diff --git a/src/deps/src/lua-resty-core/t/stream/ssl.t b/src/deps/src/lua-resty-core/t/stream/ssl.t index 10cb6c9cb..17a881015 100644 --- a/src/deps/src/lua-resty-core/t/stream/ssl.t +++ b/src/deps/src/lua-resty-core/t/stream/ssl.t @@ -2034,3 +2034,109 @@ client certificate subject: nil [error] [alert] [emerg] + + + +=== TEST 26: private key protected by passphrase +--- stream_config + lua_package_path "$TEST_NGINX_LUA_PACKAGE_PATH"; + + server { + listen unix:$TEST_NGINX_HTML_DIR/nginx.sock ssl; + ssl_certificate_by_lua_block { + local ssl = require "ngx.ssl" + + ssl.clear_certs() + + local f = assert(io.open("t/cert/test_passphrase.crt")) + local cert_data = f:read("*a") + f:close() + + local cert, err = ssl.cert_pem_to_der(cert_data) + if not cert then + ngx.log(ngx.ERR, "failed to convert pem cert to der cert: ", err) + return + end + + local ok, err = ssl.set_der_cert(cert) + if not ok then + ngx.log(ngx.ERR, "failed to set DER cert: ", err) + return + end + + local f = assert(io.open("t/cert/test_passphrase.key")) + local pkey_data = f:read("*a") + f:close() + + pkey_data, err = ssl.priv_key_pem_to_der(pkey_data, "123456") + if not pkey_data then + ngx.log(ngx.ERR, "failed to convert pem key to der key: ", err) + return + end + + local ok, err = ssl.set_der_priv_key(pkey_data) + if not ok then + ngx.log(ngx.ERR, "failed to set DER private key: ", err) + return + end + } + ssl_certificate ../../cert/test2.crt; + ssl_certificate_key ../../cert/test2.key; + + return 'it works!\n'; + } +--- stream_server_config + lua_ssl_trusted_certificate ../../cert/chain/root-ca.crt; + lua_ssl_verify_depth 3; + + content_by_lua_block { + do + local sock = ngx.socket.tcp() + + sock:settimeout(3000) + + local ok, err = sock:connect("unix:$TEST_NGINX_HTML_DIR/nginx.sock") + if not ok then + ngx.say("failed to connect: ", err) + return + end + + ngx.say("connected: ", ok) + + local sess, err = sock:sslhandshake(nil, "test.com") + if not sess then + ngx.say("failed to do SSL handshake: ", err) + return + end + + ngx.say("ssl handshake: ", type(sess)) + + while true do + local line, err = sock:receive() + if not line then + -- ngx.say("failed to receive response status line: ", err) + break + end + + ngx.say("received: ", line) + end + + local ok, err = sock:close() + ngx.say("close: ", ok, " ", err) + end -- do + -- collectgarbage() + } + +--- stream_response +connected: 1 +ssl handshake: userdata +received: it works! +close: 1 nil + +--- error_log +lua ssl server name: "test.com" + +--- no_error_log +[error] +[alert] +[emerg] diff --git a/src/deps/src/lua-resty-core/t/stream/time.t b/src/deps/src/lua-resty-core/t/stream/time.t index 02858810f..5603bb33d 100644 --- a/src/deps/src/lua-resty-core/t/stream/time.t +++ b/src/deps/src/lua-resty-core/t/stream/time.t @@ -49,11 +49,11 @@ stitch end ngx.say(t > 1400960598) local diff = os.time() - t - ngx.say(diff <= 1) + ngx.say("<= 1: ", diff <= 1) } --- stream_response true -true +<= 1: true --- error_log eval qr/\[TRACE\s+\d+ content_by_lua\(nginx\.conf:\d+\):3 loop\]/ @@ -138,3 +138,67 @@ qr/\[TRACE\s+\d+ content_by_lua\(nginx\.conf:\d+\):3 loop\]/ [error] bad argument type stitch + + + +=== TEST 7: "resty.core.time".monotonic_msec +--- stream_server_config + content_by_lua_block { + local cur_msec = require "resty.core.time".monotonic_msec + local proc = io.open("/proc/uptime", "r") + local content = proc:read() + proc:close() + local idx = string.find(content, " ", 1, true) + local uptime = 1000 * tonumber(string.sub(content, 1, idx - 1)) + ngx.update_time() + + local t + for i = 1, 500 do + t = cur_msec() + end + ngx.say(t >= uptime) + local diff = t - uptime + ngx.say("< 10: ", diff < 10) + } +--- stream_response +true +< 10: true + +--- error_log eval +qr/\[TRACE\s+\d+ content_by_lua\(nginx\.conf:\d+\):11 loop\]/ +--- no_error_log +[error] +bad argument type +stitch + + + +=== TEST 8: "resty.core.time".monotonic_time +--- stream_server_config + content_by_lua_block { + local cur_time = require "resty.core.time".monotonic_time + local proc = io.open("/proc/uptime", "r") + local content = proc:read() + proc:close() + local idx = string.find(content, " ", 1, true) + local uptime = tonumber(string.sub(content, 1, idx - 1)) + ngx.update_time() + + local t + for i = 1, 500 do + t = cur_time() + end + ngx.say(t >= uptime) + local diff = t - uptime + ngx.say("< 0.1: ", diff < 0.1) + } +--- stream_response +true +< 0.1: true + +--- error_log eval +qr/\[TRACE\s+\d+ content_by_lua\(nginx\.conf:\d+\):11 loop\]/ +--- no_error_log +[error] +bad argument type +stitch diff --git a/src/deps/src/lua-resty-core/t/time.t b/src/deps/src/lua-resty-core/t/time.t index 5adf274b1..ba2df01ed 100644 --- a/src/deps/src/lua-resty-core/t/time.t +++ b/src/deps/src/lua-resty-core/t/time.t @@ -61,14 +61,14 @@ stitch end ngx.say(t > 1400960598) local diff = os.time() - t - ngx.say(diff <= 1) + ngx.say("<= 1: ", diff <= 1) } } --- request GET /t --- response_body true -true +<= 1: true --- error_log eval qr/\[TRACE\s+\d+ content_by_lua\(nginx\.conf:\d+\):3 loop\]/ @@ -324,3 +324,77 @@ not ok: string argument only [alert] bad argument type stitch + + + +=== TEST 13: "resty.core.time".monotonic_msec +--- config + location = /t { + access_log off; + content_by_lua_block { + local cur_msec = require "resty.core.time".monotonic_msec + local proc = io.open("/proc/uptime", "r") + local content = proc:read() + proc:close() + local idx = string.find(content, " ", 1, true) + local uptime = 1000 * tonumber(string.sub(content, 1, idx - 1)) + ngx.update_time() + + local t + for i = 1, 30 do + t = cur_msec() + end + ngx.say(t >= uptime) + local diff = t - uptime + ngx.say("< 10: ", diff < 10) + } + } +--- request +GET /t +--- response_body +true +< 10: true + +--- error_log eval +qr/\[TRACE\s+\d+ content_by_lua\(nginx\.conf:\d+\):11 loop\]/ +--- no_error_log +[error] +bad argument type +stitch + + + +=== TEST 14: "resty.core.time".monotonic_time +--- config + location = /t { + access_log off; + content_by_lua_block { + local cur_time = require "resty.core.time".monotonic_time + local proc = io.open("/proc/uptime", "r") + local content = proc:read() + proc:close() + local idx = string.find(content, " ", 1, true) + local uptime = tonumber(string.sub(content, 1, idx - 1)) + ngx.update_time() + + local t + for i = 1, 30 do + t = cur_time() + end + ngx.say(t >= uptime) + local diff = t - uptime + ngx.say("< 0.01: ", diff < 0.01) + } + } +--- request +GET /t +--- response_body +true +< 0.01: true + +--- error_log eval +qr/\[TRACE\s+\d+ content_by_lua\(nginx\.conf:\d+\):11 loop\]/ +--- no_error_log +[error] +bad argument type +stitch diff --git a/src/deps/src/lua-resty-core/t/worker.t b/src/deps/src/lua-resty-core/t/worker.t index 97c2985b7..d0917e32c 100644 --- a/src/deps/src/lua-resty-core/t/worker.t +++ b/src/deps/src/lua-resty-core/t/worker.t @@ -8,7 +8,7 @@ use t::TestCore; repeat_each(2); -plan tests => repeat_each() * (blocks() * 6); +plan tests => repeat_each() * (blocks() * 6 - 3); #no_diff(); #no_long_string(); @@ -117,3 +117,33 @@ qr/\[TRACE\s+\d+ content_by_lua\(nginx\.conf:\d+\):4 loop\]/ [error] -- NYI: stitch + + + +=== TEST 5: ngx.worker.pids +--- config + location /lua { + content_by_lua_block { + local pids = ngx.worker.pids() + local pid = ngx.worker.pid() + ngx.say("worker pid: ", pid) + local count = ngx.worker.count() + if count ~= #pids then + ngx.say("worker pids is wrong.") + end + for i = 1, count do + if pids[i] == pid then + ngx.say("worker pid is correct.") + return + end + end + ngx.say("worker pid is wrong.") + } + } +--- request +GET /lua +--- response_body_like +worker pid: \d+ +worker pid is correct\. +--- no_error_log +[error] diff --git a/tests/KubernetesTest.py b/tests/KubernetesTest.py index 7dcf34d87..cada48990 100644 --- a/tests/KubernetesTest.py +++ b/tests/KubernetesTest.py @@ -48,6 +48,8 @@ class KubernetesTest(Test) : Test.replace_in_file(deploy, r"bunkerity/bunkerweb:.*$", getenv("PRIVATE_REGISTRY") + "/infra/bunkerweb-tests:" + getenv("IMAGE_TAG")) Test.replace_in_file(deploy, r"bunkerity/bunkerweb-autoconf:.*$", getenv("PRIVATE_REGISTRY") + "/infra/autoconf-tests:" + getenv("IMAGE_TAG")) Test.replace_in_file(deploy, r"bunkerity/bunkerweb-scheduler:.*$", getenv("PRIVATE_REGISTRY") + "/infra/scheduler-tests:" + getenv("IMAGE_TAG")) + Test.replace_in_file(deploy, r"#i", "i") + Test.replace_in_file(deploy, r"#-", "-") proc = run("kubectl apply -f bunkerweb.yml", cwd="/tmp/kubernetes", shell=True) if proc.returncode != 0 : raise(Exception("kubectl apply bunkerweb failed (k8s stack)")) diff --git a/tests/linux/Dockerfile-ubuntu b/tests/linux/Dockerfile-ubuntu index 2c8d05b82..f1c13756c 100644 --- a/tests/linux/Dockerfile-ubuntu +++ b/tests/linux/Dockerfile-ubuntu @@ -31,7 +31,7 @@ RUN apt update && \ apt-get update && \ apt-get install -y --no-install-recommends nginx=${NGINX_VERSION}-1~jammy -#COPY ./package-ubuntu/*.deb /opt +COPY ./package-ubuntu/*.deb /opt VOLUME ["/sys/fs/cgroup"]