Merge pull request #861 from bunkerity/dev

Merge branch "dev" into branch "staging"
This commit is contained in:
Théophile Diot 2024-01-12 16:03:08 +00:00 committed by GitHub
commit eaca7ca184
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
279 changed files with 6027 additions and 1377 deletions

View file

@ -35,12 +35,12 @@ jobs:
python -m pip install --no-cache-dir --require-hashes -r src/common/db/requirements.txt
echo "CODEQL_PYTHON=$(which python)" >> $GITHUB_ENV
- name: Initialize CodeQL
uses: github/codeql-action/init@012739e5082ff0c22ca6d6ab32e07c36df03c4a4 # v3.22.12
uses: github/codeql-action/init@e5f05b81d5b6ff8cfa111c80c22c5fd02a384118 # v3.23.0
with:
languages: ${{ matrix.language }}
config-file: ./.github/codeql.yml
setup-python-dependencies: false
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@012739e5082ff0c22ca6d6ab32e07c36df03c4a4 # v3.22.12
uses: github/codeql-action/analyze@e5f05b81d5b6ff8cfa111c80c22c5fd02a384118 # v3.23.0
with:
category: "/language:${{matrix.language}}"

View file

@ -84,7 +84,7 @@ jobs:
# Compute metadata
- name: Extract metadata
id: meta
uses: docker/metadata-action@9dc751fe249ad99385a2583ee0d084c400eee04e # v5.4.0
uses: docker/metadata-action@dbef88086f6cef02e264edb7dbf63250c17cef6c # v5.5.0
with:
images: bunkerity/${{ inputs.IMAGE }}
# Build cached image

View file

@ -135,7 +135,7 @@ jobs:
- name: Extract metadata
if: inputs.TEST == true
id: meta
uses: docker/metadata-action@9dc751fe249ad99385a2583ee0d084c400eee04e # v5.4.0
uses: docker/metadata-action@dbef88086f6cef02e264edb7dbf63250c17cef6c # v5.5.0
with:
images: ghcr.io/bunkerity/${{ inputs.LINUX }}-tests:${{ inputs.RELEASE }}
- name: Build test image

View file

@ -63,7 +63,7 @@ jobs:
# Compute metadata
- name: Extract metadata
id: meta
uses: docker/metadata-action@9dc751fe249ad99385a2583ee0d084c400eee04e # v5.4.0
uses: docker/metadata-action@dbef88086f6cef02e264edb7dbf63250c17cef6c # v5.5.0
with:
images: bunkerity/${{ inputs.IMAGE }}
# Build and push

View file

@ -19,7 +19,7 @@ jobs:
# Get PDF doc
- name: Get documentation
if: inputs.VERSION != 'testing'
uses: actions/download-artifact@f44cd7b40bfd40b6aa1cc1b9b5b7bf03d3c67110 # v4.1.0
uses: actions/download-artifact@6b208ae046db98c579e8a3aa621ab581ff575935 # v4.1.1
with:
name: BunkerWeb_documentation_v${{ inputs.VERSION }}.pdf
# Create tag

View file

@ -48,12 +48,12 @@ jobs:
- name: Install packagecloud
run: gem install package_cloud
# Download packages
- uses: actions/download-artifact@f44cd7b40bfd40b6aa1cc1b9b5b7bf03d3c67110 # v4.1.0
- uses: actions/download-artifact@6b208ae046db98c579e8a3aa621ab581ff575935 # v4.1.1
if: inputs.LINUX != 'el'
with:
name: package-${{ inputs.LINUX }}-${{ inputs.PACKAGE_ARCH }}
path: /tmp/${{ inputs.LINUX }}
- uses: actions/download-artifact@f44cd7b40bfd40b6aa1cc1b9b5b7bf03d3c67110 # v4.1.0
- uses: actions/download-artifact@6b208ae046db98c579e8a3aa621ab581ff575935 # v4.1.1
if: inputs.LINUX == 'el'
with:
name: package-rhel-${{ inputs.PACKAGE_ARCH }}

View file

@ -25,6 +25,6 @@ jobs:
results_format: sarif
publish_results: true
- name: "Upload SARIF results to code scanning"
uses: github/codeql-action/upload-sarif@012739e5082ff0c22ca6d6ab32e07c36df03c4a4 # v3.22.12
uses: github/codeql-action/upload-sarif@e5f05b81d5b6ff8cfa111c80c22c5fd02a384118 # v3.23.0
with:
sarif_file: results.sarif

View file

@ -23,7 +23,7 @@ jobs:
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- name: Install terraform
uses: hashicorp/setup-terraform@a1502cd9e758c50496cc9ac5308c4843bcd56d36 # v3.0.0
- uses: actions/download-artifact@f44cd7b40bfd40b6aa1cc1b9b5b7bf03d3c67110 # v4.1.0
- uses: actions/download-artifact@6b208ae046db98c579e8a3aa621ab581ff575935 # v4.1.1
with:
name: tf-${{ inputs.TYPE }}
path: /tmp

View file

@ -43,7 +43,7 @@ jobs:
if: inputs.TYPE == 'swarm'
- name: Install test dependencies
run: pip3 install --no-cache-dir --require-hashes --no-deps -r tests/requirements.txt
- uses: actions/download-artifact@f44cd7b40bfd40b6aa1cc1b9b5b7bf03d3c67110 # v4.1.0
- uses: actions/download-artifact@6b208ae046db98c579e8a3aa621ab581ff575935 # v4.1.1
with:
name: tf-k8s
path: /tmp

View file

@ -1,8 +1,16 @@
# Changelog
## v1.5.5 - 2024/01/09
## v1.5.6 - YYYY/MM/DD
- [BUGFIX] Fix issues with the database when upgrading from version 1.5.3 and 1.5.4 to the most recent version
- [MISC] Updated Linux base images in Dockerfiles
- [DEPS] Updated stream-lua-nginx-module to v0.0.14
- [DEPS] Updated lua-nginx-module version to v0.10.26
- [DEPS] Updated libmaxminddb version to v1.9.1
- [DEPS] Updated lua-resty-core to v0.1.28
## v1.5.5 - 2024/01/12
- [BUGFIX] Fix issues with the database when upgrading from one version to a newer one
- [BUGFIX] Fix ModSecurity-nginx to make it work with brotli
- [BUGFIX] Remove certbot renew delay causing errors on k8s
- [BUGFIX] Fix missing custom modsec files when BW instances change
@ -19,7 +27,6 @@
- [MISC] Various internal improvements in LUA code
- [MISC] Check nginx configuration before reload
- [MISC] Updated Python Docker image to 3.12.1-alpine3.18 in Dockerfiles
- [MISC] Switch gunicorn worker_class back to gevent in web UI
- [DEPS] Updated ModSecurity to v3.0.11
## v1.5.4 - 2023/12/04

View file

@ -211,16 +211,16 @@ importlib-resources==6.1.1 \
--hash=sha256:3893a00122eafde6894c59914446a512f728a0c1a45f9bb9b63721b6bacf0b4a \
--hash=sha256:e8bf90d8213b486f428c9c39714b920041cb02c184686a3dee24905aaa8105d6
# via mike
jinja2==3.1.2 \
--hash=sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852 \
--hash=sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61
jinja2==3.1.3 \
--hash=sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa \
--hash=sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90
# via
# mike
# mkdocs
# mkdocs-material
markdown==3.5.1 \
--hash=sha256:5874b47d4ee3f0b14d764324d2c94c03ea66bee56f2d929da9f2508d65e722dc \
--hash=sha256:b65d7beb248dc22f2e8a31fb706d93798093c308dc1aba295aedeb9d41a813bd
markdown==3.5.2 \
--hash=sha256:d43323865d89fc0cb9b20c75fc8ad313af307cc087e84b657d9eec768eddeadd \
--hash=sha256:e1ac7b3dc550ee80e602e71c1d168002f062e49f1b11e26a36264dafd4df2ef8
# via
# mkdocs
# mkdocs-material

View file

@ -64,7 +64,7 @@ RUN apk add --no-cache bash && \
chmod 750 cli/main.py helpers/*.sh /usr/bin/bwcli autoconf/main.py deps/python/bin/*
# Fix CVEs
# There are no CVEs to fix in this image
RUN apk add --no-cache "libcrypto3>=3.1.4-r3" "libssl3>=3.1.4-r3"
VOLUME /data /etc/nginx

View file

@ -1,6 +1,6 @@
docker==7.0.0
jinja2==3.1.2
kubernetes==28.1.0
jinja2==3.1.3
kubernetes==29.0.0
python-dotenv==1.0.0
redis==5.0.1
urllib3<2.0.0

View file

@ -114,21 +114,21 @@ docker==7.0.0 \
--hash=sha256:12ba681f2777a0ad28ffbcc846a69c31b4dfd9752b47eb425a274ee269c5e14b \
--hash=sha256:323736fb92cd9418fc5e7133bc953e11a9da04f4483f828b527db553f1e7e5a3
# via -r requirements.in
google-auth==2.26.1 \
--hash=sha256:2c8b55e3e564f298122a02ab7b97458ccfcc5617840beb5d0ac757ada92c9780 \
--hash=sha256:54385acca5c0fbdda510cd8585ba6f3fcb06eeecf8a6ecca39d3ee148b092590
google-auth==2.26.2 \
--hash=sha256:3f445c8ce9b61ed6459aad86d8ccdba4a9afed841b2d1451a11ef4db08957424 \
--hash=sha256:97327dbbf58cccb58fc5a1712bba403ae76668e64814eb30f7316f7e27126b81
# via kubernetes
idna==3.6 \
--hash=sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca \
--hash=sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f
# via requests
jinja2==3.1.2 \
--hash=sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852 \
--hash=sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61
jinja2==3.1.3 \
--hash=sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa \
--hash=sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90
# via -r requirements.in
kubernetes==28.1.0 \
--hash=sha256:10f56f8160dcb73647f15fafda268e7f60cf7dbc9f8e46d52fcd46d3beb0c18d \
--hash=sha256:1468069a573430fb1cb5ad22876868f57977930f80a6749405da31cd6086a7e9
kubernetes==29.0.0 \
--hash=sha256:ab8cb0e0576ccdfb71886366efb102c6a20f268d817be065ce7f9909c631e43e \
--hash=sha256:c4812e227ae74d07d53c88293e564e54b850452715a59a927e7e1bc6b9a60459
# via -r requirements.in
markupsafe==2.1.3 \
--hash=sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e \

View file

@ -71,9 +71,9 @@
},
{
"id": "libmaxminddb",
"name": "libmaxminddb v1.8.0",
"name": "libmaxminddb v1.9.1",
"url": "https://github.com/maxmind/libmaxminddb.git",
"commit": "93a7e0e5627686deb82aa636376f53b1c7af3d9a"
"commit": "e26013e1d2b57eff0ed22b7364270358adb72205"
},
{
"id": "lua-cjson",
@ -96,15 +96,15 @@
},
{
"id": "lua-nginx-module",
"name": "lua-nginx-module v0.10.25",
"name": "lua-nginx-module v0.10.26",
"url": "https://github.com/openresty/lua-nginx-module.git",
"commit": "c47084b5d719ce507d2419d8660f39544a9d1fea"
"commit": "0e769b76432df91e5f10aa56a56858e8a190faf7"
},
{
"id": "lua-resty-core",
"name": "lua-resty-core v0.1.27",
"name": "lua-resty-core v0.1.28",
"url": "https://github.com/openresty/lua-resty-core.git",
"commit": "31fae862a1ed64033591f991fadb0dd80358ba0b"
"commit": "812b2d3871eb0d8da8f0198759ad9164f0eccac6"
},
{
"id": "lua-resty-dns",
@ -225,9 +225,9 @@
},
{
"id": "stream-lua-nginx-module",
"name": "stream-lua-nginx-module v0.0.13",
"name": "stream-lua-nginx-module v0.0.14",
"url": "https://github.com/openresty/stream-lua-nginx-module.git",
"commit": "309198abf26266f1a3e53c71388ed7bb9d1e5ea2"
"commit": "cafa6f55333541d1c78767a286fa434c97574a4c"
},
{
"id": "zlib",

View file

@ -52,8 +52,8 @@ do
post="yes"
else
echo "⚠️ Skipping clone of $url because target directory is already present"
# echo " Updating ${name} from $url at commit/version $commit"
# do_and_check_cmd git subtree pull --prefix "src/deps/src/$id" "$url" "$commit" --squash
echo " Updating ${name} from $url at commit/version $commit"
do_and_check_cmd git subtree pull --prefix "src/deps/src/$id" "$url" "$commit" --squash
fi
if [ -d "src/deps/src/$id/.git" ] ; then

View file

@ -2,6 +2,8 @@ name: "Code scanning - action"
on:
push:
branches-ignore:
- 'dependabot/**'
pull_request:
schedule:
- cron: '0 7 * * 2'
@ -27,7 +29,7 @@ jobs:
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
uses: github/codeql-action/init@v3
- run: sudo apt install libipc-run3-perl libipc-system-simple-perl libfile-slurp-perl libfile-which-perl pandoc
- run: |
@ -37,4 +39,4 @@ jobs:
make safedist
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
uses: github/codeql-action/analyze@v3

View file

@ -2,7 +2,7 @@ cmake_minimum_required (VERSION 3.9)
project(maxminddb
LANGUAGES C
VERSION 1.8.0
VERSION 1.9.1
)
set(MAXMINDDB_SOVERSION 0.0.7)
set(CMAKE_C_STANDARD 99)
@ -37,8 +37,8 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
endif()
configure_file(${PROJECT_SOURCE_DIR}/include/maxminddb_config.h.cmake.in
${PROJECT_SOURCE_DIR}/include/maxminddb_config.h)
configure_file(${PROJECT_SOURCE_DIR}/include/maxminddb_config.h.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/generated/maxminddb_config.h)
add_library(maxminddb
src/maxminddb.c
@ -79,12 +79,14 @@ endif()
target_include_directories(maxminddb PUBLIC
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}/generated/>
$<INSTALL_INTERFACE:include>
$<INSTALL_INTERFACE:generated>
)
set(MAXMINDB_HEADERS
include/maxminddb.h
include/maxminddb_config.h
${CMAKE_CURRENT_BINARY_DIR}/generated/maxminddb_config.h
)
set_target_properties(maxminddb PROPERTIES PUBLIC_HEADER "${MAXMINDB_HEADERS}")

View file

@ -1,3 +1,19 @@
## 1.9.1 - 2024-01-09
* `SSIZE_MAX` is now defined conditionally on Windows. The 1.9.0
release would cause a redefinition warning when compiled with MinGW.
Reported by Andreas Vögele. GitHub #338.
## 1.9.0 - 2024-01-09
* On very large databases, the calculation to determine the search tree
size could overflow. This was fixed and several additional guards
against overflows were added. Reported by Sami Salonen. GitHub #335.
* Removed `sa_family_t` typedef from the public header on Windows. Pull
request by Noah Treuhaft. GitHub #334.
* The CMake build was adjusted to allow running builds in parallel.
Pull request by Vladyslav Miachkov. GitHub #332.
## 1.8.0 - 2023-11-07
* `PACKAGE_VERSION` is now a private compile definition when building

View file

@ -2,7 +2,7 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.63])
AC_INIT([libmaxminddb], [1.8.0], [support@maxmind.com])
AC_INIT([libmaxminddb], [1.9.1], [support@maxmind.com])
AC_CONFIG_SRCDIR([include/maxminddb.h])
AC_CONFIG_HEADERS([config.h include/maxminddb_config.h])

View file

@ -17,8 +17,6 @@ extern "C" {
#include <ws2tcpip.h>
/* libmaxminddb package version from configure */
typedef ADDRESS_FAMILY sa_family_t;
#if defined(_MSC_VER)
/* MSVC doesn't define signed size_t, copy it from configure */
#define ssize_t SSIZE_T

View file

