From f8faae25f3258d70082a78b19f5af8b61d29f8bd Mon Sep 17 00:00:00 2001 From: Colin Hutchinson Date: Mon, 5 Dec 2022 17:20:25 -0500 Subject: [PATCH] feat(runtime): the build & test runtime (#2) --- .env | 7 + .pre-commit-config.yaml | 2 - Dockerfile | 13 +- build.sh | 131 +- ...220411_01_patch_macro_luajit_version.patch | 25 + patches/LuaJIT-2.1-20220411_02.patch | 24 + .../lua-cjson-2.1.0.10_01-empty_array.patch | 12 + ...a-resty-core-0.1.23_01-cosocket-mtls.patch | 565 +++++++ ...ore-0.1.23_02-dyn_upstream_keepalive.patch | 230 +++ ...resty.core.shdict-compatible-with-m1.patch | 269 ++++ ...sty.core.response-compatible-with-m1.patch | 100 ++ ...-resty-websocket-0.09_01-client-mtls.patch | 91 ++ ...am_client_certificate_and_ssl_verify.patch | 52 + ...tokens-from-special-responses-output.patch | 37 + ...x-1.21.4_03-stream_proxy_ssl_disable.patch | 33 + ...nx-1.21.4_04-grpc_authority_override.patch | 25 + ...eaders-from-ngx-header-filter-module.patch | 70 + .../ngx_lua-0.10.21_01-cosocket-mtls.patch | 1432 +++++++++++++++++ ...ua-0.10.21_02-dyn_upstream_keepalive.patch | 1319 +++++++++++++++ ..._lua-0.0.11_01-expose_request_struct.patch | 26 + test.sh | 16 +- 21 files changed, 4466 insertions(+), 13 deletions(-) create mode 100644 .env create mode 100644 patches/LuaJIT-2.1-20220411_01_patch_macro_luajit_version.patch create mode 100644 patches/LuaJIT-2.1-20220411_02.patch create mode 100644 patches/lua-cjson-2.1.0.10_01-empty_array.patch create mode 100644 patches/lua-resty-core-0.1.23_01-cosocket-mtls.patch create mode 100644 patches/lua-resty-core-0.1.23_02-dyn_upstream_keepalive.patch create mode 100644 patches/lua-resty-core-0.1.23_03-make-resty.core.shdict-compatible-with-m1.patch create mode 100644 patches/lua-resty-core-0.1.23_04-make-resty.core.response-compatible-with-m1.patch create mode 100644 patches/lua-resty-websocket-0.09_01-client-mtls.patch create mode 100644 patches/nginx-1.21.4_01-upstream_client_certificate_and_ssl_verify.patch create mode 100644 patches/nginx-1.21.4_02-remove-server-tokens-from-special-responses-output.patch create mode 100644 patches/nginx-1.21.4_03-stream_proxy_ssl_disable.patch create mode 100644 patches/nginx-1.21.4_04-grpc_authority_override.patch create mode 100644 patches/nginx-1.21.4_05-remove-server-headers-from-ngx-header-filter-module.patch create mode 100644 patches/ngx_lua-0.10.21_01-cosocket-mtls.patch create mode 100644 patches/ngx_lua-0.10.21_02-dyn_upstream_keepalive.patch create mode 100644 patches/ngx_stream_lua-0.0.11_01-expose_request_struct.patch diff --git a/.env b/.env new file mode 100644 index 0000000..5e576c4 --- /dev/null +++ b/.env @@ -0,0 +1,7 @@ +OPENRESTY_VERSION=1.21.4.1 +LUAROCKS_VERSION=3.9.1 +PCRE_VERSION=8.45 +KONG_NGINX_MODULE_VERSION=0.4.0 +LUA_RESTY_LMDB_VERSION=1.0.0 +LUA_RESTY_EVENTS_VERSION=0.1.3 +ATC_ROUTER_VERSION=1.0.35 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index fa81517..709961a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -21,8 +21,6 @@ repos: hooks: - id: forbid-crlf - id: remove-crlf - - id: forbid-tabs - - id: remove-tabs - repo: https://github.com/Yelp/detect-secrets rev: v1.1.0 hooks: diff --git a/Dockerfile b/Dockerfile index f84308e..09f42e8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,18 +4,19 @@ ARG DOCKER_REGISTRY=ghcr.io ARG DOCKER_IMAGE_NAME # List out all image permutations to trick dependabot -FROM --platform=linux/amd64 kong/kong-build-tools:apk-1.8.1 as x86_64-linux-musl -FROM --platform=linux/amd64 kong/kong-build-tools:rpm-1.8.1 as x86_64-linux-gnu -FROM --platform=linux/arm64 kong/kong-build-tools:apk-1.8.1 as aarch64-linux-musl -FROM --platform=linux/arm64 kong/kong-build-tools:rpm-1.8.1 as aarch64-linux-gnu +FROM --platform=linux/amd64 ghcr.io/kong/kong-openssl:1.1.0-x86_64-linux-musl as x86_64-linux-musl +FROM --platform=linux/amd64 ghcr.io/kong/kong-openssl:1.1.0-x86_64-linux-gnu as x86_64-linux-gnu +FROM --platform=linux/arm64 ghcr.io/kong/kong-openssl:1.1.0-aarch64-linux-musl as aarch64-linux-musl +FROM --platform=linux/arm64 ghcr.io/kong/kong-openssl:1.1.0-aarch64-linux-gnu as aarch64-linux-gnu # Run the build script FROM $ARCHITECTURE-$OSTYPE as build -COPY . /src -RUN /src/build.sh && /src/test.sh +COPY . /tmp +WORKDIR /tmp +RUN /tmp/build.sh # Copy the build result to scratch so we can export the result FROM scratch as package diff --git a/build.sh b/build.sh index 8de0308..62d7530 100755 --- a/build.sh +++ b/build.sh @@ -1,14 +1,139 @@ #!/usr/bin/env bash -set -euo pipefail -IFS=$'\n\t' +set -eo pipefail if [ -n "${DEBUG:-}" ]; then set -x fi +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +export $(grep -v '^#' $SCRIPT_DIR/.env | xargs) + function main() { - rm -rf /tmp/build/* && uname -a >> /tmp/build/out + with_backoff curl --fail -sSLo pcre.tar.gz "https://downloads.sourceforge.net/project/pcre/pcre/${PCRE_VERSION}/pcre-${PCRE_VERSION}.tar.gz" + tar -xzvf pcre.tar.gz + ln -s pcre-${PCRE_VERSION} pcre + + with_backoff curl --fail -sSLo openresty.tar.gz "https://openresty.org/download/openresty-${OPENRESTY_VERSION}.tar.gz" + tar -xzvf openresty.tar.gz + ln -s openresty-${OPENRESTY_VERSION} openresty + + with_backoff curl --fail -sSLo luarocks.tar.gz "https://luarocks.org/releases/luarocks-${LUAROCKS_VERSION}.tar.gz" + tar -xzvf luarocks.tar.gz + ln -s luarocks-${LUAROCKS_VERSION} luarocks + + with_backoff git clone --single-branch --branch ${KONG_NGINX_MODULE_VERSION} https://github.com/Kong/lua-kong-nginx-module + + with_backoff git clone --single-branch --branch ${LUA_RESTY_LMDB_VERSION} https://github.com/Kong/lua-resty-lmdb --recursive + + with_backoff git clone --single-branch --branch ${LUA_RESTY_EVENTS_VERSION} https://github.com/Kong/lua-resty-events --recursive + + pushd openresty-${OPENRESTY_VERSION}/bundle + for patch_file in $(ls /tmp/patches/*.patch); do + patch -p1 < $patch_file + done + + lj_dir=$(ls -d LuaJIT*) + lj_release_date=$(echo ${lj_dir} | sed -e 's/LuaJIT-[[:digit:]]\+.[[:digit:]]\+-\([[:digit:]]\+\)/\1/') + lj_version_tag="LuaJIT\ 2.1.0-${lj_release_date}" + popd + + pushd openresty-${OPENRESTY_VERSION} + OPENRESTY_OPTS=( + "--prefix=/usr/local/openresty" + "--with-pcre-jit" + "--with-http_ssl_module" + "--with-http_sub_module" + "--with-http_realip_module" + "--with-http_stub_status_module" + "--with-http_v2_module" + "--without-http_encrypted_session_module" + "--with-luajit-xcflags='-DLUAJIT_VERSION=\\\"${lj_version_tag}\\\"'" + "-j2" + ) + + OPENRESTY_OPTS+=("--add-module=/tmp/lua-kong-nginx-module") + OPENRESTY_OPTS+=("--add-module=/tmp/lua-kong-nginx-module/stream") + OPENRESTY_OPTS+=("--add-module=/tmp/lua-resty-lmdb") + OPENRESTY_OPTS+=("--add-module=/tmp/lua-resty-events") + OPENRESTY_OPTS+=('--with-stream_realip_module') + OPENRESTY_OPTS+=('--with-stream_ssl_preread_module') + OPENRESTY_OPTS+=('--with-pcre=/tmp/pcre') + OPENRESTY_OPTS+=("--with-ld-opt='-L/tmp/build/usr/local/kong/lib -Wl,--disable-new-dtags,-rpath,/usr/local/kong/lib'") + OPENRESTY_OPTS+=("--with-cc-opt='-I/tmp/build/usr/local/kong/include'") + + eval ./configure ${OPENRESTY_OPTS[*]} || tee /tmp/00-openresty-configure.log + + make -j2 || tee /tmp/01-openresty-build.log + make -j2 install DESTDIR=/tmp/build || tee /tmp/02-openresty-install.log + popd + + pushd /tmp/lua-kong-nginx-module + make install LUA_LIB_DIR=/tmp/build/usr/local/openresty/lualib + popd + + pushd /tmp/lua-resty-lmdb + make install LUA_LIB_DIR=/tmp/build/usr/local/openresty/lualib + popd + + pushd /tmp/lua-resty-events + make install LUA_LIB_DIR=/tmp/build/usr/local/openresty/lualib + popd + + pushd /tmp/luarocks-${LUAROCKS_VERSION} + ./configure \ + --prefix=/usr/local \ + --with-lua=/tmp/build/usr/local/openresty/luajit \ + --with-lua-include=/tmp/build/usr/local/openresty/luajit/include/luajit-2.1 + + make build -j2 + make install DESTDIR=/tmp/build + popd + + arch=$(uname -m) + + package_architecture=x86_64 + if [ "$(arch)" == "aarch64" ]; then + package_architecture=aarch64 + fi + + curl -fsSLo atc-router.tar.gz https://github.com/hutchic/atc-router/releases/download/$ATC_ROUTER_VERSION/$package_architecture-unknown-$OSTYPE.tar.gz + tar -C /tmp/build -xvf atc-router.tar.gz +} + +# Retries a command a configurable number of times with backoff. +# +# The retry count is given by ATTEMPTS (default 5), the initial backoff +# timeout is given by TIMEOUT in seconds (default 1.) +# +# Successive backoffs double the timeout. +function with_backoff { + local max_attempts=${ATTEMPTS-5} + local timeout=${TIMEOUT-5} + local attempt=1 + local exitCode=0 + + while (( $attempt < $max_attempts )) + do + if "$@" + then + return 0 + else + exitCode=$? + fi + + echo "Failure! Retrying in $timeout.." 1>&2 + sleep $timeout + attempt=$(( attempt + 1 )) + timeout=$(( timeout * 2 )) + done + + if [[ $exitCode != 0 ]] + then + echo "You've failed me for the last time! ($@)" 1>&2 + fi + + return $exitCode } main diff --git a/patches/LuaJIT-2.1-20220411_01_patch_macro_luajit_version.patch b/patches/LuaJIT-2.1-20220411_01_patch_macro_luajit_version.patch new file mode 100644 index 0000000..359e4bd --- /dev/null +++ b/patches/LuaJIT-2.1-20220411_01_patch_macro_luajit_version.patch @@ -0,0 +1,25 @@ +From f53c8fa441f4233b9a3f19fcd870207fe8795456 Mon Sep 17 00:00:00 2001 +From: Qi +Date: Wed, 25 May 2022 18:35:08 +0800 +Subject: [PATCH] Patch macro `LUAJIT_VERSION` + +--- + src/luajit.h | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/LuaJIT-2.1-20220411/src/luajit.h b/LuaJIT-2.1-20220411/src/luajit.h +index a4d33001..e35f4e7e 100644 +--- a/LuaJIT-2.1-20220411/src/luajit.h ++++ b/LuaJIT-2.1-20220411/src/luajit.h +@@ -32,7 +32,9 @@ + + #define OPENRESTY_LUAJIT + ++#ifndef LUAJIT_VERSION + #define LUAJIT_VERSION "LuaJIT 2.1.0-beta3" ++#endif + #define LUAJIT_VERSION_NUM 20100 /* Version 2.1.0 = 02.01.00. */ + #define LUAJIT_VERSION_SYM luaJIT_version_2_1_0_beta3 + #define LUAJIT_COPYRIGHT "Copyright (C) 2005-2022 Mike Pall" +-- +2.34.1 diff --git a/patches/LuaJIT-2.1-20220411_02.patch b/patches/LuaJIT-2.1-20220411_02.patch new file mode 100644 index 0000000..d1784d4 --- /dev/null +++ b/patches/LuaJIT-2.1-20220411_02.patch @@ -0,0 +1,24 @@ +From dad04f1754723e76ba9dcf9f401f3134a0cd3972 Mon Sep 17 00:00:00 2001 +From: Mike Pall +Date: Wed, 14 Sep 2022 12:26:53 +0200 +Subject: [PATCH] Fix trace join to BC_JLOOP originating from BC_ITERN. + +Reported by OpenResty Inc. +--- + src/lj_record.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/LuaJIT-2.1-20220411/src/lj_record.c b/LuaJIT-2.1-20220411/src/lj_record.c +index 5d02d24a1..bfd412365 100644 +--- a/LuaJIT-2.1-20220411/src/lj_record.c ++++ b/LuaJIT-2.1-20220411/src/lj_record.c +@@ -2572,7 +2572,8 @@ void lj_record_ins(jit_State *J) + break; + case BC_JLOOP: + rec_loop_jit(J, rc, rec_loop(J, ra, +- !bc_isret(bc_op(traceref(J, rc)->startins)))); ++ !bc_isret(bc_op(traceref(J, rc)->startins)) && ++ bc_op(traceref(J, rc)->startins) != BC_ITERN)); + break; + + case BC_IFORL: diff --git a/patches/lua-cjson-2.1.0.10_01-empty_array.patch b/patches/lua-cjson-2.1.0.10_01-empty_array.patch new file mode 100644 index 0000000..29d5f3b --- /dev/null +++ b/patches/lua-cjson-2.1.0.10_01-empty_array.patch @@ -0,0 +1,12 @@ +diff -ruN a/lua-cjson-2.1.0.8/lua_cjson.c b/lua-cjson-2.1.0.8/lua_cjson.c +--- a/lua-cjson-2.1.0.10/lua_cjson.c 2022-01-11 15:11:17.495464192 +0800 ++++ b/lua-cjson-2.1.0.10/lua_cjson.c 2022-01-11 14:58:55.150669748 +0800 +@@ -800,7 +800,7 @@ + case LUA_TLIGHTUSERDATA: + if (lua_touserdata(l, -1) == NULL) { + strbuf_append_mem(json, "null", 4); +- } else if (lua_touserdata(l, -1) == &json_array) { ++ } else if (lua_touserdata(l, -1) == json_lightudata_mask(&json_array)) { + json_append_array(l, cfg, current_depth, json, 0); + } + break; diff --git a/patches/lua-resty-core-0.1.23_01-cosocket-mtls.patch b/patches/lua-resty-core-0.1.23_01-cosocket-mtls.patch new file mode 100644 index 0000000..456c10f --- /dev/null +++ b/patches/lua-resty-core-0.1.23_01-cosocket-mtls.patch @@ -0,0 +1,565 @@ +From 4f0f4bf63d23a952179aaf810c10dfffc19ee835 Mon Sep 17 00:00:00 2001 +From: chronolaw +Date: Fri, 28 Jan 2022 20:54:30 +0800 +Subject: [PATCH 1/9] move tcp.lua into socket.lua + +--- + lib/resty/core/socket.lua | 136 +++++++++++++++++++++++++++++++++++++- + 1 file changed, 133 insertions(+), 3 deletions(-) + +diff --git a/lua-resty-core-0.1.23/lib/resty/core/socket.lua b/lua-resty-core-0.1.23/lib/resty/core/socket.lua +index 1a504ec..cc0081e 100644 +--- a/lua-resty-core-0.1.23/lib/resty/core/socket.lua ++++ b/lua-resty-core-0.1.23/lib/resty/core/socket.lua +@@ -6,13 +6,21 @@ local ffi = require 'ffi' + + local error = error + local tonumber = tonumber ++local tostring = tostring ++local type = type ++local select = select + local registry = debug.getregistry() ++ ++local C = ffi.C + local ffi_new = ffi.new + local ffi_string = ffi.string +-local C = ffi.C ++local ffi_gc = ffi.gc ++ + local get_string_buf = base.get_string_buf + local get_size_ptr = base.get_size_ptr +-local tostring = tostring ++local get_request = base.get_request ++ ++local co_yield = coroutine._yield + + + local option_index = { +@@ -35,15 +43,29 @@ 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 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 ERR_BUF_SIZE = 4096 + +- + local function get_tcp_socket(cosocket) + local tcp_socket = cosocket[SOCKET_CTX_INDEX] + if not tcp_socket then +@@ -114,10 +136,118 @@ local function setoption(cosocket, option, value) + 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(self, cert, pkey) ++ if not cert and not pkey then ++ self.client_cert = nil ++ self.client_pkey = nil ++ return ++ end ++ ++ if not cert or not pkey then ++ error("client certificate must be supplied with corresponding " .. ++ "private key", 2) ++ end ++ ++ if type(cert) ~= "cdata" then ++ error("bad client cert type", 2) ++ end ++ ++ if type(pkey) ~= "cdata" then ++ error("bad client pkey type", 2) ++ end ++ ++ self.client_cert = cert ++ self.client_pkey = pkey ++end ++ ++ ++local function sslhandshake(self, reused_session, server_name, ssl_verify, ++ send_status_req, ...) ++ ++ local n = select("#", ...) ++ if not self or n > 1 then ++ error("ngx.socket sslhandshake: expecting 1 ~ 5 arguments " .. ++ "(including the object), but seen " .. (5 + n)) ++ 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 = self[SOCKET_CTX_INDEX] ++ ++ 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, ++ self.client_cert, self.client_pkey, 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_string(errmsg[0]) ++ end ++ ++ return nil, ffi_string(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) ++ ++ if session_ptr[0] == nil then ++ return nil ++ end ++ ++ return ffi_gc(session_ptr[0], C.ngx_http_lua_ffi_ssl_free_session) ++ end ++ ++ 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 + + +-- +2.32.0 (Apple Git-132) + + +From 4eab5793d741c739d9c5cfe14e0671c1d70fd6e5 Mon Sep 17 00:00:00 2001 +From: chronolaw +Date: Fri, 28 Jan 2022 21:37:45 +0800 +Subject: [PATCH 2/9] revert assert in sslhandshake + +--- + lib/resty/core/socket.lua | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/lua-resty-core-0.1.23/lib/resty/core/socket.lua b/lua-resty-core-0.1.23/lib/resty/core/socket.lua +index cc0081e..7c61d06 100644 +--- a/lua-resty-core-0.1.23/lib/resty/core/socket.lua ++++ b/lua-resty-core-0.1.23/lib/resty/core/socket.lua +@@ -5,6 +5,7 @@ local ffi = require 'ffi' + + + local error = error ++local assert = assert + local tonumber = tonumber + local tostring = tostring + local type = type +@@ -227,6 +228,8 @@ local function sslhandshake(self, reused_session, server_name, ssl_verify, + 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 nil + end +@@ -234,6 +237,8 @@ local function sslhandshake(self, reused_session, server_name, ssl_verify, + 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, +-- +2.32.0 (Apple Git-132) + + +From 58de9a44c89f07eda98bb7fd978a9e04a244d2f2 Mon Sep 17 00:00:00 2001 +From: chronolaw +Date: Fri, 28 Jan 2022 21:45:42 +0800 +Subject: [PATCH 3/9] rename ffi_string to ffi_str + +--- + lib/resty/core/socket.lua | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/lua-resty-core-0.1.23/lib/resty/core/socket.lua b/lua-resty-core-0.1.23/lib/resty/core/socket.lua +index 7c61d06..14457da 100644 +--- a/lua-resty-core-0.1.23/lib/resty/core/socket.lua ++++ b/lua-resty-core-0.1.23/lib/resty/core/socket.lua +@@ -14,7 +14,7 @@ local registry = debug.getregistry() + + local C = ffi.C + local ffi_new = ffi.new +-local ffi_string = ffi.string ++local ffi_str = ffi.string + local ffi_gc = ffi.gc + + local get_string_buf = base.get_string_buf +@@ -98,7 +98,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]) +@@ -130,7 +130,7 @@ 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 +@@ -210,10 +210,10 @@ local function sslhandshake(self, reused_session, server_name, ssl_verify, + while true do + if rc == FFI_ERROR then + if openssl_error_code[0] ~= 0 then +- return nil, openssl_error_code[0] .. ": " .. ffi_string(errmsg[0]) ++ return nil, openssl_error_code[0] .. ": " .. ffi_str(errmsg[0]) + end + +- return nil, ffi_string(errmsg[0]) ++ return nil, ffi_str(errmsg[0]) + end + + if rc == FFI_DONE then +-- +2.32.0 (Apple Git-132) + + +From ff138619432bda6b9bd4f37403c12600a4739e47 Mon Sep 17 00:00:00 2001 +From: chronolaw +Date: Sat, 29 Jan 2022 07:23:16 +0800 +Subject: [PATCH 4/9] minor style fix + +--- + lib/resty/core/socket.lua | 15 +++++++++------ + 1 file changed, 9 insertions(+), 6 deletions(-) + +diff --git a/lua-resty-core-0.1.23/lib/resty/core/socket.lua b/lua-resty-core-0.1.23/lib/resty/core/socket.lua +index 14457da..3c882af 100644 +--- a/lua-resty-core-0.1.23/lib/resty/core/socket.lua ++++ b/lua-resty-core-0.1.23/lib/resty/core/socket.lua +@@ -1,7 +1,7 @@ + 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 +@@ -45,16 +45,19 @@ 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, ++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, ++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); ++void ++ngx_http_lua_ffi_ssl_free_session(void *sess); + ]] + + +-- +2.32.0 (Apple Git-132) + + +From a843a258987efba49f0b6979389f75ee32c2150c Mon Sep 17 00:00:00 2001 +From: chronolaw +Date: Sat, 29 Jan 2022 07:28:41 +0800 +Subject: [PATCH 5/9] rename self to cosocket + +--- + lib/resty/core/socket.lua | 18 +++++++++--------- + 1 file changed, 9 insertions(+), 9 deletions(-) + +diff --git a/lua-resty-core-0.1.23/lib/resty/core/socket.lua b/lua-resty-core-0.1.23/lib/resty/core/socket.lua +index 3c882af..374d583 100644 +--- a/lua-resty-core-0.1.23/lib/resty/core/socket.lua ++++ b/lua-resty-core-0.1.23/lib/resty/core/socket.lua +@@ -146,10 +146,10 @@ local server_name_str = ffi_new("ngx_str_t[1]") + local openssl_error_code = ffi_new("int[1]") + + +-local function setclientcert(self, cert, pkey) ++local function setclientcert(cosocket, cert, pkey) + if not cert and not pkey then +- self.client_cert = nil +- self.client_pkey = nil ++ cosocket.client_cert = nil ++ cosocket.client_pkey = nil + return + end + +@@ -166,16 +166,16 @@ local function setclientcert(self, cert, pkey) + error("bad client pkey type", 2) + end + +- self.client_cert = cert +- self.client_pkey = pkey ++ cosocket.client_cert = cert ++ cosocket.client_pkey = pkey + end + + +-local function sslhandshake(self, reused_session, server_name, ssl_verify, ++local function sslhandshake(cosocket, reused_session, server_name, ssl_verify, + send_status_req, ...) + + local n = select("#", ...) +- if not self or n > 1 then ++ if not cosocket or n > 1 then + error("ngx.socket sslhandshake: expecting 1 ~ 5 arguments " .. + "(including the object), but seen " .. (5 + n)) + end +@@ -196,7 +196,7 @@ local function sslhandshake(self, reused_session, server_name, ssl_verify, + server_name_str[0].len = 0 + end + +- local u = self[SOCKET_CTX_INDEX] ++ local u = cosocket[SOCKET_CTX_INDEX] + + local rc = C.ngx_http_lua_ffi_socket_tcp_sslhandshake(r, u, + session_ptr[0], +@@ -204,7 +204,7 @@ local function sslhandshake(self, reused_session, server_name, ssl_verify, + server_name_str, + ssl_verify and 1 or 0, + send_status_req and 1 or 0, +- self.client_cert, self.client_pkey, errmsg) ++ cosocket.client_cert, cosocket.client_pkey, errmsg) + + if rc == FFI_NO_REQ_CTX then + error("no request ctx found", 2) +-- +2.32.0 (Apple Git-132) + + +From db95a049a019ff6f0d3b4e550412e40c25dda41f Mon Sep 17 00:00:00 2001 +From: chronolaw +Date: Sat, 29 Jan 2022 07:35:04 +0800 +Subject: [PATCH 6/9] use get_tcp_socket() in sslhandshake + +--- + lib/resty/core/socket.lua | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lua-resty-core-0.1.23/lib/resty/core/socket.lua b/lua-resty-core-0.1.23/lib/resty/core/socket.lua +index 374d583..ecff453 100644 +--- a/lua-resty-core-0.1.23/lib/resty/core/socket.lua ++++ b/lua-resty-core-0.1.23/lib/resty/core/socket.lua +@@ -196,7 +196,7 @@ local function sslhandshake(cosocket, reused_session, server_name, ssl_verify, + server_name_str[0].len = 0 + end + +- local u = cosocket[SOCKET_CTX_INDEX] ++ local u = get_tcp_socket(cosocket) + + local rc = C.ngx_http_lua_ffi_socket_tcp_sslhandshake(r, u, + session_ptr[0], +-- +2.32.0 (Apple Git-132) + + +From 6767f0c2e8a73fd1a09d727431bed457c5cac4c0 Mon Sep 17 00:00:00 2001 +From: chronolaw +Date: Sat, 29 Jan 2022 08:58:52 +0800 +Subject: [PATCH 7/9] fix arguments check in sslhandshake + +--- + lib/resty/core/socket.lua | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lua-resty-core-0.1.23/lib/resty/core/socket.lua b/lua-resty-core-0.1.23/lib/resty/core/socket.lua +index ecff453..15e3065 100644 +--- a/lua-resty-core-0.1.23/lib/resty/core/socket.lua ++++ b/lua-resty-core-0.1.23/lib/resty/core/socket.lua +@@ -177,7 +177,7 @@ local function sslhandshake(cosocket, reused_session, server_name, ssl_verify, + local n = select("#", ...) + if not cosocket or n > 1 then + error("ngx.socket sslhandshake: expecting 1 ~ 5 arguments " .. +- "(including the object), but seen " .. (5 + n)) ++ "(including the object), but seen " .. (cosocket and 5 + n or 0)) + end + + local r = get_request() +-- +2.32.0 (Apple Git-132) + + +From 4eeddcd2114d0097e4b9cb11f2f93d30c70d573e Mon Sep 17 00:00:00 2001 +From: chronolaw +Date: Mon, 7 Feb 2022 10:59:35 +0800 +Subject: [PATCH 8/9] setclientcert return err + +--- + lib/resty/core/socket.lua | 13 ++++++++----- + 1 file changed, 8 insertions(+), 5 deletions(-) + +diff --git a/lua-resty-core-0.1.23/lib/resty/core/socket.lua b/lua-resty-core-0.1.23/lib/resty/core/socket.lua +index 15e3065..879d678 100644 +--- a/lua-resty-core-0.1.23/lib/resty/core/socket.lua ++++ b/lua-resty-core-0.1.23/lib/resty/core/socket.lua +@@ -150,24 +150,27 @@ local function setclientcert(cosocket, cert, pkey) + if not cert and not pkey then + cosocket.client_cert = nil + cosocket.client_pkey = nil +- return ++ return true + end + + if not cert or not pkey then +- error("client certificate must be supplied with corresponding " .. +- "private key", 2) ++ return nil, ++ "client certificate must be supplied with corresponding " .. ++ "private key" + end + + if type(cert) ~= "cdata" then +- error("bad client cert type", 2) ++ return nil, "bad client cert type" + end + + if type(pkey) ~= "cdata" then +- error("bad client pkey type", 2) ++ return nil, "bad client pkey type" + end + + cosocket.client_cert = cert + cosocket.client_pkey = pkey ++ ++ return true + end + + +-- +2.32.0 (Apple Git-132) + + +From fead2a28f409117ad1b6c98d02edb6a38a64fde0 Mon Sep 17 00:00:00 2001 +From: James Hurst +Date: Wed, 9 Feb 2022 16:05:11 +0000 +Subject: [PATCH 9/9] fix(socket) add temporary backwards compatability for + tlshandshake + +--- + lib/resty/core/socket.lua | 22 ++++++++++++++++++++++ + 1 file changed, 22 insertions(+) + +diff --git a/lua-resty-core-0.1.23/lib/resty/core/socket.lua b/lua-resty-core-0.1.23/lib/resty/core/socket.lua +index 879d678..448bf36 100644 +--- a/lua-resty-core-0.1.23/lib/resty/core/socket.lua ++++ b/lua-resty-core-0.1.23/lib/resty/core/socket.lua +@@ -253,12 +253,34 @@ local function sslhandshake(cosocket, reused_session, server_name, ssl_verify, + end + + ++-- Temporary patch for backwards compatablity with existing Kong tech debt ++local function tlshandshake(cosocket, options) ++ local options = options or {} ++ ++ if options.client_cert then ++ local ok, err = cosocket:setclientcert(options.client_cert, options.client_priv_key) ++ if not ok then ++ return nil, err ++ end ++ end ++ ++ return sslhandshake( ++ cosocket, ++ options.reused_session, ++ options.server_name, ++ options.ssl_verify, ++ options.ocsp_status_req ++ ) ++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 ++ method_table.tlshandshake = tlshandshake + end + + +-- +2.32.0 (Apple Git-132) diff --git a/patches/lua-resty-core-0.1.23_02-dyn_upstream_keepalive.patch b/patches/lua-resty-core-0.1.23_02-dyn_upstream_keepalive.patch new file mode 100644 index 0000000..3f06e99 --- /dev/null +++ b/patches/lua-resty-core-0.1.23_02-dyn_upstream_keepalive.patch @@ -0,0 +1,230 @@ +From 37feb95041f183ae4fbafeebc47dc104995e6f27 Mon Sep 17 00:00:00 2001 +From: Thibault Charbonnier +Date: Tue, 17 Sep 2019 11:44:33 -0700 +Subject: [PATCH] feature: implemented the 'balancer.enable_keepalive()' API. + +--- + lua-resty-core-0.1.23/lib/ngx/balancer.lua | 165 +++++++++++++++++++++++++++++++++++++++---- + 1 file changed, 151 insertions(+), 14 deletions(-) + +diff --git a/lua-resty-core-0.1.23/lib/ngx/balancer.lua b/lua-resty-core-0.1.23/lib/ngx/balancer.lua +index d584639..614312f 100644 +--- a/lua-resty-core-0.1.23/lib/ngx/balancer.lua ++++ b/lua-resty-core-0.1.23/lib/ngx/balancer.lua +@@ -3,6 +3,7 @@ + + local base = require "resty.core.base" + base.allows_subsystem('http', 'stream') ++require "resty.core.hash" + + + local ffi = require "ffi" +@@ -17,8 +18,10 @@ local error = error + local type = type + local tonumber = tonumber + local max = math.max ++local ngx_crc32_long = ngx.crc32_long + local subsystem = ngx.config.subsystem + local ngx_lua_ffi_balancer_set_current_peer ++local ngx_lua_ffi_balancer_enable_keepalive + local ngx_lua_ffi_balancer_set_more_tries + local ngx_lua_ffi_balancer_get_last_failure + local ngx_lua_ffi_balancer_set_timeouts -- used by both stream and http +@@ -27,7 +30,11 @@ local ngx_lua_ffi_balancer_set_timeouts -- used by both stream and http + if subsystem == 'http' then + ffi.cdef[[ + int ngx_http_lua_ffi_balancer_set_current_peer(ngx_http_request_t *r, +- const unsigned char *addr, size_t addr_len, int port, char **err); ++ const unsigned char *addr, size_t addr_len, int port, ++ unsigned int cpool_crc32, unsigned int cpool_size, char **err); ++ ++ int ngx_http_lua_ffi_balancer_enable_keepalive(ngx_http_request_t *r, ++ unsigned long timeout, unsigned int max_requests, char **err); + + int ngx_http_lua_ffi_balancer_set_more_tries(ngx_http_request_t *r, + int count, char **err); +@@ -46,6 +53,9 @@ if subsystem == 'http' then + ngx_lua_ffi_balancer_set_current_peer = + C.ngx_http_lua_ffi_balancer_set_current_peer + ++ ngx_lua_ffi_balancer_enable_keepalive = ++ C.ngx_http_lua_ffi_balancer_enable_keepalive ++ + ngx_lua_ffi_balancer_set_more_tries = + C.ngx_http_lua_ffi_balancer_set_more_tries + +@@ -96,6 +106,11 @@ else + end + + ++local DEFAULT_KEEPALIVE_POOL_SIZE = 30 ++local DEFAULT_KEEPALIVE_IDLE_TIMEOUT = 60000 ++local DEFAULT_KEEPALIVE_MAX_REQUESTS = 100 ++ ++ + local peer_state_names = { + [1] = "keepalive", + [2] = "next", +@@ -106,25 +121,147 @@ local peer_state_names = { + local _M = { version = base.version } + + +-function _M.set_current_peer(addr, port) +- local r = get_request() +- if not r then +- error("no request found") ++if subsystem == "http" then ++ function _M.set_current_peer(addr, port, opts) ++ local r = get_request() ++ if not r then ++ error("no request found") ++ end ++ ++ local pool_crc32 ++ local pool_size ++ ++ if opts then ++ if type(opts) ~= "table" then ++ error("bad argument #3 to 'set_current_peer' " .. ++ "(table expected, got " .. type(opts) .. ")", 2) ++ end ++ ++ local pool = opts.pool ++ pool_size = opts.pool_size ++ ++ if pool then ++ if type(pool) ~= "string" then ++ error("bad option 'pool' to 'set_current_peer' " .. ++ "(string expected, got " .. type(pool) .. ")", 2) ++ end ++ ++ pool_crc32 = ngx_crc32_long(pool) ++ end ++ ++ if pool_size then ++ if type(pool_size) ~= "number" then ++ error("bad option 'pool_size' to 'set_current_peer' " .. ++ "(number expected, got " .. type(pool_size) .. ")", 2) ++ ++ elseif pool_size < 1 then ++ error("bad option 'pool_size' to 'set_current_peer' " .. ++ "(expected > 0)", 2) ++ end ++ end ++ end ++ ++ if not port then ++ port = 0 ++ ++ elseif type(port) ~= "number" then ++ port = tonumber(port) ++ end ++ ++ if not pool_crc32 then ++ pool_crc32 = 0 ++ end ++ ++ if not pool_size then ++ pool_size = DEFAULT_KEEPALIVE_POOL_SIZE ++ end ++ ++ local rc = ngx_lua_ffi_balancer_set_current_peer(r, addr, #addr, port, ++ pool_crc32, pool_size, ++ errmsg) ++ if rc == FFI_OK then ++ return true ++ end ++ ++ return nil, ffi_str(errmsg[0]) + end + +- if not port then +- port = 0 +- elseif type(port) ~= "number" then +- port = tonumber(port) ++else ++ function _M.set_current_peer(addr, port, opts) ++ local r = get_request() ++ if not r then ++ error("no request found") ++ end ++ ++ if opts then ++ error("bad argument #3 to 'set_current_peer' ('opts' not yet " .. ++ "implemented in " .. subsystem .. " subsystem)", 2) ++ end ++ ++ if not port then ++ port = 0 ++ ++ elseif type(port) ~= "number" then ++ port = tonumber(port) ++ end ++ ++ local rc = ngx_lua_ffi_balancer_set_current_peer(r, addr, #addr, ++ port, errmsg) ++ if rc == FFI_OK then ++ return true ++ end ++ ++ return nil, ffi_str(errmsg[0]) + end ++end + +- local rc = ngx_lua_ffi_balancer_set_current_peer(r, addr, #addr, +- port, errmsg) +- if rc == FFI_OK then +- return true ++ ++if subsystem == "http" then ++ function _M.enable_keepalive(idle_timeout, max_requests) ++ local r = get_request() ++ if not r then ++ error("no request found") ++ end ++ ++ if not idle_timeout then ++ idle_timeout = DEFAULT_KEEPALIVE_IDLE_TIMEOUT ++ ++ elseif type(idle_timeout) ~= "number" then ++ error("bad argument #1 to 'enable_keepalive' " .. ++ "(number expected, got " .. type(idle_timeout) .. ")", 2) ++ ++ elseif idle_timeout < 0 then ++ error("bad argument #1 to 'enable_keepalive' (expected >= 0)", 2) ++ ++ else ++ idle_timeout = idle_timeout * 1000 ++ end ++ ++ if not max_requests then ++ max_requests = DEFAULT_KEEPALIVE_MAX_REQUESTS ++ ++ elseif type(max_requests) ~= "number" then ++ error("bad argument #2 to 'enable_keepalive' " .. ++ "(number expected, got " .. type(max_requests) .. ")", 2) ++ ++ elseif max_requests < 0 then ++ error("bad argument #2 to 'enable_keepalive' (expected >= 0)", 2) ++ end ++ ++ local rc = ngx_lua_ffi_balancer_enable_keepalive(r, idle_timeout, ++ max_requests, errmsg) ++ if rc == FFI_OK then ++ return true ++ end ++ ++ return nil, ffi_str(errmsg[0]) + end + +- return nil, ffi_str(errmsg[0]) ++else ++ function _M.enable_keepalive() ++ error("'enable_keepalive' not yet implemented in " .. subsystem .. ++ " subsystem", 2) ++ end + end + + +-- +2.25.2 diff --git a/patches/lua-resty-core-0.1.23_03-make-resty.core.shdict-compatible-with-m1.patch b/patches/lua-resty-core-0.1.23_03-make-resty.core.shdict-compatible-with-m1.patch new file mode 100644 index 0000000..b1b04e5 --- /dev/null +++ b/patches/lua-resty-core-0.1.23_03-make-resty.core.shdict-compatible-with-m1.patch @@ -0,0 +1,269 @@ +From 85202b4306db143de55926564bf6ce981f3631b4 Mon Sep 17 00:00:00 2001 +From: Aapo Talvensaari +Date: Thu, 16 Dec 2021 19:28:43 +0200 +Subject: [PATCH] fix(shdict) make resty.core.shdict compatible with m1 (using + wrappers) + +--- + lua-resty-core-0.1.23/lib/resty/core/shdict.lua | 174 ++++++++++++++++++++++++++++++++++++++ + 1 file changed, 174 insertions(+) + +diff --git a/lua-resty-core-0.1.23/lib/resty/core/shdict.lua b/lua-resty-core-0.1.23/lib/resty/core/shdict.lua +index dedf12c..e501a38 100644 +--- a/lua-resty-core-0.1.23/lib/resty/core/shdict.lua ++++ b/lua-resty-core-0.1.23/lib/resty/core/shdict.lua +@@ -32,8 +32,11 @@ local subsystem = ngx.config.subsystem + + + local ngx_lua_ffi_shdict_get ++local ngx_lua_ffi_shdict_get_m1 + local ngx_lua_ffi_shdict_incr ++local ngx_lua_ffi_shdict_incr_m1 + local ngx_lua_ffi_shdict_store ++local ngx_lua_ffi_shdict_store_m1 + local ngx_lua_ffi_shdict_flush_all + local ngx_lua_ffi_shdict_get_ttl + local ngx_lua_ffi_shdict_set_expire +@@ -42,6 +45,53 @@ local ngx_lua_ffi_shdict_free_space + local ngx_lua_ffi_shdict_udata_to_zone + + ++local M1 = jit and jit.os == "OSX" and jit.arch == "arm64" ++if M1 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_shdict_get_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_shdict_store_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_shdict_incr_t; ++]] ++end ++ ++ + if subsystem == 'http' then + ffi.cdef[[ + int ngx_http_lua_ffi_shdict_get(void *zone, const unsigned char *key, +@@ -72,6 +122,18 @@ size_t ngx_http_lua_ffi_shdict_capacity(void *zone); + void *ngx_http_lua_ffi_shdict_udata_to_zone(void *zone_udata); + ]] + ++ if M1 then ++ ffi.cdef [[ ++int ngx_http_lua_ffi_shdict_get_m1(ngx_shdict_get_t *s); ++int ngx_http_lua_ffi_shdict_store_m1(ngx_shdict_store_t *s); ++int ngx_http_lua_ffi_shdict_incr_m1(ngx_shdict_incr_t *s); ++ ]] ++ ++ ngx_lua_ffi_shdict_get_m1 = C.ngx_http_lua_ffi_shdict_get_m1 ++ ngx_lua_ffi_shdict_store_m1 = C.ngx_http_lua_ffi_shdict_store_m1 ++ ngx_lua_ffi_shdict_incr_m1 = C.ngx_http_lua_ffi_shdict_incr_m1 ++ end ++ + 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 +@@ -126,6 +188,17 @@ size_t ngx_stream_lua_ffi_shdict_capacity(void *zone); + void *ngx_stream_lua_ffi_shdict_udata_to_zone(void *zone_udata); + ]] + ++ if M1 then ++ ffi.cdef [[ ++int ngx_stream_lua_ffi_shdict_get_m1(ngx_shdict_get_t *s); ++int ngx_stream_lua_ffi_shdict_store_m1(ngx_shdict_store_t *s); ++int ngx_stream_lua_ffi_shdict_incr_m1(ngx_shdict_incr_t *s); ++ ]] ++ ngx_lua_ffi_shdict_get_m1 = C.ngx_stream_lua_ffi_shdict_get_m1 ++ ngx_lua_ffi_shdict_store_m1 = C.ngx_stream_lua_ffi_shdict_store_m1 ++ ngx_lua_ffi_shdict_incr_m1 = C.ngx_stream_lua_ffi_shdict_incr_m1 ++ end ++ + 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 +@@ -245,6 +318,31 @@ local function shdict_store(zone, op, key, value, exptime, flags) + return nil, "bad value type" + end + ++ local rc ++ if M1 then ++ local q = ffi_new("ngx_shdict_store_t") ++ q.zone = zone ++ q.op = op ++ q.key = key ++ q.key_len = key_len ++ q.value_type = valtyp ++ q.str_value_buf = str_val_buf ++ q.str_value_len = str_val_len ++ q.num_value = num_val ++ q.exptime = exptime * 1000 ++ q.user_flags = flags ++ q.errmsg = errmsg ++ q.forcible = forcible ++ ++ local rc = ngx_lua_ffi_shdict_store_m1(q) ++ if rc == 0 then -- NGX_OK ++ return true, nil, forcible[0] == 1 ++ end ++ ++ -- NGX_DECLINED or NGX_ERROR ++ return false, ffi_str(errmsg[0]), forcible[0] == 1 ++ end ++ + local rc = ngx_lua_ffi_shdict_store(zone, op, key, key_len, + valtyp, str_val_buf, + str_val_len, num_val, +@@ -317,6 +415,30 @@ local function shdict_get(zone, key) + local value_len = get_size_ptr() + value_len[0] = size + ++ if M1 then ++ local q = ffi_new("ngx_shdict_get_t") ++ q.zone = zone ++ q.key = key ++ q.key_len = key_len ++ q.value_type = value_type ++ q.str_value_buf = str_value_buf ++ q.str_value_len = value_len ++ q.num_value = num_value ++ q.user_flags = user_flags ++ q.get_stale = 0 ++ q.is_stale = is_stale ++ q.errmsg = errmsg ++ ++ local rc = ngx_lua_ffi_shdict_get_m1(q) ++ if rc ~= 0 then ++ if errmsg[0] ~= nil then ++ return nil, ffi_str(errmsg[0]) ++ end ++ ++ error("failed to get the key") ++ end ++ else ++ + local rc = ngx_lua_ffi_shdict_get(zone, key, key_len, value_type, + str_value_buf, value_len, + num_value, user_flags, 0, +@@ -329,6 +451,8 @@ local function shdict_get(zone, key) + error("failed to get the key") + end + ++ end ++ + local typ = value_type[0] + + if typ == 0 then -- LUA_TNIL +@@ -392,6 +516,30 @@ local function shdict_get_stale(zone, key) + local value_len = get_size_ptr() + value_len[0] = size + ++ if M1 then ++ local q = ffi_new("ngx_shdict_get_t") ++ q.zone = zone ++ q.key = key ++ q.key_len = key_len ++ q.value_type = value_type ++ q.str_value_buf = str_value_buf ++ q.str_value_len = value_len ++ q.num_value = num_value ++ q.user_flags = user_flags ++ q.get_stale = 1 ++ q.is_stale = is_stale ++ q.errmsg = errmsg ++ ++ local rc = ngx_lua_ffi_shdict_get_m1(q) ++ if rc ~= 0 then ++ if errmsg[0] ~= nil then ++ return nil, ffi_str(errmsg[0]) ++ end ++ ++ error("failed to get the key") ++ end ++ else ++ + local rc = ngx_lua_ffi_shdict_get(zone, key, key_len, value_type, + str_value_buf, value_len, + num_value, user_flags, 1, +@@ -404,6 +552,8 @@ local function shdict_get_stale(zone, key) + error("failed to get the key") + end + ++ end ++ + local typ = value_type[0] + + if typ == 0 then -- LUA_TNIL +@@ -498,6 +648,28 @@ local function shdict_incr(zone, key, value, init, init_ttl) + init_ttl = 0 + end + ++ if M1 then ++ local q = ffi_new("ngx_shdict_incr_t") ++ q.zone = zone ++ q.key = key ++ q.key_len = key_len ++ q.num_value = num_value ++ q.errmsg = errmsg ++ if init then ++ q.has_init = 1 ++ q.init = init ++ else ++ q.has_init = 0 ++ end ++ q.init_ttl = init_ttl * 1000 ++ q.forcible = forcible ++ ++ local rc = ngx_lua_ffi_shdict_incr_m1(q) ++ if rc ~= 0 then -- ~= NGX_OK ++ return nil, ffi_str(errmsg[0]) ++ end ++ else ++ + local rc = ngx_lua_ffi_shdict_incr(zone, key, key_len, num_value, + errmsg, init and 1 or 0, + init or 0, init_ttl * 1000, +@@ -506,6 +678,8 @@ local function shdict_incr(zone, key, value, init, init_ttl) + return nil, ffi_str(errmsg[0]) + end + ++ end ++ + if not init then + return tonumber(num_value[0]) + end +-- +2.34.1 diff --git a/patches/lua-resty-core-0.1.23_04-make-resty.core.response-compatible-with-m1.patch b/patches/lua-resty-core-0.1.23_04-make-resty.core.response-compatible-with-m1.patch new file mode 100644 index 0000000..8829df7 --- /dev/null +++ b/patches/lua-resty-core-0.1.23_04-make-resty.core.response-compatible-with-m1.patch @@ -0,0 +1,100 @@ +From 94efefb9aaede738ec9e29e639cf5e934e9a1d5a Mon Sep 17 00:00:00 2001 +From: Aapo Talvensaari +Date: Thu, 16 Dec 2021 19:28:13 +0200 +Subject: [PATCH] fix(response) make resty.core.response compatible with m1 + (using kong wrappers) + +--- + lua-resty-core-0.1.23/lib/resty/core/response.lua | 58 +++++++++++++++++++++++++++++++++++++ + 1 file changed, 58 insertions(+) + +diff --git a/lua-resty-core-0.1.23/lib/resty/core/response.lua b/lua-resty-core-0.1.23/lib/resty/core/response.lua +index 891a07e..1efdf56 100644 +--- a/lua-resty-core-0.1.23/lib/resty/core/response.lua ++++ b/lua-resty-core-0.1.23/lib/resty/core/response.lua +@@ -45,6 +45,27 @@ ffi.cdef[[ + ]] + + ++local M1 = jit and jit.os == "OSX" and jit.arch == "arm64" ++if M1 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_set_resp_header_t; ++ ++ int ngx_http_lua_ffi_set_resp_header_m1(ngx_set_resp_header_t *s); ++]] ++end ++ ++ + local function set_resp_header(tb, key, value, no_override) + local r = get_request() + if not r then +@@ -61,6 +82,22 @@ local function set_resp_header(tb, key, value, no_override) + error("invalid header value", 3) + end + ++ if M1 then ++ local q = ffi.new("ngx_set_resp_header_t") ++ q.r = r ++ q.key_data = key ++ q.key_len = #key ++ q.is_nil = true ++ q.sval_len = 0 ++ q.mvals_len = 0 ++ q.override = 1 ++ q.errmsg = errmsg ++ ++ rc = C.ngx_http_lua_ffi_set_resp_header_m1(q) ++ ++ goto results ++ end ++ + rc = C.ngx_http_lua_ffi_set_resp_header(r, key, #key, true, nil, 0, nil, + 0, 1, errmsg) + else +@@ -99,11 +136,32 @@ local function set_resp_header(tb, key, value, no_override) + end + + local override_int = no_override and 0 or 1 ++ ++ if M1 then ++ local s = ffi.new("ngx_set_resp_header_t") ++ s.r = r ++ s.key_data = key ++ s.key_len = #key ++ s.is_nil = false ++ s.sval = sval ++ s.sval_len = sval_len ++ s.mvals = mvals ++ s.mvals_len = mvals_len ++ s.override = override_int ++ s.errmsg = errmsg ++ ++ rc = C.ngx_http_lua_ffi_set_resp_header_m1(s) ++ ++ goto results ++ end ++ + rc = C.ngx_http_lua_ffi_set_resp_header(r, key, #key, false, sval, + sval_len, mvals, mvals_len, + override_int, errmsg) + end + ++ ::results:: ++ + if rc == 0 or rc == FFI_DECLINED then + return + end +-- +2.34.1 diff --git a/patches/lua-resty-websocket-0.09_01-client-mtls.patch b/patches/lua-resty-websocket-0.09_01-client-mtls.patch new file mode 100644 index 0000000..02a2b6f --- /dev/null +++ b/patches/lua-resty-websocket-0.09_01-client-mtls.patch @@ -0,0 +1,91 @@ +From 05d0832cf96c216297810cb495706c50309b8c5a Mon Sep 17 00:00:00 2001 +From: James Hurst +Date: Mon, 7 Feb 2022 11:36:25 +0000 +Subject: [PATCH 1/2] feat: add mtls client cert support + +--- + lib/resty/websocket/client.lua | 26 ++++++++++++++++++++++---- + 1 file changed, 22 insertions(+), 4 deletions(-) + +diff --git a/lua-resty-websocket-0.09/lib/resty/websocket/client.lua b/lua-resty-websocket-0.09/lib/resty/websocket/client.lua +index 067b2a5..2ec96dd 100644 +--- a/lua-resty-websocket-0.09/lib/resty/websocket/client.lua ++++ b/lua-resty-websocket-0.09/lib/resty/websocket/client.lua +@@ -98,7 +98,8 @@ function _M.connect(self, uri, opts) + path = "/" + end + +- local ssl_verify, headers, proto_header, origin_header, sock_opts = false ++ local ssl_verify, server_name, headers, proto_header, origin_header, sock_opts = false ++ local client_cert, client_priv_key + + if opts then + local protos = opts.protocols +@@ -122,11 +123,20 @@ function _M.connect(self, uri, opts) + sock_opts = { pool = pool } + end + +- if opts.ssl_verify then ++ client_cert = opts.client_cert ++ client_priv_key = opts.client_priv_key ++ ++ if client_cert then ++ assert(client_priv_key, ++ "client_priv_key must be provided with client_cert") ++ end ++ ++ if opts.ssl_verify or opts.server_name then + if not ssl_support then + return nil, "ngx_lua 0.9.11+ required for SSL sockets" + end +- ssl_verify = true ++ ssl_verify = opts.ssl_verify ++ server_name = opts.server_name or host + end + + if opts.headers then +@@ -151,7 +161,15 @@ function _M.connect(self, uri, opts) + if not ssl_support then + return nil, "ngx_lua 0.9.11+ required for SSL sockets" + end +- ok, err = sock:sslhandshake(false, host, ssl_verify) ++ ++ if client_cert then ++ ok, err = sock:setclientcert(client_cert, client_priv_key) ++ if not ok then ++ return nil, "ssl client cert failued: " .. err ++ end ++ end ++ ++ ok, err = sock:sslhandshake(false, server_name, ssl_verify) + if not ok then + return nil, "ssl handshake failed: " .. err + end +-- +2.32.0 (Apple Git-132) + + +From fcf3370eef554cd4e1791ac92c43b420d25d66a1 Mon Sep 17 00:00:00 2001 +From: James Hurst +Date: Mon, 7 Feb 2022 15:20:48 +0000 +Subject: [PATCH 2/2] fix(client) fix typo in error message + +--- + lib/resty/websocket/client.lua | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lua-resty-websocket-0.09/lib/resty/websocket/client.lua b/lua-resty-websocket-0.09/lib/resty/websocket/client.lua +index 2ec96dd..598543f 100644 +--- a/lua-resty-websocket-0.09/lib/resty/websocket/client.lua ++++ b/lua-resty-websocket-0.09/lib/resty/websocket/client.lua +@@ -165,7 +165,7 @@ function _M.connect(self, uri, opts) + if client_cert then + ok, err = sock:setclientcert(client_cert, client_priv_key) + if not ok then +- return nil, "ssl client cert failued: " .. err ++ return nil, "ssl client cert failed: " .. err + end + end + +-- +2.32.0 (Apple Git-132) diff --git a/patches/nginx-1.21.4_01-upstream_client_certificate_and_ssl_verify.patch b/patches/nginx-1.21.4_01-upstream_client_certificate_and_ssl_verify.patch new file mode 100644 index 0000000..4e5d8b2 --- /dev/null +++ b/patches/nginx-1.21.4_01-upstream_client_certificate_and_ssl_verify.patch @@ -0,0 +1,52 @@ +diff --git a/nginx-1.21.4/src/http/ngx_http_upstream.c b/nginx-1.21.4/src/http/ngx_http_upstream.c +index 90710557..539a4db9 100644 +--- a/nginx-1.21.4/src/http/ngx_http_upstream.c ++++ b/nginx-1.21.4/src/http/ngx_http_upstream.c +@@ -8,6 +8,9 @@ + #include + #include + #include ++#if (NGX_HTTP_LUA_KONG) ++#include ++#endif + + + #if (NGX_HTTP_CACHE) +@@ -1698,7 +1698,14 @@ + return; + } + ++ ++#if (NGX_HTTP_LUA_KONG) ++ if (u->conf->ssl_server_name ++ || ngx_http_lua_kong_get_upstream_ssl_verify(r, u->conf->ssl_verify)) ++ { ++#else + if (u->conf->ssl_server_name || u->conf->ssl_verify) { ++#endif + if (ngx_http_upstream_ssl_name(r, u, c) != NGX_OK) { + ngx_http_upstream_finalize_request(r, u, + NGX_HTTP_INTERNAL_SERVER_ERROR); +@@ -1736,6 +1739,10 @@ ngx_http_upstream_ssl_init_connection(ngx_http_request_t *r, + } + } + ++#if (NGX_HTTP_LUA_KONG) ++ ngx_http_lua_kong_set_upstream_ssl(r, c); ++#endif ++ + r->connection->log->action = "SSL handshaking to upstream"; + + rc = ngx_ssl_handshake(c); +@@ -1785,7 +1785,11 @@ + + if (c->ssl->handshaked) { + ++#if (NGX_HTTP_LUA_KONG) ++ if (ngx_http_lua_kong_get_upstream_ssl_verify(r, u->conf->ssl_verify)) { ++#else + if (u->conf->ssl_verify) { ++#endif + rc = SSL_get_verify_result(c->ssl->connection); + + if (rc != X509_V_OK) { diff --git a/patches/nginx-1.21.4_02-remove-server-tokens-from-special-responses-output.patch b/patches/nginx-1.21.4_02-remove-server-tokens-from-special-responses-output.patch new file mode 100644 index 0000000..b3d41dd --- /dev/null +++ b/patches/nginx-1.21.4_02-remove-server-tokens-from-special-responses-output.patch @@ -0,0 +1,37 @@ +From 66f96c49ec4a222c4061e18aa8c3f8655b52327d Mon Sep 17 00:00:00 2001 +From: Aapo Talvensaari +Date: Fri, 16 Aug 2019 13:41:49 +0300 +Subject: [PATCH] remove server tokens from special responses output + +--- + nginx-1.21.4/src/http/ngx_http_special_response.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/nginx-1.21.4/src/http/ngx_http_special_response.c b/nginx-1.21.4/src/http/ngx_http_special_response.c +index 4b8bbf5..524cc7b 100644 +--- a/nginx-1.21.4/src/http/ngx_http_special_response.c ++++ b/nginx-1.21.4/src/http/ngx_http_special_response.c +@@ -19,21 +19,18 @@ static ngx_int_t ngx_http_send_refresh(ngx_http_request_t *r); + + + static u_char ngx_http_error_full_tail[] = +-"
" NGINX_VER "
" CRLF + "" CRLF + "" CRLF + ; + + + static u_char ngx_http_error_build_tail[] = +-"
" NGINX_VER_BUILD "
" CRLF + "" CRLF + "" CRLF + ; + + + static u_char ngx_http_error_tail[] = +-"
openresty
" CRLF + "" CRLF + "" CRLF + ; +-- +2.22.0 diff --git a/patches/nginx-1.21.4_03-stream_proxy_ssl_disable.patch b/patches/nginx-1.21.4_03-stream_proxy_ssl_disable.patch new file mode 100644 index 0000000..0d3daf3 --- /dev/null +++ b/patches/nginx-1.21.4_03-stream_proxy_ssl_disable.patch @@ -0,0 +1,33 @@ +diff --git a/nginx-1.21.4/src/stream/ngx_stream_proxy_module.c b/nginx-1.21.4/src/stream/ngx_stream_proxy_module.c +index 09493135..fc8f8479 100644 +--- a/nginx-1.21.4/src/stream/ngx_stream_proxy_module.c ++++ b/nginx-1.21.4/src/stream/ngx_stream_proxy_module.c +@@ -8,6 +8,9 @@ + #include + #include + #include ++#if (NGX_STREAM_LUA_KONG) ++#include ++#endif + + + typedef struct { +@@ -821,8 +824,18 @@ ngx_stream_proxy_init_upstream(ngx_stream_session_t *s) + + #if (NGX_STREAM_SSL) + ++#if (NGX_STREAM_LUA_KONG) ++ ++ if (pc->type == SOCK_STREAM && pscf->ssl ++ && !ngx_stream_lua_kong_get_proxy_ssl_disable(s)) ++ { ++ ++#else ++ + if (pc->type == SOCK_STREAM && pscf->ssl) { + ++#endif ++ + if (u->proxy_protocol) { + if (ngx_stream_proxy_send_proxy_protocol(s) != NGX_OK) { + return; diff --git a/patches/nginx-1.21.4_04-grpc_authority_override.patch b/patches/nginx-1.21.4_04-grpc_authority_override.patch new file mode 100644 index 0000000..1042513 --- /dev/null +++ b/patches/nginx-1.21.4_04-grpc_authority_override.patch @@ -0,0 +1,25 @@ +diff --git a/nginx-1.19.3/src/http/modules/ngx_http_grpc_module.c b/nginx-1.19.3/src/http/modules/ngx_http_grpc_module.c +index d4af66db..10d3aaed 100644 +--- a/nginx-1.21.4/src/http/modules/ngx_http_grpc_module.c ++++ b/nginx-1.21.4/src/http/modules/ngx_http_grpc_module.c +@@ -8,6 +8,9 @@ + #include + #include + #include ++#if (NGX_HTTP_LUA_KONG) ++#include ++#endif + + + typedef struct { +@@ -731,6 +734,10 @@ ngx_http_grpc_create_request(ngx_http_request_t *r) + len = sizeof(ngx_http_grpc_connection_start) - 1 + + sizeof(ngx_http_grpc_frame_t); /* headers frame */ + ++#if (NGX_HTTP_LUA_KONG) ++ ngx_http_lua_kong_set_grpc_authority(r, &ctx->host); ++#endif ++ + /* :method header */ + + if (r->method == NGX_HTTP_GET || r->method == NGX_HTTP_POST) { diff --git a/patches/nginx-1.21.4_05-remove-server-headers-from-ngx-header-filter-module.patch b/patches/nginx-1.21.4_05-remove-server-headers-from-ngx-header-filter-module.patch new file mode 100644 index 0000000..8db66d6 --- /dev/null +++ b/patches/nginx-1.21.4_05-remove-server-headers-from-ngx-header-filter-module.patch @@ -0,0 +1,70 @@ +From 42a44843445e9db12a8fc5eaf1f3e10b22a0065b Mon Sep 17 00:00:00 2001 +From: Aapo Talvensaari +Date: Tue, 15 Jun 2021 16:04:06 +0300 +Subject: [PATCH] remove server headers from nginx header filter module + +--- + nginx-1.21.4/src/http/ngx_http_header_filter_module.c | 34 ------------------- + 1 file changed, 34 deletions(-) + +diff --git a/nginx-1.21.4/src/http/ngx_http_header_filter_module.c b/nginx-1.21.4/src/http/ngx_http_header_filter_module.c +index ca13f2a..1a07dac 100644 +--- a/nginx-1.21.4/src/http/ngx_http_header_filter_module.c ++++ b/nginx-1.21.4/src/http/ngx_http_header_filter_module.c +@@ -46,11 +46,6 @@ ngx_module_t ngx_http_header_filter_module = { + }; + + +-static u_char ngx_http_server_string[] = "Server: openresty" CRLF; +-static u_char ngx_http_server_full_string[] = "Server: " NGINX_VER CRLF; +-static u_char ngx_http_server_build_string[] = "Server: " NGINX_VER_BUILD CRLF; +- +- + static ngx_str_t ngx_http_status_lines[] = { + + ngx_string("200 OK"), +@@ -279,18 +274,6 @@ ngx_http_header_filter(ngx_http_request_t *r) + + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + +- if (r->headers_out.server == NULL) { +- if (clcf->server_tokens == NGX_HTTP_SERVER_TOKENS_ON) { +- len += sizeof(ngx_http_server_full_string) - 1; +- +- } else if (clcf->server_tokens == NGX_HTTP_SERVER_TOKENS_BUILD) { +- len += sizeof(ngx_http_server_build_string) - 1; +- +- } else { +- len += sizeof(ngx_http_server_string) - 1; +- } +- } +- + if (r->headers_out.date == NULL) { + len += sizeof("Date: Mon, 28 Sep 1970 06:00:00 GMT" CRLF) - 1; + } +@@ -448,23 +431,6 @@ ngx_http_header_filter(ngx_http_request_t *r) + } + *b->last++ = CR; *b->last++ = LF; + +- if (r->headers_out.server == NULL) { +- if (clcf->server_tokens == NGX_HTTP_SERVER_TOKENS_ON) { +- p = ngx_http_server_full_string; +- len = sizeof(ngx_http_server_full_string) - 1; +- +- } else if (clcf->server_tokens == NGX_HTTP_SERVER_TOKENS_BUILD) { +- p = ngx_http_server_build_string; +- len = sizeof(ngx_http_server_build_string) - 1; +- +- } else { +- p = ngx_http_server_string; +- len = sizeof(ngx_http_server_string) - 1; +- } +- +- b->last = ngx_cpymem(b->last, p, len); +- } +- + if (r->headers_out.date == NULL) { + b->last = ngx_cpymem(b->last, "Date: ", sizeof("Date: ") - 1); + b->last = ngx_cpymem(b->last, ngx_cached_http_time.data, +-- +2.31.1 diff --git a/patches/ngx_lua-0.10.21_01-cosocket-mtls.patch b/patches/ngx_lua-0.10.21_01-cosocket-mtls.patch new file mode 100644 index 0000000..a37d499 --- /dev/null +++ b/patches/ngx_lua-0.10.21_01-cosocket-mtls.patch @@ -0,0 +1,1432 @@ +From 287d58810c450f912a8d31a94a1c86ccc039c0e1 Mon Sep 17 00:00:00 2001 +From: Datong Sun +Date: Wed, 18 Sep 2019 16:39:05 -0700 +Subject: [PATCH 04/17] cosocket: add function `tcpsock:tlshandshake`, retired + the Lua C API based `tcpsock:sslhandshake` implementation. + +--- + src/ngx_http_lua_socket_tcp.c | 387 +++++++++++++++------------------- + src/ngx_http_lua_socket_tcp.h | 3 + + 2 files changed, 177 insertions(+), 213 deletions(-) + +diff --git a/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c b/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c +index 26467fdd..4ef22c11 100644 +--- a/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c ++++ b/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c +@@ -23,6 +23,9 @@ static int ngx_http_lua_socket_tcp(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_tls_handshake_handler(ngx_connection_t *c); ++static int ngx_http_lua_tls_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); + + +@@ -324,13 +321,6 @@ ngx_http_lua_inject_socket_tcp_api(ngx_log_t *log, lua_State *L) + 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 +394,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 + } + + +@@ -1559,64 +1536,69 @@ 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; +- 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] */ ++ if (ops & SOCKET_OP_CONNECT && u->conn_waiting) { ++ return "socket busy connecting"; ++ } + +- 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); ++ if (ops & SOCKET_OP_READ && u->read_waiting) { ++ return "socket busy reading"; + } + +- r = ngx_http_lua_get_req(L); +- if (r == NULL) { +- return luaL_error(L, "no request found"); ++ if (ops & SOCKET_OP_WRITE ++ && (u->write_waiting ++ || (u->raw_downstream ++ && (r->connection->buffered & NGX_HTTP_LOWLEVEL_BUFFERED)))) ++ { ++ return "socket busy writing"; + } + +- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, +- "lua tcp socket ssl handshake"); ++ return NULL; ++} + +- luaL_checktype(L, 1, LUA_TTABLE); ++int ++ngx_http_lua_ffi_socket_tcp_tlshandshake(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, const char **errmsg) ++{ ++ ngx_int_t rc; ++ ngx_connection_t *c; ++ ngx_http_lua_ctx_t *ctx; ++ ngx_http_lua_co_ctx_t *coctx; ++ const char *busy_rc; + +- lua_rawgeti(L, 1, SOCKET_CTX_INDEX); +- u = lua_touserdata(L, -1); ++ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, ++ "lua tcp socket tls handshake"); + + 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_rc = ngx_http_lua_socket_tcp_check_busy(r, u, SOCKET_OP_CONNECT ++ | SOCKET_OP_READ ++ | SOCKET_OP_WRITE); ++ if (busy_rc != NULL) { ++ *errmsg = busy_rc; ++ 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"; ++ return NGX_ERROR; + } + + c = u->peer.connection; +@@ -1624,122 +1606,96 @@ 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; ++ if (sess != NULL) { ++ return NGX_DONE; ++ } + +- case LUA_TBOOLEAN: +- if (!lua_toboolean(L, 2)) { +- /* avoid generating the ssl session */ +- lua_pushboolean(L, 1); +- break; +- } +- /* fall through */ ++ u->ssl_session_reuse = enable_session_reuse; + +- default: +- ngx_http_lua_ssl_handshake_retval_handler(r, u, L); +- break; +- } ++ (void) ngx_http_lua_tls_handshake_retval_handler(r, u, NULL); + +- return 1; ++ 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; + } + + ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); + if (ctx == NULL) { +- return luaL_error(L, "no ctx found"); ++ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, ++ "no ngx_lua ctx found while TLS handshaking"); ++ ++ ngx_http_lua_assert(NULL); ++ ++ *errmsg = "no ctx found"; ++ return NGX_ERROR; + } + + 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); +- +- } else { +- psession = lua_touserdata(L, 2); +- +- 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; +- } +- +- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, +- "lua ssl set session: %p", *psession); +- } ++ if (sess != NULL) { ++ if (ngx_ssl_set_session(c, sess) != NGX_OK) { ++ *errmsg = "lua tls set session failed"; ++ return NGX_ERROR; + } + +- if (n >= 3) { +- name.data = (u_char *) lua_tolstring(L, 3, &name.len); ++ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, ++ "lua tls set session: %p", sess); + +- if (name.data) { +- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, +- "lua ssl server name: \"%*s\"", name.len, +- name.data); ++ } else { ++ u->ssl_session_reuse = enable_session_reuse; ++ } + +-#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME ++ if (server_name != NULL && server_name->data != NULL) { ++ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, ++ "lua tls server name: \"%V\"", server_name); + +- 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; +- } ++#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 +- +- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, +- "lua socket SNI disabled because the current " +- "version of OpenSSL lacks the support"); +- ++ *errmsg = "OpenSSL has no SNI support"; ++ return NGX_ERROR; + #endif +- } ++ } + +- if (n >= 4) { +- u->ssl_verify = lua_toboolean(L, 4); ++ u->ssl_verify = verify; + +- if (n >= 5) { +- if (lua_toboolean(L, 5)) { ++ if (ocsp_status_req) { + #ifdef NGX_HTTP_LUA_USE_OCSP +- SSL_set_tlsext_status_type(c->ssl->connection, +- TLSEXT_STATUSTYPE_ocsp); ++ SSL_set_tlsext_status_type(c->ssl->connection, ++ TLSEXT_STATUSTYPE_ocsp); ++ + #else +- return luaL_error(L, "no OCSP support"); ++ *errmsg = "no OCSP support"; ++ return NGX_ERROR; + #endif +- } +- } +- } +- } + } + +- dd("found sni name: %.*s %p", (int) name.len, name.data, name.data); +- +- if (name.len == 0) { ++ if (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 +1706,16 @@ 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 +1729,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) { +@@ -1784,13 +1740,13 @@ new_ssl_name: + ngx_add_timer(c->read, u->connect_timeout); + + u->conn_waiting = 1; +- u->write_prepare_retvals = ngx_http_lua_ssl_handshake_retval_handler; ++ u->write_prepare_retvals = ngx_http_lua_tls_handshake_retval_handler; + + ngx_http_lua_cleanup_pending_operation(coctx); + coctx->cleanup = ngx_http_lua_coctx_cleanup; + coctx->data = u; + +- c->ssl->handler = ngx_http_lua_ssl_handshake_handler; ++ c->ssl->handler = ngx_http_lua_tls_handshake_handler; + + if (ctx->entered_content_phase) { + r->write_event_handler = ngx_http_lua_content_wev_handler; +@@ -1799,21 +1755,25 @@ new_ssl_name: + r->write_event_handler = ngx_http_core_run_phases; + } + +- return lua_yield(L, 0); ++ return NGX_AGAIN; ++ } ++ ++ ngx_http_lua_tls_handshake_handler(c); ++ ++ if (rc == NGX_ERROR) { ++ *errmsg = u->error_ret; ++ ++ return NGX_ERROR; + } + +- top = lua_gettop(L); +- ngx_http_lua_ssl_handshake_handler(c); +- return lua_gettop(L) - top; ++ return NGX_OK; + } + + + static void +-ngx_http_lua_ssl_handshake_handler(ngx_connection_t *c) ++ngx_http_lua_tls_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 +1796,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 +1807,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); ++ ngx_log_error(NGX_LOG_ERR, dc->log, 0, "lua tls " ++ "certificate verify error: (%d: %s)", ++ rc, u->error_ret); + } + + goto failed; +@@ -1872,12 +1829,11 @@ 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) { +- ngx_log_error(NGX_LOG_ERR, dc->log, 0, "lua ssl " ++ ngx_log_error(NGX_LOG_ERR, dc->log, 0, "lua tls " + "certificate does not match host \"%V\"", + &u->ssl_name); + } +@@ -1892,7 +1848,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_tls_handshake_retval_handler(r, u, NULL); + } + + if (waiting) { +@@ -1902,60 +1858,84 @@ 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_tlshandshake_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 TLS 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_tls_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); ++ "lua tls save session: %p", ssl_session); + } + +- return 1; ++ return 0; ++} ++ ++ ++void ++ngx_http_lua_ffi_tls_free_session(ngx_ssl_session_t *sess) ++{ ++ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, ++ "lua tls free session: %p", sess); ++ ++ ngx_ssl_free_session(sess); + } + ++ + #endif /* NGX_HTTP_SSL */ + + +@@ -2008,12 +1988,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) { +@@ -6101,27 +6083,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/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.h b/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.h +index a0a5a518..ee9411bc 100644 +--- a/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.h ++++ b/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.h +@@ -120,6 +120,9 @@ 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 + + unsigned ft_type:16; +-- +2.32.0 (Apple Git-132) + + +From f5ba21d6f742e6b169d972a81b6124b27c076016 Mon Sep 17 00:00:00 2001 +From: Datong Sun +Date: Wed, 18 Sep 2019 16:54:32 -0700 +Subject: [PATCH 05/17] change: better error when request context couldn't be + found. + +--- + src/ngx_http_lua_socket_tcp.c | 8 +------- + 1 file changed, 1 insertion(+), 7 deletions(-) + +diff --git a/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c b/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c +index 4ef22c11..abd487fa 100644 +--- a/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c ++++ b/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c +@@ -1627,13 +1627,7 @@ ngx_http_lua_ffi_socket_tcp_tlshandshake(ngx_http_request_t *r, + + ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); + if (ctx == NULL) { +- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, +- "no ngx_lua ctx found while TLS handshaking"); +- +- ngx_http_lua_assert(NULL); +- +- *errmsg = "no ctx found"; +- return NGX_ERROR; ++ return NGX_HTTP_LUA_FFI_NO_REQ_CTX; + } + + coctx = ctx->cur_co_ctx; +-- +2.32.0 (Apple Git-132) + + +From 78a450d571febf7ba918ecc13369144925d02bcb Mon Sep 17 00:00:00 2001 +From: Datong Sun +Date: Wed, 18 Sep 2019 17:24:07 -0700 +Subject: [PATCH 06/17] feature: TCP cosocket client certificate support. + closes #534 + +--- + src/ngx_http_lua_socket_tcp.c | 60 +++++++++++++++++++++++++++++++---- + 1 file changed, 54 insertions(+), 6 deletions(-) + +diff --git a/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c b/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c +index abd487fa..61671b70 100644 +--- a/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c ++++ b/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c +@@ -22,7 +22,6 @@ + static int ngx_http_lua_socket_tcp(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_tls_handshake_handler(ngx_connection_t *c); + static int ngx_http_lua_tls_handshake_retval_handler(ngx_http_request_t *r, + ngx_http_lua_socket_tcp_upstream_t *u, lua_State *L); +@@ -219,9 +218,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" +@@ -1563,13 +1559,16 @@ int + ngx_http_lua_ffi_socket_tcp_tlshandshake(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, const char **errmsg) ++ int ocsp_status_req, STACK_OF(X509) *chain, EVP_PKEY *pkey, ++ const char **errmsg) + { +- ngx_int_t rc; ++ ngx_int_t rc, i; + ngx_connection_t *c; + ngx_http_lua_ctx_t *ctx; + ngx_http_lua_co_ctx_t *coctx; + const char *busy_rc; ++ ngx_ssl_conn_t *ssl_conn; ++ X509 *x509; + + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "lua tcp socket tls handshake"); +@@ -1625,6 +1624,8 @@ ngx_http_lua_ffi_socket_tcp_tlshandshake(ngx_http_request_t *r, + return NGX_ERROR; + } + ++ ssl_conn = c->ssl->connection; ++ + ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); + if (ctx == NULL) { + return NGX_HTTP_LUA_FFI_NO_REQ_CTX; +@@ -1647,6 +1648,53 @@ ngx_http_lua_ffi_socket_tcp_tlshandshake(ngx_http_request_t *r, + u->ssl_session_reuse = enable_session_reuse; + } + ++ 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 = "lua tls fetch client certificate from chain failed"; ++ return NGX_ERROR; ++ } ++ ++ if (SSL_use_certificate(ssl_conn, x509) == 0) { ++ ERR_clear_error(); ++ *errmsg = "lua tls 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 = "lua tls fetch client intermediate certificate " ++ "from chain failed"; ++ return NGX_ERROR; ++ } ++ ++ if (SSL_add1_chain_cert(ssl_conn, x509) == 0) { ++ ERR_clear_error(); ++ *errmsg = "lua tls set client intermediate certificate failed"; ++ return NGX_ERROR; ++ } ++ } ++ ++ if (SSL_use_PrivateKey(ssl_conn, pkey) == 0) { ++ ERR_clear_error(); ++ *errmsg = "lua ssl set client private key failed"; ++ return NGX_ERROR; ++ } ++ } ++ + if (server_name != NULL && server_name->data != NULL) { + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "lua tls server name: \"%V\"", server_name); +-- +2.32.0 (Apple Git-132) + + +From 6cc0c89e946ef42adfbc55e8a461ccc2f367254a Mon Sep 17 00:00:00 2001 +From: Datong Sun +Date: Wed, 18 Sep 2019 17:25:20 -0700 +Subject: [PATCH 07/17] style: style fixes. + +--- + src/ngx_http_lua_socket_tcp.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c b/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c +index 61671b70..a7d410c9 100644 +--- a/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c ++++ b/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c +@@ -1736,7 +1736,8 @@ ngx_http_lua_ffi_socket_tcp_tlshandshake(ngx_http_request_t *r, + + if (u->ssl_name.len >= server_name->len) { + /* reuse it */ +- ngx_memcpy(u->ssl_name.data, server_name->data, server_name->len); ++ ngx_memcpy(u->ssl_name.data, server_name->data, ++ server_name->len); + u->ssl_name.len = server_name->len; + + } else { +-- +2.32.0 (Apple Git-132) + + +From 21cd7779252732a02fa0e596b66a1d4663d2fd64 Mon Sep 17 00:00:00 2001 +From: Thibault Charbonnier +Date: Mon, 6 Jan 2020 17:56:10 -0800 +Subject: [PATCH 08/17] cleanup + +--- + src/ngx_http_lua_socket_tcp.c | 24 +++++++++++------------- + 1 file changed, 11 insertions(+), 13 deletions(-) + +diff --git a/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c b/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c +index a7d410c9..bd7cc7ca 100644 +--- a/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c ++++ b/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c +@@ -1555,6 +1555,7 @@ ngx_http_lua_socket_tcp_check_busy(ngx_http_request_t *r, + return NULL; + } + ++ + int + ngx_http_lua_ffi_socket_tcp_tlshandshake(ngx_http_request_t *r, + ngx_http_lua_socket_tcp_upstream_t *u, ngx_ssl_session_t *sess, +@@ -1596,7 +1597,7 @@ ngx_http_lua_ffi_socket_tcp_tlshandshake(ngx_http_request_t *r, + } + + if (u->raw_downstream || u->body_downstream) { +- *errmsg = "not supported for downstream"; ++ *errmsg = "not supported for downstream sockets"; + return NGX_ERROR; + } + +@@ -1637,7 +1638,7 @@ ngx_http_lua_ffi_socket_tcp_tlshandshake(ngx_http_request_t *r, + + if (sess != NULL) { + if (ngx_ssl_set_session(c, sess) != NGX_OK) { +- *errmsg = "lua tls set session failed"; ++ *errmsg = "tls set session failed"; + return NGX_ERROR; + } + +@@ -1660,13 +1661,13 @@ ngx_http_lua_ffi_socket_tcp_tlshandshake(ngx_http_request_t *r, + x509 = sk_X509_value(chain, 0); + if (x509 == NULL) { + ERR_clear_error(); +- *errmsg = "lua tls fetch client certificate from chain failed"; ++ *errmsg = "tls fetch client certificate from chain failed"; + return NGX_ERROR; + } + + if (SSL_use_certificate(ssl_conn, x509) == 0) { + ERR_clear_error(); +- *errmsg = "lua tls set client certificate failed"; ++ *errmsg = "tls set client certificate failed"; + return NGX_ERROR; + } + +@@ -1676,21 +1677,21 @@ ngx_http_lua_ffi_socket_tcp_tlshandshake(ngx_http_request_t *r, + x509 = sk_X509_value(chain, i); + if (x509 == NULL) { + ERR_clear_error(); +- *errmsg = "lua tls fetch client intermediate certificate " +- "from chain failed"; ++ *errmsg = "tls fetch client intermediate certificate from " ++ "chain failed"; + return NGX_ERROR; + } + + if (SSL_add1_chain_cert(ssl_conn, x509) == 0) { + ERR_clear_error(); +- *errmsg = "lua tls set client intermediate certificate failed"; ++ *errmsg = "tls set client intermediate certificate failed"; + return NGX_ERROR; + } + } + + if (SSL_use_PrivateKey(ssl_conn, pkey) == 0) { + ERR_clear_error(); +- *errmsg = "lua ssl set client private key failed"; ++ *errmsg = "tls set client private key failed"; + return NGX_ERROR; + } + } +@@ -1709,7 +1710,7 @@ ngx_http_lua_ffi_socket_tcp_tlshandshake(ngx_http_request_t *r, + } + + #else +- *errmsg = "OpenSSL has no SNI support"; ++ *errmsg = "no TLS extension support"; + return NGX_ERROR; + #endif + } +@@ -1752,7 +1753,6 @@ new_ssl_name: + u->ssl_name.data = ngx_alloc(server_name->len, ngx_cycle->log); + if (u->ssl_name.data == NULL) { + u->ssl_name.len = 0; +- + *errmsg = "no memory"; + return NGX_ERROR; + } +@@ -1773,7 +1773,7 @@ new_ssl_name: + rc = ngx_ssl_handshake(c); + + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, +- "ngx_ssl_handshake returned %d", rc); ++ "ngx_ssl_handshake returned: %d", rc); + + if (rc == NGX_AGAIN) { + if (c->write->timer_set) { +@@ -1805,7 +1805,6 @@ new_ssl_name: + + if (rc == NGX_ERROR) { + *errmsg = u->error_ret; +- + return NGX_ERROR; + } + +@@ -1919,7 +1918,6 @@ failed: + } + + +- + int + ngx_http_lua_ffi_socket_tcp_get_tlshandshake_result(ngx_http_request_t *r, + ngx_http_lua_socket_tcp_upstream_t *u, ngx_ssl_session_t **sess, +-- +2.32.0 (Apple Git-132) + + +From 0bcf4d1a955db9218e8b0e50685c1d0de8c90b9a Mon Sep 17 00:00:00 2001 +From: Datong Sun +Date: Tue, 24 Nov 2020 01:49:28 -0800 +Subject: [PATCH 09/17] fixed style according to @spacewander's review + +--- + src/ngx_http_lua_socket_tcp.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c b/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c +index bd7cc7ca..1aa37627 100644 +--- a/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c ++++ b/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c +@@ -1536,15 +1536,15 @@ 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) + { +- if (ops & SOCKET_OP_CONNECT && u->conn_waiting) { ++ if ((ops & SOCKET_OP_CONNECT) && u->conn_waiting) { + return "socket busy connecting"; + } + +- if (ops & SOCKET_OP_READ && u->read_waiting) { ++ if ((ops & SOCKET_OP_READ) && u->read_waiting) { + return "socket busy reading"; + } + +- if (ops & SOCKET_OP_WRITE ++ if ((ops & SOCKET_OP_WRITE) + && (u->write_waiting + || (u->raw_downstream + && (r->connection->buffered & NGX_HTTP_LOWLEVEL_BUFFERED)))) +-- +2.32.0 (Apple Git-132) + + +From 9b010940f77bbd486c1192eed23af7c35baf4cdb Mon Sep 17 00:00:00 2001 +From: chronolaw +Date: Fri, 21 Jan 2022 13:42:06 +0800 +Subject: [PATCH 10/17] resize tcp_socket_metatable to 7 + +--- + src/ngx_http_lua_socket_tcp.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c b/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c +index 1aa37627..7cdc45c4 100644 +--- a/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c ++++ b/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c +@@ -160,6 +160,8 @@ enum { + SOCKET_CONNECT_TIMEOUT_INDEX = 2, + SOCKET_SEND_TIMEOUT_INDEX = 4, + SOCKET_READ_TIMEOUT_INDEX = 5, ++ SOCKET_CLIENT_CERT_INDEX = 6, ++ SOCKET_CLIENT_KEY_INDEX = 7, + }; + + +@@ -424,7 +426,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); +-- +2.32.0 (Apple Git-132) + + +From 36245613be1031b22b0e6b2eec398dac288fe9a5 Mon Sep 17 00:00:00 2001 +From: chronolaw +Date: Fri, 21 Jan 2022 14:12:13 +0800 +Subject: [PATCH 11/17] change errms tls to ssl + +--- + src/ngx_http_lua_socket_tcp.c | 24 ++++++++++++------------ + 1 file changed, 12 insertions(+), 12 deletions(-) + +diff --git a/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c b/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c +index 7cdc45c4..af986364 100644 +--- a/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c ++++ b/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c +@@ -1574,7 +1574,7 @@ ngx_http_lua_ffi_socket_tcp_tlshandshake(ngx_http_request_t *r, + X509 *x509; + + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, +- "lua tcp socket tls handshake"); ++ "lua tcp socket ssl handshake"); + + if (u == NULL + || u->peer.connection == NULL +@@ -1640,12 +1640,12 @@ ngx_http_lua_ffi_socket_tcp_tlshandshake(ngx_http_request_t *r, + + if (sess != NULL) { + if (ngx_ssl_set_session(c, sess) != NGX_OK) { +- *errmsg = "tls set session failed"; ++ *errmsg = "ssl set session failed"; + return NGX_ERROR; + } + + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, +- "lua tls set session: %p", sess); ++ "lua ssl set session: %p", sess); + + } else { + u->ssl_session_reuse = enable_session_reuse; +@@ -1663,13 +1663,13 @@ ngx_http_lua_ffi_socket_tcp_tlshandshake(ngx_http_request_t *r, + x509 = sk_X509_value(chain, 0); + if (x509 == NULL) { + ERR_clear_error(); +- *errmsg = "tls fetch client certificate from chain failed"; ++ *errmsg = "ssl fetch client certificate from chain failed"; + return NGX_ERROR; + } + + if (SSL_use_certificate(ssl_conn, x509) == 0) { + ERR_clear_error(); +- *errmsg = "tls set client certificate failed"; ++ *errmsg = "ssl set client certificate failed"; + return NGX_ERROR; + } + +@@ -1679,28 +1679,28 @@ ngx_http_lua_ffi_socket_tcp_tlshandshake(ngx_http_request_t *r, + x509 = sk_X509_value(chain, i); + if (x509 == NULL) { + ERR_clear_error(); +- *errmsg = "tls fetch client intermediate certificate from " ++ *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 = "tls set client intermediate certificate failed"; ++ *errmsg = "ssl set client intermediate certificate failed"; + return NGX_ERROR; + } + } + + if (SSL_use_PrivateKey(ssl_conn, pkey) == 0) { + ERR_clear_error(); +- *errmsg = "tls set client private key failed"; ++ *errmsg = "ssl set client private key failed"; + return NGX_ERROR; + } + } + + if (server_name != NULL && server_name->data != NULL) { + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, +- "lua tls server name: \"%V\"", server_name); ++ "lua ssl server name: \"%V\"", server_name); + + #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME + if (SSL_set_tlsext_host_name(c->ssl->connection, +@@ -1926,7 +1926,7 @@ ngx_http_lua_ffi_socket_tcp_get_tlshandshake_result(ngx_http_request_t *r, + const char **errmsg, int *openssl_error_code) + { + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, +- "lua cosocket get TLS handshake result for upstream: %p", u); ++ "lua cosocket get SSL handshake result for upstream: %p", u); + + if (u->error_ret != NULL) { + *errmsg = u->error_ret; +@@ -1962,7 +1962,7 @@ ngx_http_lua_tls_handshake_retval_handler(ngx_http_request_t *r, + u->ssl_session_ret = ssl_session; + + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, +- "lua tls save session: %p", ssl_session); ++ "lua ssl save session: %p", ssl_session); + } + + return 0; +@@ -1973,7 +1973,7 @@ void + ngx_http_lua_ffi_tls_free_session(ngx_ssl_session_t *sess) + { + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, +- "lua tls free session: %p", sess); ++ "lua ssl free session: %p", sess); + + ngx_ssl_free_session(sess); + } +-- +2.32.0 (Apple Git-132) + + +From 1f12b89485da6b7ac5dd23810bf094f214dc324e Mon Sep 17 00:00:00 2001 +From: chronolaw +Date: Fri, 21 Jan 2022 14:38:49 +0800 +Subject: [PATCH 12/17] rename function name from tls to ssl + +--- + src/ngx_http_lua_socket_tcp.c | 28 ++++++++++++++-------------- + 1 file changed, 14 insertions(+), 14 deletions(-) + +diff --git a/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c b/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c +index af986364..76e98597 100644 +--- a/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c ++++ b/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c +@@ -22,8 +22,8 @@ + static int ngx_http_lua_socket_tcp(lua_State *L); + static int ngx_http_lua_socket_tcp_connect(lua_State *L); + #if (NGX_HTTP_SSL) +-static void ngx_http_lua_tls_handshake_handler(ngx_connection_t *c); +-static int ngx_http_lua_tls_handshake_retval_handler(ngx_http_request_t *r, ++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); +@@ -1559,7 +1559,7 @@ ngx_http_lua_socket_tcp_check_busy(ngx_http_request_t *r, + + + int +-ngx_http_lua_ffi_socket_tcp_tlshandshake(ngx_http_request_t *r, ++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, +@@ -1614,7 +1614,7 @@ ngx_http_lua_ffi_socket_tcp_tlshandshake(ngx_http_request_t *r, + + u->ssl_session_reuse = enable_session_reuse; + +- (void) ngx_http_lua_tls_handshake_retval_handler(r, u, NULL); ++ (void) ngx_http_lua_ssl_handshake_retval_handler(r, u, NULL); + + return NGX_OK; + } +@@ -1785,13 +1785,13 @@ new_ssl_name: + ngx_add_timer(c->read, u->connect_timeout); + + u->conn_waiting = 1; +- u->write_prepare_retvals = ngx_http_lua_tls_handshake_retval_handler; ++ u->write_prepare_retvals = ngx_http_lua_ssl_handshake_retval_handler; + + ngx_http_lua_cleanup_pending_operation(coctx); + coctx->cleanup = ngx_http_lua_coctx_cleanup; + coctx->data = u; + +- c->ssl->handler = ngx_http_lua_tls_handshake_handler; ++ c->ssl->handler = ngx_http_lua_ssl_handshake_handler; + + if (ctx->entered_content_phase) { + r->write_event_handler = ngx_http_lua_content_wev_handler; +@@ -1803,7 +1803,7 @@ new_ssl_name: + return NGX_AGAIN; + } + +- ngx_http_lua_tls_handshake_handler(c); ++ ngx_http_lua_ssl_handshake_handler(c); + + if (rc == NGX_ERROR) { + *errmsg = u->error_ret; +@@ -1815,7 +1815,7 @@ new_ssl_name: + + + static void +-ngx_http_lua_tls_handshake_handler(ngx_connection_t *c) ++ngx_http_lua_ssl_handshake_handler(ngx_connection_t *c) + { + int waiting; + ngx_int_t rc; +@@ -1860,7 +1860,7 @@ ngx_http_lua_tls_handshake_handler(ngx_connection_t *c) + + 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 tls " ++ ngx_log_error(NGX_LOG_ERR, dc->log, 0, "lua ssl " + "certificate verify error: (%d: %s)", + rc, u->error_ret); + } +@@ -1877,7 +1877,7 @@ ngx_http_lua_tls_handshake_handler(ngx_connection_t *c) + + 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 tls " ++ ngx_log_error(NGX_LOG_ERR, dc->log, 0, "lua ssl " + "certificate does not match host \"%V\"", + &u->ssl_name); + } +@@ -1892,7 +1892,7 @@ ngx_http_lua_tls_handshake_handler(ngx_connection_t *c) + ngx_http_lua_socket_handle_conn_success(r, u); + + } else { +- (void) ngx_http_lua_tls_handshake_retval_handler(r, u, NULL); ++ (void) ngx_http_lua_ssl_handshake_retval_handler(r, u, NULL); + } + + if (waiting) { +@@ -1921,7 +1921,7 @@ failed: + + + int +-ngx_http_lua_ffi_socket_tcp_get_tlshandshake_result(ngx_http_request_t *r, ++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) + { +@@ -1942,7 +1942,7 @@ ngx_http_lua_ffi_socket_tcp_get_tlshandshake_result(ngx_http_request_t *r, + + + static int +-ngx_http_lua_tls_handshake_retval_handler(ngx_http_request_t *r, ++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; +@@ -1970,7 +1970,7 @@ ngx_http_lua_tls_handshake_retval_handler(ngx_http_request_t *r, + + + void +-ngx_http_lua_ffi_tls_free_session(ngx_ssl_session_t *sess) ++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); +-- +2.32.0 (Apple Git-132) + + +From 84242561aa54ffed3bfab433cfef6f7797e01a47 Mon Sep 17 00:00:00 2001 +From: chronolaw +Date: Fri, 21 Jan 2022 14:46:38 +0800 +Subject: [PATCH 13/17] rename to SOCKET_CLIENT_PRIV_INDEX + +--- + src/ngx_http_lua_socket_tcp.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c b/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c +index 76e98597..90da45fc 100644 +--- a/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c ++++ b/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c +@@ -160,8 +160,8 @@ enum { + SOCKET_CONNECT_TIMEOUT_INDEX = 2, + SOCKET_SEND_TIMEOUT_INDEX = 4, + SOCKET_READ_TIMEOUT_INDEX = 5, +- SOCKET_CLIENT_CERT_INDEX = 6, +- SOCKET_CLIENT_KEY_INDEX = 7, ++ SOCKET_CLIENT_CERT_INDEX = 6, ++ SOCKET_CLIENT_PRIV_INDEX = 7, + }; + + +-- +2.32.0 (Apple Git-132) + + +From 555166646c525167f9e1e5bb81b6cb100a4834f9 Mon Sep 17 00:00:00 2001 +From: chronolaw +Date: Fri, 21 Jan 2022 14:49:18 +0800 +Subject: [PATCH 14/17] rename to SOCKET_CLIENT_PKEY_INDEX + +--- + src/ngx_http_lua_socket_tcp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c b/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c +index 90da45fc..494486de 100644 +--- a/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c ++++ b/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c +@@ -161,7 +161,7 @@ enum { + SOCKET_SEND_TIMEOUT_INDEX = 4, + SOCKET_READ_TIMEOUT_INDEX = 5, + SOCKET_CLIENT_CERT_INDEX = 6, +- SOCKET_CLIENT_PRIV_INDEX = 7, ++ SOCKET_CLIENT_PKEY_INDEX = 7, + }; + + +-- +2.32.0 (Apple Git-132) + + +From e9b54c43c05b064b831fe67d0e0aaff45b2ec505 Mon Sep 17 00:00:00 2001 +From: chronolaw +Date: Fri, 21 Jan 2022 17:17:09 +0800 +Subject: [PATCH 15/17] need not to change tcp_socket_metatable + +--- + src/ngx_http_lua_socket_tcp.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c b/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c +index 494486de..152d8cbd 100644 +--- a/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c ++++ b/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c +@@ -160,8 +160,6 @@ 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, + }; + + +@@ -426,7 +424,7 @@ ngx_http_lua_socket_tcp(lua_State *L) + + ngx_http_lua_check_context(L, ctx, NGX_HTTP_LUA_CONTEXT_YIELDABLE); + +- lua_createtable(L, 7 /* narr */, 1 /* nrec */); ++ lua_createtable(L, 5 /* narr */, 1 /* nrec */); + lua_pushlightuserdata(L, ngx_http_lua_lightudata_mask( + tcp_socket_metatable_key)); + lua_rawget(L, LUA_REGISTRYINDEX); +-- +2.32.0 (Apple Git-132) + + +From 6c47356ddc327a8692260bd6f43ea67cf2787a73 Mon Sep 17 00:00:00 2001 +From: chronolaw +Date: Wed, 26 Jan 2022 19:55:29 +0800 +Subject: [PATCH 16/17] increase nrec to 3 in the socket object + +--- + src/ngx_http_lua_socket_tcp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c b/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c +index 152d8cbd..8d71f8b4 100644 +--- a/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c ++++ b/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c +@@ -424,7 +424,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, 5 /* narr */, 3 /* nrec */); + lua_pushlightuserdata(L, ngx_http_lua_lightudata_mask( + tcp_socket_metatable_key)); + lua_rawget(L, LUA_REGISTRYINDEX); +-- +2.32.0 (Apple Git-132) + + +From 1d538552c7629310d850d4360408ddb555afcbcc Mon Sep 17 00:00:00 2001 +From: chronolaw +Date: Sat, 29 Jan 2022 09:18:52 +0800 +Subject: [PATCH 17/17] change tcp_socket_metatable nrec to 15 + +--- + src/ngx_http_lua_socket_tcp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c b/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c +index 8d71f8b4..5dcdef0e 100644 +--- a/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c ++++ b/ngx_lua-0.10.21/src/ngx_http_lua_socket_tcp.c +@@ -312,7 +312,7 @@ 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 */, 15 /* nrec */); + + lua_pushcfunction(L, ngx_http_lua_socket_tcp_connect); + lua_setfield(L, -2, "connect"); +-- +2.32.0 (Apple Git-132) diff --git a/patches/ngx_lua-0.10.21_02-dyn_upstream_keepalive.patch b/patches/ngx_lua-0.10.21_02-dyn_upstream_keepalive.patch new file mode 100644 index 0000000..342bc8e --- /dev/null +++ b/patches/ngx_lua-0.10.21_02-dyn_upstream_keepalive.patch @@ -0,0 +1,1319 @@ +From 2d12ac3e4045258b7a174b0505d92f63c26d82fc Mon Sep 17 00:00:00 2001 +From: Thibault Charbonnier +Date: Tue, 17 Sep 2019 11:43:44 -0700 +Subject: [PATCH 1/3] feature: implemented keepalive pooling in + 'balancer_by_lua*'. + +--- + src/ngx_http_lua_balancer.c | 738 ++++++++++++++++++++++++++++++------ + src/ngx_http_lua_common.h | 4 + + src/ngx_http_lua_module.c | 3 + + 3 files changed, 629 insertions(+), 116 deletions(-) + +diff --git a/ngx_lua-0.10.21/src/ngx_http_lua_balancer.c b/ngx_lua-0.10.21/src/ngx_http_lua_balancer.c +index f71a3e00..0d403716 100644 +--- a/ngx_lua-0.10.21/src/ngx_http_lua_balancer.c ++++ b/ngx_lua-0.10.21/src/ngx_http_lua_balancer.c +@@ -16,46 +16,102 @@ + #include "ngx_http_lua_directive.h" + + ++typedef struct { ++ ngx_uint_t size; ++ ngx_uint_t connections; ++ ++ uint32_t crc32; ++ ++ lua_State *lua_vm; ++ ++ ngx_queue_t cache; ++ ngx_queue_t free; ++} ngx_http_lua_balancer_keepalive_pool_t; ++ ++ ++typedef struct { ++ ngx_queue_t queue; ++ ngx_connection_t *connection; ++ ++ ngx_http_lua_balancer_keepalive_pool_t *cpool; ++} ngx_http_lua_balancer_keepalive_item_t; ++ ++ + struct ngx_http_lua_balancer_peer_data_s { +- /* the round robin data must be first */ +- ngx_http_upstream_rr_peer_data_t rrp; ++ ngx_uint_t cpool_size; ++ ngx_uint_t keepalive_requests; ++ ngx_msec_t keepalive_timeout; ++ ++ ngx_uint_t more_tries; ++ ngx_uint_t total_tries; + +- ngx_http_lua_srv_conf_t *conf; +- ngx_http_request_t *request; ++ int last_peer_state; + +- ngx_uint_t more_tries; +- ngx_uint_t total_tries; ++ uint32_t cpool_crc32; + +- struct sockaddr *sockaddr; +- socklen_t socklen; ++ void *data; + +- ngx_str_t *host; +- in_port_t port; ++ ngx_event_get_peer_pt original_get_peer; ++ ngx_event_free_peer_pt original_free_peer; + +- int last_peer_state; ++#if (NGX_HTTP_SSL) ++ ngx_event_set_peer_session_pt original_set_session; ++ ngx_event_save_peer_session_pt original_save_session; ++#endif ++ ++ ngx_http_request_t *request; ++ ngx_http_lua_srv_conf_t *conf; ++ ngx_http_lua_balancer_keepalive_pool_t *cpool; ++ ++ ngx_str_t *host; ++ ++ struct sockaddr *sockaddr; ++ socklen_t socklen; ++ ++ unsigned keepalive:1; + + #if !(HAVE_NGX_UPSTREAM_TIMEOUT_FIELDS) +- unsigned cloned_upstream_conf; /* :1 */ ++ unsigned cloned_upstream_conf:1; + #endif + }; + + +-#if (NGX_HTTP_SSL) +-static ngx_int_t ngx_http_lua_balancer_set_session(ngx_peer_connection_t *pc, +- void *data); +-static void ngx_http_lua_balancer_save_session(ngx_peer_connection_t *pc, +- void *data); +-#endif ++static ngx_int_t ngx_http_lua_balancer_by_chunk(lua_State *L, ++ ngx_http_request_t *r); + static ngx_int_t ngx_http_lua_balancer_init(ngx_conf_t *cf, + ngx_http_upstream_srv_conf_t *us); + static ngx_int_t ngx_http_lua_balancer_init_peer(ngx_http_request_t *r, + ngx_http_upstream_srv_conf_t *us); + static ngx_int_t ngx_http_lua_balancer_get_peer(ngx_peer_connection_t *pc, + void *data); +-static ngx_int_t ngx_http_lua_balancer_by_chunk(lua_State *L, +- ngx_http_request_t *r); + static void ngx_http_lua_balancer_free_peer(ngx_peer_connection_t *pc, + void *data, ngx_uint_t state); ++static ngx_int_t ngx_http_lua_balancer_create_keepalive_pool(lua_State *L, ++ ngx_log_t *log, uint32_t cpool_crc32, ngx_uint_t cpool_size, ++ ngx_http_lua_balancer_keepalive_pool_t **cpool); ++static void ngx_http_lua_balancer_get_keepalive_pool(lua_State *L, ++ uint32_t cpool_crc32, ngx_http_lua_balancer_keepalive_pool_t **cpool); ++static void ngx_http_lua_balancer_free_keepalive_pool(ngx_log_t *log, ++ ngx_http_lua_balancer_keepalive_pool_t *cpool); ++static void ngx_http_lua_balancer_close(ngx_connection_t *c); ++static void ngx_http_lua_balancer_dummy_handler(ngx_event_t *ev); ++static void ngx_http_lua_balancer_close_handler(ngx_event_t *ev); ++#if (NGX_HTTP_SSL) ++static ngx_int_t ngx_http_lua_balancer_set_session(ngx_peer_connection_t *pc, ++ void *data); ++static void ngx_http_lua_balancer_save_session(ngx_peer_connection_t *pc, ++ void *data); ++#endif ++ ++ ++#define ngx_http_lua_balancer_keepalive_is_enabled(bp) \ ++ (bp->keepalive) ++ ++#define ngx_http_lua_balancer_peer_set(bp) \ ++ (bp->sockaddr && bp->socklen) ++ ++ ++static char ngx_http_lua_balancer_keepalive_pools_table_key; + + + ngx_int_t +@@ -102,6 +158,61 @@ ngx_http_lua_balancer_handler_inline(ngx_http_request_t *r, + } + + ++static ngx_int_t ++ngx_http_lua_balancer_by_chunk(lua_State *L, ngx_http_request_t *r) ++{ ++ u_char *err_msg; ++ size_t len; ++ ngx_int_t rc; ++ ++ /* init nginx context in Lua VM */ ++ ngx_http_lua_set_req(L, r); ++ ++#ifndef OPENRESTY_LUAJIT ++ ngx_http_lua_create_new_globals_table(L, 0 /* narr */, 1 /* nrec */); ++ ++ /* {{{ make new env inheriting main thread's globals table */ ++ lua_createtable(L, 0, 1 /* nrec */); /* the metatable for the new env */ ++ ngx_http_lua_get_globals_table(L); ++ lua_setfield(L, -2, "__index"); ++ lua_setmetatable(L, -2); /* setmetatable({}, {__index = _G}) */ ++ /* }}} */ ++ ++ lua_setfenv(L, -2); /* set new running env for the code closure */ ++#endif /* OPENRESTY_LUAJIT */ ++ ++ lua_pushcfunction(L, ngx_http_lua_traceback); ++ lua_insert(L, 1); /* put it under chunk and args */ ++ ++ /* protected call user code */ ++ rc = lua_pcall(L, 0, 1, 1); ++ ++ lua_remove(L, 1); /* remove traceback function */ ++ ++ dd("rc == %d", (int) rc); ++ ++ if (rc != 0) { ++ /* error occurred when running loaded code */ ++ err_msg = (u_char *) lua_tolstring(L, -1, &len); ++ ++ if (err_msg == NULL) { ++ err_msg = (u_char *) "unknown reason"; ++ len = sizeof("unknown reason") - 1; ++ } ++ ++ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, ++ "failed to run balancer_by_lua*: %*s", len, err_msg); ++ ++ lua_settop(L, 0); /* clear remaining elems on stack */ ++ ++ return NGX_ERROR; ++ } ++ ++ lua_settop(L, 0); /* clear remaining elems on stack */ ++ return rc; ++} ++ ++ + char * + ngx_http_lua_balancer_by_lua_block(ngx_conf_t *cf, ngx_command_t *cmd, + void *conf) +@@ -125,16 +236,16 @@ char * + ngx_http_lua_balancer_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, + void *conf) + { +- u_char *cache_key = NULL; +- u_char *name; +- ngx_str_t *value; +- ngx_http_lua_srv_conf_t *lscf = conf; +- ++ u_char *cache_key = NULL; ++ u_char *name; ++ ngx_str_t *value; + ngx_http_upstream_srv_conf_t *uscf; ++ ngx_http_lua_srv_conf_t *lscf = conf; + + dd("enter"); + +- /* must specify a content handler */ ++ /* content handler setup */ ++ + if (cmd->post == NULL) { + return NGX_CONF_ERROR; + } +@@ -178,11 +289,19 @@ ngx_http_lua_balancer_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, + + lscf->balancer.src_key = cache_key; + ++ /* balancer setup */ ++ + uscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_upstream_module); + + if (uscf->peer.init_upstream) { + ngx_conf_log_error(NGX_LOG_WARN, cf, 0, + "load balancing method redefined"); ++ ++ lscf->balancer.original_init_upstream = uscf->peer.init_upstream; ++ ++ } else { ++ lscf->balancer.original_init_upstream = ++ ngx_http_upstream_init_round_robin; + } + + uscf->peer.init_upstream = ngx_http_lua_balancer_init; +@@ -198,14 +317,18 @@ ngx_http_lua_balancer_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, + + + static ngx_int_t +-ngx_http_lua_balancer_init(ngx_conf_t *cf, +- ngx_http_upstream_srv_conf_t *us) ++ngx_http_lua_balancer_init(ngx_conf_t *cf, ngx_http_upstream_srv_conf_t *us) + { +- if (ngx_http_upstream_init_round_robin(cf, us) != NGX_OK) { ++ ngx_http_lua_srv_conf_t *lscf; ++ ++ lscf = ngx_http_conf_upstream_srv_conf(us, ngx_http_lua_module); ++ ++ if (lscf->balancer.original_init_upstream(cf, us) != NGX_OK) { + return NGX_ERROR; + } + +- /* this callback is called upon individual requests */ ++ lscf->balancer.original_init_peer = us->peer.init; ++ + us->peer.init = ngx_http_lua_balancer_init_peer; + + return NGX_OK; +@@ -216,33 +339,38 @@ static ngx_int_t + ngx_http_lua_balancer_init_peer(ngx_http_request_t *r, + ngx_http_upstream_srv_conf_t *us) + { +- ngx_http_lua_srv_conf_t *bcf; ++ ngx_http_lua_srv_conf_t *lscf; + ngx_http_lua_balancer_peer_data_t *bp; + +- bp = ngx_pcalloc(r->pool, sizeof(ngx_http_lua_balancer_peer_data_t)); +- if (bp == NULL) { ++ lscf = ngx_http_conf_upstream_srv_conf(us, ngx_http_lua_module); ++ ++ if (lscf->balancer.original_init_peer(r, us) != NGX_OK) { + return NGX_ERROR; + } + +- r->upstream->peer.data = &bp->rrp; +- +- if (ngx_http_upstream_init_round_robin_peer(r, us) != NGX_OK) { ++ bp = ngx_pcalloc(r->pool, sizeof(ngx_http_lua_balancer_peer_data_t)); ++ if (bp == NULL) { + return NGX_ERROR; + } + ++ bp->conf = lscf; ++ bp->request = r; ++ bp->data = r->upstream->peer.data; ++ bp->original_get_peer = r->upstream->peer.get; ++ bp->original_free_peer = r->upstream->peer.free; ++ ++ r->upstream->peer.data = bp; + r->upstream->peer.get = ngx_http_lua_balancer_get_peer; + r->upstream->peer.free = ngx_http_lua_balancer_free_peer; + + #if (NGX_HTTP_SSL) ++ bp->original_set_session = r->upstream->peer.set_session; ++ bp->original_save_session = r->upstream->peer.save_session; ++ + r->upstream->peer.set_session = ngx_http_lua_balancer_set_session; + r->upstream->peer.save_session = ngx_http_lua_balancer_save_session; + #endif + +- bcf = ngx_http_conf_upstream_srv_conf(us, ngx_http_lua_module); +- +- bp->conf = bcf; +- bp->request = r; +- + return NGX_OK; + } + +@@ -250,25 +378,26 @@ ngx_http_lua_balancer_init_peer(ngx_http_request_t *r, + static ngx_int_t + ngx_http_lua_balancer_get_peer(ngx_peer_connection_t *pc, void *data) + { +- lua_State *L; +- ngx_int_t rc; +- ngx_http_request_t *r; +- ngx_http_lua_ctx_t *ctx; +- ngx_http_lua_srv_conf_t *lscf; +- ngx_http_lua_main_conf_t *lmcf; +- ngx_http_lua_balancer_peer_data_t *bp = data; ++ lua_State *L; ++ ngx_int_t rc; ++ ngx_queue_t *q; ++ ngx_connection_t *c; ++ ngx_http_request_t *r; ++ ngx_http_lua_ctx_t *ctx; ++ ngx_http_lua_srv_conf_t *lscf; ++ ngx_http_lua_main_conf_t *lmcf; ++ ngx_http_lua_balancer_keepalive_item_t *item; ++ ngx_http_lua_balancer_peer_data_t *bp = data; + + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0, +- "lua balancer peer, tries: %ui", pc->tries); +- +- lscf = bp->conf; ++ "lua balancer: get peer, tries: %ui", pc->tries); + + r = bp->request; ++ lscf = bp->conf; + + ngx_http_lua_assert(lscf->balancer.handler && r); + + ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); +- + if (ctx == NULL) { + ctx = ngx_http_lua_create_ctx(r); + if (ctx == NULL) { +@@ -286,9 +415,15 @@ ngx_http_lua_balancer_get_peer(ngx_peer_connection_t *pc, void *data) + + ctx->context = NGX_HTTP_LUA_CONTEXT_BALANCER; + ++ bp->cpool = NULL; + bp->sockaddr = NULL; + bp->socklen = 0; + bp->more_tries = 0; ++ bp->cpool_crc32 = 0; ++ bp->cpool_size = 0; ++ bp->keepalive_requests = 0; ++ bp->keepalive_timeout = 0; ++ bp->keepalive = 0; + bp->total_tries++; + + lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module); +@@ -300,7 +435,6 @@ ngx_http_lua_balancer_get_peer(ngx_peer_connection_t *pc, void *data) + lmcf->balancer_peer_data = bp; + + rc = lscf->balancer.handler(r, lscf, L); +- + if (rc == NGX_ERROR) { + return NGX_ERROR; + } +@@ -322,105 +456,414 @@ ngx_http_lua_balancer_get_peer(ngx_peer_connection_t *pc, void *data) + } + } + +- if (bp->sockaddr && bp->socklen) { ++ if (ngx_http_lua_balancer_peer_set(bp)) { + pc->sockaddr = bp->sockaddr; + pc->socklen = bp->socklen; ++ pc->name = bp->host; + pc->cached = 0; + pc->connection = NULL; +- pc->name = bp->host; +- +- bp->rrp.peers->single = 0; + + if (bp->more_tries) { + r->upstream->peer.tries += bp->more_tries; + } + +- dd("tries: %d", (int) r->upstream->peer.tries); ++ if (ngx_http_lua_balancer_keepalive_is_enabled(bp)) { ++ ngx_http_lua_balancer_get_keepalive_pool(L, bp->cpool_crc32, ++ &bp->cpool); ++ ++ if (bp->cpool == NULL ++ && ngx_http_lua_balancer_create_keepalive_pool(L, pc->log, ++ bp->cpool_crc32, ++ bp->cpool_size, ++ &bp->cpool) ++ != NGX_OK) ++ { ++ return NGX_ERROR; ++ } ++ ++ ngx_http_lua_assert(bp->cpool); ++ ++ if (!ngx_queue_empty(&bp->cpool->cache)) { ++ q = ngx_queue_head(&bp->cpool->cache); ++ ++ item = ngx_queue_data(q, ngx_http_lua_balancer_keepalive_item_t, ++ queue); ++ c = item->connection; ++ ++ ngx_queue_remove(q); ++ ngx_queue_insert_head(&bp->cpool->free, q); ++ ++ c->idle = 0; ++ c->sent = 0; ++ c->log = pc->log; ++ c->read->log = pc->log; ++ c->write->log = pc->log; ++ c->pool->log = pc->log; ++ ++ if (c->read->timer_set) { ++ ngx_del_timer(c->read); ++ } ++ ++ pc->cached = 1; ++ pc->connection = c; ++ ++ ngx_log_debug3(NGX_LOG_DEBUG_HTTP, pc->log, 0, ++ "lua balancer: keepalive reusing connection %p, " ++ "requests: %ui, cpool: %p", ++ c, c->requests, bp->cpool); ++ ++ return NGX_DONE; ++ } ++ ++ bp->cpool->connections++; ++ ++ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0, ++ "lua balancer: keepalive no free connection, " ++ "cpool: %p", bp->cpool); ++ } + + return NGX_OK; + } + +- return ngx_http_upstream_get_round_robin_peer(pc, &bp->rrp); ++ return bp->original_get_peer(pc, bp->data); + } + + +-static ngx_int_t +-ngx_http_lua_balancer_by_chunk(lua_State *L, ngx_http_request_t *r) ++static void ++ngx_http_lua_balancer_free_peer(ngx_peer_connection_t *pc, void *data, ++ ngx_uint_t state) + { +- u_char *err_msg; +- size_t len; +- ngx_int_t rc; ++ ngx_queue_t *q; ++ ngx_connection_t *c; ++ ngx_http_upstream_t *u; ++ ngx_http_lua_balancer_keepalive_item_t *item; ++ ngx_http_lua_balancer_keepalive_pool_t *cpool; ++ ngx_http_lua_balancer_peer_data_t *bp = data; + +- /* init nginx context in Lua VM */ +- ngx_http_lua_set_req(L, r); ++ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0, ++ "lua balancer: free peer, tries: %ui", pc->tries); + +-#ifndef OPENRESTY_LUAJIT +- ngx_http_lua_create_new_globals_table(L, 0 /* narr */, 1 /* nrec */); ++ u = bp->request->upstream; ++ c = pc->connection; + +- /* {{{ make new env inheriting main thread's globals table */ +- lua_createtable(L, 0, 1 /* nrec */); /* the metatable for the new env */ +- ngx_http_lua_get_globals_table(L); +- lua_setfield(L, -2, "__index"); +- lua_setmetatable(L, -2); /* setmetatable({}, {__index = _G}) */ +- /* }}} */ ++ if (ngx_http_lua_balancer_peer_set(bp)) { ++ bp->last_peer_state = (int) state; + +- lua_setfenv(L, -2); /* set new running env for the code closure */ +-#endif /* OPENRESTY_LUAJIT */ ++ if (pc->tries) { ++ pc->tries--; ++ } + +- lua_pushcfunction(L, ngx_http_lua_traceback); +- lua_insert(L, 1); /* put it under chunk and args */ ++ if (ngx_http_lua_balancer_keepalive_is_enabled(bp)) { ++ cpool = bp->cpool; + +- /* protected call user code */ +- rc = lua_pcall(L, 0, 1, 1); ++ if (state & NGX_PEER_FAILED ++ || c == NULL ++ || c->read->eof ++ || c->read->error ++ || c->read->timedout ++ || c->write->error ++ || c->write->timedout) ++ { ++ goto invalid; ++ } + +- lua_remove(L, 1); /* remove traceback function */ ++ if (bp->keepalive_requests ++ && c->requests >= bp->keepalive_requests) ++ { ++ goto invalid; ++ } + +- dd("rc == %d", (int) rc); ++ if (!u->keepalive) { ++ goto invalid; ++ } + +- if (rc != 0) { +- /* error occurred when running loaded code */ +- err_msg = (u_char *) lua_tolstring(L, -1, &len); ++ if (!u->request_body_sent) { ++ goto invalid; ++ } + +- if (err_msg == NULL) { +- err_msg = (u_char *) "unknown reason"; +- len = sizeof("unknown reason") - 1; ++ if (ngx_terminate || ngx_exiting) { ++ goto invalid; ++ } ++ ++ if (ngx_handle_read_event(c->read, 0) != NGX_OK) { ++ goto invalid; ++ } ++ ++ if (ngx_queue_empty(&cpool->free)) { ++ q = ngx_queue_last(&cpool->cache); ++ ngx_queue_remove(q); ++ ++ item = ngx_queue_data(q, ngx_http_lua_balancer_keepalive_item_t, ++ queue); ++ ++ ngx_http_lua_balancer_close(item->connection); ++ ++ } else { ++ q = ngx_queue_head(&cpool->free); ++ ngx_queue_remove(q); ++ ++ item = ngx_queue_data(q, ngx_http_lua_balancer_keepalive_item_t, ++ queue); ++ } ++ ++ ngx_log_debug3(NGX_LOG_DEBUG_HTTP, pc->log, 0, ++ "lua balancer: keepalive saving connection %p, " ++ "cpool: %p, connections: %ui", ++ c, cpool, cpool->connections); ++ ++ ngx_queue_insert_head(&cpool->cache, q); ++ ++ item->connection = c; ++ ++ pc->connection = NULL; ++ ++ if (bp->keepalive_timeout) { ++ c->read->delayed = 0; ++ ngx_add_timer(c->read, bp->keepalive_timeout); ++ ++ } else if (c->read->timer_set) { ++ ngx_del_timer(c->read); ++ } ++ ++ if (c->write->timer_set) { ++ ngx_del_timer(c->write); ++ } ++ ++ c->write->handler = ngx_http_lua_balancer_dummy_handler; ++ c->read->handler = ngx_http_lua_balancer_close_handler; ++ ++ c->data = item; ++ c->idle = 1; ++ c->log = ngx_cycle->log; ++ c->read->log = ngx_cycle->log; ++ c->write->log = ngx_cycle->log; ++ c->pool->log = ngx_cycle->log; ++ ++ if (c->read->ready) { ++ ngx_http_lua_balancer_close_handler(c->read); ++ } ++ ++ return; ++ ++invalid: ++ ++ cpool->connections--; ++ ++ ngx_log_debug3(NGX_LOG_DEBUG_HTTP, pc->log, 0, ++ "lua balancer: keepalive not saving connection %p, " ++ "cpool: %p, connections: %ui", ++ c, cpool, cpool->connections); ++ ++ if (cpool->connections == 0) { ++ ngx_http_lua_balancer_free_keepalive_pool(pc->log, cpool); ++ } + } + +- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, +- "failed to run balancer_by_lua*: %*s", len, err_msg); ++ return; ++ } + +- lua_settop(L, 0); /* clear remaining elems on stack */ ++ bp->original_free_peer(pc, bp->data, state); ++} ++ ++ ++static ngx_int_t ++ngx_http_lua_balancer_create_keepalive_pool(lua_State *L, ngx_log_t *log, ++ uint32_t cpool_crc32, ngx_uint_t cpool_size, ++ ngx_http_lua_balancer_keepalive_pool_t **cpool) ++{ ++ size_t size; ++ ngx_uint_t i; ++ ngx_http_lua_balancer_keepalive_pool_t *upool; ++ ngx_http_lua_balancer_keepalive_item_t *items; ++ ++ /* get upstream connection pools table */ ++ lua_pushlightuserdata(L, ngx_http_lua_lightudata_mask( ++ balancer_keepalive_pools_table_key)); ++ lua_rawget(L, LUA_REGISTRYINDEX); /* pools? */ ++ ++ ngx_http_lua_assert(lua_istable(L, -1)); ++ ++ size = sizeof(ngx_http_lua_balancer_keepalive_pool_t) ++ + sizeof(ngx_http_lua_balancer_keepalive_item_t) * cpool_size; + ++ upool = lua_newuserdata(L, size); /* pools upool */ ++ if (upool == NULL) { + return NGX_ERROR; + } + +- lua_settop(L, 0); /* clear remaining elems on stack */ +- return rc; ++ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, log, 0, ++ "lua balancer: keepalive create pool, crc32: %ui, " ++ "size: %ui", cpool_crc32, cpool_size); ++ ++ upool->lua_vm = L; ++ upool->crc32 = cpool_crc32; ++ upool->size = cpool_size; ++ upool->connections = 0; ++ ++ ngx_queue_init(&upool->cache); ++ ngx_queue_init(&upool->free); ++ ++ lua_rawseti(L, -2, cpool_crc32); /* pools */ ++ lua_pop(L, 1); /* orig stack */ ++ ++ items = (ngx_http_lua_balancer_keepalive_item_t *) (&upool->free + 1); ++ ++ ngx_http_lua_assert((void *) items == ngx_align_ptr(items, NGX_ALIGNMENT)); ++ ++ for (i = 0; i < cpool_size; i++) { ++ ngx_queue_insert_head(&upool->free, &items[i].queue); ++ items[i].cpool = upool; ++ } ++ ++ *cpool = upool; ++ ++ return NGX_OK; + } + + + static void +-ngx_http_lua_balancer_free_peer(ngx_peer_connection_t *pc, void *data, +- ngx_uint_t state) ++ngx_http_lua_balancer_get_keepalive_pool(lua_State *L, uint32_t cpool_crc32, ++ ngx_http_lua_balancer_keepalive_pool_t **cpool) + { +- ngx_http_lua_balancer_peer_data_t *bp = data; ++ ngx_http_lua_balancer_keepalive_pool_t *upool; ++ ++ /* get upstream connection pools table */ ++ lua_pushlightuserdata(L, ngx_http_lua_lightudata_mask( ++ balancer_keepalive_pools_table_key)); ++ lua_rawget(L, LUA_REGISTRYINDEX); /* pools? */ ++ ++ if (lua_isnil(L, -1)) { ++ lua_pop(L, 1); /* orig stack */ ++ ++ /* create upstream connection pools table */ ++ lua_createtable(L, 0, 0); /* pools */ ++ lua_pushlightuserdata(L, ngx_http_lua_lightudata_mask( ++ balancer_keepalive_pools_table_key)); ++ lua_pushvalue(L, -2); /* pools pools_table_key pools */ ++ lua_rawset(L, LUA_REGISTRYINDEX); /* pools */ ++ } + +- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0, +- "lua balancer free peer, tries: %ui", pc->tries); ++ ngx_http_lua_assert(lua_istable(L, -1)); + +- if (bp->sockaddr && bp->socklen) { +- bp->last_peer_state = (int) state; ++ lua_rawgeti(L, -1, cpool_crc32); /* pools upool? */ ++ upool = lua_touserdata(L, -1); ++ lua_pop(L, 2); /* orig stack */ + +- if (pc->tries) { +- pc->tries--; ++ *cpool = upool; ++} ++ ++ ++static void ++ngx_http_lua_balancer_free_keepalive_pool(ngx_log_t *log, ++ ngx_http_lua_balancer_keepalive_pool_t *cpool) ++{ ++ lua_State *L; ++ ++ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, log, 0, ++ "lua balancer: keepalive free pool %p, crc32: %ui", ++ cpool, cpool->crc32); ++ ++ ngx_http_lua_assert(cpool->connections == 0); ++ ++ L = cpool->lua_vm; ++ ++ /* get upstream connection pools table */ ++ lua_pushlightuserdata(L, ngx_http_lua_lightudata_mask( ++ balancer_keepalive_pools_table_key)); ++ lua_rawget(L, LUA_REGISTRYINDEX); /* pools? */ ++ ++ if (lua_isnil(L, -1)) { ++ lua_pop(L, 1); /* orig stack */ ++ return; ++ } ++ ++ ngx_http_lua_assert(lua_istable(L, -1)); ++ ++ lua_pushnil(L); /* pools nil */ ++ lua_rawseti(L, -2, cpool->crc32); /* pools */ ++ lua_pop(L, 1); /* orig stack */ ++} ++ ++ ++static void ++ngx_http_lua_balancer_close(ngx_connection_t *c) ++{ ++ ngx_http_lua_balancer_keepalive_item_t *item; ++ ++ item = c->data; ++ ++#if (NGX_HTTP_SSL) ++ if (c->ssl) { ++ c->ssl->no_wait_shutdown = 1; ++ c->ssl->no_send_shutdown = 1; ++ ++ if (ngx_ssl_shutdown(c) == NGX_AGAIN) { ++ c->ssl->handler = ngx_http_lua_balancer_close; ++ return; ++ } ++ } ++#endif ++ ++ ngx_destroy_pool(c->pool); ++ ngx_close_connection(c); ++ ++ item->cpool->connections--; ++ ++ ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0, ++ "lua balancer: keepalive closing connection %p, cpool: %p, " ++ "connections: %ui", ++ c, item->cpool, item->cpool->connections); ++} ++ ++ ++static void ++ngx_http_lua_balancer_dummy_handler(ngx_event_t *ev) ++{ ++ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ev->log, 0, ++ "lua balancer: dummy handler"); ++} ++ ++ ++static void ++ngx_http_lua_balancer_close_handler(ngx_event_t *ev) ++{ ++ ngx_http_lua_balancer_keepalive_item_t *item; ++ ++ int n; ++ char buf[1]; ++ ngx_connection_t *c; ++ ++ c = ev->data; ++ ++ if (c->close || c->read->timedout) { ++ goto close; ++ } ++ ++ n = recv(c->fd, buf, 1, MSG_PEEK); ++ ++ if (n == -1 && ngx_socket_errno == NGX_EAGAIN) { ++ ev->ready = 0; ++ ++ if (ngx_handle_read_event(c->read, 0) != NGX_OK) { ++ goto close; + } + + return; + } + +- /* fallback */ ++close: ++ ++ item = c->data; ++ c->log = ev->log; ++ ++ ngx_http_lua_balancer_close(c); + +- ngx_http_upstream_free_round_robin_peer(pc, data, state); ++ ngx_queue_remove(&item->queue); ++ ngx_queue_insert_head(&item->cpool->free, &item->queue); ++ ++ if (item->cpool->connections == 0) { ++ ngx_http_lua_balancer_free_keepalive_pool(ev->log, item->cpool); ++ } + } + + +@@ -431,12 +874,12 @@ ngx_http_lua_balancer_set_session(ngx_peer_connection_t *pc, void *data) + { + ngx_http_lua_balancer_peer_data_t *bp = data; + +- if (bp->sockaddr && bp->socklen) { ++ if (ngx_http_lua_balancer_peer_set(bp)) { + /* TODO */ + return NGX_OK; + } + +- return ngx_http_upstream_set_round_robin_peer_session(pc, &bp->rrp); ++ return bp->original_set_session(pc, bp->data); + } + + +@@ -445,13 +888,12 @@ ngx_http_lua_balancer_save_session(ngx_peer_connection_t *pc, void *data) + { + ngx_http_lua_balancer_peer_data_t *bp = data; + +- if (bp->sockaddr && bp->socklen) { ++ if (ngx_http_lua_balancer_peer_set(bp)) { + /* TODO */ + return; + } + +- ngx_http_upstream_save_round_robin_peer_session(pc, &bp->rrp); +- return; ++ bp->original_save_session(pc, bp->data); + } + + #endif +@@ -459,14 +901,14 @@ ngx_http_lua_balancer_save_session(ngx_peer_connection_t *pc, void *data) + + int + ngx_http_lua_ffi_balancer_set_current_peer(ngx_http_request_t *r, +- const u_char *addr, size_t addr_len, int port, char **err) ++ const u_char *addr, size_t addr_len, int port, unsigned int cpool_crc32, ++ unsigned int cpool_size, char **err) + { +- ngx_url_t url; +- ngx_http_lua_ctx_t *ctx; +- ngx_http_upstream_t *u; +- +- ngx_http_lua_main_conf_t *lmcf; +- ngx_http_lua_balancer_peer_data_t *bp; ++ ngx_url_t url; ++ ngx_http_upstream_t *u; ++ ngx_http_lua_ctx_t *ctx; ++ ngx_http_lua_main_conf_t *lmcf; ++ ngx_http_lua_balancer_peer_data_t *bp; + + if (r == NULL) { + *err = "no request found"; +@@ -536,6 +978,70 @@ ngx_http_lua_ffi_balancer_set_current_peer(ngx_http_request_t *r, + return NGX_ERROR; + } + ++ bp->cpool_crc32 = (uint32_t) cpool_crc32; ++ bp->cpool_size = (ngx_uint_t) cpool_size; ++ ++ return NGX_OK; ++} ++ ++ ++int ++ngx_http_lua_ffi_balancer_enable_keepalive(ngx_http_request_t *r, ++ unsigned long timeout, unsigned int max_requests, char **err) ++{ ++ ngx_http_upstream_t *u; ++ ngx_http_lua_ctx_t *ctx; ++ ngx_http_lua_main_conf_t *lmcf; ++ ngx_http_lua_balancer_peer_data_t *bp; ++ ++ if (r == NULL) { ++ *err = "no request found"; ++ return NGX_ERROR; ++ } ++ ++ u = r->upstream; ++ ++ if (u == NULL) { ++ *err = "no upstream found"; ++ return NGX_ERROR; ++ } ++ ++ ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); ++ if (ctx == NULL) { ++ *err = "no ctx found"; ++ return NGX_ERROR; ++ } ++ ++ if ((ctx->context & NGX_HTTP_LUA_CONTEXT_BALANCER) == 0) { ++ *err = "API disabled in the current context"; ++ return NGX_ERROR; ++ } ++ ++ lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module); ++ ++ /* we cannot read r->upstream->peer.data here directly because ++ * it could be overridden by other modules like ++ * ngx_http_upstream_keepalive_module. ++ */ ++ bp = lmcf->balancer_peer_data; ++ if (bp == NULL) { ++ *err = "no upstream peer data found"; ++ return NGX_ERROR; ++ } ++ ++ if (!ngx_http_lua_balancer_peer_set(bp)) { ++ *err = "no current peer set"; ++ return NGX_ERROR; ++ } ++ ++ if (!bp->cpool_crc32) { ++ bp->cpool_crc32 = ngx_crc32_long(bp->host->data, bp->host->len); ++ } ++ ++ bp->keepalive_timeout = (ngx_msec_t) timeout; ++ bp->keepalive_requests = (ngx_uint_t) max_requests; ++ bp->keepalive = 1; ++ + return NGX_OK; + } + +diff --git a/ngx_lua-0.10.21/src/ngx_http_lua_common.h b/ngx_lua-0.10.21/src/ngx_http_lua_common.h +index 781a2454..9ce6836a 100644 +--- a/ngx_lua-0.10.21/src/ngx_http_lua_common.h ++++ b/ngx_lua-0.10.21/src/ngx_http_lua_common.h +@@ -328,6 +328,10 @@ union ngx_http_lua_srv_conf_u { + #endif + + struct { ++ ngx_http_upstream_init_pt original_init_upstream; ++ ngx_http_upstream_init_peer_pt original_init_peer; ++ uintptr_t data; ++ + ngx_http_lua_srv_conf_handler_pt handler; + ngx_str_t src; + u_char *src_key; +diff --git a/ngx_lua-0.10.21/src/ngx_http_lua_module.c b/ngx_lua-0.10.21/src/ngx_http_lua_module.c +index 9816d864..5d7cedfd 100644 +--- a/ngx_lua-0.10.21/src/ngx_http_lua_module.c ++++ b/ngx_lua-0.10.21/src/ngx_http_lua_module.c +@@ -1117,6 +1117,9 @@ ngx_http_lua_create_srv_conf(ngx_conf_t *cf) + * lscf->srv.ssl_session_fetch_src = { 0, NULL }; + * lscf->srv.ssl_session_fetch_src_key = NULL; + * ++ * lscf->balancer.original_init_upstream = NULL; ++ * lscf->balancer.original_init_peer = NULL; ++ * lscf->balancer.data = NULL; + * lscf->balancer.handler = NULL; + * lscf->balancer.src = { 0, NULL }; + * lscf->balancer.src_key = NULL; +-- +2.26.2 + + +From 4c5cb29a265b2f9524434322adf15d07deec6c7f Mon Sep 17 00:00:00 2001 +From: Thibault Charbonnier +Date: Tue, 17 Sep 2019 11:43:54 -0700 +Subject: [PATCH 2/3] feature: we now avoid the need for 'upstream' blocks to + define a stub 'server' directive when using 'balancer_by_lua*'. + +--- + src/ngx_http_lua_balancer.c | 42 +++++++++++++++++++++++++++++++++++-- + 1 file changed, 40 insertions(+), 2 deletions(-) + +diff --git a/ngx_lua-0.10.21/src/ngx_http_lua_balancer.c b/ngx_lua-0.10.21/src/ngx_http_lua_balancer.c +index 0d403716..5c862d22 100644 +--- a/ngx_lua-0.10.21/src/ngx_http_lua_balancer.c ++++ b/ngx_lua-0.10.21/src/ngx_http_lua_balancer.c +@@ -111,7 +111,8 @@ static void ngx_http_lua_balancer_save_session(ngx_peer_connection_t *pc, + (bp->sockaddr && bp->socklen) + + +-static char ngx_http_lua_balancer_keepalive_pools_table_key; ++static char ngx_http_lua_balancer_keepalive_pools_table_key; ++static struct sockaddr *ngx_http_lua_balancer_default_server_sockaddr; + + + ngx_int_t +@@ -239,7 +240,9 @@ ngx_http_lua_balancer_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, + u_char *cache_key = NULL; + u_char *name; + ngx_str_t *value; ++ ngx_url_t url; + ngx_http_upstream_srv_conf_t *uscf; ++ ngx_http_upstream_server_t *us; + ngx_http_lua_srv_conf_t *lscf = conf; + + dd("enter"); +@@ -293,6 +296,29 @@ ngx_http_lua_balancer_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, + + uscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_upstream_module); + ++ if (uscf->servers->nelts == 0) { ++ us = ngx_array_push(uscf->servers); ++ if (us == NULL) { ++ return NGX_CONF_ERROR; ++ } ++ ++ ngx_memzero(us, sizeof(ngx_http_upstream_server_t)); ++ ngx_memzero(&url, sizeof(ngx_url_t)); ++ ++ ngx_str_set(&url.url, "0.0.0.1"); ++ url.default_port = 80; ++ ++ if (ngx_parse_url(cf->pool, &url) != NGX_OK) { ++ return NGX_CONF_ERROR; ++ } ++ ++ us->name = url.url; ++ us->addrs = url.addrs; ++ us->naddrs = url.naddrs; ++ ++ ngx_http_lua_balancer_default_server_sockaddr = us->addrs[0].sockaddr; ++ } ++ + if (uscf->peer.init_upstream) { + ngx_conf_log_error(NGX_LOG_WARN, cf, 0, + "load balancing method redefined"); +@@ -525,7 +551,19 @@ ngx_http_lua_balancer_get_peer(ngx_peer_connection_t *pc, void *data) + return NGX_OK; + } + +- return bp->original_get_peer(pc, bp->data); ++ rc = bp->original_get_peer(pc, bp->data); ++ if (rc == NGX_ERROR) { ++ return rc; ++ } ++ ++ if (pc->sockaddr == ngx_http_lua_balancer_default_server_sockaddr) { ++ ngx_log_error(NGX_LOG_ERR, pc->log, 0, ++ "lua balancer: no peer set"); ++ ++ return NGX_ERROR; ++ } ++ ++ return rc; + } + + +-- +2.26.2 + + +From 941cd893573561574bc6a326d6306f1a30127293 Mon Sep 17 00:00:00 2001 +From: Thibault Charbonnier +Date: Tue, 17 Sep 2019 11:43:58 -0700 +Subject: [PATCH 3/3] refactor: used a simpler way to stash the balancer peer + data. + +--- + src/ngx_http_lua_balancer.c | 91 +++++++++---------------------------- + src/ngx_http_lua_common.h | 7 --- + 2 files changed, 22 insertions(+), 76 deletions(-) + +diff --git a/ngx_lua-0.10.21/src/ngx_http_lua_balancer.c b/ngx_lua-0.10.21/src/ngx_http_lua_balancer.c +index 5c862d22..3ea1f067 100644 +--- a/ngx_lua-0.10.21/src/ngx_http_lua_balancer.c ++++ b/ngx_lua-0.10.21/src/ngx_http_lua_balancer.c +@@ -411,9 +411,9 @@ ngx_http_lua_balancer_get_peer(ngx_peer_connection_t *pc, void *data) + ngx_http_request_t *r; + ngx_http_lua_ctx_t *ctx; + ngx_http_lua_srv_conf_t *lscf; +- ngx_http_lua_main_conf_t *lmcf; + ngx_http_lua_balancer_keepalive_item_t *item; + ngx_http_lua_balancer_peer_data_t *bp = data; ++ void *pdata; + + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0, + "lua balancer: get peer, tries: %ui", pc->tries); +@@ -452,15 +452,13 @@ ngx_http_lua_balancer_get_peer(ngx_peer_connection_t *pc, void *data) + bp->keepalive = 0; + bp->total_tries++; + +- lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module); +- +- /* balancer_by_lua does not support yielding and +- * there cannot be any conflicts among concurrent requests, +- * thus it is safe to store the peer data in the main conf. +- */ +- lmcf->balancer_peer_data = bp; ++ pdata = r->upstream->peer.data; ++ r->upstream->peer.data = bp; + + rc = lscf->balancer.handler(r, lscf, L); ++ ++ r->upstream->peer.data = pdata; ++ + if (rc == NGX_ERROR) { + return NGX_ERROR; + } +@@ -945,7 +943,6 @@ ngx_http_lua_ffi_balancer_set_current_peer(ngx_http_request_t *r, + ngx_url_t url; + ngx_http_upstream_t *u; + ngx_http_lua_ctx_t *ctx; +- ngx_http_lua_main_conf_t *lmcf; + ngx_http_lua_balancer_peer_data_t *bp; + + if (r == NULL) { +@@ -971,18 +968,6 @@ ngx_http_lua_ffi_balancer_set_current_peer(ngx_http_request_t *r, + return NGX_ERROR; + } + +- lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module); +- +- /* we cannot read r->upstream->peer.data here directly because +- * it could be overridden by other modules like +- * ngx_http_upstream_keepalive_module. +- */ +- bp = lmcf->balancer_peer_data; +- if (bp == NULL) { +- *err = "no upstream peer data found"; +- return NGX_ERROR; +- } +- + ngx_memzero(&url, sizeof(ngx_url_t)); + + url.url.data = ngx_palloc(r->pool, addr_len); +@@ -1006,6 +991,8 @@ ngx_http_lua_ffi_balancer_set_current_peer(ngx_http_request_t *r, + return NGX_ERROR; + } + ++ bp = (ngx_http_lua_balancer_peer_data_t *) u->peer.data; ++ + if (url.addrs && url.addrs[0].sockaddr) { + bp->sockaddr = url.addrs[0].sockaddr; + bp->socklen = url.addrs[0].socklen; +@@ -1029,7 +1016,6 @@ ngx_http_lua_ffi_balancer_enable_keepalive(ngx_http_request_t *r, + { + ngx_http_upstream_t *u; + ngx_http_lua_ctx_t *ctx; +- ngx_http_lua_main_conf_t *lmcf; + ngx_http_lua_balancer_peer_data_t *bp; + + if (r == NULL) { +@@ -1055,17 +1041,7 @@ ngx_http_lua_ffi_balancer_enable_keepalive(ngx_http_request_t *r, + return NGX_ERROR; + } + +- lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module); +- +- /* we cannot read r->upstream->peer.data here directly because +- * it could be overridden by other modules like +- * ngx_http_upstream_keepalive_module. +- */ +- bp = lmcf->balancer_peer_data; +- if (bp == NULL) { +- *err = "no upstream peer data found"; +- return NGX_ERROR; +- } ++ bp = (ngx_http_lua_balancer_peer_data_t *) u->peer.data; + + if (!ngx_http_lua_balancer_peer_set(bp)) { + *err = "no current peer set"; +@@ -1089,14 +1065,13 @@ ngx_http_lua_ffi_balancer_set_timeouts(ngx_http_request_t *r, + long connect_timeout, long send_timeout, long read_timeout, + char **err) + { +- ngx_http_lua_ctx_t *ctx; +- ngx_http_upstream_t *u; ++ ngx_http_lua_ctx_t *ctx; ++ ngx_http_upstream_t *u; + + #if !(HAVE_NGX_UPSTREAM_TIMEOUT_FIELDS) + ngx_http_upstream_conf_t *ucf; +-#endif +- ngx_http_lua_main_conf_t *lmcf; + ngx_http_lua_balancer_peer_data_t *bp; ++#endif + + if (r == NULL) { + *err = "no request found"; +@@ -1121,15 +1096,9 @@ ngx_http_lua_ffi_balancer_set_timeouts(ngx_http_request_t *r, + return NGX_ERROR; + } + +- lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module); +- +- bp = lmcf->balancer_peer_data; +- if (bp == NULL) { +- *err = "no upstream peer data found"; +- return NGX_ERROR; +- } +- + #if !(HAVE_NGX_UPSTREAM_TIMEOUT_FIELDS) ++ bp = (ngx_http_lua_balancer_peer_data_t *) u->peer.data; ++ + if (!bp->cloned_upstream_conf) { + /* we clone the upstream conf for the current request so that + * we do not affect other requests at all. */ +@@ -1184,12 +1153,10 @@ ngx_http_lua_ffi_balancer_set_more_tries(ngx_http_request_t *r, + int count, char **err) + { + #if (nginx_version >= 1007005) +- ngx_uint_t max_tries, total; ++ ngx_uint_t max_tries, total; + #endif +- ngx_http_lua_ctx_t *ctx; +- ngx_http_upstream_t *u; +- +- ngx_http_lua_main_conf_t *lmcf; ++ ngx_http_lua_ctx_t *ctx; ++ ngx_http_upstream_t *u; + ngx_http_lua_balancer_peer_data_t *bp; + + if (r == NULL) { +@@ -1215,13 +1182,7 @@ ngx_http_lua_ffi_balancer_set_more_tries(ngx_http_request_t *r, + return NGX_ERROR; + } + +- lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module); +- +- bp = lmcf->balancer_peer_data; +- if (bp == NULL) { +- *err = "no upstream peer data found"; +- return NGX_ERROR; +- } ++ bp = (ngx_http_lua_balancer_peer_data_t *) u->peer.data; + + #if (nginx_version >= 1007005) + max_tries = r->upstream->conf->next_upstream_tries; +@@ -1247,12 +1208,10 @@ int + ngx_http_lua_ffi_balancer_get_last_failure(ngx_http_request_t *r, + int *status, char **err) + { +- ngx_http_lua_ctx_t *ctx; +- ngx_http_upstream_t *u; +- ngx_http_upstream_state_t *state; +- ++ ngx_http_lua_ctx_t *ctx; ++ ngx_http_upstream_t *u; ++ ngx_http_upstream_state_t *state; + ngx_http_lua_balancer_peer_data_t *bp; +- ngx_http_lua_main_conf_t *lmcf; + + if (r == NULL) { + *err = "no request found"; +@@ -1277,13 +1236,7 @@ ngx_http_lua_ffi_balancer_get_last_failure(ngx_http_request_t *r, + return NGX_ERROR; + } + +- lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module); +- +- bp = lmcf->balancer_peer_data; +- if (bp == NULL) { +- *err = "no upstream peer data found"; +- return NGX_ERROR; +- } ++ bp = (ngx_http_lua_balancer_peer_data_t *) u->peer.data; + + if (r->upstream_states && r->upstream_states->nelts > 1) { + state = r->upstream_states->elts; +diff --git a/ngx_lua-0.10.21/src/ngx_http_lua_common.h b/ngx_lua-0.10.21/src/ngx_http_lua_common.h +index 9ce6836a..9a4342df 100644 +--- a/ngx_lua-0.10.21/src/ngx_http_lua_common.h ++++ b/ngx_lua-0.10.21/src/ngx_http_lua_common.h +@@ -240,13 +240,6 @@ struct ngx_http_lua_main_conf_s { + ngx_http_lua_main_conf_handler_pt exit_worker_handler; + ngx_str_t exit_worker_src; + +- ngx_http_lua_balancer_peer_data_t *balancer_peer_data; +- /* neither yielding nor recursion is possible in +- * balancer_by_lua*, so there cannot be any races among +- * concurrent requests and it is safe to store the peer +- * data pointer in the main conf. +- */ +- + ngx_chain_t *body_filter_chain; + /* neither yielding nor recursion is possible in + * body_filter_by_lua*, so there cannot be any races among +-- +2.26.2 diff --git a/patches/ngx_stream_lua-0.0.11_01-expose_request_struct.patch b/patches/ngx_stream_lua-0.0.11_01-expose_request_struct.patch new file mode 100644 index 0000000..e957f28 --- /dev/null +++ b/patches/ngx_stream_lua-0.0.11_01-expose_request_struct.patch @@ -0,0 +1,26 @@ +From 0acb7f5ad0fbc9ee037f0c5d689f98861fe9e49b Mon Sep 17 00:00:00 2001 +From: Datong Sun +Date: Tue, 10 Dec 2019 11:51:53 -0800 +Subject: [PATCH] Sync with meta-lua-nginx-module + 1330009671cd86eaf045f9f2c5cda3727a94570f. + +--- + ngx_stream_lua-0.0.11/src/api/ngx_stream_lua_api.h | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/ngx_stream_lua-0.0.11/src/api/ngx_stream_lua_api.h b/ngx_stream_lua-0.0.11/src/api/ngx_stream_lua_api.h +index 0e5a18f..040ef84 100644 +--- a/ngx_stream_lua-0.0.11/src/api/ngx_stream_lua_api.h ++++ b/ngx_stream_lua-0.0.11/src/api/ngx_stream_lua_api.h +@@ -21,6 +21,9 @@ + + + ++#include ++#include "../ngx_stream_lua_request.h" ++ + + #include + #include +-- +2.20.1 diff --git a/test.sh b/test.sh index 3babf61..edc6d84 100755 --- a/test.sh +++ b/test.sh @@ -1,14 +1,26 @@ #!/usr/bin/env bash set -euo pipefail -IFS=$'\n\t' if [ -n "${DEBUG:-}" ]; then set -x fi +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +export $(grep -v '^#' $SCRIPT_DIR/.env | xargs) + function test() { - ls -lah /tmp/build/out + cp -R /tmp/build/* / + + /usr/local/kong/bin/openssl version # From kong-openssl test.sh + + /usr/local/openresty/bin/openresty -v 2>&1 | grep -q ${OPENRESTY_VERSION} + /usr/local/openresty/bin/openresty -V 2>&1 | grep -q pcre + /usr/local/openresty/bin/resty -e 'print(jit.version)' | grep -q 'LuaJIT[[:space:]][[:digit:]]\+.[[:digit:]]\+.[[:digit:]]\+-[[:digit:]]\{8\}' + + ls -l /usr/local/openresty/lualib/resty/websocket/*.lua + grep _VERSION /usr/local/openresty/lualib/resty/websocket/*.lua + luarocks --version } test