@ -9,8 +9,6 @@
#include <stddef.h>
#include <stdlib.h>
static bool can_multiply(size_t const, size_t const, size_t const);
// Allocate an MMDB_data_pool_s. It initially has space for size
// MMDB_entry_data_list_s structs.
MMDB_data_pool_s *data_pool_new(size_t const size) {
@ -43,7 +41,7 @@ MMDB_data_pool_s *data_pool_new(size_t const size) {
// the given max. max will typically be SIZE_MAX.
//
// We want to know if we'll wrap around.
static bool can_multiply(size_t const max, size_t const m, size_t const n) {
bool can_multiply(size_t const max, size_t const m, size_t const n) {
if (m == 0) {
return false;
}

View file

@ -44,6 +44,7 @@ typedef struct MMDB_data_pool_s {
MMDB_entry_data_list_s *blocks[DATA_POOL_NUM_BLOCKS];
} MMDB_data_pool_s;
bool can_multiply(size_t const, size_t const, size_t const);
MMDB_data_pool_s *data_pool_new(size_t const);
void data_pool_destroy(MMDB_data_pool_s *const);
MMDB_entry_data_list_s *data_pool_alloc(MMDB_data_pool_s *const);

View file

@ -23,6 +23,10 @@
#endif
#include <windows.h>
#include <ws2ipdef.h>
#ifndef SSIZE_MAX
#define SSIZE_MAX INTPTR_MAX
#endif
typedef ADDRESS_FAMILY sa_family_t;
#else
#include <arpa/inet.h>
#include <sys/mman.h>
@ -288,18 +292,29 @@ int MMDB_open(const char *const filename, uint32_t flags, MMDB_s *const mmdb) {
goto cleanup;
}
uint32_t search_tree_size =
mmdb->metadata.node_count * mmdb->full_record_byte_size;
mmdb->data_section =
mmdb->file_content + search_tree_size + MMDB_DATA_SECTION_SEPARATOR;
if (search_tree_size + MMDB_DATA_SECTION_SEPARATOR >
(uint32_t)mmdb->file_size) {
if (!can_multiply(SSIZE_MAX,
mmdb->metadata.node_count,
mmdb->full_record_byte_size)) {
status = MMDB_INVALID_METADATA_ERROR;
goto cleanup;
}
mmdb->data_section_size = (uint32_t)mmdb->file_size - search_tree_size -
MMDB_DATA_SECTION_SEPARATOR;
ssize_t search_tree_size = (ssize_t)mmdb->metadata.node_count *
(ssize_t)mmdb->full_record_byte_size;
mmdb->data_section =
mmdb->file_content + search_tree_size + MMDB_DATA_SECTION_SEPARATOR;
if (mmdb->file_size < MMDB_DATA_SECTION_SEPARATOR ||
search_tree_size > mmdb->file_size - MMDB_DATA_SECTION_SEPARATOR) {
status = MMDB_INVALID_METADATA_ERROR;
goto cleanup;
}
ssize_t data_section_size =
mmdb->file_size - search_tree_size - MMDB_DATA_SECTION_SEPARATOR;
if (data_section_size > UINT32_MAX || data_section_size <= 0) {
status = MMDB_INVALID_METADATA_ERROR;
goto cleanup;
}
mmdb->data_section_size = (uint32_t)data_section_size;
// Although it is likely not possible to construct a database with valid
// valid metadata, as parsed above, and a data_section_size less than 3,

@ -1 +1 @@
Subproject commit 56e31231e0329b202c978c676e4a897c857c7a1f
Subproject commit b53e4ef5257f80e881762b6143834d8aae29da1a

View file

@ -1,4 +1,4 @@
dist: bionic
dist: focal
branches:
only:
@ -24,6 +24,11 @@ addons:
- libtest-longstring-perl
- liblist-moreutils-perl
- libgd-dev
- time
- cmake
- libunwind-dev
- wget
- libbrotli1
cache:
directories:
@ -38,9 +43,13 @@ env:
- LUAJIT_INC=$LUAJIT_PREFIX/include/luajit-2.1
- LUA_INCLUDE_DIR=$LUAJIT_INC
- PCRE_VER=8.45
- PCRE2_VER=10.37
- PCRE_PREFIX=/opt/pcre
- PCRE2_PREFIX=/opt/pcre2
- PCRE_LIB=$PCRE_PREFIX/lib
- PCRE2_LIB=$PCRE2_PREFIX/lib
- PCRE_INC=$PCRE_PREFIX/include
- PCRE2_INC=$PCRE2_PREFIX/include
- OPENSSL_PREFIX=/opt/ssl
- OPENSSL_LIB=$OPENSSL_PREFIX/lib
- OPENSSL_INC=$OPENSSL_PREFIX/include
@ -50,9 +59,14 @@ env:
- LD_LIBRARY_PATH=$LUAJIT_LIB:$LD_LIBRARY_PATH
- DRIZZLE_VER=2011.07.21
- TEST_NGINX_SLEEP=0.006
- MALLOC_PERTURB_=9
jobs:
- NGINX_VERSION=1.21.4 OPENSSL_VER=1.1.0l OPENSSL_PATCH_VER=1.1.0d
- NGINX_VERSION=1.21.4 OPENSSL_VER=1.1.1s OPENSSL_PATCH_VER=1.1.1f
#- NGINX_VERSION=1.21.4 OPENSSL_VER=1.1.0l OPENSSL_PATCH_VER=1.1.0d
#- NGINX_VERSION=1.25.1 OPENSSL_VER=1.1.0l OPENSSL_PATCH_VER=1.1.0d
- NGINX_VERSION=1.21.4 OPENSSL_VER=1.1.1w OPENSSL_PATCH_VER=1.1.1f
- NGINX_VERSION=1.25.1 OPENSSL_VER=1.1.1w OPENSSL_PATCH_VER=1.1.1f USE_PCRE2=Y
- NGINX_VERSION=1.25.1 BORINGSSL=1 TEST_NGINX_USE_HTTP3=1 USE_PCRE2=Y
#- NGINX_VERSION=1.25.1 OPENSSL_VER=1.1.1w TEST_NGINX_USE_HTTP2=1
services:
- memcached
@ -60,16 +74,18 @@ services:
- mysql
before_install:
- sudo apt update
- sudo apt install --only-upgrade ca-certificates
- '! grep -n -P ''(?<=.{80}).+'' --color `find src -name ''*.c''` `find . -name ''*.h''` || (echo "ERROR: Found C source lines exceeding 80 columns." > /dev/stderr; exit 1)'
- '! grep -n -P ''\t+'' --color `find src -name ''*.c''` `find . -name ''*.h''` || (echo "ERROR: Cannot use tabs." > /dev/stderr; exit 1)'
- /usr/bin/env perl $(command -v cpanm) --sudo --notest Test::Nginx IPC::Run > build.log 2>&1 || (cat build.log && exit 1)
- pyenv global 2.7
install:
- if [ ! -f download-cache/drizzle7-$DRIZZLE_VER.tar.gz ]; then wget -P download-cache http://openresty.org/download/drizzle7-$DRIZZLE_VER.tar.gz; fi
- if [ ! -f download-cache/pcre-$PCRE_VER.tar.gz ]; then wget -P download-cache https://downloads.sourceforge.net/project/pcre/pcre/${PCRE_VER}/pcre-${PCRE_VER}.tar.gz; fi
- if [ ! -f download-cache/openssl-$OPENSSL_VER.tar.gz ]; then wget -P download-cache https://www.openssl.org/source/openssl-$OPENSSL_VER.tar.gz || wget -P download-cache https://www.openssl.org/source/old/${OPENSSL_VER//[a-z]/}/openssl-$OPENSSL_VER.tar.gz; fi
- if [ ! -f download-cache/drizzle7-$DRIZZLE_VER.tar.gz ]; then wget -P download-cache https://github.com/openresty/openresty-deps-prebuild/releases/download/v20230902/drizzle7-$DRIZZLE_VER.tar.gz; fi
- if [ "$USE_PCRE2" != "Y" ] && [ ! -f download-cache/pcre-$PCRE_VER.tar.gz ]; then wget -P download-cache https://downloads.sourceforge.net/project/pcre/pcre/${PCRE_VER}/pcre-${PCRE_VER}.tar.gz; fi
- if [ "$USE_PCRE2" = "Y" ] && [ ! -f download-cache/pcre2-$PCRE2_VER.tar.gz ]; then wget -P download-cache https://downloads.sourceforge.net/project/pcre/pcre2/${PCRE2_VER}/pcre2-${PCRE2_VER}.tar.gz; fi
- if [ -n "$OPENSSL_VER" ] && [ ! -f download-cache/openssl-$OPENSSL_VER.tar.gz ]; then wget -P download-cache https://www.openssl.org/source/openssl-$OPENSSL_VER.tar.gz || wget -P download-cache https://www.openssl.org/source/old/${OPENSSL_VER//[a-z]/}/openssl-$OPENSSL_VER.tar.gz; fi
- if [ -n "$OPENSSL_VER" ] && [ ! -f download-cache/openssl-$OPENSSL_VER.tar.gz ]; then wget -P download-cache https://www.openssl.org/source/openssl-$OPENSSL_VER.tar.gz || wget -P download-cache https://www.openssl.org/source/old/${OPENSSL_VER//[a-z]/}/openssl-$OPENSSL_VER.tar.gz; fi
- wget https://github.com/openresty/openresty-deps-prebuild/releases/download/v20230902/boringssl-20230902-x64-focal.tar.gz
- wget https://github.com/openresty/openresty-deps-prebuild/releases/download/v20230902/curl-h3-x64-focal.tar.gz
- git clone https://github.com/openresty/test-nginx.git
- git clone https://github.com/openresty/openresty.git ../openresty
- git clone https://github.com/openresty/no-pool-nginx.git ../no-pool-nginx
@ -91,21 +107,24 @@ install:
- git clone https://github.com/openresty/lua-resty-core.git ../lua-resty-core
- git clone https://github.com/openresty/lua-resty-lrucache.git ../lua-resty-lrucache
- git clone https://github.com/openresty/lua-resty-mysql.git ../lua-resty-mysql
- git clone https://github.com/spacewander/lua-resty-rsa.git ../lua-resty-rsa
- git clone https://github.com/openresty/lua-resty-string.git ../lua-resty-string
- git clone https://github.com/openresty/stream-lua-nginx-module.git ../stream-lua-nginx-module
- git clone -b v2.1-agentzh https://github.com/openresty/luajit2.git luajit2
before_script:
- mysql -uroot -e 'create database ngx_test; grant all on ngx_test.* to "ngx_test"@"%" identified by "ngx_test"; flush privileges;'
- mysql -uroot -e "create database ngx_test; CREATE USER 'ngx_test'@'%' IDENTIFIED WITH mysql_native_password BY 'ngx_test'; grant all on ngx_test.* to 'ngx_test'@'%'; flush privileges;"
script:
- export PATH=$PWD/work/nginx/sbin:$PWD/openresty-devel-utils:$PATH
- sudo tar -C / -xf curl-h3-x64-focal.tar.gz
- export PATH=$PWD/work/nginx/sbin:$PWD/openresty-devel-utils:/opt/curl-h3/bin:$PATH
- ngx-releng > check.txt || true
- lines=`wc -l check.txt | awk '{print $1}'`; if [ $lines -gt 5 ]; then cat check.txt; exit 1; fi
- sudo iptables -I OUTPUT 1 -p udp --dport 10086 -j REJECT
- sudo iptables -I OUTPUT -p tcp --dst 127.0.0.2 --dport 12345 -j DROP
- sudo iptables -I OUTPUT -p udp --dst 127.0.0.2 --dport 12345 -j DROP
- sudo ip route add prohibit 0.0.0.1/32
- sudo sysctl -w kernel.pid_max=10000
- cd luajit2/
- make -j$JOBS CCDEBUG=-g Q= PREFIX=$LUAJIT_PREFIX CC=$CC XCFLAGS='-DLUA_USE_APICHECK -DLUA_USE_ASSERT -msse4.2' > build.log 2>&1 || (cat build.log && exit 1)
- sudo make install PREFIX=$LUAJIT_PREFIX > build.log 2>&1 || (cat build.log && exit 1)
@ -116,19 +135,10 @@ script:
- sudo make install-libdrizzle-1.0 > build.log 2>&1 || (cat build.log && exit 1)
- cd ../mockeagain/ && make CC=$CC -j$JOBS && cd ..
- cd lua-cjson/ && make -j$JOBS && sudo make install && cd ..
- tar zxf download-cache/pcre-$PCRE_VER.tar.gz
- cd pcre-$PCRE_VER/
- ./configure --prefix=$PCRE_PREFIX --enable-jit --enable-utf --enable-unicode-properties > build.log 2>&1 || (cat build.log && exit 1)
- make -j$JOBS > build.log 2>&1 || (cat build.log && exit 1)
- sudo PATH=$PATH make install > build.log 2>&1 || (cat build.log && exit 1)
- cd ..
- tar zxf download-cache/openssl-$OPENSSL_VER.tar.gz
- cd openssl-$OPENSSL_VER/
- patch -p1 < ../../openresty/patches/openssl-$OPENSSL_PATCH_VER-sess_set_get_cb_yield.patch
- ./config shared enable-ssl3 enable-ssl3-method -g --prefix=$OPENSSL_PREFIX -DPURIFY > build.log 2>&1 || (cat build.log && exit 1)
- make -j$JOBS > build.log 2>&1 || (cat build.log && exit 1)
- sudo make PATH=$PATH install_sw > build.log 2>&1 || (cat build.log && exit 1)
- cd ..
- if [ "$USE_PCRE2" != "Y" ]; then tar zxf download-cache/pcre-$PCRE_VER.tar.gz; cd pcre-$PCRE_VER/; ./configure --prefix=$PCRE_PREFIX --enable-jit --enable-utf --enable-unicode-properties > build.log 2>&1 || (cat build.log && exit 1); make -j$JOBS > build.log 2>&1 || (cat build.log && exit 1); sudo PATH=$PATH make install > build.log 2>&1 || (cat build.log && exit 1); cd ..; fi
- if [ "$USE_PCRE2" = "Y" ]; then tar zxf download-cache/pcre2-$PCRE2_VER.tar.gz; cd pcre2-$PCRE2_VER/; ./configure --prefix=$PCRE2_PREFIX --enable-jit --enable-utf > build.log 2>&1 || (cat build.log && exit 1); make -j$JOBS > build.log 2>&1 || (cat build.log && exit 1); sudo PATH=$PATH make install > build.log 2>&1 || (cat build.log && exit 1); cd ..; fi
- if [ -n "$OPENSSL_VER" ]; then tar zxf download-cache/openssl-$OPENSSL_VER.tar.gz; cd openssl-$OPENSSL_VER/; patch -p1 < ../../openresty/patches/openssl-$OPENSSL_PATCH_VER-sess_set_get_cb_yield.patch; ./config shared enable-ssl3 enable-ssl3-method -g --prefix=$OPENSSL_PREFIX -DPURIFY > build.log 2>&1 || (cat build.log && exit 1); make -j$JOBS > build.log 2>&1 || (cat build.log && exit 1); sudo make PATH=$PATH install_sw > build.log 2>&1 || (cat build.log && exit 1); cd ..; fi
- if [ -n "$BORINGSSL" ]; then sudo mkdir -p /opt/ssl && sudo tar -C /opt/ssl -xf boringssl-20230902-x64-focal.tar.gz --strip-components=1; fi
- export NGX_BUILD_CC=$CC
- sh util/build-without-ssl.sh $NGINX_VERSION > build.log 2>&1 || (cat build.log && exit 1)
- sh util/build-with-dd.sh $NGINX_VERSION > build.log 2>&1 || (cat build.log && exit 1)
@ -139,6 +149,8 @@ script:
- ldd `which nginx`|grep -E 'luajit|ssl|pcre'
- export LD_PRELOAD=$PWD/mockeagain/mockeagain.so
- export LD_LIBRARY_PATH=$PWD/mockeagain:$LD_LIBRARY_PATH
- export TEST_NGINX_HTTP3_CRT=$PWD/t/cert/http3/http3.crt
- export TEST_NGINX_HTTP3_KEY=$PWD/t/cert/http3/http3.key
- export TEST_NGINX_RESOLVER=8.8.4.4
- dig +short myip.opendns.com @resolver1.opendns.com || exit 0
- dig +short @$TEST_NGINX_RESOLVER openresty.org || exit 0

View file

@ -4,13 +4,11 @@ Name
ngx_http_lua_module - Embed the power of Lua into Nginx HTTP Servers.
This module is a core component of [OpenResty](https://openresty.org). If you are using this module,
then you are essentially using OpenResty.
then you are essentially using OpenResty :)
*This module is not distributed with the Nginx source.* See
[the installation instructions](#installation).
This is a core component of OpenResty. If you are using this module, then you are essentially using OpenResty :)
Table of Contents
=================
@ -65,8 +63,8 @@ Version
=======
This document describes ngx_lua
[v0.10.19](https://github.com/openresty/lua-nginx-module/tags), which was released
on 3 Nov, 2020.
[v0.10.25](https://github.com/openresty/lua-nginx-module/tags), which was released
on 19 June 2023.
Videos
======
@ -309,6 +307,8 @@ Nginx Compatibility
The latest version of this module is compatible with the following versions of Nginx:
* 1.25.x (last tested: 1.25.1)
* 1.21.x (last tested: 1.21.4)
* 1.19.x (last tested: 1.19.3)
* 1.17.x (last tested: 1.17.8)
* 1.15.x (last tested: 1.15.8)
@ -964,7 +964,6 @@ TODO
* cosocket: implement LuaSocket's unconnected UDP API.
* cosocket: add support in the context of [init_by_lua*](#init_by_lua).
* cosocket: implement the `bind()` method for stream-typed cosockets.
* cosocket: review and merge aviramc's [patch](https://github.com/openresty/lua-nginx-module/pull/290) for adding the `bsdrecv` method.
* cosocket: add configure options for different strategies of handling the cosocket connection exceeding in the pools.
* review and apply vadim-pavlov's patch for [ngx.location.capture](#ngxlocationcapture)'s `extra_headers` option
@ -1166,6 +1165,8 @@ Directives
* [lua_ssl_ciphers](#lua_ssl_ciphers)
* [lua_ssl_crl](#lua_ssl_crl)
* [lua_ssl_protocols](#lua_ssl_protocols)
* [lua_ssl_certificate](#lua_ssl_certificate)
* [lua_ssl_certificate_key](#lua_ssl_certificate_key)
* [lua_ssl_trusted_certificate](#lua_ssl_trusted_certificate)
* [lua_ssl_verify_depth](#lua_ssl_verify_depth)
* [lua_ssl_conf_command](#lua_ssl_conf_command)
@ -2721,6 +2722,8 @@ lua_need_request_body
**phase:** *depends on usage*
Due to the stream processing feature of HTTP/2 or HTTP/3, this configuration could potentially block the entire request. Therefore, this configuration is effective only when HTTP/2 or HTTP/3 requests send content-length header. For requests with versions lower than HTTP/2, this configuration can still be used without any problems.
Determines whether to force the request body data to be read before running rewrite/access/content_by_lua* or not. The Nginx core does not read the client request body by default and if request body data is required, then this directive should be turned `on` or the [ngx.req.read_body](#ngxreqread_body) function should be called within the Lua code.
To read the request body data within the [$request_body](http://nginx.org/en/docs/http/ngx_http_core_module.html#var_request_body) variable,
@ -3321,24 +3324,63 @@ lua_ssl_protocols
**syntax:** *lua_ssl_protocols \[SSLv2\] \[SSLv3\] \[TLSv1\] [TLSv1.1] [TLSv1.2] [TLSv1.3]*
**default:** *lua_ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2*
**default:** *lua_ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3*
**context:** *http, server, location*
Enables the specified protocols for requests to a SSL/TLS server in the [tcpsock:sslhandshake](#tcpsocksslhandshake) method.
The support for the `TLSv1.3` parameter requires version `v0.10.12` *and* OpenSSL 1.1.1.
From version v0.10.25, the default value change from `SSLV3 TLSv1 TLSv1.1 TLSv1.2` to `TLSv1 TLSv1.1 TLSv1.2 TLSv1.3`.
This directive was first introduced in the `v0.9.11` release.
[Back to TOC](#directives)
lua_ssl_certificate
-------------------
**syntax:** *lua_ssl_certificate &lt;file&gt;*
**default:** *none*
**context:** *http, server, location*
Specifies the file path to the SSL/TLS certificate in PEM format used for the [tcpsock:sslhandshake](#tcpsocksslhandshake) method.
This directive allows you to specify the SSL/TLS certificate that will be presented to server during the SSL/TLS handshake process.
This directive was first introduced in the `v0.10.26` release.
See also [lua_ssl_certificate_key](#lua_ssl_certificate_key) and [lua_ssl_verify_depth](#lua_ssl_verify_depth).
[Back to TOC](#directives)
lua_ssl_certificate_key
-----------------------
**syntax:** *lua_ssl_certificate_key &lt;file&gt;*
**default:** *none*
**context:** *http, server, location*
Specifies the file path to the private key associated with the SSL/TLS certificate used in the [tcpsock:sslhandshake](#tcpsocksslhandshake) method.
This directive allows you to specify the private key file corresponding to the SSL/TLS certificate specified by lua_ssl_certificate. The private key should be in PEM format and must match the certificate.
This directive was first introduced in the `v0.10.26` release.
See also [lua_ssl_certificate](#lua_ssl_certificate) and [lua_ssl_verify_depth](#lua_ssl_verify_depth).
[Back to TOC](#directives)
lua_ssl_trusted_certificate
---------------------------
**syntax:** *lua_ssl_trusted_certificate &lt;file&gt;*
**default:** *no*
**default:** *none*
**context:** *http, server, location*
@ -3363,7 +3405,7 @@ Sets the verification depth in the server certificates chain.
This directive was first introduced in the `v0.9.11` release.
See also [lua_ssl_trusted_certificate](#lua_ssl_trusted_certificate).
See also [lua_ssl_certificate](#lua_ssl_certificate), [lua_ssl_certificate_key](#lua_ssl_certificate_key) and [lua_ssl_trusted_certificate](#lua_ssl_trusted_certificate).
[Back to TOC](#directives)
@ -5384,6 +5426,8 @@ Reads the client request body synchronously without blocking the Nginx event loo
local args = ngx.req.get_post_args()
```
Due to the stream processing feature of HTTP/2 or HTTP/3, this api could potentially block the entire request. Therefore, this api is effective only when HTTP/2 or HTTP/3 requests send content-length header. For requests with versions lower than HTTP/2, this api can still be used without any problems.
If the request body is already read previously by turning on [lua_need_request_body](#lua_need_request_body) or by using other modules, then this function does not run and returns immediately.
If the request body has already been explicitly discarded, either by the [ngx.req.discard_body](#ngxreqdiscard_body) function or other modules, this function does not run and returns immediately.
@ -5423,12 +5467,14 @@ See also [ngx.req.read_body](#ngxreqread_body).
ngx.req.get_body_data
---------------------
**syntax:** *data = ngx.req.get_body_data()*
**syntax:** *data = ngx.req.get_body_data(max_bytes?)*
**context:** *rewrite_by_lua&#42;, access_by_lua&#42;, content_by_lua&#42;, log_by_lua&#42;*
Retrieves in-memory request body data. It returns a Lua string rather than a Lua table holding all the parsed query arguments. Use the [ngx.req.get_post_args](#ngxreqget_post_args) function instead if a Lua table is required.
The optional `max_bytes` argument can be used when you don't need the entire body.
This function returns `nil` if
1. the request body has not been read,
@ -5597,6 +5643,8 @@ Returns a read-only cosocket object that wraps the downstream connection. Only [
In case of error, `nil` will be returned as well as a string describing the error.
Due to the streaming nature of HTTP2 and HTTP3, this API cannot be used when the downstream connection is HTTP2 and HTTP3.
The socket object returned by this method is usually used to read the current request's body in a streaming fashion. Do not turn on the [lua_need_request_body](#lua_need_request_body) directive, and do not mix this call with [ngx.req.read_body](#ngxreqread_body) and [ngx.req.discard_body](#ngxreqdiscard_body).
If any request body data has been pre-read into the Nginx core request header buffer, the resulting cosocket object will take care of this to avoid potential data loss resulting from such pre-reading.
@ -9321,12 +9369,6 @@ Only the following ngx_lua APIs could be used in `function_name` function of the
* `ngx.decode_args`
* `ngx.quote_sql_str`
* `ngx.re.match`
* `ngx.re.find`
* `ngx.re.gmatch`
* `ngx.re.sub`
* `ngx.re.gsub`
* `ngx.crc32_short`
* `ngx.crc32_long`
* `ngx.hmac_sha1`
@ -9353,7 +9395,7 @@ The second argument `module_name` specifies the lua module name to execute in th
The third argument `func_name` specifies the function field in the module table as the second argument.
The type of `arg`s must be one of type below:
The type of `args` must be one of type below:
* boolean
* number

View file

@ -17,8 +17,8 @@ Production ready.
= Version =
This document describes ngx_lua
[https://github.com/openresty/lua-nginx-module/tags v0.10.19], which was released
on 3 Nov, 2020.
[https://github.com/openresty/lua-nginx-module/tags v0.10.25], which was released
on 19 June 2023.
= Videos =
@ -2845,11 +2845,43 @@ The support for the <code>TLSv1.3</code> parameter requires version <code>v0.10.
This directive was first introduced in the <code>v0.9.11</code> release.
== lua_ssl_certificate ==
'''syntax:''' ''lua_ssl_certificate <file>''
'''default:''' ''none''
'''context:''' ''http, server, location''
Specifies the file path to the SSL/TLS certificate in PEM format used for the [[#tcpsock:sslhandshake|tcpsock:sslhandshake]] method.
This directive allows you to specify the SSL/TLS certificate that will be presented to server during the SSL/TLS handshake process.
This directive was first introduced in the <code>v0.10.26</code> release.
See also [[#lua_ssl_certificate_key|lua_ssl_certificate_key]] and [[#lua_ssl_verify_depth|lua_ssl_verify_depth]].
== lua_ssl_certificate_key ==
'''syntax:''' ''lua_ssl_certificate_key <file>''
'''default:''' ''none''
'''context:''' ''http, server, location''
Specifies the file path to the private key associated with the SSL/TLS certificate used in the [[#tcpsock:sslhandshake|tcpsock:sslhandshake]] method.
This directive allows you to specify the private key file corresponding to the SSL/TLS certificate specified by lua_ssl_certificate. The private key should be in PEM format and must match the certificate.
This directive was first introduced in the <code>v0.10.26</code> release.
See also [[#lua_ssl_certificate|lua_ssl_certificate]] and [[#lua_ssl_verify_depth|lua_ssl_verify_depth]].
== lua_ssl_trusted_certificate ==
'''syntax:''' ''lua_ssl_trusted_certificate <file>''
'''default:''' ''no''
'''default:''' ''none''
'''context:''' ''http, server, location''
@ -2871,7 +2903,7 @@ Sets the verification depth in the server certificates chain.
This directive was first introduced in the <code>v0.9.11</code> release.
See also [[#lua_ssl_trusted_certificate|lua_ssl_trusted_certificate]].
See also [[#lua_ssl_certificate|lua_ssl_certificate]], [[#lua_ssl_certificate_key|lua_ssl_certificate_key]] and [[#lua_ssl_trusted_certificate|lua_ssl_trusted_certificate]].
== lua_ssl_conf_command ==
@ -4555,12 +4587,14 @@ See also [[#ngx.req.read_body|ngx.req.read_body]].
== ngx.req.get_body_data ==
'''syntax:''' ''data = ngx.req.get_body_data()''
'''syntax:''' ''data = ngx.req.get_body_data(max_bytes?)''
'''context:''' ''rewrite_by_lua*, access_by_lua*, content_by_lua*, log_by_lua*''
Retrieves in-memory request body data. It returns a Lua string rather than a Lua table holding all the parsed query arguments. Use the [[#ngx.req.get_post_args|ngx.req.get_post_args]] function instead if a Lua table is required.
The optional <code>max_bytes</code> function argument can be used when you don't need the entire body.
This function returns <code>nil</code> if
# the request body has not been read,
@ -4707,6 +4741,8 @@ Returns a read-only cosocket object that wraps the downstream connection. Only [
In case of error, <code>nil</code> will be returned as well as a string describing the error.
Due to the streaming nature of HTTP2 and HTTP3, this API cannot be used when the downstream connection is HTTP2 and HTTP3.
The socket object returned by this method is usually used to read the current request's body in a streaming fashion. Do not turn on the [[#lua_need_request_body|lua_need_request_body]] directive, and do not mix this call with [[#ngx.req.read_body|ngx.req.read_body]] and [[#ngx.req.discard_body|ngx.req.discard_body]].
If any request body data has been pre-read into the Nginx core request header buffer, the resulting cosocket object will take care of this to avoid potential data loss resulting from such pre-reading.

View file

@ -19,7 +19,7 @@
/* Public API for other Nginx modules */
#define ngx_http_lua_version 10025
#define ngx_http_lua_version 10026
typedef struct ngx_http_lua_co_ctx_s ngx_http_lua_co_ctx_t;

View file

@ -137,6 +137,26 @@ ngx_http_lua_access_handler(ngx_http_request_t *r)
}
if (llcf->force_read_body && !ctx->read_body_done) {
#if (NGX_HTTP_V2)
if (r->main->stream && r->headers_in.content_length_n < 0) {
ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
"disable lua_need_request_body, since "
"http2 read_body may break http2 stream process");
goto done;
}
#endif
#if (NGX_HTTP_V3)
if (r->http_version == NGX_HTTP_VERSION_30
&& r->headers_in.content_length_n < 0)
{
ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
"disable lua_need_request_body, since "
"http2 read_body may break http2 stream process");
goto done;
}
#endif
r->request_body_in_single_buf = 1;
r->request_body_in_persistent_file = 1;
r->request_body_in_clean_file = 1;
@ -154,6 +174,12 @@ ngx_http_lua_access_handler(ngx_http_request_t *r)
}
}
#if defined(NGX_HTTP_V3) || defined(NGX_HTTP_V2)
done:
#endif
dd("calling access handler");
return llcf->access_handler(r);
}

View file

@ -91,7 +91,7 @@
* | Int | At which line this function is defined
* | [linedefined] |
* ---------------------
* | Int | At while line this function definition ended
* | Int | At which line this function definition ended
* | [lastlinedefined] |
* ---------------------
* | Char | Number of upvalues referenced by this function
@ -128,7 +128,7 @@
* | Vector | Debug lineinfo vector
* | [lineinfo] | Empty vector here if debug info is stripped
* ---------------------
* | Int | Number of local variable in this function
* | Int | Number of local variables in this function
* | [sizelocvars] | 0 if debug info is stripped
* ---------------------
* | String | ------------------------------------

View file

@ -55,11 +55,17 @@ typedef struct {
#if (NGX_PCRE)
#include <pcre.h>
# if (PCRE_MAJOR > 8) || (PCRE_MAJOR == 8 && PCRE_MINOR >= 21)
# if (NGX_PCRE2)
# define LUA_HAVE_PCRE_JIT 1
# else
# define LUA_HAVE_PCRE_JIT 0
#include <pcre.h>
# if (PCRE_MAJOR > 8) || (PCRE_MAJOR == 8 && PCRE_MINOR >= 21)
# define LUA_HAVE_PCRE_JIT 1
# else
# define LUA_HAVE_PCRE_JIT 0
# endif
# endif
#endif
@ -221,9 +227,14 @@ struct ngx_http_lua_main_conf_s {
ngx_int_t regex_cache_entries;
ngx_int_t regex_cache_max_entries;
ngx_int_t regex_match_limit;
# if (LUA_HAVE_PCRE_JIT)
#endif
#if (LUA_HAVE_PCRE_JIT)
#if (NGX_PCRE2)
pcre2_jit_stack *jit_stack;
#else
pcre_jit_stack *jit_stack;
# endif
#endif
#endif
ngx_array_t *shm_zones; /* of ngx_shm_zone_t* */
@ -360,6 +371,8 @@ union ngx_http_lua_srv_conf_u {
typedef struct {
#if (NGX_HTTP_SSL)
ngx_ssl_t *ssl; /* shared by SSL cosockets */
ngx_array_t *ssl_certificates;
ngx_array_t *ssl_certificate_keys;
ngx_uint_t ssl_protocols;
ngx_str_t ssl_ciphers;
ngx_uint_t ssl_verify_depth;

View file

@ -196,6 +196,26 @@ ngx_http_lua_content_handler(ngx_http_request_t *r)
}
if (llcf->force_read_body && !ctx->read_body_done) {
#if (NGX_HTTP_V2)
if (r->main->stream && r->headers_in.content_length_n < 0) {
ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
"disable lua_need_request_body, since "
"http2 read_body may break http2 stream process");
goto done;
}
#endif
#if (NGX_HTTP_V3)
if (r->http_version == NGX_HTTP_VERSION_30
&& r->headers_in.content_length_n < 0)
{
ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
"disable lua_need_request_body, since "
"http2 read_body may break http2 stream process");
goto done;
}
#endif
r->request_body_in_single_buf = 1;
r->request_body_in_persistent_file = 1;
r->request_body_in_clean_file = 1;
@ -214,6 +234,12 @@ ngx_http_lua_content_handler(ngx_http_request_t *r)
}
}
#if defined(NGX_HTTP_V3) || defined(NGX_HTTP_V2)
done:
#endif
dd("setting entered");
ctx->entered_content_phase = 1;

View file

@ -280,6 +280,9 @@ ngx_http_lua_ngx_redirect(lua_State *L)
h->value.len = len;
h->value.data = uri;
#if defined(nginx_version) && nginx_version >= 1023000
h->next = NULL;
#endif
ngx_str_set(&h->key, "Location");
r->headers_out.status = rc;

View file

@ -782,6 +782,11 @@ ngx_http_lua_ffi_req_get_headers_count(ngx_http_request_t *r, int max,
{
int count;
ngx_list_part_t *part;
#if (NGX_HTTP_V3)
int has_host = 0;
ngx_uint_t i;
ngx_table_elt_t *header;
#endif
if (r->connection->fd == (ngx_socket_t) -1) {
return NGX_HTTP_LUA_FFI_BAD_CONTEXT;
@ -794,11 +799,54 @@ ngx_http_lua_ffi_req_get_headers_count(ngx_http_request_t *r, int max,
}
part = &r->headers_in.headers.part;
#if (NGX_HTTP_V3)
count = 0;
header = part->elts;
if (r->http_version == NGX_HTTP_VERSION_30
&& r->headers_in.server.data != NULL)
{
has_host = 1;
count++;
}
if (has_host == 1) {
for (i = 0; /* void */; i++) {
if (i >= part->nelts) {
if (part->next == NULL) {
break;
}
part = part->next;
header = part->elts;
i = 0;
}
if (header[i].key.len == 4
&& ngx_strncasecmp(header[i].key.data,
(u_char *) "host", 4) == 0)
{
continue;
}
count++;
}
} else {
count = part->nelts;
while (part->next != NULL) {
part = part->next;
count += part->nelts;
}
}
#else
count = part->nelts;
while (part->next != NULL) {
part = part->next;
count += part->nelts;
}
#endif
if (max > 0 && count > max) {
*truncated = 1;
@ -821,12 +869,29 @@ ngx_http_lua_ffi_req_get_headers(ngx_http_request_t *r,
ngx_uint_t i;
ngx_list_part_t *part;
ngx_table_elt_t *header;
#if (NGX_HTTP_V3)
int has_host = 0;
#endif
if (count <= 0) {
return NGX_OK;
}
n = 0;
#if (NGX_HTTP_V3)
if (r->http_version == NGX_HTTP_VERSION_30
&& r->headers_in.server.data != NULL)
{
out[n].key.data = (u_char *) "host";
out[n].key.len = sizeof("host") - 1;
out[n].value.len = r->headers_in.server.len;
out[n].value.data = r->headers_in.server.data;
has_host = 1;
++n;
}
#endif
part = &r->headers_in.headers.part;
header = part->elts;
@ -842,6 +907,14 @@ ngx_http_lua_ffi_req_get_headers(ngx_http_request_t *r,
i = 0;
}
#if (NGX_HTTP_V3)
if (has_host == 1 && header[i].key.len == 4
&& ngx_strncasecmp(header[i].key.data, (u_char *) "host", 4) == 0)
{
continue;
}
#endif
if (raw) {
out[n].key.data = header[i].key.data;
out[n].key.len = (int) header[i].key.len;

View file

@ -280,6 +280,9 @@ new_header:
h->key = hv->key;
h->value = *value;
#if defined(nginx_version) && nginx_version >= 1023000
h->next = NULL;
#endif
h->lowcase_key = ngx_pnalloc(r->pool, h->key.len);
if (h->lowcase_key == NULL) {
@ -588,19 +591,21 @@ ngx_http_set_builtin_multi_header(ngx_http_request_t *r,
{
#if defined(nginx_version) && nginx_version >= 1023000
ngx_table_elt_t **headers, **ph, *h;
int nelts;
headers = (ngx_table_elt_t **) ((char *) &r->headers_in + hv->offset);
if (!hv->no_override && *headers != NULL) {
nelts = 0;
#if defined(DDEBUG) && (DDEBUG)
int nelts = 0;
for (h = *headers; h; h = h->next) {
nelts++;
}
*headers = NULL;
dd("clear multi-value headers: %d", nelts);
#endif
*headers = NULL;
}
if (ngx_http_set_header_helper(r, hv, value, &h) == NGX_ERROR) {

View file

@ -229,6 +229,9 @@ new_header:
h->key = hv->key;
h->value = *value;
#if defined(nginx_version) && nginx_version >= 1023000
h->next = NULL;
#endif
h->lowcase_key = ngx_pnalloc(r->pool, h->key.len);
if (h->lowcase_key == NULL) {

View file

@ -48,6 +48,8 @@ static char *ngx_http_lua_merge_loc_conf(ngx_conf_t *cf, void *parent,
static ngx_int_t ngx_http_lua_init(ngx_conf_t *cf);
static char *ngx_http_lua_lowat_check(ngx_conf_t *cf, void *post, void *data);
#if (NGX_HTTP_SSL)
static ngx_int_t ngx_http_lua_merge_ssl(ngx_conf_t *cf,
ngx_http_lua_loc_conf_t *conf, ngx_http_lua_loc_conf_t *prev);
static ngx_int_t ngx_http_lua_set_ssl(ngx_conf_t *cf,
ngx_http_lua_loc_conf_t *llcf);
#if (nginx_version >= 1019004)
@ -57,6 +59,9 @@ static char *ngx_http_lua_ssl_conf_command_check(ngx_conf_t *cf, void *post,
#endif
static char *ngx_http_lua_malloc_trim(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
#if (NGX_PCRE2)
extern void ngx_http_lua_regex_cleanup(void *data);
#endif
static ngx_conf_post_t ngx_http_lua_lowat_post =
@ -648,6 +653,20 @@ static ngx_command_t ngx_http_lua_cmds[] = {
offsetof(ngx_http_lua_loc_conf_t, ssl_verify_depth),
NULL },
{ ngx_string("lua_ssl_certificate"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_conf_set_str_array_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_lua_loc_conf_t, ssl_certificates),
NULL },
{ ngx_string("lua_ssl_certificate_key"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_conf_set_str_array_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_lua_loc_conf_t, ssl_certificate_keys),
NULL },
{ ngx_string("lua_ssl_trusted_certificate"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_conf_set_str_slot,
@ -839,6 +858,17 @@ ngx_http_lua_init(ngx_conf_t *cf)
cln->data = lmcf;
cln->handler = ngx_http_lua_sema_mm_cleanup;
#if (NGX_PCRE2)
/* add the cleanup of pcre2 regex */
cln = ngx_pool_cleanup_add(cf->pool, 0);
if (cln == NULL) {
return NGX_ERROR;
}
cln->data = lmcf;
cln->handler = ngx_http_lua_regex_cleanup;
#endif
#ifdef HAVE_NGX_LUA_PIPE
ngx_http_lua_pipe_init();
#endif
@ -1148,15 +1178,15 @@ ngx_http_lua_create_srv_conf(ngx_conf_t *cf)
* lscf->srv.ssl_cert_chunkname = NULL;
* lscf->srv.ssl_cert_src_key = NULL;
*
* lscf->srv.ssl_session_store_handler = NULL;
* lscf->srv.ssl_session_store_src = { 0, NULL };
* lscf->srv.ssl_session_store_chunkname = NULL;
* lscf->srv.ssl_session_store_src_key = NULL;
* lscf->srv.ssl_sess_store_handler = NULL;
* lscf->srv.ssl_sess_store_src = { 0, NULL };
* lscf->srv.ssl_sess_store_chunkname = NULL;
* lscf->srv.ssl_sess_store_src_key = NULL;
*
* lscf->srv.ssl_session_fetch_handler = NULL;
* lscf->srv.ssl_session_fetch_src = { 0, NULL };
* lscf->srv.ssl_session_fetch_chunkname = NULL;
* lscf->srv.ssl_session_fetch_src_key = NULL;
* lscf->srv.ssl_sess_fetch_handler = NULL;
* lscf->srv.ssl_sess_fetch_src = { 0, NULL };
* lscf->srv.ssl_sess_fetch_chunkname = NULL;
* lscf->srv.ssl_sess_fetch_src_key = NULL;
*
* lscf->balancer.handler = NULL;
* lscf->balancer.src = { 0, NULL };
@ -1399,6 +1429,8 @@ ngx_http_lua_create_loc_conf(ngx_conf_t *cf)
#if (NGX_HTTP_SSL)
conf->ssl_verify_depth = NGX_CONF_UNSET_UINT;
conf->ssl_certificates = NGX_CONF_UNSET_PTR;
conf->ssl_certificate_keys = NGX_CONF_UNSET_PTR;
#if (nginx_version >= 1019004)
conf->ssl_conf_commands = NGX_CONF_UNSET_PTR;
#endif
@ -1464,16 +1496,24 @@ ngx_http_lua_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
#if (NGX_HTTP_SSL)
if (ngx_http_lua_merge_ssl(cf, conf, prev) != NGX_OK) {
return NGX_CONF_ERROR;
}
ngx_conf_merge_bitmask_value(conf->ssl_protocols, prev->ssl_protocols,
(NGX_CONF_BITMASK_SET|NGX_SSL_SSLv3
(NGX_CONF_BITMASK_SET
|NGX_SSL_TLSv1|NGX_SSL_TLSv1_1
|NGX_SSL_TLSv1_2));
|NGX_SSL_TLSv1_2|NGX_SSL_TLSv1_3));
ngx_conf_merge_str_value(conf->ssl_ciphers, prev->ssl_ciphers,
"DEFAULT");
ngx_conf_merge_uint_value(conf->ssl_verify_depth,
prev->ssl_verify_depth, 1);
ngx_conf_merge_ptr_value(conf->ssl_certificates,
prev->ssl_certificates, NULL);
ngx_conf_merge_ptr_value(conf->ssl_certificate_keys,
prev->ssl_certificate_keys, NULL);
ngx_conf_merge_str_value(conf->ssl_trusted_certificate,
prev->ssl_trusted_certificate, "");
ngx_conf_merge_str_value(conf->ssl_crl, prev->ssl_crl, "");
@ -1527,17 +1567,77 @@ ngx_http_lua_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
#if (NGX_HTTP_SSL)
static ngx_int_t
ngx_http_lua_merge_ssl(ngx_conf_t *cf,
ngx_http_lua_loc_conf_t *conf, ngx_http_lua_loc_conf_t *prev)
{
ngx_uint_t preserve;
if (conf->ssl_protocols == 0
&& conf->ssl_ciphers.data == NULL
&& conf->ssl_verify_depth == NGX_CONF_UNSET_UINT
&& conf->ssl_certificates == NGX_CONF_UNSET_PTR
&& conf->ssl_certificate_keys == NGX_CONF_UNSET_PTR
&& conf->ssl_trusted_certificate.data == NULL
&& conf->ssl_crl.data == NULL
#if (nginx_version >= 1019004)
&& conf->ssl_conf_commands == NGX_CONF_UNSET_PTR
#endif
)
{
if (prev->ssl) {
conf->ssl = prev->ssl;
return NGX_OK;
}
preserve = 1;
} else {
preserve = 0;
}
conf->ssl = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_t));
if (conf->ssl == NULL) {
return NGX_ERROR;
}
conf->ssl->log = cf->log;
/*
* special handling to preserve conf->ssl_* in the "http" section
* to inherit it to all servers
*/
if (preserve) {
prev->ssl = conf->ssl;
}
return NGX_OK;
}
static ngx_int_t
ngx_http_lua_set_ssl(ngx_conf_t *cf, ngx_http_lua_loc_conf_t *llcf)
{
ngx_pool_cleanup_t *cln;
llcf->ssl = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_t));
if (llcf->ssl == NULL) {
return NGX_ERROR;
if (llcf->ssl->ctx) {
return NGX_OK;
}
llcf->ssl->log = cf->log;
if (llcf->ssl_certificates) {
if (llcf->ssl_certificate_keys == NULL
|| llcf->ssl_certificate_keys->nelts
< llcf->ssl_certificates->nelts)
{
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
"no \"lua_ssl_certificate_key\" is defined "
"for certificate \"%V\"",
((ngx_str_t *) llcf->ssl_certificates->elts)
+ llcf->ssl_certificates->nelts - 1);
return NGX_ERROR;
}
}
if (ngx_ssl_create(llcf->ssl, llcf->ssl_protocols, NULL) != NGX_OK) {
return NGX_ERROR;
@ -1562,6 +1662,16 @@ ngx_http_lua_set_ssl(ngx_conf_t *cf, ngx_http_lua_loc_conf_t *llcf)
return NGX_ERROR;
}
if (llcf->ssl_certificates
&& ngx_ssl_certificates(cf, llcf->ssl,
llcf->ssl_certificates,
llcf->ssl_certificate_keys,
NULL)
!= NGX_OK)
{
return NGX_ERROR;
}
if (llcf->ssl_trusted_certificate.len
&& ngx_ssl_trusted_certificate(cf, llcf->ssl,
&llcf->ssl_trusted_certificate,

View file

@ -18,15 +18,61 @@
static ngx_pool_t *ngx_http_lua_pcre_pool = NULL;
#if (NGX_PCRE2)
static ngx_uint_t ngx_regex_direct_alloc;
#else
static void *(*old_pcre_malloc)(size_t);
static void (*old_pcre_free)(void *ptr);
#endif
/* XXX: work-around to nginx regex subsystem, must init a memory pool
* to use PCRE functions. As PCRE still has memory-leaking problems,
* and nginx overwrote pcre_malloc/free hooks with its own static
* functions, so nobody else can reuse nginx regex subsystem... */
static void *
#if (NGX_PCRE2)
void *
ngx_http_lua_pcre_malloc(size_t size, void *data)
{
dd("lua pcre pool is %p", ngx_http_lua_pcre_pool);
if (ngx_http_lua_pcre_pool) {
return ngx_palloc(ngx_http_lua_pcre_pool, size);
}
if (ngx_regex_direct_alloc) {
return ngx_alloc(size, ngx_cycle->log);
}
fprintf(stderr, "error: lua pcre malloc failed due to empty pcre pool");
return NULL;
}
void
ngx_http_lua_pcre_free(void *ptr, void *data)
{
dd("lua pcre pool is %p", ngx_http_lua_pcre_pool);
if (ngx_http_lua_pcre_pool) {
ngx_pfree(ngx_http_lua_pcre_pool, ptr);
return;
}
if (ngx_regex_direct_alloc) {
ngx_free(ptr);
return;
}
fprintf(stderr, "error: lua pcre free failed due to empty pcre pool");
}
#else
void *
ngx_http_lua_pcre_malloc(size_t size)
{
dd("lua pcre pool is %p", ngx_http_lua_pcre_pool);
@ -54,6 +100,41 @@ ngx_http_lua_pcre_free(void *ptr)
fprintf(stderr, "error: lua pcre free failed due to empty pcre pool");
}
#endif
#if (NGX_PCRE2)
ngx_pool_t *
ngx_http_lua_pcre_malloc_init(ngx_pool_t *pool)
{
ngx_pool_t *old_pool;
dd("lua pcre pool was %p", ngx_http_lua_pcre_pool);
ngx_regex_direct_alloc = (pool == NULL) ? 1 : 0;
old_pool = ngx_http_lua_pcre_pool;
ngx_http_lua_pcre_pool = pool;
dd("lua pcre pool is %p", ngx_http_lua_pcre_pool);
return old_pool;
}
void
ngx_http_lua_pcre_malloc_done(ngx_pool_t *old_pool)
{
dd("lua pcre pool was %p", ngx_http_lua_pcre_pool);
ngx_http_lua_pcre_pool = old_pool;
ngx_regex_direct_alloc = 0;
dd("lua pcre pool is %p", ngx_http_lua_pcre_pool);
}
#else
ngx_pool_t *
ngx_http_lua_pcre_malloc_init(ngx_pool_t *pool)
@ -101,6 +182,7 @@ ngx_http_lua_pcre_malloc_done(ngx_pool_t *old_pool)
}
}
#endif
#endif /* NGX_PCRE */
/* vi:set ft=c ts=4 sw=4 et fdm=marker: */

View file

@ -13,8 +13,15 @@
#if (NGX_PCRE)
ngx_pool_t *ngx_http_lua_pcre_malloc_init(ngx_pool_t *pool);
void ngx_http_lua_pcre_malloc_done(ngx_pool_t *old_pool);
#if NGX_PCRE2
void *ngx_http_lua_pcre_malloc(size_t size, void *data);
void ngx_http_lua_pcre_free(void *ptr, void *data);
#endif
#endif

View file

@ -9,7 +9,6 @@
#endif
#include "ddebug.h"
#if (NGX_PCRE)
#include "ngx_http_lua_pcrefix.h"
@ -17,13 +16,24 @@
#include "ngx_http_lua_util.h"
#if (PCRE_MAJOR >= 6)
#if (PCRE_MAJOR >= 6 || NGX_PCRE2)
# define LUA_HAVE_PCRE_DFA 1
#else
# define LUA_HAVE_PCRE_DFA 0
#endif
#if (NGX_PCRE2)
static pcre2_compile_context *ngx_regex_compile_context;
static pcre2_match_context *ngx_regex_match_context;
static pcre2_match_data *ngx_regex_match_data;
static ngx_uint_t ngx_regex_match_data_size = 0;
#define PCRE2_VERSION_SIZE 64
static char ngx_pcre2_version[PCRE2_VERSION_SIZE];
#endif
#define NGX_LUA_RE_MODE_DFA (1<<1)
#define NGX_LUA_RE_MODE_JIT (1<<2)
#define NGX_LUA_RE_NO_UTF8_CHECK (1<<4)
@ -42,8 +52,17 @@ typedef struct {
int ncaptures;
int *captures;
#if (NGX_PCRE2)
pcre2_code *regex;
/*
* pcre2 doesn't use pcre_extra any more,
* just for keeping same memory layout in the lua ffi cdef
*/
void *regex_sd;
#else
pcre *regex;
pcre_extra *regex_sd;
#endif
ngx_http_lua_complex_value_t *replace;
@ -57,7 +76,11 @@ typedef struct {
ngx_pool_t *pool;
ngx_int_t options;
#if (NGX_PCRE2)
pcre2_code *regex;
#else
pcre *regex;
#endif
int captures;
ngx_str_t err;
} ngx_http_lua_regex_compile_t;
@ -65,8 +88,12 @@ typedef struct {
typedef struct {
ngx_http_request_t *request;
#if (NGX_PCRE2)
pcre2_code *regex;
#else
pcre *regex;
pcre_extra *regex_sd;
#endif
int ncaptures;
int *captures;
int captures_len;
@ -74,8 +101,6 @@ typedef struct {
} ngx_http_lua_regex_ctx_t;
static void ngx_http_lua_regex_free_study_data(ngx_pool_t *pool,
pcre_extra *sd);
static ngx_int_t ngx_http_lua_regex_compile(ngx_http_lua_regex_compile_t *rc);
@ -91,22 +116,156 @@ static ngx_int_t ngx_http_lua_regex_compile(ngx_http_lua_regex_compile_t *rc);
static void
ngx_http_lua_regex_free_study_data(ngx_pool_t *pool, pcre_extra *sd)
ngx_http_lua_regex_free_study_data(ngx_pool_t *pool, ngx_http_lua_regex_t *re)
{
ngx_pool_t *old_pool;
ngx_pool_t *old_pool;
old_pool = ngx_http_lua_pcre_malloc_init(pool);
#if (NGX_PCRE2)
if (re && re->regex) {
old_pool = ngx_http_lua_pcre_malloc_init(pool);
#if LUA_HAVE_PCRE_JIT
pcre_free_study(sd);
pcre2_code_free(re->regex);
ngx_http_lua_pcre_malloc_done(old_pool);
re->regex = NULL;
}
#else
pcre_free(sd);
if (re && re->regex_sd) {
old_pool = ngx_http_lua_pcre_malloc_init(pool);
#if LUA_HAVE_PCRE_JIT
pcre_free_study(re->regex_sd);
#else
pcre_free(re->regex_sd);
#endif
ngx_http_lua_pcre_malloc_done(old_pool);
ngx_http_lua_pcre_malloc_done(old_pool);
re->regex_sd = NULL;
}
#endif
}
#if (NGX_PCRE2)
static ngx_int_t
ngx_http_lua_regex_compile(ngx_http_lua_regex_compile_t *rc)
{
int n, errcode;
char *p;
size_t erroff;
u_char errstr[128];
pcre2_code *re;
ngx_pool_t *old_pool;
pcre2_general_context *gctx;
pcre2_compile_context *cctx;
ngx_http_lua_main_conf_t *lmcf;
if (ngx_regex_compile_context == NULL) {
/*
* Allocate a compile context if not yet allocated. This uses
* direct allocations from heap, so the result can be cached
* even at runtime.
*/
old_pool = ngx_http_lua_pcre_malloc_init(NULL);
gctx = pcre2_general_context_create(ngx_http_lua_pcre_malloc,
ngx_http_lua_pcre_free,
NULL);
if (gctx == NULL) {
ngx_http_lua_pcre_malloc_done(old_pool);
goto nomem;
}
cctx = pcre2_compile_context_create(gctx);
if (cctx == NULL) {
pcre2_general_context_free(gctx);
ngx_http_lua_pcre_malloc_done(old_pool);
goto nomem;
}
ngx_regex_compile_context = cctx;
ngx_regex_match_context = pcre2_match_context_create(gctx);
if (ngx_regex_match_context == NULL) {
pcre2_general_context_free(gctx);
ngx_http_lua_pcre_malloc_done(old_pool);
goto nomem;
}
lmcf = ngx_http_cycle_get_module_main_conf(ngx_cycle,
ngx_http_lua_module);
if (lmcf && lmcf->regex_match_limit > 0) {
pcre2_set_match_limit(ngx_regex_match_context,
lmcf->regex_match_limit);
}
pcre2_general_context_free(gctx);
ngx_http_lua_pcre_malloc_done(old_pool);
}
old_pool = ngx_http_lua_pcre_malloc_init(rc->pool);
re = pcre2_compile(rc->pattern.data,
rc->pattern.len, rc->options,
&errcode, &erroff, ngx_regex_compile_context);
ngx_http_lua_pcre_malloc_done(old_pool);
if (re == NULL) {
pcre2_get_error_message(errcode, errstr, 128);
if ((size_t) erroff == rc->pattern.len) {
rc->err.len = ngx_snprintf(rc->err.data, rc->err.len,
"pcre2_compile() failed: %s in \"%V\"",
errstr, &rc->pattern)
- rc->err.data;
} else {
rc->err.len = ngx_snprintf(rc->err.data, rc->err.len,
"pcre2_compile() failed: %s in "
"\"%V\" at \"%s\"", errstr, &rc->pattern,
rc->pattern.data + erroff)
- rc->err.data;
}
return NGX_ERROR;
}
rc->regex = re;
n = pcre2_pattern_info(re, PCRE2_INFO_CAPTURECOUNT, &rc->captures);
if (n < 0) {
p = "pcre2_pattern_info(\"%V\", PCRE_INFO_CAPTURECOUNT) failed: %d";
goto failed;
}
#if (NGX_DEBUG)
ngx_log_debug3(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
"pcre2_compile: pattern[%V], options 0x%08Xd, ncaptures %d",
&rc->pattern, rc->options, rc->captures);
#endif
return NGX_OK;
failed:
rc->err.len = ngx_snprintf(rc->err.data, rc->err.len, p, &rc->pattern, n)
- rc->err.data;
return NGX_ERROR;
nomem:
rc->err.len = ngx_snprintf(rc->err.data, rc->err.len,
"regex \"%V\" compilation failed: no memory",
&rc->pattern)
- rc->err.data;
return NGX_ERROR;
}
#else
static ngx_int_t
ngx_http_lua_regex_compile(ngx_http_lua_regex_compile_t *rc)
{
@ -159,13 +318,14 @@ failed:
- rc->err.data;
return NGX_OK;
}
#endif
ngx_int_t
ngx_http_lua_ffi_set_jit_stack_size(int size, u_char *errstr,
size_t *errstr_size)
{
#if LUA_HAVE_PCRE_JIT
#if (LUA_HAVE_PCRE_JIT)
ngx_http_lua_main_conf_t *lmcf;
ngx_pool_t *pool, *old_pool;
@ -186,15 +346,24 @@ ngx_http_lua_ffi_set_jit_stack_size(int size, u_char *errstr,
if (lmcf->jit_stack) {
old_pool = ngx_http_lua_pcre_malloc_init(pool);
#if (NGX_PCRE2)
pcre2_jit_stack_free(lmcf->jit_stack);
#else
pcre_jit_stack_free(lmcf->jit_stack);
#endif
ngx_http_lua_pcre_malloc_done(old_pool);
}
old_pool = ngx_http_lua_pcre_malloc_init(pool);
#if (NGX_PCRE2)
lmcf->jit_stack = pcre2_jit_stack_create(NGX_LUA_RE_MIN_JIT_STACK_SIZE,
size, NULL);
#else
lmcf->jit_stack = pcre_jit_stack_alloc(NGX_LUA_RE_MIN_JIT_STACK_SIZE,
size);
#endif
ngx_http_lua_pcre_malloc_done(old_pool);
@ -214,10 +383,150 @@ ngx_http_lua_ffi_set_jit_stack_size(int size, u_char *errstr,
- errstr;
return NGX_ERROR;
#endif /* LUA_HAVE_PCRE_JIT */
#endif
}
#if (NGX_PCRE2)
static void
ngx_http_lua_regex_jit_compile(ngx_http_lua_regex_t *re, int flags,
ngx_pool_t *pool, ngx_http_lua_main_conf_t *lmcf,
ngx_http_lua_regex_compile_t *re_comp)
{
ngx_int_t ret;
ngx_pool_t *old_pool;
if (flags & NGX_LUA_RE_MODE_JIT) {
old_pool = ngx_http_lua_pcre_malloc_init(pool);
ret = pcre2_jit_compile(re_comp->regex, PCRE2_JIT_COMPLETE);
if (ret != 0) {
ngx_log_error(NGX_LOG_INFO, ngx_cycle->log, 0,
"pcre2_jit_compile() failed: %d in \"%V\", "
"ignored",
ret, &re_comp->pattern);
#if (NGX_DEBUG)
} else {
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
"pcre2 JIT compiled successfully");
# endif /* !(NGX_DEBUG) */
}
ngx_http_lua_pcre_malloc_done(old_pool);
}
if (lmcf && lmcf->jit_stack) {
pcre2_jit_stack_assign(ngx_regex_match_context, NULL,
lmcf->jit_stack);
}
return;
}
#else
static void
ngx_http_lua_regex_jit_compile(ngx_http_lua_regex_t *re, int flags,
ngx_pool_t *pool, ngx_http_lua_main_conf_t *lmcf,
ngx_http_lua_regex_compile_t *re_comp)
{
const char *msg;
pcre_extra *sd = NULL;
ngx_pool_t *old_pool;
#if (LUA_HAVE_PCRE_JIT)
if (flags & NGX_LUA_RE_MODE_JIT) {
old_pool = ngx_http_lua_pcre_malloc_init(pool);
sd = pcre_study(re_comp->regex, PCRE_STUDY_JIT_COMPILE, &msg);
ngx_http_lua_pcre_malloc_done(old_pool);
# if (NGX_DEBUG)
if (msg != NULL) {
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
"pcre study failed with PCRE_STUDY_JIT_COMPILE: "
"%s (%p)", msg, sd);
}
if (sd != NULL) {
int jitted;
old_pool = ngx_http_lua_pcre_malloc_init(pool);
pcre_fullinfo(re_comp->regex, sd, PCRE_INFO_JIT, &jitted);
ngx_http_lua_pcre_malloc_done(old_pool);
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
"pcre JIT compiling result: %d", jitted);
}
# endif /* !(NGX_DEBUG) */
} else {
old_pool = ngx_http_lua_pcre_malloc_init(pool);
sd = pcre_study(re_comp->regex, 0, &msg);
ngx_http_lua_pcre_malloc_done(old_pool);
}
if (sd && lmcf && lmcf->jit_stack) {
pcre_assign_jit_stack(sd, NULL, lmcf->jit_stack);
}
if (sd
&& lmcf && lmcf->regex_match_limit > 0
&& !(flags & NGX_LUA_RE_MODE_DFA))
{
sd->flags |= PCRE_EXTRA_MATCH_LIMIT;
sd->match_limit = lmcf->regex_match_limit;
}
#endif /* LUA_HAVE_PCRE_JIT */
re->regex_sd = sd;
}
#endif
#if (NGX_PCRE2)
void
ngx_http_lua_regex_cleanup(void *data)
{
ngx_pool_t *old_pool;
ngx_http_lua_main_conf_t *lmcf;
lmcf = data;
if (ngx_regex_compile_context) {
old_pool = ngx_http_lua_pcre_malloc_init(NULL);
pcre2_compile_context_free(ngx_regex_compile_context);
ngx_regex_compile_context = NULL;
ngx_http_lua_pcre_malloc_done(old_pool);
}
if (lmcf && lmcf->jit_stack) {
old_pool = ngx_http_lua_pcre_malloc_init(NULL);
pcre2_jit_stack_free(lmcf->jit_stack);
lmcf->jit_stack = NULL;
ngx_http_lua_pcre_malloc_done(old_pool);
}
if (ngx_regex_match_data) {
old_pool = ngx_http_lua_pcre_malloc_init(NULL);
pcre2_match_data_free(ngx_regex_match_data);
ngx_regex_match_data = NULL;
ngx_regex_match_data_size = 0;
ngx_http_lua_pcre_malloc_done(old_pool);
}
}
#endif
ngx_http_lua_regex_t *
ngx_http_lua_ffi_compile_regex(const unsigned char *pat, size_t pat_len,
int flags, int pcre_opts, u_char *errstr,
@ -228,8 +537,7 @@ ngx_http_lua_ffi_compile_regex(const unsigned char *pat, size_t pat_len,
ngx_int_t rc;
const char *msg;
ngx_pool_t *pool, *old_pool;
pcre_extra *sd = NULL;
ngx_http_lua_regex_t *re;
ngx_http_lua_regex_t *re = NULL;
ngx_http_lua_main_conf_t *lmcf;
ngx_http_lua_regex_compile_t re_comp;
@ -251,6 +559,8 @@ ngx_http_lua_ffi_compile_regex(const unsigned char *pat, size_t pat_len,
}
re->pool = pool;
re->regex = NULL;
re->regex_sd = NULL;
re_comp.options = pcre_opts;
re_comp.pattern.data = (u_char *) pat;
@ -274,54 +584,7 @@ ngx_http_lua_ffi_compile_regex(const unsigned char *pat, size_t pat_len,
ngx_http_lua_assert(lmcf != NULL);
#if (LUA_HAVE_PCRE_JIT)
if (flags & NGX_LUA_RE_MODE_JIT) {
old_pool = ngx_http_lua_pcre_malloc_init(pool);
sd = pcre_study(re_comp.regex, PCRE_STUDY_JIT_COMPILE, &msg);
ngx_http_lua_pcre_malloc_done(old_pool);
# if (NGX_DEBUG)
if (msg != NULL) {
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
"pcre study failed with PCRE_STUDY_JIT_COMPILE: "
"%s (%p)", msg, sd);
}
if (sd != NULL) {
int jitted;
old_pool = ngx_http_lua_pcre_malloc_init(pool);
pcre_fullinfo(re_comp.regex, sd, PCRE_INFO_JIT, &jitted);
ngx_http_lua_pcre_malloc_done(old_pool);
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
"pcre JIT compiling result: %d", jitted);
}
# endif /* !(NGX_DEBUG) */
} else {
old_pool = ngx_http_lua_pcre_malloc_init(pool);
sd = pcre_study(re_comp.regex, 0, &msg);
ngx_http_lua_pcre_malloc_done(old_pool);
}
if (sd && lmcf->jit_stack) {
pcre_assign_jit_stack(sd, NULL, lmcf->jit_stack);
}
#endif /* LUA_HAVE_PCRE_JIT */
if (sd
&& lmcf && lmcf->regex_match_limit > 0
&& !(flags & NGX_LUA_RE_MODE_DFA))
{
sd->flags |= PCRE_EXTRA_MATCH_LIMIT;
sd->match_limit = lmcf->regex_match_limit;
}
ngx_http_lua_regex_jit_compile(re, flags, pool, lmcf, &re_comp);
if (flags & NGX_LUA_RE_MODE_DFA) {
ovecsize = 2;
@ -339,6 +602,31 @@ ngx_http_lua_ffi_compile_regex(const unsigned char *pat, size_t pat_len,
goto error;
}
#if (NGX_PCRE2)
if (pcre2_pattern_info(re_comp.regex, PCRE2_INFO_NAMECOUNT,
&re->name_count) < 0)
{
msg = "cannot acquire named subpattern count";
goto error;
}
if (re->name_count > 0) {
if (pcre2_pattern_info(re_comp.regex, PCRE2_INFO_NAMEENTRYSIZE,
&re->name_entry_size) != 0)
{
msg = "cannot acquire named subpattern entry size";
goto error;
}
if (pcre2_pattern_info(re_comp.regex, PCRE2_INFO_NAMETABLE,
&re->name_table) != 0)
{
msg = "cannot acquire named subpattern table";
goto error;
}
}
#else
if (pcre_fullinfo(re_comp.regex, NULL, PCRE_INFO_NAMECOUNT,
&re->name_count) != 0)
{
@ -361,9 +649,9 @@ ngx_http_lua_ffi_compile_regex(const unsigned char *pat, size_t pat_len,
goto error;
}
}
#endif
re->regex = re_comp.regex;
re->regex_sd = sd;
re->ncaptures = re_comp.captures;
re->captures = cap;
re->replace = NULL;
@ -379,9 +667,7 @@ error:
p = ngx_snprintf(errstr, errstr_size - 1, "%s", msg);
*p = '\0';
if (sd) {
ngx_http_lua_regex_free_study_data(pool, sd);
}
ngx_http_lua_regex_free_study_data(pool, re);
if (pool) {
ngx_destroy_pool(pool);
@ -391,6 +677,103 @@ error:
}
#if (NGX_PCRE2)
int
ngx_http_lua_ffi_exec_regex(ngx_http_lua_regex_t *re, int flags,
const u_char *s, size_t len, int pos)
{
int rc, exec_opts = 0;
size_t *ov;
ngx_uint_t ovecsize, n, i;
ngx_pool_t *old_pool;
if (flags & NGX_LUA_RE_MODE_DFA) {
ovecsize = 2;
re->ncaptures = 0;
} else {
ovecsize = (re->ncaptures + 1) * 3;
}
old_pool = ngx_http_lua_pcre_malloc_init(NULL);
if (ngx_regex_match_data == NULL
|| ovecsize > ngx_regex_match_data_size)
{
/*
* Allocate a match data if not yet allocated or smaller than
* needed.
*/
if (ngx_regex_match_data) {
pcre2_match_data_free(ngx_regex_match_data);
}
ngx_regex_match_data_size = ovecsize;
ngx_regex_match_data = pcre2_match_data_create(ovecsize / 3, NULL);
if (ngx_regex_match_data == NULL) {
rc = PCRE2_ERROR_NOMEMORY;
goto failed;
}
}
if (flags & NGX_LUA_RE_NO_UTF8_CHECK) {
exec_opts = PCRE2_NO_UTF_CHECK;
} else {
exec_opts = 0;
}
if (flags & NGX_LUA_RE_MODE_DFA) {
int ws[NGX_LUA_RE_DFA_MODE_WORKSPACE_COUNT];
rc = pcre2_dfa_match(re->regex, s, len, pos, exec_opts,
ngx_regex_match_data, ngx_regex_match_context,
ws, sizeof(ws) / sizeof(ws[0]));
} else {
rc = pcre2_match(re->regex, s, len, pos, exec_opts,
ngx_regex_match_data, ngx_regex_match_context);
}
if (rc < 0) {
#if (NGX_DEBUG)
ngx_log_debug4(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
"pcre2_match failed: flags 0x%05Xd, options 0x%08Xd, "
"rc %d, ovecsize %ui", flags, exec_opts, rc, ovecsize);
#endif
goto failed;
}
n = pcre2_get_ovector_count(ngx_regex_match_data);
ov = pcre2_get_ovector_pointer(ngx_regex_match_data);
#if (NGX_DEBUG)
ngx_log_debug5(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
"pcre2_match: flags 0x%05Xd, options 0x%08Xd, rc %d, "
"n %ui, ovecsize %ui", flags, exec_opts, rc, n, ovecsize);
#endif
if (!(flags & NGX_LUA_RE_MODE_DFA) && n > ovecsize / 3) {
n = ovecsize / 3;
}
for (i = 0; i < n; i++) {
re->captures[i * 2] = ov[i * 2];
re->captures[i * 2 + 1] = ov[i * 2 + 1];
}
failed:
ngx_http_lua_pcre_malloc_done(old_pool);
return rc;
}
#else
int
ngx_http_lua_ffi_exec_regex(ngx_http_lua_regex_t *re, int flags,
const u_char *s, size_t len, int pos)
@ -427,7 +810,8 @@ ngx_http_lua_ffi_exec_regex(ngx_http_lua_regex_t *re, int flags,
int ws[NGX_LUA_RE_DFA_MODE_WORKSPACE_COUNT];
rc = ngx_http_lua_regex_dfa_exec(re->regex, sd, &subj,
(int) pos, cap, ovecsize, ws,
sizeof(ws)/sizeof(ws[0]), exec_opts);
sizeof(ws) / sizeof(ws[0]),
exec_opts);
#else
@ -443,28 +827,19 @@ ngx_http_lua_ffi_exec_regex(ngx_http_lua_regex_t *re, int flags,
return rc;
}
#endif
void
ngx_http_lua_ffi_destroy_regex(ngx_http_lua_regex_t *re)
{
ngx_pool_t *old_pool;
dd("destroy regex called");
if (re == NULL || re->pool == NULL) {
return;
}
if (re->regex_sd) {
old_pool = ngx_http_lua_pcre_malloc_init(re->pool);
#if LUA_HAVE_PCRE_JIT
pcre_free_study(re->regex_sd);
#else
pcre_free(re->regex_sd);
#endif
ngx_http_lua_pcre_malloc_done(old_pool);
re->regex_sd = NULL;
}
ngx_http_lua_regex_free_study_data(re->pool, re);
ngx_destroy_pool(re->pool);
}
@ -592,7 +967,13 @@ ngx_http_lua_ffi_max_regex_cache_size(void)
const char *
ngx_http_lua_ffi_pcre_version(void)
{
#if (NGX_PCRE2)
pcre2_config(PCRE2_CONFIG_VERSION, ngx_pcre2_version);
return ngx_pcre2_version;
#else
return pcre_version();
#endif
}

View file

@ -85,6 +85,23 @@ ngx_http_lua_ngx_req_read_body(lua_State *L)
return luaL_error(L, "request object not found");
}
/* http2 read body may break http2 stream process */
#if (NGX_HTTP_V2)
if (r->main->stream && r->headers_in.content_length_n < 0) {
return luaL_error(L, "http2 requests are not supported"
" without content-length header");
}
#endif
#if (NGX_HTTP_V3)
if (r->http_version == NGX_HTTP_VERSION_30
&& r->headers_in.content_length_n < 0)
{
return luaL_error(L, "http3 requests are not supported"
" without content-length header");
}
#endif
r->request_body_in_single_buf = 1;
r->request_body_in_persistent_file = 1;
r->request_body_in_clean_file = 1;
@ -229,15 +246,21 @@ ngx_http_lua_ngx_req_get_body_data(lua_State *L)
{
ngx_http_request_t *r;
int n;
size_t len;
size_t len, max;
size_t size, rest;
ngx_chain_t *cl;
u_char *p;
u_char *buf;
n = lua_gettop(L);
if (n != 0) {
return luaL_error(L, "expecting 0 arguments but seen %d", n);
if (n != 0 && n != 1) {
return luaL_error(L, "expecting 0 or 1 arguments but seen %d", n);
}
max = 0;
if (n == 1) {
max = (size_t) luaL_checknumber(L, 1);
}
r = ngx_http_lua_get_req(L);
@ -265,6 +288,7 @@ ngx_http_lua_ngx_req_get_body_data(lua_State *L)
return 1;
}
len = (max > 0 && len > max) ? max : len;
lua_pushlstring(L, (char *) cl->buf->pos, len);
return 1;
}
@ -275,7 +299,13 @@ ngx_http_lua_ngx_req_get_body_data(lua_State *L)
for (; cl; cl = cl->next) {
dd("body chunk len: %d", (int) ngx_buf_size(cl->buf));
len += cl->buf->last - cl->buf->pos;
size = cl->buf->last - cl->buf->pos;
if (max > 0 && (len + size > max)) {
len = max;
break;
}
len += size;
}
if (len == 0) {
@ -286,8 +316,15 @@ ngx_http_lua_ngx_req_get_body_data(lua_State *L)
buf = (u_char *) lua_newuserdata(L, len);
p = buf;
for (cl = r->request_body->bufs; cl; cl = cl->next) {
p = ngx_copy(p, cl->buf->pos, cl->buf->last - cl->buf->pos);
rest = len;
for (cl = r->request_body->bufs; cl != NULL && rest > 0; cl = cl->next) {
size = ngx_buf_size(cl->buf);
if (size > rest) { /* reach limit*/
size = rest;
}
p = ngx_copy(p, cl->buf->pos, size);
rest -= size;
}
lua_pushlstring(L, (char *) buf, len);
@ -312,6 +349,23 @@ ngx_http_lua_ngx_req_get_body_file(lua_State *L)
return luaL_error(L, "request object not found");
}
/* http2 read body may break http2 stream process */
#if (NGX_HTTP_V2)
if (r->main->stream && r->headers_in.content_length_n < 0) {
return luaL_error(L, "http2 requests are not supported"
" without content-length header");
}
#endif
#if (NGX_HTTP_V3)
if (r->http_version == NGX_HTTP_VERSION_30
&& r->headers_in.content_length_n < 0)
{
return luaL_error(L, "http3 requests are not supported"
" without content-length header");
}
#endif
ngx_http_lua_check_fake_request(L, r);
if (r->request_body == NULL || r->request_body->temp_file == NULL) {

View file

@ -140,7 +140,12 @@ ngx_http_lua_rewrite_handler(ngx_http_request_t *r)
return NGX_DONE;
}
/* http2 read body may break http2 stream process */
#if (NGX_HTTP_V2)
if (llcf->force_read_body && !ctx->read_body_done && !r->main->stream) {
#else
if (llcf->force_read_body && !ctx->read_body_done) {
#endif
r->request_body_in_single_buf = 1;
r->request_body_in_persistent_file = 1;
r->request_body_in_clean_file = 1;

View file

@ -102,8 +102,13 @@ ngx_http_lua_server_rewrite_handler(ngx_http_request_t *r)
return NGX_DONE;
}
/* TODO: lscf do not have force_read_body */
/* TODO: lscf do not have force_read_body
* http2 read body may break http2 stream process */
#if (NGX_HTTP_V2)
if (llcf->force_read_body && !ctx->read_body_done && !r->main->stream) {
#else
if (llcf->force_read_body && !ctx->read_body_done) {
#endif
r->request_body_in_single_buf = 1;
r->request_body_in_persistent_file = 1;
r->request_body_in_clean_file = 1;

View file

@ -198,9 +198,6 @@ ngx_http_lua_shdict_lookup(ngx_shm_zone_t *shm_zone, ngx_uint_t hash,
rc = ngx_memn2cmp(kdata, sd->data, klen, (size_t) sd->key_len);
if (rc == 0) {
ngx_queue_remove(&sd->queue);
ngx_queue_insert_head(&ctx->sh->lru_queue, &sd->queue);
*sdp = sd;
dd("node expires: %lld", (long long) sd->expires);
@ -219,6 +216,9 @@ ngx_http_lua_shdict_lookup(ngx_shm_zone_t *shm_zone, ngx_uint_t hash,
}
}
ngx_queue_remove(&sd->queue);
ngx_queue_insert_head(&ctx->sh->lru_queue, &sd->queue);
return NGX_OK;
}
@ -654,7 +654,7 @@ ngx_http_lua_shared_dict_get(ngx_shm_zone_t *zone, u_char *key_data,
return NGX_ERROR;
}
ngx_memcpy(&value->value.b, data, len);
ngx_memcpy(&value->value.n, data, len);
break;
case SHDICT_TBOOLEAN:

View file

@ -75,6 +75,8 @@ static void ngx_http_lua_socket_dummy_handler(ngx_http_request_t *r,
ngx_http_lua_socket_tcp_upstream_t *u);
static int ngx_http_lua_socket_tcp_receive_helper(ngx_http_request_t *r,
ngx_http_lua_socket_tcp_upstream_t *u, lua_State *L);
static void ngx_http_lua_socket_tcp_read_prepare(ngx_http_request_t *r,
ngx_http_lua_socket_tcp_upstream_t *u, void *data, lua_State *L);
static ngx_int_t ngx_http_lua_socket_tcp_read(ngx_http_request_t *r,
ngx_http_lua_socket_tcp_upstream_t *u);
static int ngx_http_lua_socket_tcp_receive_retval_handler(ngx_http_request_t *r,
@ -863,7 +865,9 @@ ngx_http_lua_socket_tcp_bind(lua_State *L)
| NGX_HTTP_LUA_CONTEXT_ACCESS
| NGX_HTTP_LUA_CONTEXT_CONTENT
| NGX_HTTP_LUA_CONTEXT_TIMER
| NGX_HTTP_LUA_CONTEXT_SSL_CERT);
| NGX_HTTP_LUA_CONTEXT_SSL_CERT
| NGX_HTTP_LUA_CONTEXT_SSL_SESS_FETCH
| NGX_HTTP_LUA_CONTEXT_SSL_CLIENT_HELLO);
luaL_checktype(L, 1, LUA_TTABLE);
@ -2163,8 +2167,6 @@ ngx_http_lua_socket_tcp_receive_helper(ngx_http_request_t *r,
ngx_http_lua_ctx_t *ctx;
ngx_http_lua_co_ctx_t *coctx;
u->input_filter_ctx = u;
ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
if (u->bufs_in == NULL) {
@ -2193,6 +2195,8 @@ ngx_http_lua_socket_tcp_receive_helper(ngx_http_request_t *r,
u->read_waiting = 0;
u->read_co_ctx = NULL;
ngx_http_lua_socket_tcp_read_prepare(r, u, u, L);
rc = ngx_http_lua_socket_tcp_read(r, u);
if (rc == NGX_ERROR) {
@ -2409,7 +2413,7 @@ ngx_http_lua_socket_tcp_receive(lua_State *L)
case LUA_TNUMBER:
bytes = lua_tointeger(L, 2);
if (bytes < 0) {
return luaL_argerror(L, 2, "bad pattern argument");
return luaL_argerror(L, 2, "bad number argument");
}
#if 1
@ -2426,7 +2430,7 @@ ngx_http_lua_socket_tcp_receive(lua_State *L)
break;
default:
return luaL_argerror(L, 2, "bad pattern argument");
return luaL_argerror(L, 2, "bad argument");
break;
}
@ -2514,6 +2518,87 @@ ngx_http_lua_socket_read_any(void *data, ssize_t bytes)
}
static void
ngx_http_lua_socket_tcp_read_prepare(ngx_http_request_t *r,
ngx_http_lua_socket_tcp_upstream_t *u, void *data, lua_State *L)
{
ngx_http_lua_ctx_t *ctx;
ngx_chain_t *new_cl;
ngx_buf_t *b;
off_t size;
ngx_http_lua_socket_compiled_pattern_t *cp;
/* input_filter_ctx doesn't change, no need recovering */
if (u->input_filter_ctx == data) {
return;
}
/* last input_filter_ctx is null or upstream, no data pending */
if (u->input_filter_ctx == NULL || u->input_filter_ctx == u) {
u->input_filter_ctx = data;
return;
}
/* compiled pattern may be with data pending */
cp = u->input_filter_ctx;
u->input_filter_ctx = data;
cp->upstream = NULL;
/* no data pending */
if (cp->state <= 0) {
return;
}
b = &u->buffer;
if (b->pos - b->start >= cp->state) {
dd("pending data in one buffer");
b->pos -= cp->state;
u->buf_in->buf->pos = b->pos;
u->buf_in->buf->last = b->pos;
/* reset dfa state for future matching */
cp->state = 0;
return;
}
dd("pending data in multiple buffers");
ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
size = ngx_buf_size(b);
new_cl =
ngx_http_lua_chain_get_free_buf(r->connection->log, r->pool,
&ctx->free_recv_bufs,
cp->state + size);
if (new_cl == NULL) {
luaL_error(L, "no memory");
return;
}
ngx_memcpy(b, new_cl->buf, sizeof(ngx_buf_t));
b->last = ngx_copy(b->last, cp->pattern.data, cp->state);
b->last = ngx_copy(b->last, u->buf_in->buf->pos, size);
u->buf_in->next = ctx->free_recv_bufs;
ctx->free_recv_bufs = u->buf_in;
u->bufs_in = new_cl;
u->buf_in = new_cl;
/* reset dfa state for future matching */
cp->state = 0;
}
static ngx_int_t
ngx_http_lua_socket_tcp_read(ngx_http_request_t *r,
ngx_http_lua_socket_tcp_upstream_t *u)
@ -3261,7 +3346,7 @@ ngx_http_lua_socket_tcp_settimeouts(lua_State *L)
n = lua_gettop(L);
if (n != 4) {
return luaL_error(L, "ngx.socket settimeout: expecting 4 arguments "
return luaL_error(L, "ngx.socket settimeouts: expecting 4 arguments "
"(including the object) but seen %d", lua_gettop(L));
}
@ -4243,6 +4328,11 @@ ngx_http_lua_socket_tcp_finalize(ngx_http_request_t *r,
ngx_http_lua_socket_tcp_finalize_read_part(r, u);
ngx_http_lua_socket_tcp_finalize_write_part(r, u);
if (u->input_filter_ctx != NULL && u->input_filter_ctx != u) {
((ngx_http_lua_socket_compiled_pattern_t *)
u->input_filter_ctx)->upstream = NULL;
}
if (u->raw_downstream || u->body_downstream) {
u->peer.connection = NULL;
return;
@ -4496,7 +4586,7 @@ ngx_http_lua_socket_receiveuntil_iterator(lua_State *L)
n = lua_gettop(L);
if (n > 1) {
return luaL_error(L, "expecting 0 or 1 arguments, "
return luaL_error(L, "expecting 0 or 1 argument, "
"but seen %d", n);
}
@ -4559,8 +4649,6 @@ ngx_http_lua_socket_receiveuntil_iterator(lua_State *L)
(u_char *) lua_tolstring(L, lua_upvalueindex(2),
&cp->pattern.len);
u->input_filter_ctx = cp;
ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module);
if (u->bufs_in == NULL) {
@ -4587,6 +4675,8 @@ ngx_http_lua_socket_receiveuntil_iterator(lua_State *L)
u->read_waiting = 0;
u->read_co_ctx = NULL;
ngx_http_lua_socket_tcp_read_prepare(r, u, cp, L);
rc = ngx_http_lua_socket_tcp_read(r, u);
if (rc == NGX_ERROR) {
@ -4915,13 +5005,24 @@ ngx_http_lua_socket_cleanup_compiled_pattern(lua_State *L)
{
ngx_http_lua_socket_compiled_pattern_t *cp;
ngx_http_lua_dfa_edge_t *edge, *p;
unsigned i;
ngx_http_lua_socket_tcp_upstream_t *u;
ngx_http_lua_dfa_edge_t *edge, *p;
unsigned i;
dd("cleanup compiled pattern");
cp = lua_touserdata(L, 1);
if (cp == NULL || cp->recovering == NULL) {
if (cp == NULL) {
return 0;
}
u = cp->upstream;
if (u != NULL) {
ngx_http_lua_socket_tcp_read_prepare(u->request, u, NULL, L);
u->input_filter_ctx = NULL;
}
if (cp->recovering == NULL) {
return 0;
}
@ -4975,7 +5076,7 @@ ngx_http_lua_req_socket(lua_State *L)
lua_pop(L, 1);
} else {
return luaL_error(L, "expecting zero arguments, but got %d",
return luaL_error(L, "expecting 0 or 1 argument, but got %d",
lua_gettop(L));
}
@ -4998,6 +5099,12 @@ ngx_http_lua_req_socket(lua_State *L)
}
#endif
#if (NGX_HTTP_V3)
if (r->http_version == NGX_HTTP_VERSION_30) {
return luaL_error(L, "http v3 not supported yet");
}
#endif
if (!raw && r->headers_in.chunked) {
lua_pushnil(L);
lua_pushliteral(L, "chunked request bodies not supported yet");
@ -5494,6 +5601,7 @@ ngx_http_lua_socket_tcp_setkeepalive(lua_State *L)
if (c->read->ready) {
rc = ngx_http_lua_socket_keepalive_close_handler(c->read);
if (rc != NGX_OK) {
ngx_http_lua_socket_tcp_finalize(r, u);
lua_pushnil(L);
lua_pushliteral(L, "connection in dubious state");
return 2;

View file

@ -390,7 +390,7 @@ ngx_http_lua_ssl_client_hello_aborted(void *data)
{
ngx_http_lua_ssl_ctx_t *cctx = data;
dd("lua ssl client hello done");
dd("lua ssl client hello aborted");
if (cctx->done) {
/* completed successfully already */

View file

@ -52,6 +52,8 @@ ngx_str_t ngx_http_lua_patch_method =
ngx_str_t ngx_http_lua_trace_method =
ngx_http_lua_method_name("TRACE");
ngx_str_t host_header = ngx_string("host");
static ngx_str_t ngx_http_lua_content_length_header_key =
ngx_string("Content-Length");
@ -1667,6 +1669,9 @@ ngx_http_lua_copy_request_headers(ngx_http_request_t *sr,
clh->hash = ngx_http_lua_content_length_hash;
clh->key = ngx_http_lua_content_length_header_key;
#if defined(nginx_version) && nginx_version >= 1023000
clh->next = NULL;
#endif
clh->lowcase_key = ngx_pnalloc(sr->pool, clh->key.len);
if (clh->lowcase_key == NULL) {
return NGX_ERROR;
@ -1696,6 +1701,17 @@ ngx_http_lua_copy_request_headers(ngx_http_request_t *sr,
part = &pr->headers_in.headers.part;
header = part->elts;
#if (NGX_HTTP_V3)
if (pr->headers_in.server.data != NULL) {
if (ngx_http_lua_set_input_header(sr, host_header,
pr->headers_in.server, 0)
== NGX_ERROR)
{
return NGX_ERROR;
}
}
#endif
for (i = 0; /* void */; i++) {
if (i >= part->nelts) {

View file

@ -70,6 +70,18 @@ ngx_http_lua_ffi_var_get(ngx_http_request_t *r, u_char *name_data,
}
#endif
#if (NGX_HTTP_V3)
if (name_len == 9
&& r->http_version == NGX_HTTP_VERSION_30
&& ngx_strncasecmp(name_data, (u_char *) "http_host", 9) == 0
&& r->headers_in.server.data != NULL)
{
*value = r->headers_in.server.data;
*value_len = r->headers_in.server.len;
return NGX_OK;
}
#endif
hash = ngx_hash_strlow(lowcase_buf, name_data, name_len);
name.data = lowcase_buf;

View file

@ -42,7 +42,7 @@ typedef struct {
ngx_http_lua_co_ctx_t *wait_co_ctx;
int n_args;
int rc;
int is_abort:1;
ngx_uint_t is_abort:1;
} ngx_http_lua_worker_thread_ctx_t;
@ -157,15 +157,6 @@ ngx_http_lua_get_task_ctx(lua_State *L, ngx_http_request_t *r)
ngx_http_lua_inject_shdict_api(lmcf, vm);
lua_setglobal(vm, "ngx");
/* inject API via ffi */
lua_getglobal(vm, "require");
lua_pushstring(vm, "resty.core.regex");
if (lua_pcall(vm, 1, 0, 0) != 0) {
lua_close(vm);
ngx_free(ctx);
return NULL;
}
lua_getglobal(vm, "require");
lua_pushstring(vm, "resty.core.hash");
if (lua_pcall(vm, 1, 0, 0) != 0) {

View file

@ -11,7 +11,7 @@ $ENV{TEST_NGINX_MYSQL_PORT} ||= 3306;
our $http_config = <<'_EOC_';
# lua-resty-string is required for lua-resty-mysql
lua_package_path "../lua-resty-mysql/lib/?.lua;../lua-resty-string/lib/?.lua;;";
lua_package_path "../lua-resty-rsa/lib/?.lua;../lua-resty-mysql/lib/?.lua;../lua-resty-string/lib/?.lua;;";
_EOC_
no_shuffle();

View file

@ -389,8 +389,8 @@ GET /lua
GET /lua
--- response_body_like: 500 Internal Server Error
--- error_code: 500
--- error_log
API disabled in the context of set_by_lua*
--- error_log eval
qr/(?:API disabled in the context of set_by_lua\*|http3 requests are not supported without content-length header)/ms
@ -404,8 +404,16 @@ API disabled in the context of set_by_lua*
GET /lua
--- response_body_like: 500 Internal Server Error
--- error_code: 500
--- error_log
API disabled in the context of set_by_lua*
--- error_log eval
my $err_log;
if (defined $ENV{TEST_NGINX_USE_HTTP3}) {
$err_log = "http v3 not supported yet";
} else {
$err_log = "API disabled in the context of set_by_lua*";
}
$err_log;

View file

@ -65,7 +65,7 @@ GET /lua
--- error_log
attempt to set status 404 via ngx.exit after sending out the response status 200
--- no_error_log
alert
[alert]
--- response_body
hi
@ -123,6 +123,7 @@ GET /api?user=agentz
=== TEST 6: working with ngx_auth_request (simplest form, w/o ngx_memc)
--- skip_eval: 3:$ENV{TEST_NGINX_USE_HTTP3}
--- http_config eval
"
lua_package_cpath '$::LuaCpath';
@ -195,6 +196,7 @@ Logged in 56
=== TEST 7: working with ngx_auth_request (simplest form)
--- skip_eval: 3:$ENV{TEST_NGINX_USE_HTTP3}
--- http_config eval
"
lua_package_cpath '$::LuaCpath';
@ -267,6 +269,7 @@ Logged in 56
=== TEST 8: working with ngx_auth_request
--- skip_eval: 3:$ENV{TEST_NGINX_USE_HTTP3}
--- http_config eval
"
lua_package_cpath '$::LuaCpath';
@ -771,6 +774,8 @@ GET /t
--- response_body
--- no_error_log
[error]
--- curl_error
curl: (95) HTTP/3 stream 0 reset by server
@ -787,6 +792,8 @@ GET /t
--- response_body
--- no_error_log
[error]
--- curl_error
curl: (95) HTTP/3 stream 0 reset by server

View file

@ -270,3 +270,22 @@ Expect: 100-Continue
http finalize request: 500, "/echo_body?" a:1, c:2
http finalize request: 500, "/echo_body?" a:1, c:0
--- log_level: debug
--- skip_eval: 4:$ENV{TEST_NGINX_USE_HTTP3}
=== TEST 13: test reading the first n bytes of request body
--- config
location /echo_body {
lua_need_request_body on;
content_by_lua_block {
local data = ngx.req.get_body_data(1)
ngx.say(data)
}
}
--- request
POST /echo_body
hello
--- response_body
h
--- skip_eval: 2:$ENV{TEST_NGINX_USE_HTTP3}

View file

@ -194,6 +194,14 @@ Hi"
=== TEST 8: github issue 37: header bug
https://github.com/chaoslawful/lua-nginx-module/issues/37
https://datatracker.ietf.org/doc/html/rfc7540#section-8.1.2
Just as in HTTP/1.x, header field names are strings of ASCII
characters that are compared in a case-insensitive fashion. However,
header field names MUST be converted to lowercase prior to their
encoding in HTTP/2. A request or response containing uppercase
header field names MUST be treated as malformed
--- config
location /sub {
content_by_lua '
@ -220,8 +228,17 @@ https://github.com/chaoslawful/lua-nginx-module/issues/37
--- request
GET /lua
--- raw_response_headers_like eval
".*Set-Cookie: TestCookie1=foo\r
my $headers;
if (defined $ENV{TEST_NGINX_USE_HTTP3}) {
$headers = ".*set-cookie: TestCookie1=foo\r
set-cookie: TestCookie2=bar.*"
} else {
$headers = ".*Set-Cookie: TestCookie1=foo\r
Set-Cookie: TestCookie2=bar.*"
}
$headers;
@ -714,6 +731,7 @@ Content-Type: application/json; charset=utf-8
=== TEST 32: hang on upstream_next (from kindy)
--- no_http2
--- no_check_leak
--- http_config
upstream xx {
@ -770,6 +788,10 @@ eof found in body stream
=== TEST 34: testing a segfault when using ngx_poll_module + ngx_resolver
See more details here: http://mailman.nginx.org/pipermail/nginx-devel/2013-January/003275.html
http3 may cache the dns result.
so need to skip for http3
--- skip_eval: 2:$ENV{TEST_NGINX_USE_HTTP3}
--- config
location /t {
set $myserver nginx.org;
@ -786,6 +808,8 @@ See more details here: http://mailman.nginx.org/pipermail/nginx-devel/2013-Janua
[alert]
--- error_log eval
qr/(?:send|recv)\(\) failed \(\d+: Connection refused\) while resolving/
--- curl_error eval
qr/curl: \(28\) Operation timed out after \d+ milliseconds with 0 bytes received/
@ -861,6 +885,7 @@ GET /t
--- no_error_log
[error]
--- timeout: 10
--- skip_eval: 3:$ENV{TEST_NGINX_USE_HTTP3}
@ -868,7 +893,7 @@ GET /t
--- http_config eval
"lua_package_path '$::HtmlDir/?.lua;./?.lua;;';
server {
listen 12354;
listen \$TEST_NGINX_RAND_PORT_1;
location = /t {
echo 'args: \$args';
@ -878,7 +903,7 @@ GET /t
--- config
location = /t {
set $args "foo=1&bar=2";
proxy_pass http://127.0.0.1:12354;
proxy_pass http://127.0.0.1:$TEST_NGINX_RAND_PORT_1;
}
--- request
@ -1281,8 +1306,17 @@ location /t {
--- response_body
Hello world
--- shutdown_error_log eval
qr|failed to read a line: closed|
my $expr;
if ($ENV{TEST_NGINX_USE_HTTP3}) {
$expr = qr|lua close the global Lua VM|
} else {
$expr = qr|failed to read a line: closed|
}
$expr;
--- timeout: 1.2
--- skip_eval: 2:$ENV{TEST_NGINX_USE_HTTP3}

View file

@ -233,6 +233,8 @@ GET /t
--- error_code: 101
--- no_error_log
[error]
--- skip_eval: 3:$ENV{TEST_NGINX_USE_HTTP3}
--- no_http2

View file

@ -65,6 +65,7 @@ GET /read
Content-Length: 3
--- response_body chop
Hel
--- skip_eval: 3:defined($ENV{TEST_NGINX_USE_HTTP3}) || defined($ENV{TEST_NGINX_USE_HTTP2})
@ -113,8 +114,16 @@ Hello
}
--- request
GET /read
--- raw_response_headers_like chomp
X-Foo: a\r\n.*?X-Foo: bc\r\n
--- raw_response_headers_like eval
my $headers;
if (defined($ENV{TEST_NGINX_USE_HTTP3}) || defined($ENV{TEST_NGINX_USE_HTTP2})) {
$headers = qr/x-foo: a\r\n.*?x-foo: bc\r\n/
} else {
$headers = qr/X-Foo: a\r\n.*?X-Foo: bc\r\n/
}
$headers;
--- response_body
Hello
@ -184,8 +193,16 @@ Hello
}
--- request
GET /read
--- raw_response_headers_like chomp
X-Foo: a\r\n.*?X-Foo: abc\r\n
--- raw_response_headers_like eval
my $headers;
if (defined($ENV{TEST_NGINX_USE_HTTP3}) || defined($ENV{TEST_NGINX_USE_HTTP2})) {
$headers = "x-foo: a\r\n.*?x-foo: abc\r\n"
} else {
$headers = "X-Foo: a\r\n.*?X-Foo: abc\r\n"
}
$headers;
--- response_body
Hello
@ -203,8 +220,17 @@ Hello
--- request
GET /lua
--- raw_response_headers_like eval
".*Foo: a\r
Foo: b.*"
my $headers;
if (defined($ENV{TEST_NGINX_USE_HTTP3}) || defined($ENV{TEST_NGINX_USE_HTTP2})) {
$headers = ".*foo: a\r
foo: b.*";
} else {
$headers = ".*Foo: a\r
Foo: b.*";
}
$headers;
--- response_body
@ -222,8 +248,17 @@ Foo: b.*"
--- request
GET /lua
--- raw_response_headers_like eval
".*Foo: a\r
Foo: b.*"
my $headers;
if (defined($ENV{TEST_NGINX_USE_HTTP3}) || defined($ENV{TEST_NGINX_USE_HTTP2})) {
$headers = ".*foo: a\r
foo: b.*";
} else {
$headers = ".*Foo: a\r
Foo: b.*";
}
$headers;
--- response_body
@ -278,7 +313,7 @@ hello
--- error_log
attempt to set ngx.header.HEADER after sending out response headers
--- no_error_log eval
["alert", "warn"]
["[alert]", "[warn]"]
@ -1071,8 +1106,8 @@ GET /t
--- more_headers
Foo: bar
Bah: baz
--- response_headers
Location: http://localhost:$ServerPort/t/
--- response_headers_like
Location: https?://localhost:\d+/t/
--- response_body_like: 301 Moved Permanently
--- error_code: 301
--- no_error_log
@ -1094,8 +1129,8 @@ GET /t
Foo: bar
Bah: baz
--- response_body_like: 301 Moved Permanently
--- response_headers
Location: http://localhost:$ServerPort/t/
--- response_headers_like
Location: https?://localhost:\d+/t/
--- error_code: 301
--- no_error_log
[error]
@ -1115,8 +1150,8 @@ GET /t
--- more_headers
Foo: bar
Bah: baz
--- response_headers
Location: http://localhost:$ServerPort/t/
--- response_headers_like
Location: https?://localhost:\d+/t/
Foo: /t/
--- response_body_like: 301 Moved Permanently
--- error_code: 301
@ -1139,8 +1174,8 @@ GET /t
--- more_headers
Foo: bar
Bah: baz
--- response_headers
Location: http://localhost:$ServerPort/t/
--- response_headers_like
Location: https?://localhost:\d+/t/
Foo: /t/
--- response_body_like: 301 Moved Permanently
--- error_code: 301
@ -1159,8 +1194,16 @@ Foo: /t/
}
--- request
GET /lua
--- raw_response_headers_like chop
cache-Control: private
--- raw_response_headers_like eval
my $headers;
if (defined($ENV{TEST_NGINX_USE_HTTP3}) || defined($ENV{TEST_NGINX_USE_HTTP2})) {
$headers = "cache-control: private"
} else {
$headers = "cache-Control: private"
}
$headers;
--- response_body
Cache-Control: private
@ -1509,6 +1552,7 @@ hi
--- error_log
my Transfer-Encoding: chunked
my transfer-encoding: chunked
--- skip_eval: 6:defined($ENV{TEST_NGINX_USE_HTTP3}) || defined($ENV{TEST_NGINX_USE_HTTP2})
@ -2165,8 +2209,8 @@ upstream prematurely closed connection while sending to client
Foo
--- request
GET /a.txt
--- raw_response_headers_like chomp
Age: \d\r\n
--- raw_response_headers_like eval
qr/^(a|A)ge: \d\r\n/ms
--- no_error_log
[error]
@ -2196,8 +2240,8 @@ Age: \d\r\n
Foo
--- request
GET /test/a.txt
--- raw_response_headers_like chomp
Age: \d\r\n
--- raw_response_headers_like eval
qr/^(a|A)ge: \d\r\n/ms
--- no_error_log
[error]

View file

@ -1227,6 +1227,8 @@ F(ngx_http_finalize_request) {
--- error_code
--- no_error_log
[error]
--- curl_error eval
qr{(\Qcurl: (52) Empty reply from server\E|\Qcurl: (95) HTTP/3 stream 0 reset by server\E)}ms
@ -1238,7 +1240,7 @@ F(ngx_http_finalize_request) {
set $memc_key 'foo';
#set $memc_exptime 300;
memc_pass 127.0.0.1:19112; #$TEST_NGINX_MEMCACHED_PORT;
memc_pass 127.0.0.1:$TEST_NGINX_RAND_PORT_1; #$TEST_NGINX_MEMCACHED_PORT;
}
location /main {
@ -1251,7 +1253,7 @@ F(ngx_http_finalize_request) {
}
--- request
GET /main
--- tcp_listen: 19112
--- tcp_listen: $TEST_NGINX_RAND_PORT_1
--- tcp_query_len: 9
--- tcp_reply eval
"VALUE foo 0 1024\r\nhello world"
@ -1308,7 +1310,7 @@ upstream prematurely closed connection
set $memc_key 'foo';
#set $memc_exptime 300;
memc_pass 127.0.0.1:19112; #$TEST_NGINX_MEMCACHED_PORT;
memc_pass 127.0.0.1:$TEST_NGINX_RAND_PORT_1; #$TEST_NGINX_MEMCACHED_PORT;
}
location /main {
@ -1321,7 +1323,7 @@ upstream prematurely closed connection
}
--- request
GET /main
--- tcp_listen: 19112
--- tcp_listen: $TEST_NGINX_RAND_PORT_1
--- tcp_no_close
--- tcp_reply eval
"VALUE foo 0 1024\r\nhello world"
@ -1381,7 +1383,7 @@ upstream timed out
#proxy_read_timeout 100ms;
proxy_buffering on;
proxy_pass http://127.0.0.1:19113;
proxy_pass http://127.0.0.1:$TEST_NGINX_RAND_PORT_2;
}
location /main {
@ -1394,7 +1396,7 @@ upstream timed out
}
--- request
GET /main
--- tcp_listen: 19113
--- tcp_listen: $TEST_NGINX_RAND_PORT_2
--- tcp_query_len: 65
--- tcp_reply eval
"HTTP/1.0 200 OK\r\nContent-Length: 1024\r\n\r\nhello world"
@ -1441,7 +1443,7 @@ upstream prematurely closed connection
proxy_read_timeout 100ms;
proxy_buffering on;
proxy_pass http://127.0.0.1:19113;
proxy_pass http://127.0.0.1:$TEST_NGINX_RAND_PORT_2;
}
location /main {
@ -1454,7 +1456,7 @@ upstream prematurely closed connection
}
--- request
GET /main
--- tcp_listen: 19113
--- tcp_listen: $TEST_NGINX_RAND_PORT_2
--- tcp_no_close
--- tcp_reply eval
"HTTP/1.0 200 OK\r\nContent-Length: 1024\r\n\r\nhello world"
@ -1503,7 +1505,7 @@ upstream timed out
#proxy_read_timeout 100ms;
proxy_buffering on;
proxy_pass http://127.0.0.1:19113;
proxy_pass http://127.0.0.1:$TEST_NGINX_RAND_PORT_2;
}
location /main {
@ -1516,7 +1518,7 @@ upstream timed out
}
--- request
GET /main
--- tcp_listen: 19113
--- tcp_listen: $TEST_NGINX_RAND_PORT_2
--- tcp_query_len: 65
--- tcp_reply eval
"HTTP/1.0 200 OK\r\n\r\nhello world"
@ -1563,7 +1565,7 @@ truncated: false
proxy_read_timeout 100ms;
proxy_buffering on;
proxy_pass http://127.0.0.1:19113;
proxy_pass http://127.0.0.1:$TEST_NGINX_RAND_PORT_2;
}
location /main {
@ -1576,7 +1578,7 @@ truncated: false
}
--- request
GET /main
--- tcp_listen: 19113
--- tcp_listen: $TEST_NGINX_RAND_PORT_2
--- tcp_no_close
--- tcp_reply eval
"HTTP/1.0 200 OK\r\n\r\nhello world"
@ -1626,7 +1628,7 @@ upstream timed out
#proxy_read_timeout 100ms;
proxy_buffering off;
proxy_pass http://127.0.0.1:19113;
proxy_pass http://127.0.0.1:$TEST_NGINX_RAND_PORT_2;
}
location /main {
@ -1639,7 +1641,7 @@ upstream timed out
}
--- request
GET /main
--- tcp_listen: 19113
--- tcp_listen: $TEST_NGINX_RAND_PORT_2
--- tcp_query_len: 65
--- tcp_reply eval
"HTTP/1.0 200 OK\r\n\r\nhello world"
@ -1686,7 +1688,7 @@ truncated: false
proxy_read_timeout 500ms;
proxy_buffering off;
proxy_pass http://127.0.0.1:19113;
proxy_pass http://127.0.0.1:$TEST_NGINX_RAND_PORT_2;
}
location /main {
@ -1699,7 +1701,7 @@ truncated: false
}
--- request
GET /main
--- tcp_listen: 19113
--- tcp_listen: $TEST_NGINX_RAND_PORT_2
--- tcp_no_close
--- tcp_reply eval
"HTTP/1.0 200 OK\r\n\r\nhello world"
@ -1912,7 +1914,7 @@ a client request body is buffered to a temporary file
#proxy_read_timeout 100ms;
proxy_http_version 1.1;
proxy_buffering on;
proxy_pass http://127.0.0.1:19113;
proxy_pass http://127.0.0.1:$TEST_NGINX_RAND_PORT_2;
}
location /main {
@ -1925,7 +1927,7 @@ a client request body is buffered to a temporary file
}
--- request
GET /main
--- tcp_listen: 19113
--- tcp_listen: $TEST_NGINX_RAND_PORT_2
--- tcp_query_len: 65
--- tcp_reply eval
"HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\nb\r\nhello world\r"
@ -1975,7 +1977,7 @@ upstream prematurely closed connection
#proxy_read_timeout 100ms;
proxy_http_version 1.1;
proxy_buffering off;
proxy_pass http://127.0.0.1:19113;
proxy_pass http://127.0.0.1:$TEST_NGINX_RAND_PORT_2;
}
location /main {
@ -1988,7 +1990,7 @@ upstream prematurely closed connection
}
--- request
GET /main
--- tcp_listen: 19113
--- tcp_listen: $TEST_NGINX_RAND_PORT_2
--- tcp_query_len: 65
--- tcp_reply eval
"HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\nb\r\nhello world\r"
@ -2036,7 +2038,7 @@ upstream prematurely closed connection
proxy_read_timeout 100ms;
proxy_buffering on;
proxy_http_version 1.1;
proxy_pass http://127.0.0.1:19113;
proxy_pass http://127.0.0.1:$TEST_NGINX_RAND_PORT_2;
}
location /main {
@ -2049,7 +2051,7 @@ upstream prematurely closed connection
}
--- request
GET /main
--- tcp_listen: 19113
--- tcp_listen: $TEST_NGINX_RAND_PORT_2
--- tcp_no_close
--- tcp_reply eval
"HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\nb\r\nhello world\r"
@ -2098,7 +2100,7 @@ upstream timed out
#proxy_read_timeout 100ms;
proxy_buffering on;
proxy_http_version 1.1;
proxy_pass http://127.0.0.1:19113;
proxy_pass http://127.0.0.1:$TEST_NGINX_RAND_PORT_2;
}
location /main {
@ -2111,7 +2113,7 @@ upstream timed out
}
--- request
GET /main
--- tcp_listen: 19113
--- tcp_listen: $TEST_NGINX_RAND_PORT_2
--- tcp_no_close
--- tcp_reply eval
"HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n5\r\nhello\r\n0\r\n\r\n"
@ -2156,7 +2158,7 @@ truncated: false
#proxy_read_timeout 100ms;
proxy_buffering off;
proxy_http_version 1.1;
proxy_pass http://127.0.0.1:19113;
proxy_pass http://127.0.0.1:$TEST_NGINX_RAND_PORT_2;
}
location /main {
@ -2169,7 +2171,7 @@ truncated: false
}
--- request
GET /main
--- tcp_listen: 19113
--- tcp_listen: $TEST_NGINX_RAND_PORT_2
--- tcp_no_close
--- tcp_reply eval
"HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n5\r\nhello\r\n0\r\n\r\n"
@ -2215,7 +2217,7 @@ truncated: false
#proxy_read_timeout 100ms;
proxy_buffering off;
proxy_pass http://127.0.0.1:19113;
proxy_pass http://127.0.0.1:$TEST_NGINX_RAND_PORT_2;
}
location /main {
@ -2228,7 +2230,7 @@ truncated: false
}
--- request
GET /main
--- tcp_listen: 19113
--- tcp_listen: $TEST_NGINX_RAND_PORT_2
--- tcp_query_len: 65
--- tcp_reply eval
"HTTP/1.0 200 OK\r\nContent-Length: 1024\r\n\r\nhello world"
@ -2338,6 +2340,7 @@ hello world
nil
--- no_error_log
[error]
--- skip_eval: 3:$ENV{TEST_NGINX_USE_HTTP3}
@ -2622,6 +2625,7 @@ pr: Host: localhost
--- no_error_log
[error]
--- skip_eval: 3:$ENV{TEST_NGINX_USE_HTTP3}
@ -2655,6 +2659,7 @@ pr: Host: localhost
--- no_error_log
[error]
--- skip_eval: 3:$ENV{TEST_NGINX_USE_HTTP3}

View file

@ -122,7 +122,16 @@ GET /read
}
--- request
GET /read
--- raw_response_headers_like: Location: /echo\r\n
--- raw_response_headers_like eval
my $headers;
if (defined $ENV{TEST_NGINX_USE_HTTP3}) {
$headers = "location: /echo\r\n"
} else {
$headers = "Location: /echo\r\n"
}
$headers;
--- response_body_like: 302 Found
--- error_code: 302

View file

@ -19,7 +19,13 @@ our $StapScript = $t::StapThread::StapScript;
repeat_each(2);
plan tests => repeat_each() * (blocks() * 3 - 1);
if (defined $ENV{TEST_NGINX_USE_HTTP3}) {
plan(skip_all => "HTTP3 does not support client abort");
} elsif (defined $ENV{TEST_NGINX_USE_HTTP2}) {
plan(skip_all => "HTTP2 does not support client abort");
} else {
plan tests => repeat_each() * (blocks() * 3 - 1);
}
$ENV{TEST_NGINX_RESOLVER} ||= '8.8.8.8';
$ENV{TEST_NGINX_MEMCACHED_PORT} ||= '11211';

View file

@ -187,6 +187,7 @@ ngx.var.uid = res[1].uid;
GET /api?uid=32
--- response_body
Logged in 56
--- skip_eval: 2:$ENV{TEST_NGINX_USE_HTTP3}
@ -258,6 +259,7 @@ ngx.var.uid = res[1].uid;
GET /api?uid=32
--- response_body
Logged in 56
--- skip_eval: 2:$ENV{TEST_NGINX_USE_HTTP3}
@ -342,6 +344,7 @@ GET /api?uid=32
Logged in 56
--- no_error_log
[error]
--- skip_eval: 3:$ENV{TEST_NGINX_USE_HTTP3}

View file

@ -19,7 +19,13 @@ our $StapScript = $t::StapThread::StapScript;
repeat_each(2);
plan tests => repeat_each() * (blocks() * 4 + 15);
if (defined $ENV{TEST_NGINX_USE_HTTP3}) {
plan(skip_all => "HTTP3 does not support on_abort");
} elsif (defined $ENV{TEST_NGINX_USE_HTTP2}) {
plan(skip_all => "HTTP2 does not support on_abort");
} else {
plan tests => repeat_each() * (blocks() * 4 + 15);
}
$ENV{TEST_NGINX_RESOLVER} ||= '8.8.8.8';
$ENV{TEST_NGINX_MEMCACHED_PORT} ||= '11211';

View file

@ -119,7 +119,16 @@ GET /read
}
--- request
GET /read
--- raw_response_headers_like: Location: /foo\r\n
--- raw_response_headers_like eval
my $headers;
if (defined($ENV{TEST_NGINX_USE_HTTP3}) || defined($ENV{TEST_NGINX_USE_HTTP2})) {
$headers = "location: /foo\r\n"
} else {
$headers = "Location: /foo\r\n"
}
$headers;
--- response_body_like: 302 Found
--- error_code: 302

View file

@ -125,6 +125,7 @@ Expect: 100-Continue
[alert]
[error]
http finalize request: 500, "/test?" a:1, c:0
--- skip_eval: 3:$ENV{TEST_NGINX_USE_HTTP3}

View file

@ -1,6 +1,14 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua;
our $SkipReason;
BEGIN {
if ($ENV{TEST_NGINX_USE_HTTP3}) {
$SkipReason = "http3 does not support ngx.req.socket";
}
}
use Test::Nginx::Socket::Lua $SkipReason ? (skip_all => $SkipReason) : ();
repeat_each(2);

View file

@ -170,3 +170,26 @@ Expect: 100-Continue
http finalize request: 500, "/echo_body?" a:1, c:2
http finalize request: 500, "/echo_body?" a:1, c:0
--- log_level: debug
--- skip_eval: 4:$ENV{TEST_NGINX_USE_HTTP3}
=== TEST 9: test HTTP2 reading request body was disabled
--- config
location /echo_body {
lua_need_request_body on;
rewrite_by_lua_block {
ngx.print(ngx.var.request_body or "nil")
}
content_by_lua 'ngx.exit(ngx.OK)';
}
--- http2
--- request eval
"POST /echo_body
hello\x00\x01\x02
world\x03\x04\xff"
--- more_headers
Content-Length:
--- response_body eval
"nil"
--- no_error_log

View file

@ -110,6 +110,7 @@ bad argument #1 to 'sleep'
=== TEST 5: sleep 0.5 - multi-times
--- quic_max_idle_timeout: 1.0
--- config
location /test {
rewrite_by_lua '
@ -135,6 +136,7 @@ lua sleep timer expired: "/test?"
=== TEST 6: sleep 0.5 - interleaved by ngx.say() - ended by ngx.sleep
--- quic_max_idle_timeout: 2.05
--- config
location /test {
rewrite_by_lua '
@ -163,6 +165,7 @@ lua sleep timer expired: "/test?"
=== TEST 7: sleep 0.5 - interleaved by ngx.say() - not ended by ngx.sleep
--- quic_max_idle_timeout: 0.85
--- config
location /test {
rewrite_by_lua '

View file

@ -176,6 +176,7 @@ received: OK
=== TEST 3: upstream sockets close prematurely
--- no_http3
--- http_config eval
"lua_package_path '$::HtmlDir/?.lua;./?.lua;;';"
--- config
@ -253,6 +254,7 @@ done
=== TEST 4: http keepalive
--- no_http3
--- http_config eval
"lua_package_path '$::HtmlDir/?.lua;./?.lua;;';"
--- config
@ -330,6 +332,7 @@ done
=== TEST 5: lua_socket_keepalive_timeout
--- quic_max_idle_timeout: 1.1
--- config
server_tokens off;
location /t {
@ -409,6 +412,7 @@ qr/lua tcp socket connection pool size: 30\b/]
=== TEST 6: lua_socket_pool_size
--- quic_max_idle_timeout: 1.1
--- config
server_tokens off;
location /t {
@ -489,6 +493,7 @@ qr/lua tcp socket connection pool size: 1\b/]
=== TEST 7: "lua_socket_keepalive_timeout 0" means unlimited
--- quic_max_idle_timeout: 1.2
--- config
server_tokens off;
location /t {
@ -571,6 +576,7 @@ lua tcp socket keepalive timeout: unlimited
=== TEST 8: setkeepalive(timeout) overrides lua_socket_keepalive_timeout
--- quic_max_idle_timeout: 1.1
--- config
server_tokens off;
location /t {
@ -650,6 +656,7 @@ qr/lua tcp socket connection pool size: 30\b/]
=== TEST 9: sock:setkeepalive(timeout, size) overrides lua_socket_pool_size
--- quic_max_idle_timeout: 1.1
--- config
server_tokens off;
location /t {
@ -730,6 +737,7 @@ qr/lua tcp socket connection pool size: 25\b/]
=== TEST 10: sock:keepalive_timeout(0) means unlimited
--- quic_max_idle_timeout: 1.1
--- config
server_tokens off;
location /t {

View file

@ -16,6 +16,7 @@ BEGIN {
$ENV{MOCKEAGAIN} = 'w';
}
delete($ENV{TEST_NGINX_USE_HTTP2});
$ENV{TEST_NGINX_EVENT_TYPE} = 'poll';
$ENV{MOCKEAGAIN_WRITE_TIMEOUT_PATTERN} = 'get helloworld';
}

View file

@ -86,6 +86,7 @@ failed to receive a line: closed []
close: 1 nil
--- no_error_log
[error]
--- no_http2
@ -155,6 +156,7 @@ failed to receive a line: closed [foo]
closed
--- no_error_log
[error]
--- no_http2
@ -197,6 +199,7 @@ connected: nil
failed to send request: closed
--- error_log
attempt to send data on a closed socket:
--- no_http2
@ -521,6 +524,7 @@ failed to receive a line: closed
close: 1 nil
--- no_error_log
[error]
--- no_http2
@ -591,6 +595,7 @@ close: 1 nil
"
--- no_error_log
[error]
--- no_http2
@ -672,6 +677,7 @@ close: 1 nil
"
--- no_error_log
[error]
--- no_http2
@ -749,6 +755,7 @@ close: 1 nil
"
--- no_error_log
[error]
--- no_http2
@ -827,6 +834,7 @@ close: 1 nil
"
--- no_error_log
[error]
--- no_http2
@ -898,6 +906,7 @@ failed to receive a line: closed []
close: 1 nil
--- no_error_log
[error]
--- no_http2
@ -967,6 +976,7 @@ failed to receive a line: closed []
close: 1 nil
--- no_error_log
[error]
--- no_http2
@ -1077,6 +1087,7 @@ close: 1 nil
"
--- no_error_log
[error]
--- no_http2
@ -1521,6 +1532,7 @@ GET /t
2: close: 1 nil
--- no_error_log
[error]
--- no_http2
@ -1593,6 +1605,7 @@ failed to receive a line: closed []
close: 1 nil
--- no_error_log
[error]
--- no_http2
@ -1654,6 +1667,9 @@ GET /t
--- ignore_response
--- error_log
bad argument #1 to 'send' (bad data type nil found)
--- curl_error eval
qr#curl: \(52\) Empty reply from server|curl: \(95\) HTTP/3 stream 0 reset by server#
--- no_http2
@ -1715,6 +1731,9 @@ GET /t
--- ignore_response
--- error_log
bad argument #1 to 'send' (bad data type boolean found)
--- curl_error eval
qr#curl: \(52\) Empty reply from server|curl: \(95\) HTTP/3 stream 0 reset by server#
--- no_http2
@ -1776,6 +1795,9 @@ GET /t
--- ignore_response
--- error_log
bad argument #1 to 'send' (bad data type userdata found)
--- curl_error eval
qr#curl: \(52\) Empty reply from server|curl: \(95\) HTTP/3 stream 0 reset by server#
--- no_http2
@ -1845,6 +1867,7 @@ subrequest: 200, OK\r
"
--- no_error_log
[error]
--- no_http2
@ -1916,6 +1939,7 @@ close: 1 nil
--- no_error_log
[error]
--- SKIP
--- no_http2
@ -1976,6 +2000,7 @@ receive(0): []
close: 1 nil
--- no_error_log
[error]
--- no_http2
@ -2036,6 +2061,7 @@ send(""): 0
close: 1 nil
--- no_error_log
[error]
--- no_http2
@ -2092,6 +2118,7 @@ qr/runtime error: rewrite_by_lua\(nginx\.conf:\d+\):7: bad request/
--- no_error_log
[alert]
--- no_http2
@ -2151,6 +2178,7 @@ qr/runtime error: rewrite_by_lua\(nginx\.conf:\d+\):14: bad request/
--- no_error_log
[alert]
--- no_http2

View file

@ -987,6 +987,7 @@ hello in thread
after
--- no_error_log
[error]
--- skip_eval: 4:$ENV{TEST_NGINX_USE_HTTP3}
@ -1072,6 +1073,7 @@ hello in thread
after
--- no_error_log
[error]
--- skip_eval: 4:$ENV{TEST_NGINX_USE_HTTP3}

View file

@ -1120,6 +1120,7 @@ body: hello world)$
--- no_error_log
[error]
--- skip_eval: 4:$ENV{TEST_NGINX_USE_HTTP3}

View file

@ -1,6 +1,16 @@
# vim:set ft= ts=4 sw=4 et fdm=marker:
use Test::Nginx::Socket::Lua;
our $SkipReason;
BEGIN {
if ($ENV{TEST_NGINX_USE_HTTP3}) {
$SkipReason = "http3 does not support ngx.req.socket and lua_check_client_abort";
} elsif ($ENV{TEST_NGINX_USE_HTTP2}) {
$SkipReason = "http2 does not support ngx.req.socket and lua_check_client_abort";
}
}
use Test::Nginx::Socket::Lua $SkipReason ? (skip_all => $SkipReason) : ();
use t::StapThread;
our $GCScript = <<_EOC_;

View file

@ -177,6 +177,7 @@ GET /api?uid=32
--- response_body
Logged in 56
--- timeout: 3
--- skip_eval: 2:$ENV{TEST_NGINX_USE_HTTP3}
@ -243,6 +244,7 @@ ngx.var.uid = res[1].uid;
GET /api?uid=32
--- response_body
Logged in 56
--- skip_eval: 2:$ENV{TEST_NGINX_USE_HTTP3}
@ -320,6 +322,7 @@ ngx.var.uid = res[1].uid;
GET /api?uid=32
--- response_body
Logged in 56
--- skip_eval: 2:$ENV{TEST_NGINX_USE_HTTP3}

View file

@ -19,7 +19,13 @@ our $StapScript = $t::StapThread::StapScript;
repeat_each(2);
plan tests => repeat_each() * (blocks() * 4 + 15);
if (defined $ENV{TEST_NGINX_USE_HTTP3}) {
plan(skip_all => "HTTP3 does not support on_abort");
} elsif (defined $ENV{TEST_NGINX_USE_HTTP2}) {
plan(skip_all => "HTTP2 does not support on_abort");
} else {
plan tests => repeat_each() * (blocks() * 4 + 15);
}
$ENV{TEST_NGINX_RESOLVER} ||= '8.8.8.8';
$ENV{TEST_NGINX_MEMCACHED_PORT} ||= '11211';

View file

@ -119,6 +119,15 @@ GET /read
}
--- request
GET /read
--- raw_response_headers_like: Location: /foo\r\n
--- raw_response_headers_like eval
my $headers;
if (defined($ENV{TEST_NGINX_USE_HTTP3}) || defined($ENV{TEST_NGINX_USE_HTTP2})) {
$headers = "location: /foo\r\n"
} else {
$headers = "Location: /foo\r\n"
}
$headers;
--- response_body_like: 302 Found
--- error_code: 302

View file

@ -122,6 +122,7 @@ Expect: 100-Continue
[alert]
[error]
http finalize request: 500, "/test?" a:1, c:0
--- skip_eval: 3:$ENV{TEST_NGINX_USE_HTTP3}

View file

@ -170,3 +170,26 @@ Expect: 100-Continue
http finalize request: 500, "/echo_body?" a:1, c:2
http finalize request: 500, "/echo_body?" a:1, c:0
--- log_level: debug
--- skip_eval: 4:$ENV{TEST_NGINX_USE_HTTP3}
=== TEST 9: test HTTP2 reading request body was disabled
--- config
location /echo_body {
lua_need_request_body on;
access_by_lua_block {
ngx.print(ngx.var.request_body or "nil")
}
content_by_lua 'ngx.exit(ngx.OK)';
}
--- http2
--- request eval
"POST /echo_body
hello\x00\x01\x02
world\x03\x04\xff"
--- more_headers
Content-Length:
--- response_body eval
"nil"
--- no_error_log

View file

@ -110,6 +110,7 @@ bad argument #1 to 'sleep'
=== TEST 5: sleep 0.5 - multi-times
--- quic_max_idle_timeout: 1.0
--- config
location /test {
access_by_lua '
@ -135,6 +136,7 @@ lua sleep timer expired: "/test?"
=== TEST 6: sleep 0.5 - interleaved by ngx.say() - ended by ngx.sleep
--- quic_max_idle_timeout: 2.2
--- config
location /test {
access_by_lua '
@ -163,6 +165,7 @@ lua sleep timer expired: "/test?"
=== TEST 7: sleep 0.5 - interleaved by ngx.say() - not ended by ngx.sleep
--- quic_max_idle_timeout: 0.85
--- config
location /test {
access_by_lua '

View file

@ -880,6 +880,7 @@ after
=== TEST 11: exit in user thread (entry thread is still pending on reqsock:receive)
--- skip_eval: 5:$ENV{TEST_NGINX_USE_HTTP3}
--- config
location /lua {
access_by_lua '
@ -973,6 +974,7 @@ after
=== TEST 12: exit in user thread (entry thread is still pending on ngx.req.read_body)
--- skip_eval: 3:$ENV{TEST_NGINX_USE_HTTP3}
--- config
location /lua {
client_body_timeout 12000ms;

View file

@ -1120,3 +1120,4 @@ body: hello world)$
--- no_error_log
[error]
--- skip_eval: 4:$ENV{TEST_NGINX_USE_HTTP3}

View file

@ -966,6 +966,7 @@ qr/\[alert\] \S+ lua_code_cache is off; this will hurt performance/,
=== TEST 27: GC issue with the on_abort thread object
curl: (52) Empty reply from server
--- config
lua_code_cache off;
location = /t {
@ -991,6 +992,8 @@ decrementing the reference count for Lua VM: 3
qr/\[alert\] \S+ lua_code_cache is off; this will hurt performance/,
"lua close the global Lua VM",
]
--- curl_error eval
qr/curl: \(\d+\) Empty reply from server|curl: \(28\) Operation timed out after \d+ milliseconds with 0 bytes received/
@ -1720,6 +1723,7 @@ grep me: b
}
--- config
lua_ssl_trusted_certificate $TEST_NGINX_CERT_DIR/cert/test.crt;
lua_ssl_protocols TLSv1 TLSv1.1 TLSV1.2;
location = /proxy {
proxy_pass http://backend;
@ -1877,3 +1881,4 @@ qr/log_by_lua\(nginx.conf:\d+\):\d+: hello/,
--- log_level: debug
--- no_error_log
[error]
--- skip_eval: 14:$ENV{TEST_NGINX_USE_HTTP3}

View file

@ -69,6 +69,7 @@ kill status = 200
kill body = \{"errcode":0\}$
--- error_log eval
qr{upstream timed out \(\d+: Connection timed out\) while sending query to drizzle upstream}
--- skip_eval: 3:$ENV{TEST_NGINX_USE_HTTP3}

View file

@ -59,8 +59,13 @@ lua exceeding request header limit
for k, v in pairs(headers) do
h[k] = v
end
ngx.say("Foo: ", h["Foo"] or "nil")
ngx.say("Bar: ", h["Bar"] or "nil")
if (ngx.req.http_version() == 3 or ngx.req.http_version() == 2) then
ngx.say("Foo: ", h["foo"] or "nil")
ngx.say("Bar: ", h["bar"] or "nil")
else
ngx.say("Foo: ", h["Foo"] or "nil")
ngx.say("Bar: ", h["Bar"] or "nil")
end
';
}
--- request
@ -127,6 +132,8 @@ Foo:
--- response_body eval
"a" x 2048
--- timeout: 15
--- skip_eval: 2:$ENV{TEST_NGINX_USE_HTTP3}
--- no_http2
@ -145,6 +152,8 @@ Foo:
--- response_body eval
"a" x 2048
--- timeout: 15
--- skip_eval: 2:$ENV{TEST_NGINX_USE_HTTP3}
--- no_http2
@ -273,8 +282,13 @@ Content-Type:
}
--- request
GET /bar
--- response_body
Foo: a
--- response_body eval
# Since nginx version 1.23.0, nginx combines same $http_* variable together
$Test::Nginx::Util::NginxVersion >= 1.023000 ?
"Foo: a, b\n"
:
"Foo: a\n"
@ -480,6 +494,8 @@ for my $k (@k) {
--- timeout: 4
--- error_log
lua exceeding request header limit 101 > 100
--- skip_eval: 3:$ENV{TEST_NGINX_USE_HTTP3}
--- no_http2
@ -518,20 +534,30 @@ while ($i <= 98) {
$s
--- response_body eval
my @k;
if (defined($ENV{TEST_NGINX_USE_HTTP3}) || defined($ENV{TEST_NGINX_USE_HTTP2})) {
push @k, "host: localhost\n";
}
my $i = 1;
while ($i <= 98) {
push @k, "x-$i";
$i++;
}
push @k, "connection: close\n";
push @k, "host: localhost\n";
my $found_headers = "found 99 headers\n";
if (!defined($ENV{TEST_NGINX_USE_HTTP3}) && !defined($ENV{TEST_NGINX_USE_HTTP2})) {
push @k, "connection: close\n";
push @k, "host: localhost\n";
$found_headers = "found 100 headers\n";
}
@k = sort @k;
for my $k (@k) {
if ($k =~ /\d+/) {
$k .= ": $&\n";
}
}
CORE::join("", @k) . "found 100 headers\n";
CORE::join("", @k) . $found_headers;
--- timeout: 4
--- no_error_log
[error]
@ -571,6 +597,9 @@ while ($i <= 101) {
$s
--- response_body eval
my @k;
if (defined $ENV{TEST_NGINX_USE_HTTP3}) {
push @k, "host: localhost\n";
}
my $i = 1;
while ($i <= 100) {
push @k, "x-$i";
@ -588,6 +617,8 @@ for my $k (@k) {
--- timeout: 4
--- error_log
lua exceeding request header limit 103 > 102
--- skip_eval: 3:$ENV{TEST_NGINX_USE_HTTP3}
--- no_http2
@ -623,13 +654,20 @@ while ($i <= 100) {
$s
--- response_body eval
my @k;
if (defined($ENV{TEST_NGINX_USE_HTTP3}) || defined($ENV{TEST_NGINX_USE_HTTP2})) {
push @k, "host: localhost\n";
}
my $i = 1;
while ($i <= 100) {
push @k, "x-$i";
$i++;
}
push @k, "connection: close\n";
push @k, "host: localhost\n";
if (!defined($ENV{TEST_NGINX_USE_HTTP3}) && !defined($ENV{TEST_NGINX_USE_HTTP2})) {
push @k, "connection: close\n";
push @k, "host: localhost\n";
}
@k = sort @k;
for my $k (@k) {
if ($k =~ /\d+/) {
@ -676,13 +714,18 @@ while ($i <= 105) {
$s
--- response_body eval
my @k;
if (defined($ENV{TEST_NGINX_USE_HTTP3}) || defined($ENV{TEST_NGINX_USE_HTTP2})) {
push @k, "host: localhost\n";
}
my $i = 1;
while ($i <= 105) {
push @k, "x-$i";
$i++;
}
push @k, "connection: close\n";
push @k, "host: localhost\n";
if (!defined($ENV{TEST_NGINX_USE_HTTP3}) && !defined($ENV{TEST_NGINX_USE_HTTP2})) {
push @k, "connection: close\n";
push @k, "host: localhost\n";
}
@k = sort @k;
for my $k (@k) {
if ($k =~ /\d+/) {
@ -825,10 +868,21 @@ hello world
Content-Type: application/ocsp-request
Test-Header: 1
--- response_body_like eval
qr/Connection: close\r
my $body;
if (defined $ENV{TEST_NGINX_USE_HTTP3}) {
$body = qr/Connection: close\r
test-header: 1\r
\r
$/;
} else {
$body = qr/Connection: close\r
Test-Header: 1\r
\r
$/
$/;
}
$body;
--- no_error_log
[error]
@ -876,7 +930,36 @@ Foo20: foo20
Foo21: foo21
Foo22: foo22
--- response_body_like eval
qr/Bah: bah\r
my $headers;
if (defined $ENV{TEST_NGINX_USE_HTTP3}) {
$headers = qr/bah: bah\r
test-header: 1\r
foo1: foo1\r
foo2: foo2\r
foo3: foo3\r
foo4: foo4\r
foo5: foo5\r
foo6: foo6\r
foo7: foo7\r
foo8: foo8\r
foo9: foo9\r
foo10: foo10\r
foo11: foo11\r
foo12: foo12\r
foo13: foo13\r
foo14: foo14\r
foo15: foo15\r
foo16: foo16\r
foo17: foo17\r
foo18: foo18\r
foo19: foo19\r
foo20: foo20\r
foo21: foo21\r
foo22: foo22\r
/;
} else {
$headers = qr/Bah: bah\r
Test-Header: 1\r
Foo1: foo1\r
Foo2: foo2\r
@ -900,7 +983,10 @@ Foo19: foo19\r
Foo20: foo20\r
Foo21: foo21\r
Foo22: foo22\r
/
/;
}
$headers;
@ -931,11 +1017,21 @@ GET /t
--- more_headers
My-Foo: bar
Bar: baz
--- response_body
Bar: baz
--- response_body eval
my $body;
if ($ENV{TEST_NGINX_USE_HTTP3} || $ENV{TEST_NGINX_USE_HTTP2}) {
$body = "bar: baz
host: localhost
my-foo: bar
";
} else {
$body = "Bar: baz
Connection: close
Host: localhost
My-Foo: bar
";
}
$body;
@ -1005,29 +1101,23 @@ for my $i ('a' .. 'r') {
}
$s
--- response_body eval
"GET /back HTTP/1.0\r
my $s = "GET /back HTTP/1.0\r
Host: foo\r
Connection: close\r
User-Agent: curl\r
A: a\r
B: b\r
C: c\r
D: d\r
E: e\r
F: f\r
G: g\r
H: h\r
I: i\r
J: j\r
K: k\r
L: l\r
M: m\r
N: n\r
O: o\r
P: p\r
Q: q\r
\r
"
Connection: close\r\n";
if (defined $ENV{TEST_NGINX_USE_HTTP3}) {
$s .= "user-agent: curl\r\n";
for my $i ('a' .. 'q') {
$s .= $i . ": " . "$i\r\n"
}
} else {
$s .= "User-Agent: curl\r\n";
for my $i ('a' .. 'q') {
$s .= uc($i) . ": " . "$i\r\n"
}
}
$s . "\r\n";
@ -1058,7 +1148,55 @@ for my $i ('a' .. 'r') {
}
$s
--- response_body eval
"GET /back HTTP/1.0\r
my $body;
if (defined $ENV{TEST_NGINX_USE_HTTP3}) {
$body = "GET /back HTTP/1.0\r
Host: foo\r
Connection: close\r
user-agent: curl\r
a: a\r
b: b\r
c: c\r
d: d\r
e: e\r
f: f\r
g: g\r
h: h\r
i: i\r
j: j\r
k: k\r
l: l\r
m: m\r
n: n\r
o: o\r
p: p\r
q: q\r
foo-1: 1\r
foo-2: 2\r
foo-3: 3\r
foo-4: 4\r
foo-5: 5\r
foo-6: 6\r
foo-7: 7\r
foo-8: 8\r
foo-9: 9\r
foo-10: 10\r
foo-11: 11\r
foo-12: 12\r
foo-13: 13\r
foo-14: 14\r
foo-15: 15\r
foo-16: 16\r
foo-17: 17\r
foo-18: 18\r
foo-19: 19\r
foo-20: 20\r
foo-21: 21\r
\r
";
} else {
$body = "GET /back HTTP/1.0\r
Host: foo\r
Connection: close\r
User-Agent: curl\r
@ -1101,7 +1239,10 @@ foo-19: 19\r
foo-20: 20\r
foo-21: 21\r
\r
"
";
}
$body;
@ -1130,7 +1271,34 @@ for my $i ('a' .. 'r') {
}
$s
--- response_body eval
"GET /back HTTP/1.0\r
my $body;
if ($ENV{TEST_NGINX_USE_HTTP3}) {
$body = "GET /back HTTP/1.0\r
Host: foo\r
Connection: close\r
user-agent: curl\r
bah: bah\r
a: a\r
b: b\r
c: c\r
d: d\r
e: e\r
f: f\r
g: g\r
h: h\r
i: i\r
j: j\r
k: k\r
l: l\r
m: m\r
n: n\r
o: o\r
p: p\r
\r
"
} else {
$body = "GET /back HTTP/1.0\r
Host: foo\r
Connection: close\r
User-Agent: curl\r
@ -1153,6 +1321,9 @@ O: o\r
P: p\r
\r
"
}
$body;
@ -1184,7 +1355,55 @@ for my $i ('a' .. 'r') {
}
$s
--- response_body eval
"GET /back HTTP/1.0\r
my $body;
if (defined $ENV{TEST_NGINX_USE_HTTP3}) {
$body = "GET /back HTTP/1.0\r
Host: foo\r
Connection: close\r
user-agent: curl\r
bah: bah\r
a: a\r
b: b\r
c: c\r
d: d\r
e: e\r
f: f\r
g: g\r
h: h\r
i: i\r
j: j\r
k: k\r
l: l\r
m: m\r
n: n\r
o: o\r
p: p\r
foo-1: 1\r
foo-2: 2\r
foo-3: 3\r
foo-4: 4\r
foo-5: 5\r
foo-6: 6\r
foo-7: 7\r
foo-8: 8\r
foo-9: 9\r
foo-10: 10\r
foo-11: 11\r
foo-12: 12\r
foo-13: 13\r
foo-14: 14\r
foo-15: 15\r
foo-16: 16\r
foo-17: 17\r
foo-18: 18\r
foo-19: 19\r
foo-20: 20\r
foo-21: 21\r
\r
";
} else {
$body = "GET /back HTTP/1.0\r
Host: foo\r
Connection: close\r
User-Agent: curl\r
@ -1228,6 +1447,9 @@ foo-20: 20\r
foo-21: 21\r
\r
"
}
$body;
@ -1259,11 +1481,23 @@ GET /t
--- more_headers
My-Foo: bar
Bar: baz
--- response_body
Bar: baz
--- response_body eval
my $body;
if (defined($ENV{TEST_NGINX_USE_HTTP3})|| defined($ENV{TEST_NGINX_USE_HTTP2})) {
$body="bar: baz
host: localhost
my-foo: bar
";
} else {
$body="Bar: baz
Connection: close
Host: localhost
My-Foo: bar
";
}
$body;
--- no_error_log
[error]
@ -1898,6 +2132,8 @@ found 3 headers.
lua exceeding request header limit 4 > 3
--- no_error_log
[error]
--- skip_eval: 4:$ENV{TEST_NGINX_USE_HTTP3}
--- no_http2
@ -1934,6 +2170,8 @@ found 3 headers.
--- no_error_log
lua exceeding request header limit
[error]
--- skip_eval: 4: $ENV{TEST_NGINX_USE_HTTP3}
--- no_http2
@ -1972,6 +2210,8 @@ found 3 headers.
lua exceeding request header limit 4 > 3
--- no_error_log
[error]
--- skip_eval: 4: $ENV{TEST_NGINX_USE_HTTP3}
--- no_http2
@ -2002,12 +2242,22 @@ while ($i <= 1) {
$i++;
}
$s
--- response_body
found 3 headers.
--- response_body eval
my $body;
if (!defined $ENV{TEST_NGINX_USE_HTTP2}) {
$body = "found 3 headers.
";
} else {
$body = "found 2 headers.
";
}
$body;
--- timeout: 4
--- no_error_log
lua exceeding request header limit
[error]
--- skip_eval: 4: $ENV{TEST_NGINX_USE_HTTP3}

View file

@ -108,6 +108,7 @@ a=3&b=4&c
--- request
POST /lua
--- response_body
--- skip_eval: 2:$ENV{TEST_NGINX_USE_HTTP3}

View file

@ -278,6 +278,8 @@ GET /t
[error]
--- error_log
ngx.ctx = 32
--- curl_error eval
qr/curl: \(52\) Empty reply from server|curl: \(92\) HTTP\/2 stream 0 was not closed cleanly|curl: \(95\) HTTP\/3 stream 0 reset by server/

View file

@ -361,8 +361,11 @@ he
}
--- request
GET /re
--- response_body
error: pcre_compile() failed: missing ) in "(abc"
--- response_body eval
$Test::Nginx::Util::PcreVersion == 2 ?
"error: pcre2_compile() failed: missing closing parenthesis in \"(abc\"\n"
:
"error: pcre_compile() failed: missing ) in \"(abc\"\n"
--- no_error_log
[error]
@ -648,8 +651,12 @@ regex: (?:>[\w\s]*</?\w{2,}>)
}
--- request
GET /re
--- response_body
error: pcre_compile() failed: missing ) in "([0-9]+"
--- response_body eval
$Test::Nginx::Util::PcreVersion == 2 ?
"error: pcre2_compile\(\) failed: missing closing parenthesis in \"\([0-9]+\"\n"
:
"error: pcre_compile\(\) failed: missing \) in \"\([0-9]+\"\n"
--- no_error_log
[error]
@ -939,8 +946,11 @@ nil
}
--- request
GET /t
--- response_body_like chop
^error: pcre_exec\(\) failed: -10$
--- response_body eval
$Test::Nginx::Util::PcreVersion == 2 ?
"error: pcre_exec\(\) failed: -4\n"
:
"error: pcre_exec\(\) failed: -10\n"
--- no_error_log
[error]
@ -1050,8 +1060,14 @@ end
--- request
GET /re
--- response_body
error: pcre_exec() failed: -8
--- response_body eval
# lua_regex_match_limit uses pcre_extra->match_limit in the PCRE,
# but PCRE2 replaces this with pcre2_set_match_limit interface,
# which has different effects.
$Test::Nginx::Util::PcreVersion == 2 ?
"failed to match\n"
:
"error: pcre_exec() failed: -8\n"

View file

@ -698,8 +698,11 @@ not matched!
}
--- request
GET /re
--- response_body
error: pcre_compile() failed: missing ) in "(abc"
--- response_body eval
$Test::Nginx::Util::PcreVersion == 2 ?
"error: pcre2_compile() failed: missing closing parenthesis in \"(abc\"\n"
:
"error: pcre_compile() failed: missing ) in \"(abc\"\n"
--- no_error_log
[error]
@ -735,8 +738,11 @@ error: pcre_compile() failed: missing ) in "(abc"
}
--- request
GET /t
--- response_body_like chop
error: pcre_exec\(\) failed: -10
--- response_body eval
$Test::Nginx::Util::PcreVersion == 2 ?
"error: pcre_exec\(\) failed: -4\n"
:
"error: pcre_exec\(\) failed: -10\n"
--- no_error_log
[error]
@ -854,8 +860,14 @@ end
--- request
GET /re
--- response_body
error: pcre_exec() failed: -8
--- response_body eval
# lua_regex_match_limit uses pcre_extra->match_limit in the PCRE,
# but PCRE2 replaces this with pcre2_set_match_limit interface,
# which has different effects.
$Test::Nginx::Util::PcreVersion == 2 ?
"failed to match\n"
:
"error: pcre_exec() failed: -8\n"

View file

@ -480,8 +480,11 @@ a [b c] [b] [c] [] [] d
}
--- request
GET /re
--- response_body
error: pcre_compile() failed: missing ) in "(abc"
--- response_body eval
$Test::Nginx::Util::PcreVersion == 2 ?
"error: pcre2_compile() failed: missing closing parenthesis in \"(abc\"\n"
:
"error: pcre_compile() failed: missing ) in \"(abc\"\n"
--- no_error_log
[error]
@ -506,8 +509,11 @@ error: pcre_compile() failed: missing ) in "(abc"
}
--- request
GET /t
--- response_body_like chop
error: pcre_exec\(\) failed: -10
--- response_body eval
$Test::Nginx::Util::PcreVersion == 2 ?
"error: pcre_exec\(\) failed: -4\n"
:
"error: pcre_exec\(\) failed: -10\n"
--- no_error_log
[error]
@ -610,8 +616,14 @@ ngx.say("sub: ", cnt)
--- request
GET /re
--- response_body
error: pcre_exec() failed: -8
--- response_body eval
# lua_regex_match_limit uses pcre_extra->match_limit in the PCRE,
# but PCRE2 replaces this with pcre2_set_match_limit interface,
# which has different effects.
$Test::Nginx::Util::PcreVersion == 2 ?
"sub: 0\n"
:
"error: pcre_exec() failed: -8\n"

View file

@ -423,8 +423,11 @@ n: 1
}
--- request
GET /t
--- response_body_like chop
error: pcre_exec\(\) failed: -10
--- response_body eval
$Test::Nginx::Util::PcreVersion == 2 ?
"error: pcre_exec\(\) failed: -4\n"
:
"error: pcre_exec\(\) failed: -10\n"
--- no_error_log
[error]
@ -531,8 +534,14 @@ ngx.say("gsub: ", cnt)
--- request
GET /re
--- response_body
error: pcre_exec() failed: -8
--- response_body eval
# lua_regex_match_limit uses pcre_extra->match_limit in the PCRE,
# but PCRE2 replaces this with pcre2_set_match_limit interface,
# which has different effects.
$Test::Nginx::Util::PcreVersion == 2 ?
"gsub: 0\n"
:
"error: pcre_exec() failed: -8\n"

View file

@ -336,8 +336,11 @@ he
}
--- request
GET /re
--- response_body
error: pcre_compile() failed: missing ) in "(abc"
--- response_body eval
$Test::Nginx::Util::PcreVersion == 2 ?
"error: pcre2_compile() failed: missing closing parenthesis in \"(abc\"\n"
:
"error: pcre_compile() failed: missing ) in \"(abc\"\n"
--- no_error_log
[error]

View file

@ -124,6 +124,8 @@ Hi
GET /read
--- error_code
--- response_body
--- curl_error eval
qr/curl: \(52\) Empty reply from server|curl: \(92\) HTTP\/2 stream 0 was not closed cleanly|curl: \(95\) HTTP\/3 stream 0 reset by server/
@ -465,6 +467,8 @@ GET /lua
failed to run header_filter_by_lua*: header_filter_by_lua(nginx.conf:47):2: Something bad
--- no_error_log
[alert]
--- curl_error eval
qr/curl: \(56\) Failure when receiving data from the peer|curl: \(92\) HTTP\/2 stream 0 was not closed cleanly|curl: \(52\) Empty reply from server|curl: \(95\) HTTP\/3 stream 0 reset by server/
@ -487,6 +491,8 @@ GET /lua
failed to run header_filter_by_lua*: unknown reason
--- no_error_log
[alert]
--- curl_error eval
qr/curl: \(56\) Failure when receiving data from the peer|curl: \(92\) HTTP\/2 stream 0 was not closed cleanly|curl: \(52\) Empty reply from server|curl: \(95\) HTTP\/3 stream 0 reset by server/
@ -501,6 +507,8 @@ GET /lua
--- ignore_response
--- error_log
API disabled in the context of header_filter_by_lua*
--- curl_error eval
qr/curl: \(52\) Empty reply from server|curl: \(92\) HTTP\/2 stream 0 was not closed cleanly|curl: \(95\) HTTP\/3 stream 0 reset by server/
@ -515,6 +523,8 @@ GET /lua
--- ignore_response
--- error_log
API disabled in the context of header_filter_by_lua*
--- curl_error eval
qr/curl: \(52\) Empty reply from server|curl: \(92\) HTTP\/2 stream 0 was not closed cleanly|curl: \(95\) HTTP\/3 stream 0 reset by server/
@ -529,6 +539,8 @@ GET /lua
--- ignore_response
--- error_log
API disabled in the context of header_filter_by_lua*
--- curl_error eval
qr/curl: \(52\) Empty reply from server|curl: \(92\) HTTP\/2 stream 0 was not closed cleanly|curl: \(95\) HTTP\/3 stream 0 reset by server/
@ -543,6 +555,8 @@ GET /lua
--- ignore_response
--- error_log
API disabled in the context of header_filter_by_lua*
--- curl_error eval
qr/curl: \(52\) Empty reply from server|curl: \(92\) HTTP\/2 stream 0 was not closed cleanly|curl: \(95\) HTTP\/3 stream 0 reset by server/
@ -557,6 +571,8 @@ GET /lua
--- ignore_response
--- error_log
API disabled in the context of header_filter_by_lua*
--- curl_error eval
qr/curl: \(52\) Empty reply from server|curl: \(92\) HTTP\/2 stream 0 was not closed cleanly|curl: \(95\) HTTP\/3 stream 0 reset by server/
@ -575,6 +591,8 @@ GET /lua
--- ignore_response
--- error_log
API disabled in the context of header_filter_by_lua*
--- curl_error eval
qr/curl: \(52\) Empty reply from server|curl: \(92\) HTTP\/2 stream 0 was not closed cleanly|curl: \(95\) HTTP\/3 stream 0 reset by server/
@ -593,6 +611,8 @@ GET /lua
--- ignore_response
--- error_log
API disabled in the context of header_filter_by_lua*
--- curl_error eval
qr/curl: \(52\) Empty reply from server|curl: \(92\) HTTP\/2 stream 0 was not closed cleanly|curl: \(95\) HTTP\/3 stream 0 reset by server/
@ -607,6 +627,8 @@ GET /lua
--- ignore_response
--- error_log
API disabled in the context of header_filter_by_lua*
--- curl_error eval
qr/curl: \(52\) Empty reply from server|curl: \(92\) HTTP\/2 stream 0 was not closed cleanly|curl: \(95\) HTTP\/3 stream 0 reset by server/
@ -621,6 +643,8 @@ GET /lua
--- ignore_response
--- error_log
API disabled in the context of header_filter_by_lua*
--- curl_error eval
qr/curl: \(52\) Empty reply from server|curl: \(92\) HTTP\/2 stream 0 was not closed cleanly|curl: \(95\) HTTP\/3 stream 0 reset by server/
@ -635,6 +659,8 @@ GET /lua
--- ignore_response
--- error_log
API disabled in the context of header_filter_by_lua*
--- curl_error eval
qr/curl: \(52\) Empty reply from server|curl: \(92\) HTTP\/2 stream 0 was not closed cleanly|curl: \(95\) HTTP\/3 stream 0 reset by server/
@ -665,8 +691,10 @@ uri: /blah
--- request
GET /lua
--- ignore_response
--- error_log
API disabled in the context of header_filter_by_lua*
--- error_log eval
qr/API disabled in the context of header_filter_by_lua\*|http3 requests are not supported without content-length header/ms
--- curl_error eval
qr/curl: \(52\) Empty reply from server|curl: \(92\) HTTP\/2 stream 0 was not closed cleanly|curl: \(95\) HTTP\/3 stream 0 reset by server/
@ -679,8 +707,18 @@ API disabled in the context of header_filter_by_lua*
--- request
GET /lua
--- ignore_response
--- error_log
API disabled in the context of header_filter_by_lua*
--- error_log eval
my $err_log;
if (defined $ENV{TEST_NGINX_USE_HTTP3}) {
$err_log = "http v3 not supported yet";
} else {
$err_log = "API disabled in the context of header_filter_by_lua*";
}
$err_log;
--- curl_error eval
qr/curl: \(52\) Empty reply from server|curl: \(92\) HTTP\/2 stream 0 was not closed cleanly|curl: \(95\) HTTP\/3 stream 0 reset by server/
@ -695,6 +733,8 @@ GET /lua
--- ignore_response
--- error_log
API disabled in the context of header_filter_by_lua*
--- curl_error eval
qr/curl: \(52\) Empty reply from server|curl: \(92\) HTTP\/2 stream 0 was not closed cleanly|curl: \(95\) HTTP\/3 stream 0 reset by server/
@ -709,6 +749,8 @@ GET /lua
--- ignore_response
--- error_log
API disabled in the context of header_filter_by_lua*
--- curl_error eval
qr/curl: \(52\) Empty reply from server|curl: \(92\) HTTP\/2 stream 0 was not closed cleanly|curl: \(95\) HTTP\/3 stream 0 reset by server/
@ -756,6 +798,8 @@ stack traceback:
in function 'error'
in function 'bar'
in function 'foo'
--- curl_error eval
qr/curl: \(52\) Empty reply from server|curl: \(92\) HTTP\/2 stream 0 was not closed cleanly|curl: \(95\) HTTP\/3 stream 0 reset by server/
@ -774,6 +818,8 @@ GET /lua?a=1&b=2
--- ignore_response
--- error_log eval
qr/failed to load external Lua file ".*?test2\.lua": cannot open .*? No such file or directory/
--- curl_error eval
qr/curl: \(52\) Empty reply from server|curl: \(92\) HTTP\/2 stream 0 was not closed cleanly|curl: \(95\) HTTP\/3 stream 0 reset by server/
@ -820,6 +866,8 @@ GET /lua
failed to load inlined Lua code: header_filter_by_lua(nginx.conf:41):2: unexpected symbol near ''for end''
--- no_error_log
no_such_error
--- curl_error eval
qr/curl: \(56\) Failure when receiving data from the peer/
@ -849,6 +897,8 @@ GET /lua
failed to load inlined Lua code: header_filter_by_lua(nginx.conf:49):2: unexpected symbol near ''for end''
--- no_error_log
no_such_error
--- curl_error eval
qr/curl: \(56\) Failure when receiving data from the peer/
@ -873,3 +923,5 @@ GET /lua
failed to load inlined Lua code: header_filter_by_lua(...901234567890123456789012345.conf:1):2: unexpected symbol near ''for end''
--- no_error_log
[alert]
--- curl_error eval
qr/curl: \(56\) Failure when receiving data from the peer/

View file

@ -768,7 +768,7 @@ foo = 10502
dogs:set("bar", 32, 0.001)
dogs:set("baz", 32, 0.001)
dogs:set("foo", 32, 0.001)
ngx.location.capture("/sleep/0.002")
ngx.location.capture("/sleep/0.003")
local res, err, forcible = dogs:add("foo", 10502)
ngx.say("add: ", res, " ", err, " ", forcible)
ngx.say("foo = ", dogs:get("foo"))
@ -797,7 +797,7 @@ foo = 10502
dogs:set("bar", 32, 0.001)
dogs:set("baz", 32, 0.001)
dogs:set("foo", "hi", 0.001)
ngx.location.capture("/sleep/0.002")
ngx.location.capture("/sleep/0.003")
local res, err, forcible = dogs:add("foo", "hello")
ngx.say("add: ", res, " ", err, " ", forcible)
ngx.say("foo = ", dogs:get("foo"))
@ -1184,6 +1184,7 @@ nil nil
=== TEST 45: flush_expires
--- quic_max_idle_timeout: 1.6
--- http_config
lua_shared_dict dogs 1m;
--- config
@ -1210,6 +1211,7 @@ GET /t
=== TEST 46: flush_expires with number
--- quic_max_idle_timeout: 1.6
--- http_config
lua_shared_dict dogs 1m;
--- config
@ -1337,6 +1339,7 @@ GET /t
=== TEST 51: list all keys in a shdict with expires
--- quic_max_idle_timeout: 1.6
--- http_config
lua_shared_dict dogs 1m;
--- config
@ -1426,6 +1429,7 @@ GET /t
=== TEST 55: list all keys in a shdict with all keys expired
--- quic_max_idle_timeout: 1.6
--- http_config
lua_shared_dict dogs 1m;
--- config

View file

@ -7,7 +7,7 @@ log_level('warn');
repeat_each(2);
plan tests => repeat_each() * (blocks() * 4 + 52 );
plan tests => repeat_each() * (blocks() * 4 + 56);
#no_diff();
no_long_string();
@ -351,9 +351,18 @@ hello, world
--- user_files
>>> a.txt
Will you change this world?
--- raw_response_headers_like
X-Old: \S+/client_body_temp/\d+\r
.*?X-New: \S+/html/a\.txt\r
--- raw_response_headers_like eval
my $headers;
if (defined $ENV{TEST_NGINX_USE_HTTP3}) {
$headers = qr#x-old: \S+/client_body_temp/\d+\r
.*?x-new: \S+/html/a\.txt\r#;
} else {
$headers = qr#X-Old: \S+/client_body_temp/\d+\r
.*?X-New: \S+/html/a\.txt\r#;
}
$headers;
--- response_body
Will you change this world?
--- no_error_log
@ -390,9 +399,18 @@ hello, world!
--- user_files
>>> a.txt
Will you change this world?
--- raw_response_headers_like
X-Old: \S+/client_body_temp/\d+\r
.*?X-New: \S+/html/a\.txt\r
--- raw_response_headers_like eval
my $headers;
if (defined $ENV{TEST_NGINX_USE_HTTP3}) {
$headers = qr#x-old: \S+/client_body_temp/\d+\r
.*?x-new: \S+/html/a\.txt\r#;
} else {
$headers = qr#X-Old: \S+/client_body_temp/\d+\r
.*?X-New: \S+/html/a\.txt\r#;
}
$headers;
--- response_body
Will you change this world?
--- no_error_log
@ -898,6 +916,7 @@ body: hell
--- no_error_log
[error]
[alert]
--- skip_eval: 4:$ENV{TEST_NGINX_USE_HTTP3}
@ -959,6 +978,7 @@ body file: hello
[alert]
--- error_log
a client request body is buffered to a temporary file
--- skip_eval: 5:$ENV{TEST_NGINX_USE_HTTP3}
@ -985,9 +1005,9 @@ a client request body is buffered to a temporary file
--- error_code: 500
--- error_log eval
qr/lua entry thread aborted: runtime error: content_by_lua\(nginx\.conf:\d+\):2: request body not read yet/
--- no_error_log
[alert]
--- skip_eval: 4:$ENV{TEST_NGINX_USE_HTTP3}
@ -1017,8 +1037,8 @@ body: hell
--- no_error_log
[error]
[alert]
--- no_error_log
a client request body is buffered to a temporary file
--- skip_eval: 5:$ENV{TEST_NGINX_USE_HTTP3}
@ -1241,8 +1261,8 @@ body: hello, my dear friend!
--- no_error_log
[error]
[alert]
--- no_error_log
a client request body is buffered to a temporary file
--- skip_eval: 5:$ENV{TEST_NGINX_USE_HTTP3}
@ -1382,8 +1402,8 @@ failed to get req socket: request body already exists
--- no_error_log
[error]
[alert]
--- no_error_log
a client request body is buffered to a temporary file
--- skip_eval: 5:$ENV{TEST_NGINX_USE_HTTP3}
@ -1405,6 +1425,7 @@ Expect: 100-Continue
[alert]
[error]
http finalize request: 500, "/test?" a:1, c:0
--- skip_eval: 3:$ENV{TEST_NGINX_USE_HTTP3}
@ -1480,13 +1501,22 @@ probe syscall.fcntl {
--- stap_out_unlike
fcntl\(O_DIRECT\)
--- raw_response_headers_like
.*?X-New: \S+/html/a\.txt\r
--- raw_response_headers_like eval
my $headers;
if (defined $ENV{TEST_NGINX_USE_HTTP3}) {
$headers = qr#.*?x-new: \S+/html/a\.txt\r#;
} else {
$headers = qr#.*?X-New: \S+/html/a\.txt\r#;
}
$headers;
--- response_body
Will you change this world?
--- no_error_log
[error]
[alert]
--- skip_eval: 6:$ENV{TEST_NGINX_USE_HTTP3}
@ -1744,3 +1774,23 @@ content length: 5
--- no_error_log
[error]
[alert]
--- skip_eval: 4:$ENV{TEST_NGINX_USE_HTTP3}
=== TEST 53: HTTP2 read buffered body was discarded
--- config
location = /test {
content_by_lua_block {
local err = pcall(ngx.req.read_body())
ngx.say(err)
}
}
--- http2
--- request
POST /test
hello, world
--- more_headers
Content-Length:
--- error_code: 500
--- error_log: http2 requests are not supported without content-length header

View file

@ -170,10 +170,22 @@ invalid referer: 1
}
--- request
GET /t
--- raw_response_headers_like
Proxy-Host: 127.0.0.1\:\d+\r
--- raw_response_headers_like eval
my $headers;
if (defined $ENV{TEST_NGINX_USE_HTTP3}) {
$headers =
qr/proxy-host: 127.0.0.1\:\d+\r
proxy-port: \d+\r
proxy-add-x-forwarded-for: 127.0.0.1\r/;
} else {
$headers =
qr/Proxy-Host: 127.0.0.1\:\d+\r
Proxy-Port: \d+\r
Proxy-Add-X-Forwarded-For: 127.0.0.1\r
Proxy-Add-X-Forwarded-For: 127.0.0.1\r/;
}
$headers;
--- response_body
hello
--- no_error_log
@ -248,19 +260,19 @@ variable "query_string" not changeable
}
server {
# this is the real entry point
listen 8091;
listen $TEST_NGINX_RAND_PORT_1;
location / {
content_by_lua_block{
ngx.print("this is backend peer 8091")
ngx.print("this is backend peer $TEST_NGINX_RAND_PORT_1")
}
}
}
server {
# this is the real entry point
listen 8092;
listen $TEST_NGINX_RAND_PORT_2;
location / {
content_by_lua_block{
ngx.print("this is backend peer 8092")
ngx.print("this is backend peer $TEST_NGINX_RAND_PORT_2")
}
}
}
@ -275,6 +287,6 @@ variable "query_string" not changeable
proxy_pass http://balancer;
}
--- pipelined_requests eval
["GET /balancer?port=8091", "GET /balancer?port=8092"]
["GET /balancer?port=\$TEST_NGINX_RAND_PORT_1", "GET /balancer?port=\$TEST_NGINX_RAND_PORT_2"]
--- response_body eval
["this is backend peer 8091", "this is backend peer 8092"]
["this is backend peer \$TEST_NGINX_RAND_PORT_1", "this is backend peer \$TEST_NGINX_RAND_PORT_2"]

View file

@ -32,8 +32,11 @@ __DATA__
GET /re
--- response_body
1234
--- error_log
pcre JIT compiling result: 1
--- error_log eval
$Test::Nginx::Util::PcreVersion == 2 ?
"pcre2 JIT compiled successfully\n"
:
"pcre JIT compiling result: 1\n"
@ -53,8 +56,11 @@ pcre JIT compiling result: 1
GET /re
--- response_body
not matched!
--- error_log
pcre JIT compiling result: 1
--- error_log eval
$Test::Nginx::Util::PcreVersion == 2 ?
"pcre2 JIT compiled successfully\n"
:
"pcre JIT compiling result: 1\n"
@ -76,9 +82,15 @@ pcre JIT compiling result: 1
1234
--- grep_error_log eval
qr/pcre JIT compiling result: \d+/
$Test::Nginx::Util::PcreVersion == 2 ?
"pcre2 JIT compiled successfully"
:
"pcre JIT compiling result: 1"
--- grep_error_log_out eval
$Test::Nginx::Util::PcreVersion == 2 ?
["pcre2 JIT compiled successfully\n", ""]
:
["pcre JIT compiling result: 1\n", ""]
@ -101,9 +113,15 @@ qr/pcre JIT compiling result: \d+/
not matched!
--- grep_error_log eval
qr/pcre JIT compiling result: \d+/
$Test::Nginx::Util::PcreVersion == 2 ?
"pcre2 JIT compiled successfully"
:
"pcre JIT compiling result: 1"
--- grep_error_log_out eval
$Test::Nginx::Util::PcreVersion == 2 ?
["pcre2 JIT compiled successfully\n", ""]
:
["pcre JIT compiling result: 1\n", ""]
@ -128,8 +146,11 @@ qr/pcre JIT compiling result: \d+/
}
--- request
GET /re
--- response_body
error: pcre_compile() failed: missing ) in "(abc"
--- response_body eval
$Test::Nginx::Util::PcreVersion == 2 ?
"error: pcre2_compile() failed: missing closing parenthesis in \"(abc\"\n"
:
"error: pcre_compile() failed: missing ) in \"(abc\"\n"
--- no_error_log
[error]
@ -170,8 +191,15 @@ end
--- request
GET /re
--- response_body
error: pcre_exec() failed: -8
--- response_body eval
# lua_regex_match_limit uses pcre_extra->match_limit in the PCRE,
# but PCRE2 replaces this with pcre2_set_match_limit interface,
# which has different effects.
$Test::Nginx::Util::PcreVersion == 2 ?
# PCRE2_ERROR_MATCHLIMIT (-47)
"error: pcre_exec() failed: -47\n"
:
"error: pcre_exec() failed: -8\n"

View file

@ -34,8 +34,11 @@ __DATA__
--- response_body
hello
world
--- error_log
pcre JIT compiling result: 1
--- error_log eval
$Test::Nginx::Util::PcreVersion == 2 ?
"pcre2 JIT compiled successfully\n"
:
"pcre JIT compiling result: 1\n"
@ -60,8 +63,11 @@ pcre JIT compiling result: 1
nil
nil
nil
--- error_log
pcre JIT compiling result: 1
--- error_log eval
$Test::Nginx::Util::PcreVersion == 2 ?
"pcre2 JIT compiled successfully\n"
:
"pcre JIT compiling result: 1\n"
@ -77,8 +83,11 @@ pcre JIT compiling result: 1
GET /re
--- response_body
done
--- error_log
pcre JIT compiling result: 1
--- error_log eval
$Test::Nginx::Util::PcreVersion == 2 ?
"pcre2 JIT compiled successfully\n"
:
"pcre JIT compiling result: 1\n"
@ -99,8 +108,11 @@ pcre JIT compiling result: 1
GET /re
--- response_body
hello
--- error_log
pcre JIT compiling result: 1
--- error_log eval
$Test::Nginx::Util::PcreVersion == 2 ?
"pcre2 JIT compiled successfully\n"
:
"pcre JIT compiling result: 1\n"
@ -124,9 +136,15 @@ hello
world
--- grep_error_log eval
qr/pcre JIT compiling result: \d+/
$Test::Nginx::Util::PcreVersion == 2 ?
"pcre2 JIT compiled successfully"
:
"pcre JIT compiling result: 1"
--- grep_error_log_out eval
$Test::Nginx::Util::PcreVersion == 2 ?
["pcre2 JIT compiled successfully\n", ""]
:
["pcre JIT compiling result: 1\n", ""]
@ -154,9 +172,15 @@ nil
nil
--- grep_error_log eval
qr/pcre JIT compiling result: \d+/
$Test::Nginx::Util::PcreVersion == 2 ?
"pcre2 JIT compiled successfully"
:
"pcre JIT compiling result: 1"
--- grep_error_log_out eval
$Test::Nginx::Util::PcreVersion == 2 ?
["pcre2 JIT compiled successfully\n", ""]
:
["pcre JIT compiling result: 1\n", ""]
@ -175,9 +199,15 @@ qr/pcre JIT compiling result: \d+/
done
--- grep_error_log eval
qr/pcre JIT compiling result: \d+/
$Test::Nginx::Util::PcreVersion == 2 ?
"pcre2 JIT compiled successfully"
:
"pcre JIT compiling result: 1"
--- grep_error_log_out eval
$Test::Nginx::Util::PcreVersion == 2 ?
["pcre2 JIT compiled successfully\n", ""]
:
["pcre JIT compiling result: 1\n", ""]
@ -201,9 +231,15 @@ qr/pcre JIT compiling result: \d+/
hello
--- grep_error_log eval
qr/pcre JIT compiling result: \d+/
$Test::Nginx::Util::PcreVersion == 2 ?
"pcre2 JIT compiled successfully"
:
"pcre JIT compiling result: 1"
--- grep_error_log_out eval
$Test::Nginx::Util::PcreVersion == 2 ?
["pcre2 JIT compiled successfully\n", ""]
:
["pcre JIT compiling result: 1\n", ""]
@ -222,7 +258,10 @@ qr/pcre JIT compiling result: \d+/
}
--- request
GET /re
--- response_body
error: pcre_compile() failed: missing ) in "(abc"
--- response_body eval
$Test::Nginx::Util::PcreVersion == 2 ?
"error: pcre2_compile() failed: missing closing parenthesis in \"(abc\"\n"
:
"error: pcre_compile() failed: missing ) in \"(abc\"\n"
--- no_error_log
[error]

View file

@ -214,8 +214,11 @@ hello
}
--- request
GET /re
--- response_body
error: pcre_compile() failed: missing ) in "(abc"
--- response_body eval
$Test::Nginx::Util::PcreVersion == 2 ?
"error: pcre2_compile() failed: missing closing parenthesis in \"(abc\"\n"
:
"error: pcre_compile() failed: missing ) in \"(abc\"\n"
--- no_error_log
[error]

View file

@ -32,8 +32,11 @@ __DATA__
GET /re
--- response_body
hello, world 5678: 1
--- error_log
pcre JIT compiling result: 1
--- error_log eval
$Test::Nginx::Util::PcreVersion == 2 ?
"pcre2 JIT compiled successfully\n"
:
"pcre JIT compiling result: 1\n"
@ -53,8 +56,11 @@ pcre JIT compiling result: 1
GET /re
--- response_body
hello, world: 0
--- error_log
pcre JIT compiling result: 1
--- error_log eval
$Test::Nginx::Util::PcreVersion == 2 ?
"pcre2 JIT compiled successfully\n"
:
"pcre JIT compiling result: 1\n"
@ -76,9 +82,15 @@ pcre JIT compiling result: 1
hello, world 5678: 1
--- grep_error_log eval
qr/pcre JIT compiling result: \d+/
$Test::Nginx::Util::PcreVersion == 2 ?
"pcre2 JIT compiled successfully"
:
"pcre JIT compiling result: 1"
--- grep_error_log_out eval
$Test::Nginx::Util::PcreVersion == 2 ?
["pcre2 JIT compiled successfully\n", ""]
:
["pcre JIT compiling result: 1\n", ""]
@ -101,9 +113,15 @@ qr/pcre JIT compiling result: \d+/
hello, world: 0
--- grep_error_log eval
qr/pcre JIT compiling result: \d+/
$Test::Nginx::Util::PcreVersion == 2 ?
"pcre2 JIT compiled successfully"
:
"pcre JIT compiling result: 1"
--- grep_error_log_out eval
$Test::Nginx::Util::PcreVersion == 2 ?
["pcre2 JIT compiled successfully\n", ""]
:
["pcre JIT compiling result: 1\n", ""]
@ -122,8 +140,11 @@ qr/pcre JIT compiling result: \d+/
}
--- request
GET /re
--- response_body
error: pcre_compile() failed: missing ) in "(abc"
--- response_body eval
$Test::Nginx::Util::PcreVersion == 2 ?
"error: pcre2_compile() failed: missing closing parenthesis in \"(abc\"\n"
:
"error: pcre_compile() failed: missing ) in \"(abc\"\n"
--- no_error_log
[error]
@ -143,7 +164,10 @@ error: pcre_compile() failed: missing ) in "(abc"
}
--- request
GET /re
--- response_body
error: pcre_compile() failed: missing ) in "(abc"
--- response_body eval
$Test::Nginx::Util::PcreVersion == 2 ?
"error: pcre2_compile() failed: missing closing parenthesis in \"(abc\"\n"
:
"error: pcre_compile() failed: missing ) in \"(abc\"\n"
--- no_error_log
[error]

View file

@ -107,8 +107,11 @@ hello, world: 0
}
--- request
GET /re
--- response_body
error: pcre_compile() failed: missing ) in "(abc"
--- response_body eval
$Test::Nginx::Util::PcreVersion == 2 ?
"error: pcre2_compile() failed: missing closing parenthesis in \"(abc\"\n"
:
"error: pcre_compile() failed: missing ) in \"(abc\"\n"
--- no_error_log
[error]
@ -129,8 +132,11 @@ error: pcre_compile() failed: missing ) in "(abc"
}
--- request
GET /re
--- response_body
error: pcre_compile() failed: missing ) in "(abc"
--- response_body eval
$Test::Nginx::Util::PcreVersion == 2 ?
"error: pcre2_compile() failed: missing closing parenthesis in \"(abc\"\n"
:
"error: pcre_compile() failed: missing ) in \"(abc\"\n"
--- no_error_log
[error]

Some files were not shown because too many files have changed in this diff Show more