mirror of
https://github.com/bunkerity/bunkerweb
synced 2026-05-24 09:28:37 +00:00
Merge pull request #884 from bunkerity/dev
Merge branch "dev" into branch "ui"
This commit is contained in:
commit
ee24d61de1
512 changed files with 21853 additions and 3184 deletions
4
.github/workflows/codeql.yml
vendored
4
.github/workflows/codeql.yml
vendored
|
|
@ -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@0b21cf2492b6b02c465a3e5d7c473717ad7721ba # v3.23.1
|
||||
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@0b21cf2492b6b02c465a3e5d7c473717ad7721ba # v3.23.1
|
||||
with:
|
||||
category: "/language:${{matrix.language}}"
|
||||
|
|
|
|||
4
.github/workflows/container-build.yml
vendored
4
.github/workflows/container-build.yml
vendored
|
|
@ -56,6 +56,8 @@ jobs:
|
|||
echo "$SSH_KEY" > ~/.ssh/id_rsa_arm
|
||||
chmod 600 ~/.ssh/id_rsa_arm
|
||||
echo "$SSH_CONFIG" | sed "s/SSH_IP/$SSH_IP/g" > ~/.ssh/config
|
||||
echo "ServerAliveInterval 60" >> ~/.ssh/config
|
||||
echo "ServerAliveCountMax 10" >> ~/.ssh/config
|
||||
env:
|
||||
SSH_KEY: ${{ secrets.ARM_SSH_KEY }}
|
||||
SSH_IP: ${{ secrets.ARM_SSH_IP }}
|
||||
|
|
@ -84,7 +86,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
|
||||
|
|
|
|||
4
.github/workflows/create-arm.yml
vendored
4
.github/workflows/create-arm.yml
vendored
|
|
@ -46,7 +46,7 @@ jobs:
|
|||
default-organization-id: ${{ secrets.SCW_DEFAULT_ORGANIZATION_ID }}
|
||||
- name: Extract ARM type
|
||||
run: |
|
||||
TYPE=$(echo "$JSON" | jq '.servers | with_entries(select(.key | contains("AMP"))) | with_entries(select(.value.availability != "shortage")) | keys[] | select(. | test("^AMP2-C[0-9]+$")) | sub("AMP2-C"; "") | tonumber' | sort -n | tail -n 1 | xargs -I {} echo "AMP2-C{}")
|
||||
TYPE=$(echo "$JSON" | jq '.servers | with_entries(select(.key | contains("COPARM1-"))) | with_entries(select(.value.availability != "shortage")) | keys[] | select(. | test("^COPARM1-[0-9]+C-[0-9]+G$"))' | sed 's/"//g' | cut -d '-' -f 2,3 | sort -g | tail -n 1 | xargs -I {} echo "COPARM1-{}")
|
||||
echo "Type is $TYPE"
|
||||
echo "TYPE=$TYPE" >> "$GITHUB_ENV"
|
||||
env:
|
||||
|
|
@ -81,6 +81,6 @@ jobs:
|
|||
SSH_IP: ${{ fromJson(steps.scw.outputs.json).public_ip.address }}
|
||||
SSH_CONFIG: ${{ secrets.ARM_SSH_CONFIG }}
|
||||
- name: Install Docker
|
||||
run: ssh root@$SSH_IP "curl -fsSL https://test.docker.com -o test-docker.sh ; sh test-docker.sh"
|
||||
run: ssh root@$SSH_IP "curl -fsSL https://test.docker.com -o test-docker.sh ; sh test-docker.sh ; echo 'ClientAliveInterval 60' >> /etc/ssh/sshd_config ; echo 'ClientAliveCountMax 0' >> /etc/ssh/sshd_config ; systemctl restart ssh"
|
||||
env:
|
||||
SSH_IP: ${{ fromJson(steps.scw.outputs.json).public_ip.address }}
|
||||
|
|
|
|||
6
.github/workflows/dev.yml
vendored
6
.github/workflows/dev.yml
vendored
|
|
@ -13,6 +13,7 @@ jobs:
|
|||
contents: read
|
||||
packages: write
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
image: [bunkerweb, scheduler, autoconf, ui]
|
||||
include:
|
||||
|
|
@ -84,7 +85,6 @@ jobs:
|
|||
|
||||
# Core tests
|
||||
prepare-tests-core:
|
||||
needs: [build-containers, build-packages]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
|
|
@ -96,7 +96,7 @@ jobs:
|
|||
outputs:
|
||||
tests: ${{ steps.set-matrix.outputs.tests }}
|
||||
tests-core:
|
||||
needs: prepare-tests-core
|
||||
needs: [build-containers, prepare-tests-core]
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
|
|
@ -106,7 +106,7 @@ jobs:
|
|||
TEST: ${{ matrix.test }}
|
||||
RELEASE: dev
|
||||
tests-core-linux:
|
||||
needs: prepare-tests-core
|
||||
needs: [build-packages, prepare-tests-core]
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
|
|
|
|||
6
.github/workflows/doc-to-pdf.yml
vendored
6
.github/workflows/doc-to-pdf.yml
vendored
|
|
@ -18,8 +18,8 @@ jobs:
|
|||
uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # v5.0.0
|
||||
with:
|
||||
python-version: "3.10"
|
||||
- name: Install doc requirements
|
||||
run: pip install --no-cache-dir --require-hashes -r docs/requirements.txt
|
||||
- name: Install doc dependencies
|
||||
run: pip install --no-cache-dir --require-hashes -r docs/requirements.txt && sudo apt install -y libcairo2-dev libfreetype6-dev libffi-dev libjpeg-dev libpng-dev libz-dev
|
||||
- name: Install chromium
|
||||
run: sudo apt install chromium-browser
|
||||
- name: Install node
|
||||
|
|
@ -32,7 +32,7 @@ jobs:
|
|||
run: mkdocs serve & sleep 10
|
||||
- name: Run pdf script
|
||||
run: node docs/misc/pdf.js http://localhost:8000/print_page/ BunkerWeb_documentation_v${{ inputs.VERSION }}.pdf 'BunkerWeb documentation v${{ inputs.VERSION }}'
|
||||
- uses: actions/upload-artifact@c7d193f32edcb7bfad88892161225aeda64e9392 # v4.0.0
|
||||
- uses: actions/upload-artifact@694cdabd8bdb0f10b2cea11669e1bf5453eed0a6 # v4.2.0
|
||||
with:
|
||||
name: BunkerWeb_documentation_v${{ inputs.VERSION }}.pdf
|
||||
path: BunkerWeb_documentation_v${{ inputs.VERSION }}.pdf
|
||||
|
|
|
|||
6
.github/workflows/linux-build.yml
vendored
6
.github/workflows/linux-build.yml
vendored
|
|
@ -65,6 +65,8 @@ jobs:
|
|||
echo "$SSH_KEY" > ~/.ssh/id_rsa_arm
|
||||
chmod 600 ~/.ssh/id_rsa_arm
|
||||
echo "$SSH_CONFIG" | sed "s/SSH_IP/$SSH_IP/g" > ~/.ssh/config
|
||||
echo "ServerAliveInterval 60" >> ~/.ssh/config
|
||||
echo "ServerAliveCountMax 10" >> ~/.ssh/config
|
||||
env:
|
||||
SSH_KEY: ${{ secrets.ARM_SSH_KEY }}
|
||||
SSH_IP: ${{ secrets.ARM_SSH_IP }}
|
||||
|
|
@ -127,7 +129,7 @@ jobs:
|
|||
scp -r root@arm:/root/package-${{ inputs.LINUX }} ./package-${{ inputs.LINUX }}
|
||||
env:
|
||||
LARCH: ${{ env.LARCH }}
|
||||
- uses: actions/upload-artifact@c7d193f32edcb7bfad88892161225aeda64e9392 # v4.0.0
|
||||
- uses: actions/upload-artifact@694cdabd8bdb0f10b2cea11669e1bf5453eed0a6 # v4.2.0
|
||||
with:
|
||||
name: package-${{ inputs.LINUX }}-${{ env.LARCH }}
|
||||
path: package-${{ inputs.LINUX }}/*.${{ inputs.PACKAGE }}
|
||||
|
|
@ -135,7 +137,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
|
||||
|
|
|
|||
4
.github/workflows/push-doc.yml
vendored
4
.github/workflows/push-doc.yml
vendored
|
|
@ -32,8 +32,8 @@ jobs:
|
|||
- uses: actions/setup-python@0a5c61591373683505ea898e09a3ea4f39ef2b9c # v5.0.0
|
||||
with:
|
||||
python-version: "3.10"
|
||||
- name: Install doc requirements
|
||||
run: pip install --no-cache-dir --require-hashes -r docs/requirements.txt
|
||||
- name: Install doc dependencies
|
||||
run: pip install --no-cache-dir --require-hashes -r docs/requirements.txt && sudo apt install -y libcairo2-dev libfreetype6-dev libffi-dev libjpeg-dev libpng-dev libz-dev
|
||||
- name: Push doc
|
||||
run: mike deploy --update-aliases --push --alias-type=copy ${{ inputs.VERSION }} ${{ inputs.ALIAS }}
|
||||
- name: Set default doc
|
||||
|
|
|
|||
4
.github/workflows/push-docker.yml
vendored
4
.github/workflows/push-docker.yml
vendored
|
|
@ -51,6 +51,8 @@ jobs:
|
|||
echo "$SSH_KEY" > ~/.ssh/id_rsa_arm
|
||||
chmod 600 ~/.ssh/id_rsa_arm
|
||||
echo "$SSH_CONFIG" | sed "s/SSH_IP/$SSH_IP/g" > ~/.ssh/config
|
||||
echo "ServerAliveInterval 60" >> ~/.ssh/config
|
||||
echo "ServerAliveCountMax 10" >> ~/.ssh/config
|
||||
env:
|
||||
SSH_KEY: ${{ secrets.ARM_SSH_KEY }}
|
||||
SSH_IP: ${{ secrets.ARM_SSH_IP }}
|
||||
|
|
@ -63,7 +65,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
|
||||
|
|
|
|||
2
.github/workflows/push-github.yml
vendored
2
.github/workflows/push-github.yml
vendored
|
|
@ -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
|
||||
|
|
|
|||
6
.github/workflows/push-packagecloud.yml
vendored
6
.github/workflows/push-packagecloud.yml
vendored
|
|
@ -42,18 +42,18 @@ jobs:
|
|||
- name: Check out repository code
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- name: Install ruby
|
||||
uses: ruby/setup-ruby@360dc864d5da99d54fcb8e9148c14a84b90d3e88 # v1.165.1
|
||||
uses: ruby/setup-ruby@5daca165445f0ae10478593083f72ca2625e241d # v1.169.0
|
||||
with:
|
||||
ruby-version: "3.0"
|
||||
- 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 }}
|
||||
|
|
|
|||
2
.github/workflows/scorecards-analysis.yml
vendored
2
.github/workflows/scorecards-analysis.yml
vendored
|
|
@ -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@0b21cf2492b6b02c465a3e5d7c473717ad7721ba # v3.23.1
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
|
|
|
|||
2
.github/workflows/staging-create-infra.yml
vendored
2
.github/workflows/staging-create-infra.yml
vendored
|
|
@ -55,7 +55,7 @@ jobs:
|
|||
if: always()
|
||||
env:
|
||||
SECRET_KEY: ${{ secrets.SECRET_KEY }}
|
||||
- uses: actions/upload-artifact@c7d193f32edcb7bfad88892161225aeda64e9392 # v4.0.0
|
||||
- uses: actions/upload-artifact@694cdabd8bdb0f10b2cea11669e1bf5453eed0a6 # v4.2.0
|
||||
if: always()
|
||||
with:
|
||||
name: tf-${{ inputs.TYPE }}
|
||||
|
|
|
|||
2
.github/workflows/staging-delete-infra.yml
vendored
2
.github/workflows/staging-delete-infra.yml
vendored
|
|
@ -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
|
||||
|
|
|
|||
2
.github/workflows/staging-tests.yml
vendored
2
.github/workflows/staging-tests.yml
vendored
|
|
@ -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
|
||||
|
|
|
|||
5
.github/workflows/staging.yml
vendored
5
.github/workflows/staging.yml
vendored
|
|
@ -85,7 +85,6 @@ jobs:
|
|||
SECRET_KEY: ${{ secrets.SECRET_KEY }}
|
||||
K8S_IP: ${{ secrets.K8S_IP }}
|
||||
prepare-tests-core:
|
||||
needs: [codeql, build-containers, build-packages]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
|
|
@ -130,7 +129,7 @@ jobs:
|
|||
RUNS_ON: ${{ matrix.runs_on }}
|
||||
secrets: inherit
|
||||
tests-core:
|
||||
needs: prepare-tests-core
|
||||
needs: [build-containers, prepare-tests-core]
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
|
|
@ -140,7 +139,7 @@ jobs:
|
|||
TEST: ${{ matrix.test }}
|
||||
RELEASE: testing
|
||||
tests-core-linux:
|
||||
needs: prepare-tests-core
|
||||
needs: [build-packages, prepare-tests-core]
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
|
|
|
|||
4
.github/workflows/test-core-linux.yml
vendored
4
.github/workflows/test-core-linux.yml
vendored
|
|
@ -97,7 +97,7 @@ jobs:
|
|||
run: |
|
||||
export MAKEFLAGS="-j $(nproc)"
|
||||
pip install --no-cache-dir --ignore-installed --require-hashes -r src/deps/requirements-deps.txt
|
||||
MAKEFLAGS="-j $(nproc)" find tests/core -name "requirements.txt" -exec pip install --no-cache-dir --require-hashes --no-deps -r {} \;
|
||||
cd ./tests/core/${{ inputs.TEST }}
|
||||
cd tests/core/${{ inputs.TEST }}
|
||||
find . -name "requirements.txt" -exec pip install --no-cache-dir --require-hashes --no-deps -r {} \;
|
||||
sudo truncate -s 0 /var/log/bunkerweb/error.log
|
||||
./test.sh "linux"
|
||||
|
|
|
|||
5
.github/workflows/tests-ui-linux.yml
vendored
5
.github/workflows/tests-ui-linux.yml
vendored
|
|
@ -66,14 +66,13 @@ jobs:
|
|||
- name: Fix version without a starting number
|
||||
if: inputs.RELEASE == 'testing' || inputs.RELEASE == 'dev' || inputs.RELEASE == 'ui'
|
||||
run: echo "force-bad-version" | sudo tee -a /etc/dpkg/dpkg.cfg
|
||||
- name: Install BunkerWeb
|
||||
run: sudo apt install -fy /tmp/bunkerweb.deb
|
||||
- name: Edit configuration files
|
||||
run: |
|
||||
# Misc
|
||||
echo "127.0.0.1 www.example.com" | sudo tee -a /etc/hosts
|
||||
echo "127.0.0.1 app1.example.com" | sudo tee -a /etc/hosts
|
||||
# BunkerWeb
|
||||
sudo mkdir -p /etc/bunkerweb
|
||||
echo "SERVER_NAME=" | sudo tee /etc/bunkerweb/variables.env
|
||||
echo "HTTP_PORT=80" | sudo tee -a /etc/bunkerweb/variables.env
|
||||
echo 'DNS_RESOLVERS=9.9.9.9 8.8.8.8 8.8.4.4' | sudo tee -a /etc/bunkerweb/variables.env
|
||||
|
|
@ -92,6 +91,8 @@ jobs:
|
|||
|
||||
sudo chown nginx:nginx /etc/bunkerweb/variables.env /etc/bunkerweb/ui.env
|
||||
sudo chmod 777 /etc/bunkerweb/variables.env /etc/bunkerweb/ui.env
|
||||
- name: Install BunkerWeb
|
||||
run: sudo apt install -fy /tmp/bunkerweb.deb
|
||||
- name: Run tests
|
||||
run: |
|
||||
export MAKEFLAGS="-j $(nproc)"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# See https://pre-commit.com for more information
|
||||
# See https://pre-commit.com/hooks.html for more hooks
|
||||
exclude: (^LICENSE.md$|^src/VERSION$|^env/|^src/(bw/misc/root-ca.pem$|deps/src/|common/core/modsecurity/files|ui/static/js/(editor/|utils/purify/|tsparticles\.bundle\.min\.js))|\.(svg|drawio|patch\d?|ascii|tf|tftpl|key)$)
|
||||
exclude: (^LICENSE.md$|^src/VERSION$|^env/|^src/(bw/misc/root-ca.pem$|deps/src/|common/core/modsecurity/files|ui/static/(js/(editor/|utils/purify/|tsparticles\.bundle\.min\.js)|css/dashboard\.css))|\.(svg|drawio|patch\d?|ascii|tf|tftpl|key)$)
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: c4a0b883114b00d8d76b479c820ce7950211c99b # frozen: v4.5.0
|
||||
|
|
@ -30,7 +30,7 @@ repos:
|
|||
name: Prettier Code Formatter
|
||||
|
||||
- repo: https://github.com/JohnnyMorganz/StyLua
|
||||
rev: f9afc7f33bc19f7708fbc1d7eea0606e0d41080a # frozen: v0.19.1
|
||||
rev: 84c370104d6a8d1eef00c80a3ebd42f7033aaaad # frozen: v0.20.0
|
||||
hooks:
|
||||
- id: stylua-github
|
||||
exclude: ^src/(bw/lua/middleclass.lua|common/core/antibot/captcha.lua)$
|
||||
|
|
@ -50,7 +50,7 @@ repos:
|
|||
args: ["--max-line-length=250", "--ignore=E266,E402,E722,W503"]
|
||||
|
||||
- repo: https://github.com/dosisod/refurb
|
||||
rev: a7c461fcfaa2ca3248d489cdf7fed8e2d4fd8520 # frozen: v1.26.0
|
||||
rev: a295cee6d188f5797aefe5d7cf77a353ed48ea93 # frozen: v1.27.0
|
||||
hooks:
|
||||
- id: refurb
|
||||
name: Refurb Python Refactoring Tool
|
||||
|
|
@ -62,7 +62,7 @@ repos:
|
|||
- id: codespell
|
||||
name: Codespell Spell Checker
|
||||
exclude: (^src/(ui/templates|common/core/.+/files|bw/loading)/.+.html|modsecurity-rules.conf.*)$
|
||||
entry: codespell --ignore-regex="(tabEl|Widgits)" --skip src/ui/static/js/utils/flatpickr.js,CHANGELOG.md
|
||||
entry: codespell --ignore-regex="(tabEl|Widgits)" --skip src/ui/static/js/utils/flatpickr.js,src/ui/static/css/style.css,CHANGELOG.md
|
||||
language: python
|
||||
types: [text]
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
CVE-2023-6129
|
||||
18
CHANGELOG.md
18
CHANGELOG.md
|
|
@ -1,15 +1,26 @@
|
|||
# Changelog
|
||||
|
||||
## v1.5.5 - YYYY/MM/DD
|
||||
## 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
|
||||
- [DEPS] Updated zlib version to v1.3.1
|
||||
|
||||
## 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
|
||||
- [BUGFIX] Fix inconsistency on config changes when using Redis
|
||||
- [BUGFIX] Fix web UI not working when using / URL
|
||||
- [FEATURE] Add Anonymous reporting feature
|
||||
- [FEATURE] Add support for fallback Referrer-Policies
|
||||
- [FEATURE] Add profile page to web ui and the possibility to activate the 2FA
|
||||
- [FEATURE] Add 2FA support to web UI
|
||||
- [FEATURE] Add username and password management to web UI
|
||||
- [FEATURE] Add setting REVERSE_PROXY_INCLUDES to manually add "include" directives in the reverse proxies
|
||||
- [FEATURE] Add support for Redis Sentinel
|
||||
- [FEATURE] Add support for tls in Ingress definition
|
||||
|
|
@ -17,7 +28,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
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<p align="center">
|
||||
<img alt="BunkerWeb logo" src="https://github.com/bunkerity/bunkerweb/raw/v1.5.5/misc/logo.png" />
|
||||
<img alt="BunkerWeb logo" src="https://github.com/bunkerity/bunkerweb/raw/v1.5.5/misc/logo.png" height=100 width=350 />
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
|
|
|
|||
5
docs/package.json
Normal file
5
docs/package.json
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"dependencies": {
|
||||
"puppeteer": "^21.3.6"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
mike==2.0.0
|
||||
mkdocs==1.5.3
|
||||
mkdocs-material[imaging]==9.5.3
|
||||
mkdocs-material[imaging]==9.5.4
|
||||
mkdocs-print-site-plugin==2.3.6
|
||||
pytablewriter==1.2.0
|
||||
|
|
|
|||
|
|
@ -211,81 +211,81 @@ 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
|
||||
# pymdown-extensions
|
||||
markupsafe==2.1.3 \
|
||||
--hash=sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e \
|
||||
--hash=sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e \
|
||||
--hash=sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431 \
|
||||
--hash=sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686 \
|
||||
--hash=sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c \
|
||||
--hash=sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559 \
|
||||
--hash=sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc \
|
||||
--hash=sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb \
|
||||
--hash=sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939 \
|
||||
--hash=sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c \
|
||||
--hash=sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0 \
|
||||
--hash=sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4 \
|
||||
--hash=sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9 \
|
||||
--hash=sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575 \
|
||||
--hash=sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba \
|
||||
--hash=sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d \
|
||||
--hash=sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd \
|
||||
--hash=sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3 \
|
||||
--hash=sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00 \
|
||||
--hash=sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155 \
|
||||
--hash=sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac \
|
||||
--hash=sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52 \
|
||||
--hash=sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f \
|
||||
--hash=sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8 \
|
||||
--hash=sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b \
|
||||
--hash=sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007 \
|
||||
--hash=sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24 \
|
||||
--hash=sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea \
|
||||
--hash=sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198 \
|
||||
--hash=sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0 \
|
||||
--hash=sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee \
|
||||
--hash=sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be \
|
||||
--hash=sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2 \
|
||||
--hash=sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1 \
|
||||
--hash=sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707 \
|
||||
--hash=sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6 \
|
||||
--hash=sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c \
|
||||
--hash=sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58 \
|
||||
--hash=sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823 \
|
||||
--hash=sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779 \
|
||||
--hash=sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636 \
|
||||
--hash=sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c \
|
||||
--hash=sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad \
|
||||
--hash=sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee \
|
||||
--hash=sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc \
|
||||
--hash=sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2 \
|
||||
--hash=sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48 \
|
||||
--hash=sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7 \
|
||||
--hash=sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e \
|
||||
--hash=sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b \
|
||||
--hash=sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa \
|
||||
--hash=sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5 \
|
||||
--hash=sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e \
|
||||
--hash=sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb \
|
||||
--hash=sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9 \
|
||||
--hash=sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57 \
|
||||
--hash=sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc \
|
||||
--hash=sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc \
|
||||
--hash=sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2 \
|
||||
--hash=sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11
|
||||
markupsafe==2.1.4 \
|
||||
--hash=sha256:0042d6a9880b38e1dd9ff83146cc3c9c18a059b9360ceae207805567aacccc69 \
|
||||
--hash=sha256:0c26f67b3fe27302d3a412b85ef696792c4a2386293c53ba683a89562f9399b0 \
|
||||
--hash=sha256:0fbad3d346df8f9d72622ac71b69565e621ada2ce6572f37c2eae8dacd60385d \
|
||||
--hash=sha256:15866d7f2dc60cfdde12ebb4e75e41be862348b4728300c36cdf405e258415ec \
|
||||
--hash=sha256:1c98c33ffe20e9a489145d97070a435ea0679fddaabcafe19982fe9c971987d5 \
|
||||
--hash=sha256:21e7af8091007bf4bebf4521184f4880a6acab8df0df52ef9e513d8e5db23411 \
|
||||
--hash=sha256:23984d1bdae01bee794267424af55eef4dfc038dc5d1272860669b2aa025c9e3 \
|
||||
--hash=sha256:31f57d64c336b8ccb1966d156932f3daa4fee74176b0fdc48ef580be774aae74 \
|
||||
--hash=sha256:3583a3a3ab7958e354dc1d25be74aee6228938312ee875a22330c4dc2e41beb0 \
|
||||
--hash=sha256:36d7626a8cca4d34216875aee5a1d3d654bb3dac201c1c003d182283e3205949 \
|
||||
--hash=sha256:396549cea79e8ca4ba65525470d534e8a41070e6b3500ce2414921099cb73e8d \
|
||||
--hash=sha256:3a66c36a3864df95e4f62f9167c734b3b1192cb0851b43d7cc08040c074c6279 \
|
||||
--hash=sha256:3aae9af4cac263007fd6309c64c6ab4506dd2b79382d9d19a1994f9240b8db4f \
|
||||
--hash=sha256:3ab3a886a237f6e9c9f4f7d272067e712cdb4efa774bef494dccad08f39d8ae6 \
|
||||
--hash=sha256:47bb5f0142b8b64ed1399b6b60f700a580335c8e1c57f2f15587bd072012decc \
|
||||
--hash=sha256:49a3b78a5af63ec10d8604180380c13dcd870aba7928c1fe04e881d5c792dc4e \
|
||||
--hash=sha256:4df98d4a9cd6a88d6a585852f56f2155c9cdb6aec78361a19f938810aa020954 \
|
||||
--hash=sha256:5045e892cfdaecc5b4c01822f353cf2c8feb88a6ec1c0adef2a2e705eef0f656 \
|
||||
--hash=sha256:5244324676254697fe5c181fc762284e2c5fceeb1c4e3e7f6aca2b6f107e60dc \
|
||||
--hash=sha256:54635102ba3cf5da26eb6f96c4b8c53af8a9c0d97b64bdcb592596a6255d8518 \
|
||||
--hash=sha256:54a7e1380dfece8847c71bf7e33da5d084e9b889c75eca19100ef98027bd9f56 \
|
||||
--hash=sha256:55d03fea4c4e9fd0ad75dc2e7e2b6757b80c152c032ea1d1de487461d8140efc \
|
||||
--hash=sha256:698e84142f3f884114ea8cf83e7a67ca8f4ace8454e78fe960646c6c91c63bfa \
|
||||
--hash=sha256:6aa5e2e7fc9bc042ae82d8b79d795b9a62bd8f15ba1e7594e3db243f158b5565 \
|
||||
--hash=sha256:7653fa39578957bc42e5ebc15cf4361d9e0ee4b702d7d5ec96cdac860953c5b4 \
|
||||
--hash=sha256:765f036a3d00395a326df2835d8f86b637dbaf9832f90f5d196c3b8a7a5080cb \
|
||||
--hash=sha256:78bc995e004681246e85e28e068111a4c3f35f34e6c62da1471e844ee1446250 \
|
||||
--hash=sha256:7a07f40ef8f0fbc5ef1000d0c78771f4d5ca03b4953fc162749772916b298fc4 \
|
||||
--hash=sha256:8b570a1537367b52396e53325769608f2a687ec9a4363647af1cded8928af959 \
|
||||
--hash=sha256:987d13fe1d23e12a66ca2073b8d2e2a75cec2ecb8eab43ff5624ba0ad42764bc \
|
||||
--hash=sha256:9896fca4a8eb246defc8b2a7ac77ef7553b638e04fbf170bff78a40fa8a91474 \
|
||||
--hash=sha256:9e9e3c4020aa2dc62d5dd6743a69e399ce3de58320522948af6140ac959ab863 \
|
||||
--hash=sha256:a0b838c37ba596fcbfca71651a104a611543077156cb0a26fe0c475e1f152ee8 \
|
||||
--hash=sha256:a4d176cfdfde84f732c4a53109b293d05883e952bbba68b857ae446fa3119b4f \
|
||||
--hash=sha256:a76055d5cb1c23485d7ddae533229039b850db711c554a12ea64a0fd8a0129e2 \
|
||||
--hash=sha256:a76cd37d229fc385738bd1ce4cba2a121cf26b53864c1772694ad0ad348e509e \
|
||||
--hash=sha256:a7cc49ef48a3c7a0005a949f3c04f8baa5409d3f663a1b36f0eba9bfe2a0396e \
|
||||
--hash=sha256:abf5ebbec056817057bfafc0445916bb688a255a5146f900445d081db08cbabb \
|
||||
--hash=sha256:b0fe73bac2fed83839dbdbe6da84ae2a31c11cfc1c777a40dbd8ac8a6ed1560f \
|
||||
--hash=sha256:b6f14a9cd50c3cb100eb94b3273131c80d102e19bb20253ac7bd7336118a673a \
|
||||
--hash=sha256:b83041cda633871572f0d3c41dddd5582ad7d22f65a72eacd8d3d6d00291df26 \
|
||||
--hash=sha256:b835aba863195269ea358cecc21b400276747cc977492319fd7682b8cd2c253d \
|
||||
--hash=sha256:bf1196dcc239e608605b716e7b166eb5faf4bc192f8a44b81e85251e62584bd2 \
|
||||
--hash=sha256:c669391319973e49a7c6230c218a1e3044710bc1ce4c8e6eb71f7e6d43a2c131 \
|
||||
--hash=sha256:c7556bafeaa0a50e2fe7dc86e0382dea349ebcad8f010d5a7dc6ba568eaaa789 \
|
||||
--hash=sha256:c8f253a84dbd2c63c19590fa86a032ef3d8cc18923b8049d91bcdeeb2581fbf6 \
|
||||
--hash=sha256:d18b66fe626ac412d96c2ab536306c736c66cf2a31c243a45025156cc190dc8a \
|
||||
--hash=sha256:d5291d98cd3ad9a562883468c690a2a238c4a6388ab3bd155b0c75dd55ece858 \
|
||||
--hash=sha256:d5c31fe855c77cad679b302aabc42d724ed87c043b1432d457f4976add1c2c3e \
|
||||
--hash=sha256:d6e427c7378c7f1b2bef6a344c925b8b63623d3321c09a237b7cc0e77dd98ceb \
|
||||
--hash=sha256:dac1ebf6983148b45b5fa48593950f90ed6d1d26300604f321c74a9ca1609f8e \
|
||||
--hash=sha256:de8153a7aae3835484ac168a9a9bdaa0c5eee4e0bc595503c95d53b942879c84 \
|
||||
--hash=sha256:e1a0d1924a5013d4f294087e00024ad25668234569289650929ab871231668e7 \
|
||||
--hash=sha256:e7902211afd0af05fbadcc9a312e4cf10f27b779cf1323e78d52377ae4b72bea \
|
||||
--hash=sha256:e888ff76ceb39601c59e219f281466c6d7e66bd375b4ec1ce83bcdc68306796b \
|
||||
--hash=sha256:f06e5a9e99b7df44640767842f414ed5d7bedaaa78cd817ce04bbd6fd86e2dd6 \
|
||||
--hash=sha256:f6be2d708a9d0e9b0054856f07ac7070fbe1754be40ca8525d5adccdbda8f475 \
|
||||
--hash=sha256:f9917691f410a2e0897d1ef99619fd3f7dd503647c8ff2475bf90c3cf222ad74 \
|
||||
--hash=sha256:fc1a75aa8f11b87910ffd98de62b29d6520b6d6e8a3de69a70ca34dea85d2a8a \
|
||||
--hash=sha256:fe8512ed897d5daf089e5bd010c3dc03bb1bdae00b35588c49b98268d4a01e00
|
||||
# via
|
||||
# jinja2
|
||||
# mkdocs
|
||||
|
|
@ -311,9 +311,9 @@ mkdocs==1.5.3 \
|
|||
# -r requirements.in
|
||||
# mike
|
||||
# mkdocs-material
|
||||
mkdocs-material==9.5.3 \
|
||||
--hash=sha256:5899219f422f0a6de784232d9d40374416302ffae3c160cacc72969fcc1ee372 \
|
||||
--hash=sha256:76c93a8525cceb0b395b9cedab3428bf518cf6439adef2b940f1c1574b775d89
|
||||
mkdocs-material==9.5.4 \
|
||||
--hash=sha256:3d196ee67fad16b2df1a458d650a8ac1890294eaae368d26cee71bc24ad41c40 \
|
||||
--hash=sha256:efd7cc8ae03296d728da9bd38f4db8b07ab61f9738a0cbd0dfaf2a15a50e7343
|
||||
# via
|
||||
# -r requirements.in
|
||||
# mkdocs-material
|
||||
|
|
@ -477,6 +477,7 @@ pyyaml==6.0.1 \
|
|||
--hash=sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4 \
|
||||
--hash=sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba \
|
||||
--hash=sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8 \
|
||||
--hash=sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef \
|
||||
--hash=sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5 \
|
||||
--hash=sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd \
|
||||
--hash=sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3 \
|
||||
|
|
|
|||
|
|
@ -550,4 +550,3 @@ Allow access based on internal and external IP/network/rDNS/ASN whitelists.
|
|||
|`WHITELIST_USER_AGENT_URLS`| |global |no |List of URLs, separated with spaces, containing good User-Agent to whitelist. |
|
||||
|`WHITELIST_URI` | |multisite|no |List of URI (PCRE regex), separated with spaces, to whitelist. |
|
||||
|`WHITELIST_URI_URLS` | |global |no |List of URLs, separated with spaces, containing bad URI to whitelist. |
|
||||
|
||||
|
|
|
|||
|
|
@ -465,4 +465,4 @@ In case you lost your UI credentials or have 2FA issues, you can connect to the
|
|||
1|<username>|<password_hash>|0||(manual or ui)
|
||||
```
|
||||
|
||||
You should now be able to log into the web UI only using your username and password.
|
||||
You should now be able to log into the web UI only using your username and password.
|
||||
|
|
|
|||
|
|
@ -37,7 +37,9 @@ Because the web UI is a web application, the recommended installation procedure
|
|||
|
||||
## Setup wizard
|
||||
|
||||
The setup wizard is a feature that helps you to **configure** and **install the web UI** using a **user-friendly interface**. You will need to set the `UI_HOST` setting (`http://hostname-of-web-ui:7000`) and browse the `/setup` URI of your server to access the setup wizard.
|
||||
!!! info "Wizard"
|
||||
|
||||
The setup wizard is a feature that helps you to **configure** and **install the web UI** using a **user-friendly interface**. You will need to set the `UI_HOST` setting (`http://hostname-of-web-ui:7000`) and browse the `/setup` URI of your server to access the setup wizard.
|
||||
|
||||
<figure markdown>
|
||||
{ align=center, width="350" }
|
||||
|
|
@ -66,6 +68,11 @@ Review your final BunkerWeb UI URL and then click on the `Setup` button. Once th
|
|||
|
||||
If you want to use the setup wizard, you will need to set the `UI_HOST` setting to the HTTP endpoint of your web UI container. For example, if your web UI container is named `bw-ui` and is listening on the `7000` port, you will need to set the `UI_HOST` setting to `http://bw-ui:7000`.
|
||||
|
||||
!!! tip "Accessing the setup wizard"
|
||||
|
||||
You can access the setup wizard by browsing the `http://your-ip-address/setup` URI of your server.
|
||||
|
||||
|
||||
Here is the docker-compose boilerplate that you can use (don't forget to edit the `changeme` data) :
|
||||
|
||||
```yaml
|
||||
|
|
@ -153,6 +160,10 @@ Review your final BunkerWeb UI URL and then click on the `Setup` button. Once th
|
|||
|
||||
If you want to use the setup wizard, you will need to set the `UI_HOST` setting to the HTTP endpoint of your web UI container. For example, if your web UI container is named `bw-ui` and is listening on the `7000` port, you will need to set the `UI_HOST` setting to `http://bw-ui:7000`.
|
||||
|
||||
!!! tip "Accessing the setup wizard"
|
||||
|
||||
You can access the setup wizard by browsing the `http://your-ip-address/setup` URI of your server.
|
||||
|
||||
Here is the docker-compose boilerplate that you can use (don't forget to edit the `changeme` data) :
|
||||
|
||||
```yaml
|
||||
|
|
@ -256,6 +267,10 @@ Review your final BunkerWeb UI URL and then click on the `Setup` button. Once th
|
|||
|
||||
If you want to use the setup wizard, you will need to set the `UI_HOST` setting to the HTTP endpoint of your web UI container. For example, if your web UI container is named `bw-ui` and is listening on the `7000` port, you will need to set the `UI_HOST` setting to `http://bw-ui:7000`.
|
||||
|
||||
!!! tip "Accessing the setup wizard"
|
||||
|
||||
You can access the setup wizard by browsing the `http://your-ip-address/setup` URI of your server.
|
||||
|
||||
Here is the stack boilerplate that you can use (don't forget to edit the `changeme` data) :
|
||||
|
||||
```yaml
|
||||
|
|
@ -382,6 +397,10 @@ Review your final BunkerWeb UI URL and then click on the `Setup` button. Once th
|
|||
|
||||
If you want to use the setup wizard, you will need to set the `UI_HOST` setting to the HTTP endpoint of your web UI SERVICE. For example, if your web UI service is named `svc-bunkerweb-ui` and is listening on the `7000` port, you will need to set the `UI_HOST` setting to `http://svc-bunkerweb-ui:7000`.
|
||||
|
||||
!!! tip "Accessing the setup wizard"
|
||||
|
||||
You can access the setup wizard by browsing the `http://your-ip-address/setup` URI of your server.
|
||||
|
||||
Here is the yaml boilerplate that you can use (don't forget to edit the `changeme` data) :
|
||||
|
||||
```yaml
|
||||
|
|
@ -695,6 +714,10 @@ Review your final BunkerWeb UI URL and then click on the `Setup` button. Once th
|
|||
|
||||
If you want to use the setup wizard, you will need to set the `UI_HOST` setting to the HTTP endpoint of your web UI SERVICE. Since the web UI is listening on the same machine as BunkerWeb, you will need to set the `UI_HOST` setting `http://127.0.0.1:7000`.
|
||||
|
||||
!!! tip "Accessing the setup wizard"
|
||||
|
||||
You can access the setup wizard by browsing the `http://your-ip-address/setup` URI of your server.
|
||||
|
||||
Here is the `/etc/bunkerweb/variables.env` boilerplate you can use :
|
||||
|
||||
```conf
|
||||
|
|
@ -772,7 +795,7 @@ The following steps are needed to enable the TOTP feature from the web UI :
|
|||
- Enter your current password
|
||||
|
||||
!!! info "Secret key refresh"
|
||||
A new secret key is **generated each time** you visit the page or submit the form. In case something went wrong (e.g. : expired TOTP code), you will need to copy the new secret key to your authenticator app until 2FA is successfuly enabled.
|
||||
A new secret key is **generated each time** you visit the page or submit the form. In case something went wrong (e.g. : expired TOTP code), you will need to copy the new secret key to your authenticator app until 2FA is successfully enabled.
|
||||
|
||||
Once enabled, 2FA authentication can be disabled at the same place.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "autoconf-configs",
|
||||
"kinds": ["autoconf"],
|
||||
"delay": 60,
|
||||
"delay": 180,
|
||||
"timeout": 60,
|
||||
"tests": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "docker-configs",
|
||||
"kinds": ["docker"],
|
||||
"delay": 30,
|
||||
"delay": 120,
|
||||
"timeout": 60,
|
||||
"tests": [
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
"name": "kubernetes-ingress",
|
||||
"kinds": ["kubernetes"],
|
||||
"timeout": 60,
|
||||
"delay": 60,
|
||||
"delay": 120,
|
||||
"tests": [
|
||||
{
|
||||
"type": "string",
|
||||
|
|
|
|||
|
|
@ -1,26 +1,29 @@
|
|||
{
|
||||
"name": "kubernetes-ingress",
|
||||
"name": "kubernetes-tls",
|
||||
"kinds": ["kubernetes"],
|
||||
"timeout": 60,
|
||||
"delay": 60,
|
||||
"delay": 300,
|
||||
"tests": [
|
||||
{
|
||||
"type": "string",
|
||||
"url": "https://app1.example.com",
|
||||
"string": "hello",
|
||||
"tls": "app1.example.com,app2.example.com"
|
||||
"tls": "app1.example.com,app2.example.com",
|
||||
"tls_edit": false
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"url": "https://app2.example.com",
|
||||
"string": "hello",
|
||||
"tls": "app1.example.com,app2.example.com"
|
||||
"tls": "app1.example.com,app2.example.com",
|
||||
"tls_edit": false
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"url": "https://app3.example.com",
|
||||
"string": "hello",
|
||||
"tls": "app3.example.com"
|
||||
"tls": "app3.example.com",
|
||||
"tls_edit": false
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
{
|
||||
"name": "swarm-configs",
|
||||
"kinds": ["swarm"],
|
||||
"timeout": 120,
|
||||
"timeout": 60,
|
||||
"delay": 120,
|
||||
"tests": [
|
||||
{
|
||||
"type": "string",
|
||||
|
|
|
|||
|
|
@ -1,3 +1,14 @@
|
|||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: pvc-bunkerweb
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 5Gi
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
|
|
@ -247,14 +258,3 @@ spec:
|
|||
protocol: TCP
|
||||
port: 6379
|
||||
targetPort: 6379
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: pvc-bunkerweb
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 5Gi
|
||||
|
|
|
|||
|
|
@ -100,10 +100,15 @@ class DockerController(Controller):
|
|||
first=not self._loaded,
|
||||
)
|
||||
|
||||
def __process_event(self, event):
|
||||
return "Actor" in event and "Attributes" in event["Actor"] and ("bunkerweb.INSTANCE" in event["Actor"]["Attributes"] or "bunkerweb.SERVER_NAME" in event["Actor"]["Attributes"])
|
||||
|
||||
def process_events(self):
|
||||
self._set_autoconf_load_db()
|
||||
for _ in self.__client.events(decode=True, filters={"type": "container"}):
|
||||
for event in self.__client.events(decode=True, filters={"type": "container"}):
|
||||
try:
|
||||
if not self.__process_event(event):
|
||||
continue
|
||||
self._update_settings()
|
||||
self._instances = self.get_instances()
|
||||
self._services = self.get_services()
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
FROM python:3.12.1-alpine3.18@sha256:af0d8da43677e3000ebdf4045508d891a87e7bd2d3ec87bc6e40403be97291b8 AS builder
|
||||
FROM python:3.12.1-alpine3.18@sha256:fb759579d60cfe1f70b110a27be95aaa7cf758d2fa21cf54fffb71c2ba3f8034 AS builder
|
||||
|
||||
# Copy python requirements
|
||||
COPY src/deps/requirements.txt /tmp/requirements-deps.txt
|
||||
|
|
@ -34,7 +34,7 @@ COPY src/common/helpers helpers
|
|||
COPY src/common/settings.json settings.json
|
||||
COPY src/common/utils utils
|
||||
|
||||
FROM python:3.12.1-alpine3.18@sha256:af0d8da43677e3000ebdf4045508d891a87e7bd2d3ec87bc6e40403be97291b8
|
||||
FROM python:3.12.1-alpine3.18@sha256:fb759579d60cfe1f70b110a27be95aaa7cf758d2fa21cf54fffb71c2ba3f8034
|
||||
|
||||
# Set default umask to prevent huge recursive chmod increasing the final image size
|
||||
RUN umask 027
|
||||
|
|
@ -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" "sqlite-libs>=3.41.2-r3"
|
||||
|
||||
VOLUME /data /etc/nginx
|
||||
|
||||
|
|
|
|||
|
|
@ -146,15 +146,16 @@ class IngressController(Controller):
|
|||
for host in tls.hosts:
|
||||
for service in services:
|
||||
if host in service["SERVER_NAME"].split(" "):
|
||||
secret_tls = self.__corev1.list_secret_for_all_namespaces(
|
||||
secrets_tls = self.__corev1.list_secret_for_all_namespaces(
|
||||
watch=False,
|
||||
field_selector=f"metadata.name={tls.secret_name},metadata.namespace={namespace}",
|
||||
).items
|
||||
if not secret_tls:
|
||||
if len(secrets_tls) == 0:
|
||||
self._logger.warning(
|
||||
f"Ignoring tls setting for {host} : secret {tls.secret_name} not found.",
|
||||
)
|
||||
break
|
||||
secret_tls = secrets_tls[0]
|
||||
if not secret_tls.data:
|
||||
self._logger.warning(
|
||||
f"Ignoring tls setting for {host} : secret {tls.secret_name} contains no data.",
|
||||
|
|
@ -227,6 +228,22 @@ class IngressController(Controller):
|
|||
configs[config_type][f"{config_site}{config_name}"] = config_data
|
||||
return configs
|
||||
|
||||
def __process_event(self, event):
|
||||
obj = event["object"]
|
||||
metadata = obj.metadata if obj else None
|
||||
annotations = metadata.annotations if metadata else None
|
||||
if not obj:
|
||||
return False
|
||||
if obj.kind == "Pod":
|
||||
return annotations and "bunkerweb.io/INSTANCE" in annotations
|
||||
if obj.kind == "Ingress":
|
||||
return True
|
||||
if obj.kind == "ConfigMap":
|
||||
return annotations and "bunkerweb.io/CONFIG_TYPE" in annotations
|
||||
if obj.kind == "Service":
|
||||
return True
|
||||
return False
|
||||
|
||||
def __watch(self, watch_type):
|
||||
w = watch.Watch()
|
||||
what = None
|
||||
|
|
@ -245,9 +262,13 @@ class IngressController(Controller):
|
|||
locked = False
|
||||
error = False
|
||||
try:
|
||||
for _ in w.stream(what):
|
||||
for event in w.stream(what):
|
||||
self.__internal_lock.acquire()
|
||||
locked = True
|
||||
if not self.__process_event(event):
|
||||
self.__internal_lock.release()
|
||||
locked = False
|
||||
continue
|
||||
self._update_settings()
|
||||
self._instances = self.get_instances()
|
||||
self._services = self.get_services()
|
||||
|
|
|
|||
|
|
@ -16,14 +16,20 @@ class SwarmController(Controller):
|
|||
super().__init__("swarm")
|
||||
self.__client = DockerClient(base_url=docker_host)
|
||||
self.__internal_lock = Lock()
|
||||
self.__swarm_instances = []
|
||||
self.__swarm_services = []
|
||||
self.__swarm_configs = []
|
||||
|
||||
def _get_controller_instances(self) -> List[Service]:
|
||||
self.__swarm_instances = []
|
||||
return self.__client.services.list(filters={"label": "bunkerweb.INSTANCE"})
|
||||
|
||||
def _get_controller_services(self) -> List[Service]:
|
||||
self.__swarm_services = []
|
||||
return self.__client.services.list(filters={"label": "bunkerweb.SERVER_NAME"})
|
||||
|
||||
def _to_instances(self, controller_instance) -> List[dict]:
|
||||
self.__swarm_instances.append(controller_instance.id)
|
||||
instances = []
|
||||
instance_env = {}
|
||||
for env in controller_instance.attrs["Spec"]["TaskTemplate"]["ContainerSpec"]["Env"]:
|
||||
|
|
@ -46,6 +52,7 @@ class SwarmController(Controller):
|
|||
return instances
|
||||
|
||||
def _to_services(self, controller_service) -> List[dict]:
|
||||
self.__swarm_services.append(controller_service.id)
|
||||
service = {}
|
||||
for variable, value in controller_service.attrs["Spec"]["Labels"].items():
|
||||
if not variable.startswith("bunkerweb."):
|
||||
|
|
@ -80,6 +87,7 @@ class SwarmController(Controller):
|
|||
return services
|
||||
|
||||
def get_configs(self) -> Dict[str, Dict[str, Any]]:
|
||||
self.__swarm_configs = []
|
||||
configs = {}
|
||||
for config_type in self._supported_config_types:
|
||||
configs[config_type] = {}
|
||||
|
|
@ -103,6 +111,7 @@ class SwarmController(Controller):
|
|||
continue
|
||||
config_site = f"{config.attrs['Spec']['Labels']['bunkerweb.CONFIG_SITE']}/"
|
||||
configs[config_type][f"{config_site}{config_name}"] = b64decode(config.attrs["Spec"]["Data"])
|
||||
self.__swarm_configs.append(config.id)
|
||||
return configs
|
||||
|
||||
def apply_config(self) -> bool:
|
||||
|
|
@ -113,14 +122,40 @@ class SwarmController(Controller):
|
|||
first=not self._loaded,
|
||||
)
|
||||
|
||||
def __process_event(self, event):
|
||||
if "Actor" not in event or "ID" not in event["Actor"] or "Type" not in event:
|
||||
return False
|
||||
if event["Type"] not in ("service", "config"):
|
||||
return False
|
||||
if event["Type"] == "service":
|
||||
if event["Actor"]["ID"] in self.__swarm_instances or event["Actor"]["ID"] in self.__swarm_services:
|
||||
return True
|
||||
try:
|
||||
labels = self.__client.services.get(event["Actor"]["ID"]).attrs["Spec"]["Labels"]
|
||||
return "bunkerweb.INSTANCE" in labels or "bunkerweb.SERVER_NAME" in labels
|
||||
except:
|
||||
return False
|
||||
if event["Type"] == "config":
|
||||
if event["Actor"]["ID"] in self.__swarm_configs:
|
||||
return True
|
||||
try:
|
||||
return "bunkerweb.CONFIG_TYPE" in self.__client.configs.get(event["Actor"]["ID"]).attrs["Spec"]["Labels"]
|
||||
except:
|
||||
return False
|
||||
return False
|
||||
|
||||
def __event(self, event_type):
|
||||
while True:
|
||||
locked = False
|
||||
error = False
|
||||
try:
|
||||
for _ in self.__client.events(decode=True, filters={"type": event_type}):
|
||||
for event in self.__client.events(decode=True, filters={"type": event_type}):
|
||||
self.__internal_lock.acquire()
|
||||
locked = True
|
||||
if not self.__process_event(event):
|
||||
self.__internal_lock.release()
|
||||
locked = False
|
||||
continue
|
||||
try:
|
||||
self._update_settings()
|
||||
self._instances = self.get_instances()
|
||||
|
|
@ -137,6 +172,7 @@ class SwarmController(Controller):
|
|||
self._logger.info(
|
||||
"Successfully deployed new configuration 🚀",
|
||||
)
|
||||
self._set_autoconf_load_db()
|
||||
except:
|
||||
self._logger.error(f"Exception while processing Swarm event ({event_type}) :\n{format_exc()}")
|
||||
self.__internal_lock.release()
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ RUN apk add --no-cache pcre bash python3 yajl && \
|
|||
ln -s /proc/1/fd/1 /var/log/bunkerweb/access.log
|
||||
|
||||
# Fix CVEs
|
||||
RUN apk add --no-cache "libwebp>=1.2.4-r3" "curl>=8.3.0-r0" "libcurl>=8.3.0-r0" "nghttp2-libs>=1.51.0-r2" "libcrypto3>=3.0.12-r0" "libssl3>=3.0.12-r0" "libx11>=1.8.7-r0"
|
||||
RUN apk add --no-cache "libwebp>=1.2.4-r3" "curl>=8.3.0-r0" "libcurl>=8.3.0-r0" "nghttp2-libs>=1.51.0-r2" "libx11>=1.8.7-r0" "libssl3>=3.0.12-r1" "libcrypto3>=3.0.12-r1"
|
||||
|
||||
EXPOSE 8080/tcp 8443/tcp
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@ local get_body_data = ngx_req.get_body_data
|
|||
local get_body_file = ngx_req.get_body_file
|
||||
local decode = cjson.decode
|
||||
local encode = cjson.encode
|
||||
local floor = math.floor
|
||||
local match = string.match
|
||||
local require_plugin = helpers.require_plugin
|
||||
local new_plugin = helpers.new_plugin
|
||||
|
|
@ -216,7 +215,26 @@ api.global.POST["^/ban$"] = function(self)
|
|||
if not ok then
|
||||
return self:response(HTTP_INTERNAL_SERVER_ERROR, "error", "can't decode JSON : " .. ip)
|
||||
end
|
||||
datastore:set("bans_ip_" .. ip["ip"], "manual", ip["exp"])
|
||||
local ban = {
|
||||
ip = "",
|
||||
exp = 86400,
|
||||
reason = "manual",
|
||||
}
|
||||
ban.ip = ip["ip"]
|
||||
if ip["exp"] then
|
||||
ban.exp = ip["exp"]
|
||||
end
|
||||
if ip["reason"] then
|
||||
ban.reason = ip["reason"]
|
||||
end
|
||||
datastore:set(
|
||||
"bans_ip_" .. ban["ip"],
|
||||
encode({
|
||||
reason = ban["reason"],
|
||||
date = os.time(),
|
||||
}),
|
||||
ban["exp"]
|
||||
)
|
||||
return self:response(HTTP_OK, "success", "ip " .. ip["ip"] .. " banned")
|
||||
end
|
||||
|
||||
|
|
@ -224,12 +242,12 @@ api.global.GET["^/bans$"] = function(self)
|
|||
local data = {}
|
||||
for _, k in ipairs(datastore:keys()) do
|
||||
if k:find("^bans_ip_") then
|
||||
local reason, err = datastore:get(k)
|
||||
local result, err = datastore:get(k)
|
||||
if err then
|
||||
return self:response(
|
||||
HTTP_INTERNAL_SERVER_ERROR,
|
||||
"error",
|
||||
"can't access " .. k .. " from datastore : " .. reason
|
||||
"can't access " .. k .. " from datastore : " .. result
|
||||
)
|
||||
end
|
||||
local ok, ttl = datastore:ttl(k)
|
||||
|
|
@ -240,7 +258,9 @@ api.global.GET["^/bans$"] = function(self)
|
|||
"can't access ttl " .. k .. " from datastore : " .. ttl
|
||||
)
|
||||
end
|
||||
local ban = { ip = k:sub(9, #k), reason = reason, exp = floor(ttl) }
|
||||
local ban_data = decode(result)
|
||||
local ban =
|
||||
{ ip = k:sub(9, #k), reason = ban_data["reason"], date = ban_data["date"], exp = math.floor(ttl) }
|
||||
table.insert(data, ban)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ local ngx = ngx
|
|||
local class = require "middleclass"
|
||||
local clogger = require "bunkerweb.logger"
|
||||
local rc = require "resty.redis.connector"
|
||||
local rs = require("resty.redis.sentinel")
|
||||
local utils = require "bunkerweb.utils"
|
||||
|
||||
local clusterstore = class("clusterstore")
|
||||
|
|
@ -12,10 +11,10 @@ local logger = clogger:new("CLUSTERSTORE")
|
|||
local get_variable = utils.get_variable
|
||||
local is_cosocket_available = utils.is_cosocket_available
|
||||
local ERR = ngx.ERR
|
||||
local WARN = ngx.WARN
|
||||
local INFO = ngx.INFO
|
||||
local tonumber = tonumber
|
||||
local tostring = tostring
|
||||
local random = math.random
|
||||
|
||||
function clusterstore:initialize(pool)
|
||||
-- Get variables
|
||||
|
|
@ -25,6 +24,7 @@ function clusterstore:initialize(pool)
|
|||
["REDIS_PORT"] = "",
|
||||
["REDIS_DATABASE"] = "",
|
||||
["REDIS_SSL"] = "",
|
||||
["REDIS_SSL_VERIFY"] = "",
|
||||
["REDIS_TIMEOUT"] = "",
|
||||
["REDIS_KEEPALIVE_IDLE"] = "",
|
||||
["REDIS_KEEPALIVE_POOL"] = "",
|
||||
|
|
@ -57,6 +57,7 @@ function clusterstore:initialize(pool)
|
|||
keepalive_poolsize = tonumber(self.variables["REDIS_KEEPALIVE_POOL"]),
|
||||
connection_options = {
|
||||
ssl = self.variables["REDIS_SSL"] == "yes",
|
||||
ssl_verify = self.variables["REDIS_SSL_VERIFY"] == "yes",
|
||||
},
|
||||
host = self.variables["REDIS_HOST"],
|
||||
port = tonumber(self.variables["REDIS_PORT"]),
|
||||
|
|
@ -71,7 +72,6 @@ function clusterstore:initialize(pool)
|
|||
}
|
||||
self.pool = pool == nil or pool
|
||||
if self.pool then
|
||||
options.connection_options.pool = "bw-redis"
|
||||
options.connection_options.pool_size = tonumber(self.variables["REDIS_KEEPALIVE_POOL"])
|
||||
end
|
||||
if self.variables["REDIS_SENTINEL_HOSTS"] ~= "" then
|
||||
|
|
@ -82,7 +82,14 @@ function clusterstore:initialize(pool)
|
|||
else
|
||||
sport = tonumber(sport)
|
||||
end
|
||||
table.insert(options.sentinel, { host = shost, port = sport })
|
||||
local data = { host = shost, port = sport }
|
||||
if options.sentinel_username ~= "" then
|
||||
data.username = options.sentinel_username
|
||||
end
|
||||
if options.sentinel_password ~= "" then
|
||||
data.password = options.sentinel_password
|
||||
end
|
||||
table.insert(options.sentinels, data)
|
||||
end
|
||||
end
|
||||
self.options = options
|
||||
|
|
@ -107,33 +114,37 @@ function clusterstore:connect(readonly)
|
|||
self:close()
|
||||
end
|
||||
-- Connect to sentinels if needed
|
||||
local redis_client, err
|
||||
if #self.options.sentinels > 0 then
|
||||
local redis_sentinel
|
||||
redis_sentinel, err = self.redis_connector:connect()
|
||||
if not redis_sentinel then
|
||||
return false, "error while connecting to sentinels : " .. err
|
||||
end
|
||||
if readonly then
|
||||
local redis_clients, _ = rs.get_slaves(redis_sentinel, self.options.master_name)
|
||||
if redis_clients then
|
||||
redis_client = redis_clients[random(#redis_clients)]
|
||||
else
|
||||
redis_client = nil
|
||||
local redis_client, err, previous_errors
|
||||
if #self.options.sentinels > 0 and readonly then
|
||||
redis_client, err, previous_errors = self.redis_connector:connect({ role = "slave" })
|
||||
if not redis_client then
|
||||
if previous_errors then
|
||||
err = err .. " ( previous errors : "
|
||||
for _, e in ipairs(previous_errors) do
|
||||
err = err .. e .. ", "
|
||||
end
|
||||
err = err:sub(1, -3) .. " )"
|
||||
end
|
||||
else
|
||||
redis_client, err = rs.get_master(redis_sentinel, self.options.master_name)
|
||||
logger:log(WARN, "error while getting redis slave client : " .. err .. ", fallback to master")
|
||||
redis_client, err, previous_errors = self.redis_connector:connect()
|
||||
end
|
||||
-- Classic connection
|
||||
else
|
||||
redis_client, err = self.redis_connector:connect()
|
||||
redis_client, err, previous_errors = self.redis_connector:connect()
|
||||
end
|
||||
self.redis_client = redis_client
|
||||
if not self.redis_client then
|
||||
if previous_errors then
|
||||
err = err .. " ( previous errors : "
|
||||
for _, e in ipairs(previous_errors) do
|
||||
err = err .. e .. ", "
|
||||
end
|
||||
err = err:sub(1, -3) .. " )"
|
||||
end
|
||||
return false, "error while getting redis client : " .. err
|
||||
end
|
||||
-- Everything went well
|
||||
local times, err = self.redis_client:get_reused_times()
|
||||
local times
|
||||
times, err = self.redis_client:get_reused_times()
|
||||
if times == nil then
|
||||
self:close()
|
||||
return false, "error while getting reused times : " .. err
|
||||
|
|
|
|||
|
|
@ -15,8 +15,10 @@ if not lru then
|
|||
logger:log(ERR, "failed to instantiate LRU cache : " .. err_lru)
|
||||
end
|
||||
|
||||
function datastore:initialize()
|
||||
if subsystem == "http" then
|
||||
function datastore:initialize(dict)
|
||||
if dict then
|
||||
self.dict = dict
|
||||
elseif subsystem == "http" then
|
||||
self.dict = shared.datastore
|
||||
else
|
||||
self.dict = shared.datastore_stream
|
||||
|
|
@ -112,4 +114,32 @@ function datastore:flush_lru()
|
|||
lru:flush_all()
|
||||
end
|
||||
|
||||
function datastore:safe_rpush(key, value)
|
||||
local length, err = self.dict:rpush(key, value)
|
||||
if not length and err == "no memory" then
|
||||
local i = 0
|
||||
while i < 5 do
|
||||
local val
|
||||
val, err = self.dict:lpop(key)
|
||||
if not val then
|
||||
return val, err
|
||||
end
|
||||
length, err = self.dict:rpush(key, value)
|
||||
if not length and err ~= "no memory" then
|
||||
return length, err
|
||||
end
|
||||
i = i + 1
|
||||
end
|
||||
end
|
||||
return length, err
|
||||
end
|
||||
|
||||
function datastore:lpop(key)
|
||||
return self.dict:lpop(key)
|
||||
end
|
||||
|
||||
function datastore:llen(key)
|
||||
return self.dict:llen(key)
|
||||
end
|
||||
|
||||
return datastore
|
||||
|
|
|
|||
|
|
@ -185,6 +185,7 @@ helpers.fill_ctx = function(no_ref)
|
|||
end
|
||||
data.remote_addr = var.remote_addr
|
||||
data.server_name = var.server_name
|
||||
data.local_time = var.local_time
|
||||
if data.kind == "http" then
|
||||
data.uri = var.uri
|
||||
data.request_uri = var.request_uri
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@ local decode = cjson.decode
|
|||
local char = string.char
|
||||
local random = math.random
|
||||
local session_start = session.start
|
||||
local session_open = session.open
|
||||
local tonumber = tonumber
|
||||
|
||||
local utils = {}
|
||||
|
|
@ -569,86 +568,86 @@ utils.get_deny_status = function()
|
|||
return 444
|
||||
end
|
||||
|
||||
utils.check_session = function(ctx)
|
||||
local _session, _, exists, _ = session_start({ audience = "metadata" })
|
||||
utils.get_session = function(ctx)
|
||||
-- Return session from ctx if already there
|
||||
if ctx.bw.sessions_session then
|
||||
return ctx.bw.sessions_session
|
||||
end
|
||||
-- Open/create and do an optional refresh
|
||||
local err, exists, refreshed
|
||||
session, err, exists, refreshed = session_start()
|
||||
if not session then
|
||||
return nil, err
|
||||
end
|
||||
if err then
|
||||
logger:log(WARN, "can't open session : " .. err)
|
||||
end
|
||||
local checks = {
|
||||
["IP"] = ctx.bw.remote_addr,
|
||||
["USER_AGENT"] = ctx.bw.http_user_agent or "",
|
||||
}
|
||||
if exists then
|
||||
for _, check in ipairs(ctx.bw.sessions_checks) do
|
||||
local key = check[1]
|
||||
local value = check[2]
|
||||
if _session:get(key) ~= value then
|
||||
_session:clear_request_cookie()
|
||||
local ok, err = _session:destroy()
|
||||
if not ok then
|
||||
return false, "session:destroy() error : " .. err
|
||||
logger:log(INFO, "opening an existing session")
|
||||
if refreshed then
|
||||
logger:log(INFO, "existing session refreshed")
|
||||
end
|
||||
-- Get metadata
|
||||
local metadata = session:get("metadata")
|
||||
if metadata then
|
||||
-- Check if session passes the checks
|
||||
for check, value in pairs(checks) do
|
||||
local check_value
|
||||
check_value, err = utils.get_variable("SESSIONS_CHECK_" .. check, false, nil)
|
||||
if not check_value then
|
||||
logger:log(ERR, "error while getting variable SESSIONS_CHECK_" .. check .. " : " .. err)
|
||||
elseif check_value == "yes" and value ~= metadata[check] then
|
||||
logger:log(WARN, "session check failed : " .. check .. "!=" .. metadata[check])
|
||||
local ok
|
||||
ok, err = session:destroy()
|
||||
if not ok then
|
||||
return nil, err
|
||||
end
|
||||
return utils.get_session(ctx)
|
||||
end
|
||||
logger:log(WARN, "session check " .. key .. " failed, destroying session")
|
||||
return utils.check_session(ctx)
|
||||
end
|
||||
end
|
||||
else
|
||||
for _, check in ipairs(ctx.bw.sessions_checks) do
|
||||
_session:set(check[1], check[2])
|
||||
end
|
||||
local ok, err = _session:save()
|
||||
if not ok then
|
||||
_session:close()
|
||||
return false, "session:save() error : " .. err
|
||||
end
|
||||
logger:log(INFO, "creating a new session")
|
||||
session:set("metadata", checks)
|
||||
ctx.bw.sessions_updated = true
|
||||
end
|
||||
ctx.bw.sessions_is_checked = true
|
||||
return true, exists
|
||||
ctx.bw.sessions_session = session
|
||||
return session
|
||||
end
|
||||
|
||||
utils.get_session = function(audience, ctx)
|
||||
-- Check session
|
||||
if not ctx.bw.sessions_is_checked then
|
||||
local ok, err = utils.check_session(ctx)
|
||||
if not ok then
|
||||
return false, "error while checking session, " .. err
|
||||
utils.save_session = function(ctx)
|
||||
if ctx.bw.sessions_session then
|
||||
if ctx.bw.sessions_updated then
|
||||
local ok, err = ctx.bw.sessions_session:save()
|
||||
if not err then
|
||||
err = "session saved"
|
||||
end
|
||||
return ok, err
|
||||
else
|
||||
return true, "session not updated"
|
||||
end
|
||||
else
|
||||
return true, "no session"
|
||||
end
|
||||
-- Open session with specific audience
|
||||
local _session, err, _ = session_open({ audience = audience })
|
||||
if err then
|
||||
logger:log(INFO, "session:open() error : " .. err)
|
||||
end
|
||||
return _session
|
||||
end
|
||||
|
||||
-- luacheck: ignore 214
|
||||
utils.get_session_data = function(_session, site, ctx)
|
||||
local site_only = site == nil or site
|
||||
local data = _session:get_data()
|
||||
if site_only then
|
||||
return data[ctx.bw.server_name] or {}
|
||||
end
|
||||
return data
|
||||
end
|
||||
|
||||
-- luacheck: ignore 214
|
||||
utils.set_session_data = function(_session, data, site, ctx)
|
||||
local site_only = site == nil or site
|
||||
if site_only then
|
||||
local all_data = _session:get_data()
|
||||
all_data[ctx.bw.server_name] = data
|
||||
_session:set_data(all_data)
|
||||
return _session:save()
|
||||
end
|
||||
_session:set_data(data)
|
||||
return _session:save()
|
||||
end
|
||||
|
||||
utils.is_banned = function(ip)
|
||||
-- Check on local datastore
|
||||
local reason, err = datastore:get("bans_ip_" .. ip)
|
||||
if not reason and err ~= "not found" then
|
||||
return nil, "datastore:get() error : " .. reason
|
||||
elseif reason and err ~= "not found" then
|
||||
local result, err = datastore:get("bans_ip_" .. ip)
|
||||
if not result and err ~= "not found" then
|
||||
return nil, "datastore:get() error : " .. result
|
||||
elseif result and err ~= "not found" then
|
||||
local ok, ttl = datastore:ttl("bans_ip_" .. ip)
|
||||
local ban_data = decode(result)
|
||||
if not ok then
|
||||
return true, reason, -1
|
||||
return true, ban_data, -1
|
||||
end
|
||||
return true, reason, ttl
|
||||
return true, ban_data, ttl
|
||||
end
|
||||
-- Redis case
|
||||
local use_redis, err = utils.get_variable("USE_REDIS", false)
|
||||
|
|
@ -703,7 +702,11 @@ end
|
|||
|
||||
utils.add_ban = function(ip, reason, ttl)
|
||||
-- Set on local datastore
|
||||
local ok, err = datastore:set("bans_ip_" .. ip, reason, ttl)
|
||||
local ban_data = encode({
|
||||
reason = reason,
|
||||
date = os.time(),
|
||||
})
|
||||
local ok, err = datastore:set("bans_ip_" .. ip, ban_data, ttl)
|
||||
if not ok then
|
||||
return false, "datastore:set() error : " .. err
|
||||
end
|
||||
|
|
@ -721,7 +724,7 @@ utils.add_ban = function(ip, reason, ttl)
|
|||
return false, "can't connect to redis server : " .. err
|
||||
end
|
||||
-- SET call
|
||||
ok, err = clusterstore:call("set", "bans_ip_" .. ip, reason, "EX", ttl)
|
||||
ok, err = clusterstore:call("set", "bans_ip_" .. ip, ban_data, "EX", ttl)
|
||||
if not ok then
|
||||
clusterstore:close()
|
||||
return false, "redis SET failed : " .. err
|
||||
|
|
|
|||
|
|
@ -1,12 +1,15 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from datetime import datetime
|
||||
from json import dumps, loads
|
||||
from time import time
|
||||
from dotenv import dotenv_values
|
||||
from os import getenv, sep
|
||||
from os.path import join
|
||||
from pathlib import Path
|
||||
from redis import StrictRedis
|
||||
from redis import StrictRedis, Sentinel
|
||||
from sys import path as sys_path
|
||||
from typing import Optional, Tuple
|
||||
from typing import Any, Optional, Tuple
|
||||
|
||||
|
||||
for deps_path in [join(sep, "usr", "share", "bunkerweb", *paths) for paths in (("utils",), ("db",))]:
|
||||
|
|
@ -19,10 +22,19 @@ from logger import setup_logger # type: ignore
|
|||
|
||||
|
||||
def format_remaining_time(seconds):
|
||||
days, seconds = divmod(seconds, 86400)
|
||||
hours, seconds = divmod(seconds, 3600)
|
||||
years, seconds = divmod(seconds, 60 * 60 * 24 * 365)
|
||||
months, seconds = divmod(seconds, 60 * 60 * 24 * 30)
|
||||
while months >= 12:
|
||||
years += 1
|
||||
months -= 12
|
||||
days, seconds = divmod(seconds, 60 * 60 * 24)
|
||||
hours, seconds = divmod(seconds, 60 * 60)
|
||||
minutes, seconds = divmod(seconds, 60)
|
||||
time_parts = []
|
||||
if years > 0:
|
||||
time_parts.append(f"{int(years)} year{'' if years == 1 else 's'}")
|
||||
if months > 0:
|
||||
time_parts.append(f"{int(months)} month{'' if months == 1 else 's'}")
|
||||
if days > 0:
|
||||
time_parts.append(f"{int(days)} day{'' if days == 1 else 's'}")
|
||||
if hours > 0:
|
||||
|
|
@ -49,6 +61,8 @@ class CLI(ApiCaller):
|
|||
if Path(sep, "usr", "share", "bunkerweb", "db").exists():
|
||||
from Database import Database # type: ignore
|
||||
|
||||
self.__logger.info("Getting variables from database")
|
||||
|
||||
db = Database(self.__logger, sqlalchemy_string=self.__get_variable("DATABASE_URI", None))
|
||||
self.__variables = db.get_config()
|
||||
|
||||
|
|
@ -58,6 +72,7 @@ class CLI(ApiCaller):
|
|||
self.__use_redis = self.__get_variable("USE_REDIS", "no") == "yes"
|
||||
self.__redis = None
|
||||
if self.__use_redis:
|
||||
self.__logger.info("Fetching redis configuration")
|
||||
redis_host = self.__get_variable("REDIS_HOST")
|
||||
if redis_host:
|
||||
redis_port = self.__get_variable("REDIS_PORT", "6379")
|
||||
|
|
@ -89,16 +104,71 @@ class CLI(ApiCaller):
|
|||
redis_keepalive_pool = "10"
|
||||
redis_keepalive_pool = int(redis_keepalive_pool)
|
||||
|
||||
self.__redis = StrictRedis(
|
||||
host=redis_host,
|
||||
port=redis_port,
|
||||
db=redis_db,
|
||||
socket_timeout=redis_timeout,
|
||||
socket_connect_timeout=redis_timeout,
|
||||
socket_keepalive=True,
|
||||
max_connections=redis_keepalive_pool,
|
||||
ssl=self.__get_variable("REDIS_SSL", "no") == "yes",
|
||||
)
|
||||
self.__logger.info("Redis configuration is valid")
|
||||
|
||||
redis_ssl = self.__get_variable("REDIS_SSL", "no") == "yes"
|
||||
username = self.__get_variable("REDIS_USERNAME", None) or None
|
||||
password = self.__get_variable("REDIS_PASSWORD", None) or None
|
||||
sentinel_hosts = self.__get_variable("REDIS_SENTINEL_HOSTS", [])
|
||||
|
||||
if isinstance(sentinel_hosts, str):
|
||||
sentinel_hosts = [host.split(":") if ":" in host else host for host in sentinel_hosts.split(" ") if host]
|
||||
|
||||
if sentinel_hosts:
|
||||
sentinel_username = self.__get_variable("REDIS_SENTINEL_USERNAME", None) or None
|
||||
sentinel_password = self.__get_variable("REDIS_SENTINEL_PASSWORD", None) or None
|
||||
sentinel_master = self.__get_variable("REDIS_SENTINEL_MASTER", "")
|
||||
|
||||
self.__logger.info(
|
||||
f"Connecting to redis sentinel cluster with the following parameters:\n{sentinel_hosts=}\n{sentinel_username=}\n{sentinel_password=}\n{sentinel_master=}\n{redis_timeout=}\nmax_connections={redis_keepalive_pool}\n{redis_ssl=}"
|
||||
)
|
||||
sentinel = Sentinel(
|
||||
sentinel_hosts,
|
||||
username=sentinel_username,
|
||||
password=sentinel_password,
|
||||
ssl=redis_ssl,
|
||||
socket_timeout=redis_timeout,
|
||||
socket_connect_timeout=redis_timeout,
|
||||
socket_keepalive=True,
|
||||
max_connections=redis_keepalive_pool,
|
||||
)
|
||||
try:
|
||||
sentinel.discover_master(sentinel_master)
|
||||
except Exception as e:
|
||||
self.__logger.error(f"Failed to connect to redis sentinel cluster: {e}, disabling redis")
|
||||
self.__use_redis = False
|
||||
|
||||
if self.__use_redis:
|
||||
self.__logger.info(f"Connected to redis sentinel cluster, getting master with the following parameters:\n{sentinel_master=}\n{redis_db=}\n{username=}\n{password=}")
|
||||
self.__redis = sentinel.master_for(
|
||||
sentinel_master,
|
||||
db=redis_db,
|
||||
username=username,
|
||||
password=password,
|
||||
)
|
||||
else:
|
||||
self.__logger.info(f"Connecting to redis with the following parameters:\n{redis_host=}\n{redis_port=}\n{redis_db=}\n{username=}\n{password=}\n{redis_timeout=}\nmax_connections={redis_keepalive_pool}\n{redis_ssl=}")
|
||||
self.__redis = StrictRedis(
|
||||
host=redis_host,
|
||||
port=redis_port,
|
||||
db=redis_db,
|
||||
username=username,
|
||||
password=password,
|
||||
socket_timeout=redis_timeout,
|
||||
socket_connect_timeout=redis_timeout,
|
||||
socket_keepalive=True,
|
||||
max_connections=redis_keepalive_pool,
|
||||
ssl=redis_ssl,
|
||||
)
|
||||
|
||||
try:
|
||||
if self.__use_redis:
|
||||
assert self.__redis, "Redis connection is None"
|
||||
self.__redis.ping()
|
||||
except Exception as e:
|
||||
self.__logger.error(f"Failed to connect to redis: {e}, disabling redis")
|
||||
self.__use_redis = False
|
||||
self.__logger.info("Connected to redis")
|
||||
else:
|
||||
self.__logger.error("USE_REDIS is set to yes but REDIS_HOST is not set, disabling redis")
|
||||
self.__use_redis = False
|
||||
|
|
@ -116,7 +186,7 @@ class CLI(ApiCaller):
|
|||
super().__init__()
|
||||
self.auto_setup(self.__integration)
|
||||
|
||||
def __get_variable(self, variable: str, default: Optional[str] = None) -> Optional[str]:
|
||||
def __get_variable(self, variable: str, default: Optional[Any] = None) -> Optional[str]:
|
||||
return getenv(variable, self.__variables.get(variable, default))
|
||||
|
||||
def __detect_integration(self) -> str:
|
||||
|
|
@ -148,14 +218,15 @@ class CLI(ApiCaller):
|
|||
return True, f"IP {ip} has been unbanned"
|
||||
return False, "error"
|
||||
|
||||
def ban(self, ip: str, exp: float) -> Tuple[bool, str]:
|
||||
def ban(self, ip: str, exp: float, reason: str) -> Tuple[bool, str]:
|
||||
if self.__redis:
|
||||
ok = self.__redis.set(f"bans_ip_{ip}", "manual", ex=exp)
|
||||
ok = self.__redis.set(f"bans_ip_{ip}", dumps({"reason": reason, "date": time()}))
|
||||
if not ok:
|
||||
self.__logger.error(f"Failed to ban {ip} in redis")
|
||||
self.__redis.expire(f"bans_ip_{ip}", int(exp))
|
||||
|
||||
if self.send_to_apis("POST", "/ban", data={"ip": ip, "exp": exp}):
|
||||
return (True, f"IP {ip} has been banned for {format_remaining_time(exp)}")
|
||||
if self.send_to_apis("POST", "/ban", data={"ip": ip, "exp": exp, "reason": reason}):
|
||||
return (True, f"IP {ip} has been banned for {format_remaining_time(exp)} with reason {reason}")
|
||||
return False, "error"
|
||||
|
||||
def bans(self) -> Tuple[bool, str]:
|
||||
|
|
@ -172,8 +243,13 @@ class CLI(ApiCaller):
|
|||
servers["redis"] = []
|
||||
for key in self.__redis.scan_iter("bans_ip_*"):
|
||||
ip = key.decode("utf-8").replace("bans_ip_", "")
|
||||
data = self.__redis.get(key)
|
||||
if not data:
|
||||
continue
|
||||
exp = self.__redis.ttl(key)
|
||||
servers["redis"].append({"ip": ip, "exp": exp, "reason": "manual"})
|
||||
servers["redis"].append({"ip": ip, "exp": exp} | loads(data))
|
||||
|
||||
servers = {k: sorted(v, key=lambda x: x["date"]) for k, v in servers.items()}
|
||||
|
||||
cli_str = ""
|
||||
for server, bans in servers.items():
|
||||
|
|
@ -182,7 +258,7 @@ class CLI(ApiCaller):
|
|||
cli_str += "No ban found\n"
|
||||
|
||||
for ban in bans:
|
||||
cli_str += f"- {ban['ip']} for {format_remaining_time(ban['exp'])} : {ban.get('reason', 'no reason given')}\n"
|
||||
cli_str += f"- {ban['ip']} ; banned the {datetime.fromtimestamp(ban['date']).strftime('%d-%m-%Y at %H:%M:%S')} for {format_remaining_time(ban['exp'])} remaining with reason \"{ban.get('reason', 'no reason given')}\"\n"
|
||||
cli_str += "\n"
|
||||
|
||||
return True, cli_str
|
||||
|
|
|
|||
|
|
@ -40,6 +40,12 @@ if __name__ == "__main__":
|
|||
help=f"banning time in seconds (default : {ban_time})",
|
||||
default=ban_time,
|
||||
)
|
||||
parser_ban.add_argument(
|
||||
"-reason",
|
||||
type=str,
|
||||
help="reason for ban (default : manual)",
|
||||
default="manual",
|
||||
)
|
||||
|
||||
# Bans subparser
|
||||
parser_bans = subparsers.add_parser("bans", help="list current bans")
|
||||
|
|
@ -55,7 +61,7 @@ if __name__ == "__main__":
|
|||
if args.command == "unban":
|
||||
ret, err = cli.unban(args.ip)
|
||||
elif args.command == "ban":
|
||||
ret, err = cli.ban(args.ip, args.exp)
|
||||
ret, err = cli.ban(args.ip, args.exp, args.reason)
|
||||
elif args.command == "bans":
|
||||
ret, err = cli.bans()
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,11 @@ server {
|
|||
# default mime type is JSON
|
||||
default_type 'application/json';
|
||||
|
||||
# variables
|
||||
set $reason '';
|
||||
set $reason_data '';
|
||||
set $ctx_ref '';
|
||||
|
||||
# check IP and do the API call
|
||||
access_by_lua_block {
|
||||
-- Instantiate objects and import required modules
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
server {
|
||||
|
||||
# reason variable
|
||||
# variables
|
||||
set $reason '';
|
||||
set $reason_data '';
|
||||
set $ctx_ref '';
|
||||
|
||||
server_name _;
|
||||
|
||||
|
|
@ -99,6 +101,8 @@ server {
|
|||
local ok, ret = call_plugin(plugin_obj, "log_default")
|
||||
if not ok then
|
||||
logger:log(ERR, ret)
|
||||
elseif not ret.ret then
|
||||
logger:log(ERR, plugin_id .. ":log_default() call failed : " .. ret.msg)
|
||||
else
|
||||
logger:log(INFO, plugin_id .. ":log_default() call successful : " .. ret.msg)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ access_by_lua_block {
|
|||
local is_banned = utils.is_banned
|
||||
local set_reason = utils.set_reason
|
||||
local get_deny_status = utils.get_deny_status
|
||||
local save_session = utils.save_session
|
||||
local tostring = tostring
|
||||
|
||||
-- Don't process internal requests
|
||||
|
|
@ -120,6 +121,14 @@ access_by_lua_block {
|
|||
end
|
||||
logger:log(INFO, "called access() methods of plugins")
|
||||
|
||||
-- Save session
|
||||
ok, err = save_session(ctx)
|
||||
if ok then
|
||||
logger:log(INFO, err)
|
||||
else
|
||||
logger:log(ERR, err)
|
||||
end
|
||||
|
||||
-- Save ctx
|
||||
save_ctx(ctx)
|
||||
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ ssl_certificate_by_lua_block {
|
|||
if not ok then
|
||||
logger:log(ERR, "error while setting private key : " .. err)
|
||||
else
|
||||
logger:log(INFO, "certificate set by " .. plugin_id)
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -12,11 +12,10 @@ local ngx = ngx
|
|||
local subsystem = ngx.config.subsystem
|
||||
local HTTP_INTERNAL_SERVER_ERROR = ngx.HTTP_INTERNAL_SERVER_ERROR
|
||||
local OK = ngx.OK
|
||||
local INFO = ngx.INFO
|
||||
local tonumber = tonumber
|
||||
local tostring = tostring
|
||||
local get_session = utils.get_session
|
||||
local get_session_data = utils.get_session_data
|
||||
local set_session_data = utils.set_session_data
|
||||
local get_deny_status = utils.get_deny_status
|
||||
local rand = utils.rand
|
||||
local now = ngx.now
|
||||
|
|
@ -46,37 +45,26 @@ function antibot:header()
|
|||
return self:ret(true, "antibot not activated")
|
||||
end
|
||||
-- Check if antibot uri
|
||||
if self.ctx.bw.uri ~= self.variables["ANTIBOT_URI"] then
|
||||
return self:ret(true, "Not antibot uri")
|
||||
end
|
||||
|
||||
-- Get session data
|
||||
local session, err = get_session("antibot", self.ctx)
|
||||
if not session then
|
||||
return self:ret(false, "can't get session : " .. err, HTTP_INTERNAL_SERVER_ERROR)
|
||||
end
|
||||
self.session = session
|
||||
self.session_data = get_session_data(self.session, true, self.ctx)
|
||||
-- Check if session is valid
|
||||
self:check_session()
|
||||
|
||||
-- Don't go further if client resolved the challenge
|
||||
if self.session_data.resolved then
|
||||
if self.ctx.bw.uri == self.variables["ANTIBOT_URI"] then
|
||||
return self:ret(true, "client already resolved the challenge", nil, self.session_data.original_uri)
|
||||
end
|
||||
return self:ret(true, "client already resolved the challenge")
|
||||
end
|
||||
|
||||
if self.ctx.bw.uri ~= self.variables["ANTIBOT_URI"] then
|
||||
return self:ret(true, "not antibot uri")
|
||||
end
|
||||
|
||||
-- Get session data
|
||||
self.session_data = self.ctx.bw.antibot_session_data
|
||||
if not self.session_data then
|
||||
return self:ret(false, "can't get session data", HTTP_INTERNAL_SERVER_ERROR)
|
||||
end
|
||||
|
||||
-- Don't go further if client resolved the challenge
|
||||
if self.session_data.resolved then
|
||||
return self:ret(true, "client already resolved the challenge", nil, self.session_data.original_uri)
|
||||
end
|
||||
|
||||
-- Override headers
|
||||
local header = "Content-Security-Policy"
|
||||
if self.variables["CONTENT_SECURITY_POLICY_REPORT_ONLY"] == "yes" then
|
||||
header = header .. "-Report-Only"
|
||||
end
|
||||
|
||||
if self.session_data.type == "recaptcha" then
|
||||
ngx.header[header] = "default-src 'none'; form-action 'self'; script-src 'strict-dynamic' 'nonce-"
|
||||
.. self.session_data.nonce_script
|
||||
|
|
@ -108,7 +96,7 @@ function antibot:header()
|
|||
.. self.session_data.nonce_style
|
||||
.. "'; font-src 'self' data:; base-uri 'self';"
|
||||
end
|
||||
return self:ret(true, "Successfully overridden CSP header")
|
||||
return self:ret(true, "successfully overridden CSP header")
|
||||
end
|
||||
|
||||
function antibot:access()
|
||||
|
|
@ -118,14 +106,17 @@ function antibot:access()
|
|||
end
|
||||
|
||||
-- Get session data
|
||||
local session, err = get_session("antibot", self.ctx)
|
||||
local session, err = get_session(self.ctx)
|
||||
if not session then
|
||||
return self:ret(false, "can't get session : " .. err, HTTP_INTERNAL_SERVER_ERROR)
|
||||
return self:ret(false, "can't get session : " .. err)
|
||||
end
|
||||
self.session = session
|
||||
self.session_data = get_session_data(self.session, true, self.ctx)
|
||||
self.session_data = session:get("antibot") or {}
|
||||
self.ctx.bw.antibot_session_data = self.session_data
|
||||
|
||||
-- Check if session is valid
|
||||
self:check_session()
|
||||
local msg = self:check_session()
|
||||
self.logger:log(INFO, "check_session returned : " .. msg)
|
||||
|
||||
-- Don't go further if client resolved the challenge
|
||||
if self.session_data.resolved then
|
||||
|
|
@ -137,10 +128,6 @@ function antibot:access()
|
|||
|
||||
-- Prepare challenge if needed
|
||||
self:prepare_challenge()
|
||||
local ok, err = self:set_session_data()
|
||||
if not ok then
|
||||
return self:ret(false, "can't save session : " .. err, HTTP_INTERNAL_SERVER_ERROR)
|
||||
end
|
||||
|
||||
-- Redirect to challenge page
|
||||
if self.ctx.bw.uri ~= self.variables["ANTIBOT_URI"] then
|
||||
|
|
@ -162,10 +149,6 @@ function antibot:access()
|
|||
if self.ctx.bw.request_method == "POST" then
|
||||
-- luacheck: ignore 421
|
||||
local ok, err, redirect = self:check_challenge()
|
||||
local set_ok, set_err = self:set_session_data()
|
||||
if not set_ok then
|
||||
return self:ret(false, "can't save session : " .. set_err, HTTP_INTERNAL_SERVER_ERROR)
|
||||
end
|
||||
if ok == nil then
|
||||
return self:ret(false, "check challenge error : " .. err, HTTP_INTERNAL_SERVER_ERROR)
|
||||
elseif not ok then
|
||||
|
|
@ -175,10 +158,6 @@ function antibot:access()
|
|||
return self:ret(true, "check challenge redirect : " .. redirect, nil, redirect)
|
||||
end
|
||||
self:prepare_challenge()
|
||||
ok, err = self:set_session_data()
|
||||
if not ok then
|
||||
return self:ret(false, "can't save session : " .. err, HTTP_INTERNAL_SERVER_ERROR)
|
||||
end
|
||||
self.ctx.bw.antibot_display_content = true
|
||||
return self:ret(true, "displaying challenge to client", OK)
|
||||
end
|
||||
|
|
@ -202,12 +181,10 @@ function antibot:content()
|
|||
end
|
||||
|
||||
-- Get session data
|
||||
local session, err = get_session("antibot", self.ctx)
|
||||
if not session then
|
||||
return self:ret(false, "can't get session : " .. err, HTTP_INTERNAL_SERVER_ERROR)
|
||||
self.session_data = self.ctx.bw.antibot_session_data
|
||||
if not self.session_data then
|
||||
return self:ret(false, "missing session data", HTTP_INTERNAL_SERVER_ERROR)
|
||||
end
|
||||
self.session = session
|
||||
self.session_data = get_session_data(self.session, true, self.ctx)
|
||||
|
||||
-- Direct access without session
|
||||
if not self.session_data.prepared then
|
||||
|
|
@ -229,42 +206,36 @@ function antibot:check_session()
|
|||
-- Not resolved and not prepared
|
||||
if not time_resolve and not time_valid then
|
||||
self.session_data = {}
|
||||
self.session_updated = true
|
||||
return
|
||||
self:set_session_data()
|
||||
return "not prepared"
|
||||
end
|
||||
-- Check if still valid
|
||||
local time = ngx.now()
|
||||
local time = now()
|
||||
local resolved = self.session_data.resolved
|
||||
if resolved and (time_valid > time or time - time_valid > tonumber(self.variables["ANTIBOT_TIME_VALID"])) then
|
||||
self.session_data = {}
|
||||
self.session_updated = true
|
||||
return
|
||||
self:set_session_data()
|
||||
return "need new resolve"
|
||||
end
|
||||
-- Check if new prepare is needed
|
||||
if
|
||||
not resolved and (time_resolve > time or time - time_resolve > tonumber(self.variables["ANTIBOT_TIME_RESOLVE"]))
|
||||
then
|
||||
self.session_data = {}
|
||||
self.session_updated = true
|
||||
return
|
||||
self:set_session_data()
|
||||
return "need new prepare"
|
||||
end
|
||||
return "valid"
|
||||
end
|
||||
|
||||
function antibot:set_session_data()
|
||||
if self.session_updated then
|
||||
local ok, err = set_session_data(self.session, self.session_data, true, self.ctx)
|
||||
if not ok then
|
||||
return false, err
|
||||
end
|
||||
self.session_updated = false
|
||||
return true, "updated"
|
||||
end
|
||||
return true, "no update"
|
||||
self.session:set("antibot", self.session_data)
|
||||
self.ctx.bw.antibot_session_data = self.session_data
|
||||
self.ctx.bw.sessions_updated = true
|
||||
end
|
||||
|
||||
function antibot:prepare_challenge()
|
||||
if not self.session_data.prepared then
|
||||
self.session_updated = true
|
||||
self.session_data.prepared = true
|
||||
self.session_data.time_resolve = ngx.now()
|
||||
self.session_data.type = self.variables["USE_ANTIBOT"]
|
||||
|
|
@ -283,6 +254,7 @@ function antibot:prepare_challenge()
|
|||
elseif self.session_data.type == "captcha" then
|
||||
self.session_data.captcha = rand(6, true)
|
||||
end
|
||||
self:set_session_data()
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -363,6 +335,7 @@ function antibot:check_challenge()
|
|||
end
|
||||
self.session_data.resolved = true
|
||||
self.session_data.time_valid = now()
|
||||
self:set_session_data()
|
||||
return true, "resolved", self.session_data.original_uri
|
||||
end
|
||||
|
||||
|
|
@ -374,10 +347,11 @@ function antibot:check_challenge()
|
|||
return nil, "missing challenge arg", nil
|
||||
end
|
||||
if self.session_data.captcha ~= args["captcha"] then
|
||||
return false, "wrong value", nil
|
||||
return false, "wrong value, expected " .. self.session_data.captcha, nil
|
||||
end
|
||||
self.session_data.resolved = true
|
||||
self.session_data.time_valid = now()
|
||||
self:set_session_data()
|
||||
return true, "resolved", self.session_data.original_uri
|
||||
end
|
||||
|
||||
|
|
@ -417,6 +391,7 @@ function antibot:check_challenge()
|
|||
end
|
||||
self.session_data.resolved = true
|
||||
self.session_data.time_valid = now()
|
||||
self:set_session_data()
|
||||
return true, "resolved", self.session_data.original_uri
|
||||
end
|
||||
|
||||
|
|
@ -456,6 +431,7 @@ function antibot:check_challenge()
|
|||
end
|
||||
self.session_data.resolved = true
|
||||
self.session_data.time_valid = now()
|
||||
self:set_session_data()
|
||||
return true, "resolved", self.session_data.original_uri
|
||||
end
|
||||
|
||||
|
|
@ -495,6 +471,7 @@ function antibot:check_challenge()
|
|||
end
|
||||
self.session_data.resolved = true
|
||||
self.session_data.time_valid = now()
|
||||
self:set_session_data()
|
||||
return true, "resolved", self.session_data.original_uri
|
||||
end
|
||||
|
||||
|
|
|
|||
1
src/common/core/antibot/files/captcha.html
vendored
1
src/common/core/antibot/files/captcha.html
vendored
|
|
@ -250,6 +250,7 @@
|
|||
class="mt-3 px-2 text-gray-800 h-8 w-full max-w-[300px] rounded-lg outline-secondary"
|
||||
type="text"
|
||||
name="captcha"
|
||||
required
|
||||
/>
|
||||
<button
|
||||
class="hover:brightness-90 mt-2 rounded-lg bg-secondary px-6 py-2 text-white text-sm xs:text-base font-bold"
|
||||
|
|
|
|||
|
|
@ -137,10 +137,6 @@ function bunkernet:access()
|
|||
if not self:is_needed() then
|
||||
return self:ret(true, "service doesn't use BunkerNet, skipping access")
|
||||
end
|
||||
-- Check id
|
||||
if not self.bunkernet_id then
|
||||
return self:ret(false, "missing instance ID")
|
||||
end
|
||||
-- Check if IP is global
|
||||
if not self.ctx.bw.ip_is_global then
|
||||
return self:ret(true, "IP is not global")
|
||||
|
|
@ -149,6 +145,10 @@ function bunkernet:access()
|
|||
if is_whitelisted(self.ctx) then
|
||||
return self:ret(true, "client is whitelisted")
|
||||
end
|
||||
-- Check id
|
||||
if not self.bunkernet_id then
|
||||
return self:ret(false, "missing instance ID")
|
||||
end
|
||||
-- Extract DB
|
||||
local db, err = self.datastore:get("plugin_bunkernet_db", true)
|
||||
if db then
|
||||
|
|
@ -175,10 +175,6 @@ function bunkernet:log(bypass_checks)
|
|||
if not self:is_needed() then
|
||||
return self:ret(true, "service doesn't use BunkerNet, skipping log")
|
||||
end
|
||||
-- Check id
|
||||
if not self.bunkernet_id then
|
||||
return self:ret(false, "missing instance ID")
|
||||
end
|
||||
end
|
||||
-- Check if IP has been blocked
|
||||
local reason, reason_data = get_reason(self.ctx)
|
||||
|
|
@ -192,6 +188,10 @@ function bunkernet:log(bypass_checks)
|
|||
if not self.ctx.bw.ip_is_global then
|
||||
return self:ret(true, "IP is not global")
|
||||
end
|
||||
-- Check id
|
||||
if not self.bunkernet_id then
|
||||
return self:ret(false, "missing instance ID")
|
||||
end
|
||||
-- Check if IP has been reported recently
|
||||
local ok, data = self.cachestore:get("plugin_bunkernet_" .. self.ctx.bw.remote_addr .. "_" .. reason)
|
||||
if not ok then
|
||||
|
|
@ -239,10 +239,6 @@ function bunkernet:log_default()
|
|||
if not self:is_needed() then
|
||||
return self:ret(true, "no service uses BunkerNet, skipping log_default")
|
||||
end
|
||||
-- Check id
|
||||
if not self.bunkernet_id then
|
||||
return self:ret(false, "missing instance ID")
|
||||
end
|
||||
-- Check if default server is disabled
|
||||
local check, err = get_variable("DISABLE_DEFAULT_SERVER", false)
|
||||
if check == nil then
|
||||
|
|
|
|||
|
|
@ -32,12 +32,7 @@ try:
|
|||
bunkernet_activated = False
|
||||
# Multisite case
|
||||
if getenv("MULTISITE", "no") == "yes":
|
||||
servers = getenv("SERVER_NAME") or []
|
||||
|
||||
if isinstance(servers, str):
|
||||
servers = servers.split(" ")
|
||||
|
||||
for first_server in servers:
|
||||
for first_server in getenv("SERVER_NAME", "").split(" "):
|
||||
if getenv(f"{first_server}_USE_BUNKERNET", getenv("USE_BUNKERNET", "yes")) == "yes":
|
||||
bunkernet_activated = True
|
||||
break
|
||||
|
|
|
|||
|
|
@ -36,8 +36,8 @@ function customcert:init()
|
|||
for server_name, multisite_vars in pairs(vars) do
|
||||
if multisite_vars["USE_CUSTOM_SSL"] == "yes" and server_name ~= "global" then
|
||||
local check, data = read_files({
|
||||
"/var/cache/bunkerweb/customcert/" .. server_name .. "/cert.pem",
|
||||
"/var/cache/bunkerweb/customcert/" .. server_name .. "/key.pem",
|
||||
"/var/cache/bunkerweb/customcert/" .. server_name .. ".cert.pem",
|
||||
"/var/cache/bunkerweb/customcert/" .. server_name .. ".key.pem",
|
||||
})
|
||||
if not check then
|
||||
self.logger:log(ERR, "error while reading files : " .. data)
|
||||
|
|
@ -60,8 +60,8 @@ function customcert:init()
|
|||
return self:ret(false, "can't get SERVER_NAME variable : " .. err)
|
||||
end
|
||||
local check, data = read_files({
|
||||
"/var/cache/bunkerweb/customcert/" .. server_name:match("%S+") .. "/cert.pem",
|
||||
"/var/cache/bunkerweb/customcert/" .. server_name:match("%S+") .. "/key.pem",
|
||||
"/var/cache/bunkerweb/customcert/" .. server_name:match("%S+") .. ".cert.pem",
|
||||
"/var/cache/bunkerweb/customcert/" .. server_name:match("%S+") .. ".key.pem",
|
||||
})
|
||||
if not check then
|
||||
self.logger:log(ERR, "error while reading files : " .. data)
|
||||
|
|
@ -87,15 +87,11 @@ function customcert:ssl_certificate()
|
|||
if not server_name then
|
||||
return self:ret(false, "can't get server_name : " .. err)
|
||||
end
|
||||
if self.variables["USE_CUSTOM_SSL"] == "yes" then
|
||||
local data
|
||||
data, err = self.datastore:get("plugin_customcert_" .. server_name, true)
|
||||
if not data then
|
||||
return self:ret(
|
||||
false,
|
||||
"error while getting plugin_customcert_" .. server_name .. " from datastore : " .. err
|
||||
)
|
||||
end
|
||||
local data
|
||||
data, err = self.datastore:get("plugin_customcert_" .. server_name, true)
|
||||
if not data and err ~= "not found" then
|
||||
return self:ret(false, "error while getting plugin_customcert_" .. server_name .. " from datastore : " .. err)
|
||||
elseif data then
|
||||
return self:ret(true, "certificate/key data found", data)
|
||||
end
|
||||
return self:ret(true, "custom certificate is not used")
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ for deps_path in [
|
|||
if deps_path not in sys_path:
|
||||
sys_path.append(deps_path)
|
||||
|
||||
from jobs import cache_file, cache_hash, file_hash
|
||||
from jobs import del_file_in_db, cache_file, cache_hash, file_hash
|
||||
from Database import Database # type: ignore
|
||||
from logger import setup_logger # type: ignore
|
||||
|
||||
|
|
@ -28,6 +28,7 @@ db = None
|
|||
|
||||
def check_cert(cert_path: str, key_path: str, first_server: str) -> bool:
|
||||
try:
|
||||
ret = False
|
||||
if not cert_path or not key_path:
|
||||
logger.warning("Both variables CUSTOM_SSL_CERT and CUSTOM_SSL_KEY have to be set to use custom certificates")
|
||||
return False
|
||||
|
|
@ -48,19 +49,17 @@ def check_cert(cert_path: str, key_path: str, first_server: str) -> bool:
|
|||
"cache",
|
||||
"bunkerweb",
|
||||
"customcert",
|
||||
first_server,
|
||||
"cert.pem",
|
||||
f"{first_server}.cert.pem",
|
||||
)
|
||||
cert_cache_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
cert_hash = file_hash(cert_path)
|
||||
old_hash = cache_hash(cert_cache_path, db)
|
||||
if old_hash == cert_hash:
|
||||
return False
|
||||
|
||||
cached, err = cache_file(cert_path, cert_cache_path, cert_hash, db, delete_file=False)
|
||||
if not cached:
|
||||
logger.error(f"Error while caching custom-cert cert.pem file : {err}")
|
||||
if old_hash != cert_hash:
|
||||
ret = True
|
||||
cached, err = cache_file(cert_path, cert_cache_path, cert_hash, db, delete_file=False)
|
||||
if not cached:
|
||||
logger.error(f"Error while caching custom-cert cert.pem file : {err}")
|
||||
|
||||
key_cache_path = Path(
|
||||
sep,
|
||||
|
|
@ -68,19 +67,19 @@ def check_cert(cert_path: str, key_path: str, first_server: str) -> bool:
|
|||
"cache",
|
||||
"bunkerweb",
|
||||
"customcert",
|
||||
first_server,
|
||||
"key.pem",
|
||||
f"{first_server}.key.pem",
|
||||
)
|
||||
key_cache_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
key_hash = file_hash(key_path)
|
||||
old_hash = cache_hash(key_cache_path, db)
|
||||
if old_hash != key_hash:
|
||||
ret = True
|
||||
cached, err = cache_file(key_path, key_cache_path, key_hash, db, delete_file=False)
|
||||
if not cached:
|
||||
logger.error(f"Error while caching custom-cert key.pem file : {err}")
|
||||
|
||||
return True
|
||||
return ret
|
||||
except:
|
||||
logger.error(
|
||||
f"Exception while running custom-cert.py (check_cert) :\n{format_exc()}",
|
||||
|
|
@ -103,9 +102,8 @@ try:
|
|||
cert_data = b64decode(getenv("CUSTOM_SSL_CERT_DATA", ""))
|
||||
key_data = b64decode(getenv("CUSTOM_SSL_KEY_DATA", ""))
|
||||
for file, data in (("cert.pem", cert_data), ("key.pem", key_data)):
|
||||
if data != b"":
|
||||
file_path = Path(sep, "var", "tmp", "bunkerweb", "customcert", first_server, file)
|
||||
file_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
if data:
|
||||
file_path = Path(sep, "var", "tmp", "bunkerweb", "customcert", f"{first_server}.{file}")
|
||||
file_path.write_bytes(data)
|
||||
if file == "cert.pem":
|
||||
cert_path = str(file_path)
|
||||
|
|
@ -120,7 +118,28 @@ try:
|
|||
status = 1
|
||||
else:
|
||||
logger.info(f"No change for certificate {cert_path}")
|
||||
|
||||
elif not cert_path or not key_path:
|
||||
logger.warning("Both variables CUSTOM_SSL_CERT and CUSTOM_SSL_KEY (or CUSTOM_SSL_CERT_DATA and CUSTOM_SSL_KEY_DATA) have to be set to use custom certificates, clearing cache ...")
|
||||
cert_cache_path = Path(
|
||||
sep,
|
||||
"var",
|
||||
"cache",
|
||||
"bunkerweb",
|
||||
"customcert",
|
||||
f"{first_server}.cert.pem",
|
||||
)
|
||||
cert_cache_path.unlink(missing_ok=True)
|
||||
del_file_in_db(f"{first_server}.cert.pem", db, service_id=first_server)
|
||||
key_cache_path = Path(
|
||||
sep,
|
||||
"var",
|
||||
"cache",
|
||||
"bunkerweb",
|
||||
"customcert",
|
||||
f"{first_server}.key.pem",
|
||||
)
|
||||
key_cache_path.unlink(missing_ok=True)
|
||||
del_file_in_db(f"{first_server}.key.pem", db, service_id=first_server)
|
||||
elif getenv("MULTISITE", "no") == "yes":
|
||||
servers = getenv("SERVER_NAME") or []
|
||||
|
||||
|
|
@ -141,7 +160,7 @@ try:
|
|||
key_data = b64decode(getenv(f"{first_server}_CUSTOM_SSL_KEY_DATA", ""))
|
||||
for file, data in (("cert.pem", cert_data), ("key.pem", key_data)):
|
||||
if data != b"":
|
||||
file_path = Path(sep, "var", "tmp", "bunkerweb", "customcert", first_server, file)
|
||||
file_path = Path(sep, "var", "tmp", "bunkerweb", "customcert", f"{first_server}.{file}")
|
||||
file_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
file_path.write_bytes(data)
|
||||
if file == "cert.pem":
|
||||
|
|
@ -163,6 +182,28 @@ try:
|
|||
logger.info(
|
||||
f"No change for certificate {cert_path}",
|
||||
)
|
||||
elif not cert_path or not key_path:
|
||||
logger.warning("Both variables CUSTOM_SSL_CERT and CUSTOM_SSL_KEY (or CUSTOM_SSL_CERT_DATA and CUSTOM_SSL_KEY_DATA) have to be set to use custom certificates, clearing cache ...")
|
||||
cert_cache_path = Path(
|
||||
sep,
|
||||
"var",
|
||||
"cache",
|
||||
"bunkerweb",
|
||||
"customcert",
|
||||
f"{first_server}.cert.pem",
|
||||
)
|
||||
cert_cache_path.unlink(missing_ok=True)
|
||||
del_file_in_db(f"{first_server}.cert.pem", db)
|
||||
key_cache_path = Path(
|
||||
sep,
|
||||
"var",
|
||||
"cache",
|
||||
"bunkerweb",
|
||||
"customcert",
|
||||
f"{first_server}.key.pem",
|
||||
)
|
||||
key_cache_path.unlink(missing_ok=True)
|
||||
del_file_in_db(f"{first_server}.key.pem", db)
|
||||
except:
|
||||
status = 2
|
||||
logger.error(f"Exception while running custom-cert.py :\n{format_exc()}")
|
||||
|
|
|
|||
|
|
@ -100,15 +100,11 @@ function letsencrypt:ssl_certificate()
|
|||
if not server_name then
|
||||
return self:ret(false, "can't get server_name : " .. err)
|
||||
end
|
||||
if self.variables["AUTO_LETS_ENCRYPT"] == "yes" then
|
||||
local data
|
||||
data, err = self.datastore:get("plugin_letsencrypt_" .. server_name, true)
|
||||
if not data then
|
||||
return self:ret(
|
||||
false,
|
||||
"error while getting plugin_letsencrypt_" .. server_name .. " from datastore : " .. err
|
||||
)
|
||||
end
|
||||
local data
|
||||
data, err = self.datastore:get("plugin_letsencrypt_" .. server_name, true)
|
||||
if not data and err ~= "not found" then
|
||||
return self:ret(false, "error while getting plugin_letsencrypt_" .. server_name .. " from datastore : " .. err)
|
||||
elseif data then
|
||||
return self:ret(true, "certificate/key data found", data)
|
||||
end
|
||||
return self:ret(true, "let's encrypt is not used")
|
||||
|
|
@ -175,9 +171,9 @@ function letsencrypt:api()
|
|||
if not ok then
|
||||
return self:ret(true, "can't remove validation token : " .. err, HTTP_INTERNAL_SERVER_ERROR)
|
||||
end
|
||||
return true, HTTP_OK, { status = "success", msg = "validation token removed" }
|
||||
return self:ret(true, "validation token removed", HTTP_OK)
|
||||
end
|
||||
return true, HTTP_NOT_FOUND, { status = "error", msg = "unknown request" }
|
||||
return self:ret(true, "unknown request", HTTP_NOT_FOUND)
|
||||
end
|
||||
|
||||
return letsencrypt
|
||||
|
|
|
|||
1
src/common/core/metrics/confs/http/metrics.conf
Normal file
1
src/common/core/metrics/confs/http/metrics.conf
Normal file
|
|
@ -0,0 +1 @@
|
|||
lua_shared_dict metrics_datastore {{ METRICS_MEMORY_SIZE }};
|
||||
1
src/common/core/metrics/confs/stream/metrics.conf
Normal file
1
src/common/core/metrics/confs/stream/metrics.conf
Normal file
|
|
@ -0,0 +1 @@
|
|||
lua_shared_dict metrics_datastore_stream {{ METRICS_MEMORY_SIZE }};
|
||||
107
src/common/core/metrics/metrics.lua
Normal file
107
src/common/core/metrics/metrics.lua
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
local cjson = require "cjson"
|
||||
local class = require "middleclass"
|
||||
local datastore = require "datastore"
|
||||
local plugin = require "bunkerweb.plugin"
|
||||
local utils = require "bunkerweb.utils"
|
||||
|
||||
local metrics = class("metrics", plugin)
|
||||
|
||||
local ngx = ngx
|
||||
local shared = ngx.shared
|
||||
local subsystem = ngx.config.subsystem
|
||||
local ERR = ngx.ERR
|
||||
local HTTP_INTERNAL_SERVER_ERROR = ngx.HTTP_INTERNAL_SERVER_ERROR
|
||||
local HTTP_OK = ngx.HTTP_OK
|
||||
|
||||
local get_reason = utils.get_reason
|
||||
local get_country = utils.get_country
|
||||
local encode = cjson.encode
|
||||
local decode = cjson.decode
|
||||
|
||||
local match = string.match
|
||||
|
||||
function metrics:initialize(ctx)
|
||||
-- Call parent initialize
|
||||
plugin.initialize(self, "metrics", ctx)
|
||||
local dict
|
||||
if subsystem == "http" then
|
||||
dict = shared.metrics_datastore
|
||||
else
|
||||
dict = shared.metrics_datastore_stream
|
||||
end
|
||||
self.metrics_datastore = datastore:new(dict)
|
||||
end
|
||||
|
||||
function metrics:log()
|
||||
-- Don't go further if metrics is not enabled
|
||||
if self.variables["USE_METRICS"] == "no" then
|
||||
return self:ret(true, "metrics are disabled")
|
||||
end
|
||||
-- Store blocked requests
|
||||
local reason, data = get_reason(self.ctx)
|
||||
if reason then
|
||||
local country = "local"
|
||||
local err
|
||||
if self.ctx.bw.ip_is_global then
|
||||
country, err = get_country(self.ctx.bw.remote_addr)
|
||||
if not country then
|
||||
country = "unknown"
|
||||
self.logger:log(ERR, "can't get country code " .. err)
|
||||
end
|
||||
end
|
||||
local request = {
|
||||
date = self.ctx.bw.local_time,
|
||||
ip = self.ctx.bw.remote_addr,
|
||||
country = country,
|
||||
method = self.ctx.bw.request_method,
|
||||
url = self.ctx.bw.request_uri,
|
||||
code = ngx.status,
|
||||
["user-agent"] = self.ctx.bw.http_user_agent or "",
|
||||
reason = reason,
|
||||
data = data,
|
||||
}
|
||||
local ok
|
||||
ok, err = self.metrics_datastore:safe_rpush("metrics_requests", encode(request))
|
||||
if not ok then
|
||||
self.logger:log(ERR, "can't save request to datastore : " .. err)
|
||||
end
|
||||
end
|
||||
return self:ret(true, "success")
|
||||
end
|
||||
|
||||
function metrics:log_default()
|
||||
return self:log()
|
||||
end
|
||||
|
||||
function metrics:api()
|
||||
-- Match request
|
||||
if not match(self.ctx.bw.uri, "^/metrics/requests$") or self.ctx.bw.request_method ~= "GET" then
|
||||
return self:ret(false, "success")
|
||||
end
|
||||
|
||||
-- Get requests metrics
|
||||
local len, err = self.metrics_datastore:llen("metrics_requests")
|
||||
if not len then
|
||||
return self:ret(true, "error while getting length of metrics_requests : " .. err, HTTP_INTERNAL_SERVER_ERROR)
|
||||
end
|
||||
local i = 0
|
||||
local data = {}
|
||||
while i < len do
|
||||
local request
|
||||
request, err = self.metrics_datastore:lpop("metrics_requests")
|
||||
if request then
|
||||
table.insert(data, decode(request))
|
||||
else
|
||||
return self:ret(true, "error while getting metrics_requests : " .. err, HTTP_INTERNAL_SERVER_ERROR)
|
||||
end
|
||||
local ok
|
||||
ok, err = self.metrics_datastore:safe_rpush("metrics_requests", request)
|
||||
if not ok then
|
||||
self.logger:log(ERR, "can't save request to datastore : " .. err)
|
||||
end
|
||||
i = i + 1
|
||||
end
|
||||
return self:ret(true, data, HTTP_OK)
|
||||
end
|
||||
|
||||
return metrics
|
||||
27
src/common/core/metrics/plugin.json
Normal file
27
src/common/core/metrics/plugin.json
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"id": "metrics",
|
||||
"name": "Metrics",
|
||||
"description": "Metrics collection and retrieve.",
|
||||
"version": "1.0",
|
||||
"stream": "partial",
|
||||
"settings": {
|
||||
"USE_METRICS": {
|
||||
"context": "global",
|
||||
"default": "yes",
|
||||
"help": "Enable collection and retrieval of internal metrics.",
|
||||
"id": "use-metrics",
|
||||
"label": "Use metrics",
|
||||
"regex": "^(yes|no)$",
|
||||
"type": "check"
|
||||
},
|
||||
"METRICS_MEMORY_SIZE": {
|
||||
"context": "global",
|
||||
"default": "16m",
|
||||
"help": "Size of the internal storage for metrics.",
|
||||
"id": "metrics-memory-size",
|
||||
"label": "Metrics memory size",
|
||||
"regex": "^\\d+[kKmMgG]?$",
|
||||
"type": "text"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -32,7 +32,7 @@
|
|||
"antibot"
|
||||
],
|
||||
"headers": ["headers", "cors", "reverseproxy", "clientcache", "antibot"],
|
||||
"log": ["badbehavior", "bunkernet"],
|
||||
"log": ["badbehavior", "bunkernet", "metrics"],
|
||||
"preread": [
|
||||
"whitelist",
|
||||
"blacklist",
|
||||
|
|
@ -42,5 +42,5 @@
|
|||
"reversescan"
|
||||
],
|
||||
"log_stream": ["badbehavior", "bunkernet"],
|
||||
"log_default": ["badbehavior", "bunkernet"]
|
||||
"log_default": ["badbehavior", "bunkernet", "metrics"]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,6 +50,15 @@
|
|||
"regex": "^(yes|no)$",
|
||||
"type": "check"
|
||||
},
|
||||
"REDIS_SSL_VERIFY": {
|
||||
"context": "global",
|
||||
"default": "no",
|
||||
"help": "Verify the certificate of Redis server.",
|
||||
"id": "redis-ssl-verify",
|
||||
"label": "Redis SSL/TLS verify",
|
||||
"regex": "^(yes|no)$",
|
||||
"type": "check"
|
||||
},
|
||||
"REDIS_TIMEOUT": {
|
||||
"context": "global",
|
||||
"default": "1000",
|
||||
|
|
|
|||
|
|
@ -87,18 +87,14 @@ function selfsigned:ssl_certificate()
|
|||
if not server_name then
|
||||
return self:ret(false, "can't get server_name : " .. err)
|
||||
end
|
||||
if self.variables["GENERATE_SELF_SIGNED_SSL"] == "yes" then
|
||||
local data
|
||||
data, err = self.datastore:get("plugin_selfsigned_" .. server_name, true)
|
||||
if not data then
|
||||
return self:ret(
|
||||
false,
|
||||
"error while getting plugin_selfsigned_" .. server_name .. " from datastore : " .. err
|
||||
)
|
||||
end
|
||||
local data
|
||||
data, err = self.datastore:get("plugin_selfsigned_" .. server_name, true)
|
||||
if not data and err ~= "not found" then
|
||||
return self:ret(false, "error while getting plugin_selfsigned_" .. server_name .. " from datastore : " .. err)
|
||||
elseif data then
|
||||
return self:ret(true, "certificate/key data found", data)
|
||||
end
|
||||
return self:ret(true, "selfsigned is not used")
|
||||
return self:ret(true, "self signed is not used")
|
||||
end
|
||||
|
||||
function selfsigned:load_data(data, server_name)
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ function sessions:init()
|
|||
["REDIS_PORT"] = "",
|
||||
["REDIS_DATABASE"] = "",
|
||||
["REDIS_SSL"] = "",
|
||||
["REDIS_SSL_VERIFY"] = "",
|
||||
["REDIS_TIMEOUT"] = "",
|
||||
["REDIS_KEEPALIVE_IDLE"] = "",
|
||||
["REDIS_KEEPALIVE_POOL"] = "",
|
||||
|
|
@ -121,9 +122,9 @@ function sessions:init()
|
|||
send_timeout = tonumber(redis_vars["REDIS_TIMEOUT"]),
|
||||
read_timeout = tonumber(redis_vars["REDIS_TIMEOUT"]),
|
||||
keepalive_timeout = tonumber(redis_vars["REDIS_KEEPALIVE_IDLE"]),
|
||||
pool = "bw-redis",
|
||||
pool_size = tonumber(redis_vars["REDIS_KEEPALIVE_POOL"]),
|
||||
ssl = redis_vars["REDIS_SSL"] == "yes",
|
||||
ssl_verify = redis_vars["REDIS_SSL_VERIFY"] == "yes",
|
||||
database = tonumber(redis_vars["REDIS_DATABASE"]),
|
||||
}
|
||||
if redis_vars["REDIS_SENTINEL_HOSTS"] ~= nil then
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ install_as_MySQLdb()
|
|||
|
||||
|
||||
class Database:
|
||||
DB_STRING_RX = re_compile(r"^(?P<database>(mariadb|mysql)(\+pymysql)?|sqlite(\+pysqlite)?|postgresql):/+(?P<path>/[^\s]+)")
|
||||
DB_STRING_RX = re_compile(r"^(?P<database>(mariadb|mysql)(\+pymysql)?|sqlite(\+pysqlite)?|postgresql(\+psycopg)?):/+(?P<path>/[^\s]+)")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
|
|
@ -85,6 +85,10 @@ class Database:
|
|||
sleep(1)
|
||||
else:
|
||||
db_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
elif match.group("database").startswith("m") and not match.group("database").endswith("+pymysql"):
|
||||
sqlalchemy_string = sqlalchemy_string.replace(match.group("database"), f"{match.group('database')}+pymysql") # ? This is mandatory for alemic to work with mariadb and mysql
|
||||
elif match.group("database").startswith("postgresql") and not match.group("database").endswith("+psycopg"):
|
||||
sqlalchemy_string = sqlalchemy_string.replace(match.group("database"), f"{match.group('database')}+psycopg") # ? This is strongly recommended as psycopg is the new way to connect to postgresql
|
||||
|
||||
self.database_uri = sqlalchemy_string
|
||||
error = False
|
||||
|
|
@ -1039,10 +1043,10 @@ class Database:
|
|||
|
||||
return ""
|
||||
|
||||
def delete_job_cache(self, file_name: str, *, job_name: Optional[str] = None):
|
||||
def delete_job_cache(self, file_name: str, *, job_name: Optional[str] = None, service_id: Optional[str] = None):
|
||||
job_name = job_name or basename(getsourcefile(_getframe(1))).replace(".py", "")
|
||||
with self.__db_session() as session:
|
||||
session.query(Jobs_cache).filter_by(job_name=job_name, file_name=file_name).delete()
|
||||
session.query(Jobs_cache).filter_by(job_name=job_name, file_name=file_name, service_id=service_id).delete()
|
||||
|
||||
def update_job_cache(
|
||||
self,
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ class Global_values(Base):
|
|||
ForeignKey("bw_settings.id", onupdate="cascade", ondelete="cascade"),
|
||||
primary_key=True,
|
||||
)
|
||||
value = Column(String(4096), nullable=False)
|
||||
value = Column(String(8192), nullable=False)
|
||||
suffix = Column(Integer, primary_key=True, nullable=True, default=0)
|
||||
method = Column(METHODS_ENUM, nullable=False)
|
||||
|
||||
|
|
@ -128,7 +128,7 @@ class Services_settings(Base):
|
|||
ForeignKey("bw_settings.id", onupdate="cascade", ondelete="cascade"),
|
||||
primary_key=True,
|
||||
)
|
||||
value = Column(String(4096), nullable=False)
|
||||
value = Column(String(8192), nullable=False)
|
||||
suffix = Column(Integer, primary_key=True, nullable=True, default=0)
|
||||
method = Column(METHODS_ENUM, nullable=False)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
cryptography==41.0.7
|
||||
psycopg2-binary==2.9.9
|
||||
cryptography==42.0.0
|
||||
psycopg[binary,pool]==3.1.17
|
||||
PyMySQL==1.1.0
|
||||
sqlalchemy==2.0.25
|
||||
|
|
|
|||
|
|
@ -58,30 +58,39 @@ cffi==1.16.0 \
|
|||
--hash=sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956 \
|
||||
--hash=sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357
|
||||
# via cryptography
|
||||
cryptography==41.0.7 \
|
||||
--hash=sha256:079b85658ea2f59c4f43b70f8119a52414cdb7be34da5d019a77bf96d473b960 \
|
||||
--hash=sha256:09616eeaef406f99046553b8a40fbf8b1e70795a91885ba4c96a70793de5504a \
|
||||
--hash=sha256:13f93ce9bea8016c253b34afc6bd6a75993e5c40672ed5405a9c832f0d4a00bc \
|
||||
--hash=sha256:37a138589b12069efb424220bf78eac59ca68b95696fc622b6ccc1c0a197204a \
|
||||
--hash=sha256:3c78451b78313fa81607fa1b3f1ae0a5ddd8014c38a02d9db0616133987b9cdf \
|
||||
--hash=sha256:43f2552a2378b44869fe8827aa19e69512e3245a219104438692385b0ee119d1 \
|
||||
--hash=sha256:48a0476626da912a44cc078f9893f292f0b3e4c739caf289268168d8f4702a39 \
|
||||
--hash=sha256:49f0805fc0b2ac8d4882dd52f4a3b935b210935d500b6b805f321addc8177406 \
|
||||
--hash=sha256:5429ec739a29df2e29e15d082f1d9ad683701f0ec7709ca479b3ff2708dae65a \
|
||||
--hash=sha256:5a1b41bc97f1ad230a41657d9155113c7521953869ae57ac39ac7f1bb471469a \
|
||||
--hash=sha256:68a2dec79deebc5d26d617bfdf6e8aab065a4f34934b22d3b5010df3ba36612c \
|
||||
--hash=sha256:7a698cb1dac82c35fcf8fe3417a3aaba97de16a01ac914b89a0889d364d2f6be \
|
||||
--hash=sha256:841df4caa01008bad253bce2a6f7b47f86dc9f08df4b433c404def869f590a15 \
|
||||
--hash=sha256:90452ba79b8788fa380dfb587cca692976ef4e757b194b093d845e8d99f612f2 \
|
||||
--hash=sha256:928258ba5d6f8ae644e764d0f996d61a8777559f72dfeb2eea7e2fe0ad6e782d \
|
||||
--hash=sha256:af03b32695b24d85a75d40e1ba39ffe7db7ffcb099fe507b39fd41a565f1b157 \
|
||||
--hash=sha256:b640981bf64a3e978a56167594a0e97db71c89a479da8e175d8bb5be5178c003 \
|
||||
--hash=sha256:c5ca78485a255e03c32b513f8c2bc39fedb7f5c5f8535545bdc223a03b24f248 \
|
||||
--hash=sha256:c7f3201ec47d5207841402594f1d7950879ef890c0c495052fa62f58283fde1a \
|
||||
--hash=sha256:d5ec85080cce7b0513cfd233914eb8b7bbd0633f1d1703aa28d1dd5a72f678ec \
|
||||
--hash=sha256:d6c391c021ab1f7a82da5d8d0b3cee2f4b2c455ec86c8aebbc84837a631ff309 \
|
||||
--hash=sha256:e3114da6d7f95d2dee7d3f4eec16dacff819740bbab931aff8648cb13c5ff5e7 \
|
||||
--hash=sha256:f983596065a18a2183e7f79ab3fd4c475205b839e02cbc0efbbf9666c4b3083d
|
||||
cryptography==42.0.0 \
|
||||
--hash=sha256:0a68bfcf57a6887818307600c3c0ebc3f62fbb6ccad2240aa21887cda1f8df1b \
|
||||
--hash=sha256:146e971e92a6dd042214b537a726c9750496128453146ab0ee8971a0299dc9bd \
|
||||
--hash=sha256:14e4b909373bc5bf1095311fa0f7fcabf2d1a160ca13f1e9e467be1ac4cbdf94 \
|
||||
--hash=sha256:206aaf42e031b93f86ad60f9f5d9da1b09164f25488238ac1dc488334eb5e221 \
|
||||
--hash=sha256:3005166a39b70c8b94455fdbe78d87a444da31ff70de3331cdec2c568cf25b7e \
|
||||
--hash=sha256:324721d93b998cb7367f1e6897370644751e5580ff9b370c0a50dc60a2003513 \
|
||||
--hash=sha256:33588310b5c886dfb87dba5f013b8d27df7ffd31dc753775342a1e5ab139e59d \
|
||||
--hash=sha256:35cf6ed4c38f054478a9df14f03c1169bb14bd98f0b1705751079b25e1cb58bc \
|
||||
--hash=sha256:3ca482ea80626048975360c8e62be3ceb0f11803180b73163acd24bf014133a0 \
|
||||
--hash=sha256:56ce0c106d5c3fec1038c3cca3d55ac320a5be1b44bf15116732d0bc716979a2 \
|
||||
--hash=sha256:5a217bca51f3b91971400890905a9323ad805838ca3fa1e202a01844f485ee87 \
|
||||
--hash=sha256:678cfa0d1e72ef41d48993a7be75a76b0725d29b820ff3cfd606a5b2b33fda01 \
|
||||
--hash=sha256:69fd009a325cad6fbfd5b04c711a4da563c6c4854fc4c9544bff3088387c77c0 \
|
||||
--hash=sha256:6cf9b76d6e93c62114bd19485e5cb003115c134cf9ce91f8ac924c44f8c8c3f4 \
|
||||
--hash=sha256:74f18a4c8ca04134d2052a140322002fef535c99cdbc2a6afc18a8024d5c9d5b \
|
||||
--hash=sha256:85f759ed59ffd1d0baad296e72780aa62ff8a71f94dc1ab340386a1207d0ea81 \
|
||||
--hash=sha256:87086eae86a700307b544625e3ba11cc600c3c0ef8ab97b0fda0705d6db3d4e3 \
|
||||
--hash=sha256:8814722cffcfd1fbd91edd9f3451b88a8f26a5fd41b28c1c9193949d1c689dc4 \
|
||||
--hash=sha256:8fedec73d590fd30c4e3f0d0f4bc961aeca8390c72f3eaa1a0874d180e868ddf \
|
||||
--hash=sha256:9515ea7f596c8092fdc9902627e51b23a75daa2c7815ed5aa8cf4f07469212ec \
|
||||
--hash=sha256:988b738f56c665366b1e4bfd9045c3efae89ee366ca3839cd5af53eaa1401bce \
|
||||
--hash=sha256:a2a8d873667e4fd2f34aedab02ba500b824692c6542e017075a2efc38f60a4c0 \
|
||||
--hash=sha256:bd7cf7a8d9f34cc67220f1195884151426ce616fdc8285df9054bfa10135925f \
|
||||
--hash=sha256:bdce70e562c69bb089523e75ef1d9625b7417c6297a76ac27b1b8b1eb51b7d0f \
|
||||
--hash=sha256:be14b31eb3a293fc6e6aa2807c8a3224c71426f7c4e3639ccf1a2f3ffd6df8c3 \
|
||||
--hash=sha256:be41b0c7366e5549265adf2145135dca107718fa44b6e418dc7499cfff6b4689 \
|
||||
--hash=sha256:c310767268d88803b653fffe6d6f2f17bb9d49ffceb8d70aed50ad45ea49ab08 \
|
||||
--hash=sha256:c58115384bdcfe9c7f644c72f10f6f42bed7cf59f7b52fe1bf7ae0a622b3a139 \
|
||||
--hash=sha256:c640b0ef54138fde761ec99a6c7dc4ce05e80420262c20fa239e694ca371d434 \
|
||||
--hash=sha256:ca20550bb590db16223eb9ccc5852335b48b8f597e2f6f0878bbfd9e7314eb17 \
|
||||
--hash=sha256:d97aae66b7de41cdf5b12087b5509e4e9805ed6f562406dfcf60e8481a9a28f8 \
|
||||
--hash=sha256:e9326ca78111e4c645f7e49cbce4ed2f3f85e17b61a563328c85a5208cf34440
|
||||
# via -r requirements.in
|
||||
greenlet==3.0.3 \
|
||||
--hash=sha256:01bc7ea167cf943b4c802068e178bbf70ae2e8c080467070d01bfa02f337ee67 \
|
||||
|
|
@ -143,80 +152,83 @@ greenlet==3.0.3 \
|
|||
--hash=sha256:fd096eb7ffef17c456cfa587523c5f92321ae02427ff955bebe9e3c63bc9f0da \
|
||||
--hash=sha256:fe754d231288e1e64323cfad462fcee8f0288654c10bdf4f603a39ed923bef33
|
||||
# via sqlalchemy
|
||||
psycopg2-binary==2.9.9 \
|
||||
--hash=sha256:03ef7df18daf2c4c07e2695e8cfd5ee7f748a1d54d802330985a78d2a5a6dca9 \
|
||||
--hash=sha256:0a602ea5aff39bb9fac6308e9c9d82b9a35c2bf288e184a816002c9fae930b77 \
|
||||
--hash=sha256:0c009475ee389757e6e34611d75f6e4f05f0cf5ebb76c6037508318e1a1e0d7e \
|
||||
--hash=sha256:0ef4854e82c09e84cc63084a9e4ccd6d9b154f1dbdd283efb92ecd0b5e2b8c84 \
|
||||
--hash=sha256:1236ed0952fbd919c100bc839eaa4a39ebc397ed1c08a97fc45fee2a595aa1b3 \
|
||||
--hash=sha256:143072318f793f53819048fdfe30c321890af0c3ec7cb1dfc9cc87aa88241de2 \
|
||||
--hash=sha256:15208be1c50b99203fe88d15695f22a5bed95ab3f84354c494bcb1d08557df67 \
|
||||
--hash=sha256:1873aade94b74715be2246321c8650cabf5a0d098a95bab81145ffffa4c13876 \
|
||||
--hash=sha256:18d0ef97766055fec15b5de2c06dd8e7654705ce3e5e5eed3b6651a1d2a9a152 \
|
||||
--hash=sha256:1ea665f8ce695bcc37a90ee52de7a7980be5161375d42a0b6c6abedbf0d81f0f \
|
||||
--hash=sha256:2293b001e319ab0d869d660a704942c9e2cce19745262a8aba2115ef41a0a42a \
|
||||
--hash=sha256:246b123cc54bb5361588acc54218c8c9fb73068bf227a4a531d8ed56fa3ca7d6 \
|
||||
--hash=sha256:275ff571376626195ab95a746e6a04c7df8ea34638b99fc11160de91f2fef503 \
|
||||
--hash=sha256:281309265596e388ef483250db3640e5f414168c5a67e9c665cafce9492eda2f \
|
||||
--hash=sha256:2d423c8d8a3c82d08fe8af900ad5b613ce3632a1249fd6a223941d0735fce493 \
|
||||
--hash=sha256:2e5afae772c00980525f6d6ecf7cbca55676296b580c0e6abb407f15f3706996 \
|
||||
--hash=sha256:30dcc86377618a4c8f3b72418df92e77be4254d8f89f14b8e8f57d6d43603c0f \
|
||||
--hash=sha256:31a34c508c003a4347d389a9e6fcc2307cc2150eb516462a7a17512130de109e \
|
||||
--hash=sha256:323ba25b92454adb36fa425dc5cf6f8f19f78948cbad2e7bc6cdf7b0d7982e59 \
|
||||
--hash=sha256:34eccd14566f8fe14b2b95bb13b11572f7c7d5c36da61caf414d23b91fcc5d94 \
|
||||
--hash=sha256:3a58c98a7e9c021f357348867f537017057c2ed7f77337fd914d0bedb35dace7 \
|
||||
--hash=sha256:3f78fd71c4f43a13d342be74ebbc0666fe1f555b8837eb113cb7416856c79682 \
|
||||
--hash=sha256:4154ad09dac630a0f13f37b583eae260c6aa885d67dfbccb5b02c33f31a6d420 \
|
||||
--hash=sha256:420f9bbf47a02616e8554e825208cb947969451978dceb77f95ad09c37791dae \
|
||||
--hash=sha256:4686818798f9194d03c9129a4d9a702d9e113a89cb03bffe08c6cf799e053291 \
|
||||
--hash=sha256:57fede879f08d23c85140a360c6a77709113efd1c993923c59fde17aa27599fe \
|
||||
--hash=sha256:60989127da422b74a04345096c10d416c2b41bd7bf2a380eb541059e4e999980 \
|
||||
--hash=sha256:64cf30263844fa208851ebb13b0732ce674d8ec6a0c86a4e160495d299ba3c93 \
|
||||
--hash=sha256:68fc1f1ba168724771e38bee37d940d2865cb0f562380a1fb1ffb428b75cb692 \
|
||||
--hash=sha256:6e6f98446430fdf41bd36d4faa6cb409f5140c1c2cf58ce0bbdaf16af7d3f119 \
|
||||
--hash=sha256:729177eaf0aefca0994ce4cffe96ad3c75e377c7b6f4efa59ebf003b6d398716 \
|
||||
--hash=sha256:72dffbd8b4194858d0941062a9766f8297e8868e1dd07a7b36212aaa90f49472 \
|
||||
--hash=sha256:75723c3c0fbbf34350b46a3199eb50638ab22a0228f93fb472ef4d9becc2382b \
|
||||
--hash=sha256:77853062a2c45be16fd6b8d6de2a99278ee1d985a7bd8b103e97e41c034006d2 \
|
||||
--hash=sha256:78151aa3ec21dccd5cdef6c74c3e73386dcdfaf19bced944169697d7ac7482fc \
|
||||
--hash=sha256:7f01846810177d829c7692f1f5ada8096762d9172af1b1a28d4ab5b77c923c1c \
|
||||
--hash=sha256:804d99b24ad523a1fe18cc707bf741670332f7c7412e9d49cb5eab67e886b9b5 \
|
||||
--hash=sha256:81ff62668af011f9a48787564ab7eded4e9fb17a4a6a74af5ffa6a457400d2ab \
|
||||
--hash=sha256:8359bf4791968c5a78c56103702000105501adb557f3cf772b2c207284273984 \
|
||||
--hash=sha256:83791a65b51ad6ee6cf0845634859d69a038ea9b03d7b26e703f94c7e93dbcf9 \
|
||||
--hash=sha256:8532fd6e6e2dc57bcb3bc90b079c60de896d2128c5d9d6f24a63875a95a088cf \
|
||||
--hash=sha256:876801744b0dee379e4e3c38b76fc89f88834bb15bf92ee07d94acd06ec890a0 \
|
||||
--hash=sha256:8dbf6d1bc73f1d04ec1734bae3b4fb0ee3cb2a493d35ede9badbeb901fb40f6f \
|
||||
--hash=sha256:8f8544b092a29a6ddd72f3556a9fcf249ec412e10ad28be6a0c0d948924f2212 \
|
||||
--hash=sha256:911dda9c487075abd54e644ccdf5e5c16773470a6a5d3826fda76699410066fb \
|
||||
--hash=sha256:977646e05232579d2e7b9c59e21dbe5261f403a88417f6a6512e70d3f8a046be \
|
||||
--hash=sha256:9dba73be7305b399924709b91682299794887cbbd88e38226ed9f6712eabee90 \
|
||||
--hash=sha256:a148c5d507bb9b4f2030a2025c545fccb0e1ef317393eaba42e7eabd28eb6041 \
|
||||
--hash=sha256:a6cdcc3ede532f4a4b96000b6362099591ab4a3e913d70bcbac2b56c872446f7 \
|
||||
--hash=sha256:ac05fb791acf5e1a3e39402641827780fe44d27e72567a000412c648a85ba860 \
|
||||
--hash=sha256:b0605eaed3eb239e87df0d5e3c6489daae3f7388d455d0c0b4df899519c6a38d \
|
||||
--hash=sha256:b58b4710c7f4161b5e9dcbe73bb7c62d65670a87df7bcce9e1faaad43e715245 \
|
||||
--hash=sha256:b6356793b84728d9d50ead16ab43c187673831e9d4019013f1402c41b1db9b27 \
|
||||
--hash=sha256:b76bedd166805480ab069612119ea636f5ab8f8771e640ae103e05a4aae3e417 \
|
||||
--hash=sha256:bc7bb56d04601d443f24094e9e31ae6deec9ccb23581f75343feebaf30423359 \
|
||||
--hash=sha256:c2470da5418b76232f02a2fcd2229537bb2d5a7096674ce61859c3229f2eb202 \
|
||||
--hash=sha256:c332c8d69fb64979ebf76613c66b985414927a40f8defa16cf1bc028b7b0a7b0 \
|
||||
--hash=sha256:c6af2a6d4b7ee9615cbb162b0738f6e1fd1f5c3eda7e5da17861eacf4c717ea7 \
|
||||
--hash=sha256:c77e3d1862452565875eb31bdb45ac62502feabbd53429fdc39a1cc341d681ba \
|
||||
--hash=sha256:ca08decd2697fdea0aea364b370b1249d47336aec935f87b8bbfd7da5b2ee9c1 \
|
||||
--hash=sha256:ca49a8119c6cbd77375ae303b0cfd8c11f011abbbd64601167ecca18a87e7cdd \
|
||||
--hash=sha256:cb16c65dcb648d0a43a2521f2f0a2300f40639f6f8c1ecbc662141e4e3e1ee07 \
|
||||
--hash=sha256:d2997c458c690ec2bc6b0b7ecbafd02b029b7b4283078d3b32a852a7ce3ddd98 \
|
||||
--hash=sha256:d3f82c171b4ccd83bbaf35aa05e44e690113bd4f3b7b6cc54d2219b132f3ae55 \
|
||||
--hash=sha256:dc4926288b2a3e9fd7b50dc6a1909a13bbdadfc67d93f3374d984e56f885579d \
|
||||
--hash=sha256:ead20f7913a9c1e894aebe47cccf9dc834e1618b7aa96155d2091a626e59c972 \
|
||||
--hash=sha256:ebdc36bea43063116f0486869652cb2ed7032dbc59fbcb4445c4862b5c1ecf7f \
|
||||
--hash=sha256:ed1184ab8f113e8d660ce49a56390ca181f2981066acc27cf637d5c1e10ce46e \
|
||||
--hash=sha256:ee825e70b1a209475622f7f7b776785bd68f34af6e7a46e2e42f27b659b5bc26 \
|
||||
--hash=sha256:f7ae5d65ccfbebdfa761585228eb4d0df3a8b15cfb53bd953e713e09fbb12957 \
|
||||
--hash=sha256:f7fc5a5acafb7d6ccca13bfa8c90f8c51f13d8fb87d95656d3950f0158d3ce53 \
|
||||
--hash=sha256:f9b5571d33660d5009a8b3c25dc1db560206e2d2f89d3df1cb32d72c0d117d52
|
||||
# via -r requirements.in
|
||||
psycopg==3.1.17 \
|
||||
--hash=sha256:437e7d7925459f21de570383e2e10542aceb3b9cb972ce957fdd3826ca47edc6 \
|
||||
--hash=sha256:96b7b13af6d5a514118b759a66b2799a8a4aa78675fa6bb0d3f7d52d67eff002
|
||||
# via
|
||||
# -r requirements.in
|
||||
# psycopg
|
||||
psycopg-binary==3.1.17 \
|
||||
--hash=sha256:00377f6963ee7e4bf71cab17c2c235ef0624df9483f3b615d86aa24cde889d42 \
|
||||
--hash=sha256:0227885686c2cc0104ceb22d6eebc732766e9ad48710408cb0123237432e5435 \
|
||||
--hash=sha256:02ac573f5a6e79bb6df512b3a6279f01f033bbd45c47186e8872fee45f6681d0 \
|
||||
--hash=sha256:02cd2eb62ffc56f8c847d68765cbf461b3d11b438fe48951e44b6c563ec27d18 \
|
||||
--hash=sha256:0340ef87a888fd940796c909e038426f4901046f61856598582a817162c64984 \
|
||||
--hash=sha256:0b1ec6895cab887b92c303565617f994c9b9db53befda81fa2a31b76fe8a3ab1 \
|
||||
--hash=sha256:12eab8bc91b4ba01b2ecee3b5b80501934b198f6e1f8d4b13596f3f38ba6e762 \
|
||||
--hash=sha256:267a82548c21476120e43dc72b961f1af52c380c0b4c951bdb34cf14cb26bd35 \
|
||||
--hash=sha256:2a05400e9314fc30bc1364865ba9f6eaa2def42b5e7e67f71f9a4430f870023e \
|
||||
--hash=sha256:2b2a689eaede08cf91a36b10b0da6568dd6e4669200f201e082639816737992b \
|
||||
--hash=sha256:3d0d154c780cc7b28a3a0886e8a4b18689202a1dbb522b3c771eb3a1289cf7c3 \
|
||||
--hash=sha256:3e2cc2bbf37ff1cf11e8b871c294e3532636a3cf7f0c82518b7537158923d77b \
|
||||
--hash=sha256:40af298b209dd77ca2f3e7eb3fbcfb87a25999fc015fcd14140bde030a164c7e \
|
||||
--hash=sha256:420c1eb1626539c261cf3fbe099998da73eb990f9ce1a34da7feda414012ea5f \
|
||||
--hash=sha256:4b20013051f1fd7d02b8d0766cfe8d009e8078babc00a6d39bc7e2d50a7b96af \
|
||||
--hash=sha256:4fa26836ce074a1104249378727e1f239a01530f36bae16e77cf6c50968599b4 \
|
||||
--hash=sha256:5ccbe8b2ec444763a51ecb1213befcbb75defc1ef36e7dd5dff501a23d7ce8cf \
|
||||
--hash=sha256:5f5f5bcbb772d8c243d605fc7151beec760dd27532d42145a58fb74ef9c5fbf2 \
|
||||
--hash=sha256:61104b8e7a43babf2bbaa36c08e31a12023e2f967166e99d6b052b11a4c7db06 \
|
||||
--hash=sha256:67a5b93101bc85a95a189c0a23d02a29cf06c1080a695a0dedfdd50dd734662a \
|
||||
--hash=sha256:6a728beefd89b430ebe2729d04ba10e05036b5e9d01648da60436000d2fcd242 \
|
||||
--hash=sha256:6b2ae342d69684555bfe77aed5546d125b4a99012e0b83a8b3da68c8829f0935 \
|
||||
--hash=sha256:6b40fa54a02825d3d6a8009d9a82a2b4fad80387acf2b8fd6d398fd2813cb2d9 \
|
||||
--hash=sha256:6d4f2e15d33ed4f9776fdf23683512d76f4e7825c4b80677e9e3ce6c1b193ff2 \
|
||||
--hash=sha256:6e3543edc18553e31a3884af3cd7eea43d6c44532d8b9b16f3e743cdf6cfe6c5 \
|
||||
--hash=sha256:704f6393d758b12a4369887fe956b2a8c99e4aced839d9084de8e3f056015d40 \
|
||||
--hash=sha256:73e7097b81cad9ae358334e3cec625246bb3b8013ae6bb287758dd6435e12f65 \
|
||||
--hash=sha256:751b31c2faae0348f87f22b45ef58f704bdcfc2abdd680fa0c743c124071157e \
|
||||
--hash=sha256:78ebb43dca7d5b41eee543cd005ee5a0256cecc74d84acf0fab4f025997b837e \
|
||||
--hash=sha256:7b4e4c2b05f3b431e9026e82590b217e87696e7a7548f512ae8059d59fa8af3b \
|
||||
--hash=sha256:7e28024204dc0c61094268c682041d2becfedfea2e3b46bed5f6138239304d98 \
|
||||
--hash=sha256:83404a353240fdff5cfe9080665fdfdcaa2d4d0c5112e15b0a2fe2e59200ed57 \
|
||||
--hash=sha256:86bb3656c8d744cc1e42003414cd6c765117d70aa23da6c0f4ff2b826e0fd0fd \
|
||||
--hash=sha256:8c5c38129cc79d7e3ba553035b9962a442171e9f97bb1b8795c0885213f206f3 \
|
||||
--hash=sha256:9124b6db07e8d8b11f4512b8b56cbe136bf1b7d0417d1280e62291a9dcad4408 \
|
||||
--hash=sha256:914254849486e14aa931b0b3382cd16887f1507068ffba775cbdc5a55fe9ef19 \
|
||||
--hash=sha256:92fad8f1aa80a5ab316c0493dc6d1b54c1dba21937e43eea7296ff4a0ccc071e \
|
||||
--hash=sha256:93921178b9a40c60c26e47eb44970f88c49fe484aaa3bb7ec02bb8b514eab3d9 \
|
||||
--hash=sha256:9690a535d9ccd361bbc3590bfce7fe679e847f44fa7cc97f3b885f4744ca8a2c \
|
||||
--hash=sha256:a0c4ba73f9e7721dd6cc3e6953016652dbac206f654229b7a1a8ac182b16e689 \
|
||||
--hash=sha256:a16abab0c1abc58feb6ab11d78d0f8178a67c3586bd70628ec7c0218ec04c4ef \
|
||||
--hash=sha256:a343261701a8f63f0d8268f7fd32be40ffe28d24b65d905404ca03e7281f7bb5 \
|
||||
--hash=sha256:a3f1196d76860e72d338fab0d2b6722e8d47e2285d693e366ae36011c4a5898a \
|
||||
--hash=sha256:a880e4113af3ab84d6a0991e3f85a2424924c8a182733ab8d964421df8b5190a \
|
||||
--hash=sha256:a89f36bf7b612ff6ed3e789bd987cbd0787cf0d66c49386fa3bad816dd7bee87 \
|
||||
--hash=sha256:adb670031b27949c9dc5cf585c4a5a6b4469d3879fd2fb9d39b6d53e5f66b9bc \
|
||||
--hash=sha256:b0711e46361ea3047cd049868419d030c8236a9dea7e9ed1f053cbd61a853ec9 \
|
||||
--hash=sha256:b447ea765e71bc33a82cf070bba814b1efa77967442d116b95ccef8ce5da7631 \
|
||||
--hash=sha256:bf424d92dd7e94705b31625b02d396297a7c8fab4b6f7de8dba6388323a7b71c \
|
||||
--hash=sha256:c10b7713e3ed31df7319c2a72d5fea5a2536476d7695a3e1d18a1f289060997c \
|
||||
--hash=sha256:c8a46f77ba0ca7c5a5449b777170a518fa7820e1710edb40e777c9798f00d033 \
|
||||
--hash=sha256:ca1757a6e080086f7234dc45684e81a47a66a6dd492a37d6ce38c58a1a93e9ff \
|
||||
--hash=sha256:d01c4faae66de60fcd3afd3720dcc8ffa03bc2087f898106da127774db12aac5 \
|
||||
--hash=sha256:d1c0115bdf80cf6c8c9109cb10cf6f650fd1a8d841f884925e8cb12f34eb5371 \
|
||||
--hash=sha256:d2e9ed88d9a6a475c67bf70fc8285e88ccece0391727c7701e5a512e0eafbb05 \
|
||||
--hash=sha256:d54bcf2dfc0880bf13f38512d44b194c092794e4ee9e01d804bc6cd3eed9bfb7 \
|
||||
--hash=sha256:d613a23f8928f30acb2b6b2398cb7775ba9852e8968e15df13807ba0d3ebd565 \
|
||||
--hash=sha256:d90c0531e9d591bde8cea04e75107fcddcc56811b638a34853436b23c9a3cb7d \
|
||||
--hash=sha256:dceb3930ec426623c0cacc78e447a90882981e8c49d6fea8d1e48850e24a0170 \
|
||||
--hash=sha256:e1e867c2a729348df218a14ba1b862e627177fd57c7b4f3db0b4c708f6d03696 \
|
||||
--hash=sha256:e6ae27b0617ad3809449964b5e901b21acff8e306abacb8ba71d5ee7c8c47eeb \
|
||||
--hash=sha256:ea425a8dcd808a7232a5417d2633bfa543da583a2701b5228e9e29989a50deda \
|
||||
--hash=sha256:f4028443bf25c1e04ecffdc552c0a98d826903dec76a1568dfddf5ebbbb03db7 \
|
||||
--hash=sha256:f6898bf1ca5aa01115807643138e3e20ec603b17a811026bc4a49d43055720a7 \
|
||||
--hash=sha256:f9ba559eabb0ba1afd4e0504fa0b10e00a212cac0c4028b8a1c3b087b5c1e5de
|
||||
# via psycopg
|
||||
psycopg-pool==3.2.1 \
|
||||
--hash=sha256:060b551d1b97a8d358c668be58b637780b884de14d861f4f5ecc48b7563aafb7 \
|
||||
--hash=sha256:6509a75c073590952915eddbba7ce8b8332a440a31e77bba69561483492829ad
|
||||
# via psycopg
|
||||
pycparser==2.21 \
|
||||
--hash=sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9 \
|
||||
--hash=sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206
|
||||
|
|
@ -279,4 +291,7 @@ sqlalchemy==2.0.25 \
|
|||
typing-extensions==4.9.0 \
|
||||
--hash=sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783 \
|
||||
--hash=sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd
|
||||
# via sqlalchemy
|
||||
# via
|
||||
# psycopg
|
||||
# psycopg-pool
|
||||
# sqlalchemy
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
docker==7.0.0
|
||||
jinja2==3.1.2
|
||||
kubernetes==28.1.0
|
||||
python-dotenv==1.0.0
|
||||
jinja2==3.1.3
|
||||
kubernetes==29.0.0
|
||||
python-dotenv==1.0.1
|
||||
redis==5.0.1
|
||||
urllib3<2.0.0
|
||||
|
|
|
|||
|
|
@ -114,83 +114,83 @@ 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 \
|
||||
--hash=sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e \
|
||||
--hash=sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431 \
|
||||
--hash=sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686 \
|
||||
--hash=sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c \
|
||||
--hash=sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559 \
|
||||
--hash=sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc \
|
||||
--hash=sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb \
|
||||
--hash=sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939 \
|
||||
--hash=sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c \
|
||||
--hash=sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0 \
|
||||
--hash=sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4 \
|
||||
--hash=sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9 \
|
||||
--hash=sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575 \
|
||||
--hash=sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba \
|
||||
--hash=sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d \
|
||||
--hash=sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd \
|
||||
--hash=sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3 \
|
||||
--hash=sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00 \
|
||||
--hash=sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155 \
|
||||
--hash=sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac \
|
||||
--hash=sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52 \
|
||||
--hash=sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f \
|
||||
--hash=sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8 \
|
||||
--hash=sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b \
|
||||
--hash=sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007 \
|
||||
--hash=sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24 \
|
||||
--hash=sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea \
|
||||
--hash=sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198 \
|
||||
--hash=sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0 \
|
||||
--hash=sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee \
|
||||
--hash=sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be \
|
||||
--hash=sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2 \
|
||||
--hash=sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1 \
|
||||
--hash=sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707 \
|
||||
--hash=sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6 \
|
||||
--hash=sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c \
|
||||
--hash=sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58 \
|
||||
--hash=sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823 \
|
||||
--hash=sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779 \
|
||||
--hash=sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636 \
|
||||
--hash=sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c \
|
||||
--hash=sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad \
|
||||
--hash=sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee \
|
||||
--hash=sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc \
|
||||
--hash=sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2 \
|
||||
--hash=sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48 \
|
||||
--hash=sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7 \
|
||||
--hash=sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e \
|
||||
--hash=sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b \
|
||||
--hash=sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa \
|
||||
--hash=sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5 \
|
||||
--hash=sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e \
|
||||
--hash=sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb \
|
||||
--hash=sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9 \
|
||||
--hash=sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57 \
|
||||
--hash=sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc \
|
||||
--hash=sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc \
|
||||
--hash=sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2 \
|
||||
--hash=sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11
|
||||
markupsafe==2.1.4 \
|
||||
--hash=sha256:0042d6a9880b38e1dd9ff83146cc3c9c18a059b9360ceae207805567aacccc69 \
|
||||
--hash=sha256:0c26f67b3fe27302d3a412b85ef696792c4a2386293c53ba683a89562f9399b0 \
|
||||
--hash=sha256:0fbad3d346df8f9d72622ac71b69565e621ada2ce6572f37c2eae8dacd60385d \
|
||||
--hash=sha256:15866d7f2dc60cfdde12ebb4e75e41be862348b4728300c36cdf405e258415ec \
|
||||
--hash=sha256:1c98c33ffe20e9a489145d97070a435ea0679fddaabcafe19982fe9c971987d5 \
|
||||
--hash=sha256:21e7af8091007bf4bebf4521184f4880a6acab8df0df52ef9e513d8e5db23411 \
|
||||
--hash=sha256:23984d1bdae01bee794267424af55eef4dfc038dc5d1272860669b2aa025c9e3 \
|
||||
--hash=sha256:31f57d64c336b8ccb1966d156932f3daa4fee74176b0fdc48ef580be774aae74 \
|
||||
--hash=sha256:3583a3a3ab7958e354dc1d25be74aee6228938312ee875a22330c4dc2e41beb0 \
|
||||
--hash=sha256:36d7626a8cca4d34216875aee5a1d3d654bb3dac201c1c003d182283e3205949 \
|
||||
--hash=sha256:396549cea79e8ca4ba65525470d534e8a41070e6b3500ce2414921099cb73e8d \
|
||||
--hash=sha256:3a66c36a3864df95e4f62f9167c734b3b1192cb0851b43d7cc08040c074c6279 \
|
||||
--hash=sha256:3aae9af4cac263007fd6309c64c6ab4506dd2b79382d9d19a1994f9240b8db4f \
|
||||
--hash=sha256:3ab3a886a237f6e9c9f4f7d272067e712cdb4efa774bef494dccad08f39d8ae6 \
|
||||
--hash=sha256:47bb5f0142b8b64ed1399b6b60f700a580335c8e1c57f2f15587bd072012decc \
|
||||
--hash=sha256:49a3b78a5af63ec10d8604180380c13dcd870aba7928c1fe04e881d5c792dc4e \
|
||||
--hash=sha256:4df98d4a9cd6a88d6a585852f56f2155c9cdb6aec78361a19f938810aa020954 \
|
||||
--hash=sha256:5045e892cfdaecc5b4c01822f353cf2c8feb88a6ec1c0adef2a2e705eef0f656 \
|
||||
--hash=sha256:5244324676254697fe5c181fc762284e2c5fceeb1c4e3e7f6aca2b6f107e60dc \
|
||||
--hash=sha256:54635102ba3cf5da26eb6f96c4b8c53af8a9c0d97b64bdcb592596a6255d8518 \
|
||||
--hash=sha256:54a7e1380dfece8847c71bf7e33da5d084e9b889c75eca19100ef98027bd9f56 \
|
||||
--hash=sha256:55d03fea4c4e9fd0ad75dc2e7e2b6757b80c152c032ea1d1de487461d8140efc \
|
||||
--hash=sha256:698e84142f3f884114ea8cf83e7a67ca8f4ace8454e78fe960646c6c91c63bfa \
|
||||
--hash=sha256:6aa5e2e7fc9bc042ae82d8b79d795b9a62bd8f15ba1e7594e3db243f158b5565 \
|
||||
--hash=sha256:7653fa39578957bc42e5ebc15cf4361d9e0ee4b702d7d5ec96cdac860953c5b4 \
|
||||
--hash=sha256:765f036a3d00395a326df2835d8f86b637dbaf9832f90f5d196c3b8a7a5080cb \
|
||||
--hash=sha256:78bc995e004681246e85e28e068111a4c3f35f34e6c62da1471e844ee1446250 \
|
||||
--hash=sha256:7a07f40ef8f0fbc5ef1000d0c78771f4d5ca03b4953fc162749772916b298fc4 \
|
||||
--hash=sha256:8b570a1537367b52396e53325769608f2a687ec9a4363647af1cded8928af959 \
|
||||
--hash=sha256:987d13fe1d23e12a66ca2073b8d2e2a75cec2ecb8eab43ff5624ba0ad42764bc \
|
||||
--hash=sha256:9896fca4a8eb246defc8b2a7ac77ef7553b638e04fbf170bff78a40fa8a91474 \
|
||||
--hash=sha256:9e9e3c4020aa2dc62d5dd6743a69e399ce3de58320522948af6140ac959ab863 \
|
||||
--hash=sha256:a0b838c37ba596fcbfca71651a104a611543077156cb0a26fe0c475e1f152ee8 \
|
||||
--hash=sha256:a4d176cfdfde84f732c4a53109b293d05883e952bbba68b857ae446fa3119b4f \
|
||||
--hash=sha256:a76055d5cb1c23485d7ddae533229039b850db711c554a12ea64a0fd8a0129e2 \
|
||||
--hash=sha256:a76cd37d229fc385738bd1ce4cba2a121cf26b53864c1772694ad0ad348e509e \
|
||||
--hash=sha256:a7cc49ef48a3c7a0005a949f3c04f8baa5409d3f663a1b36f0eba9bfe2a0396e \
|
||||
--hash=sha256:abf5ebbec056817057bfafc0445916bb688a255a5146f900445d081db08cbabb \
|
||||
--hash=sha256:b0fe73bac2fed83839dbdbe6da84ae2a31c11cfc1c777a40dbd8ac8a6ed1560f \
|
||||
--hash=sha256:b6f14a9cd50c3cb100eb94b3273131c80d102e19bb20253ac7bd7336118a673a \
|
||||
--hash=sha256:b83041cda633871572f0d3c41dddd5582ad7d22f65a72eacd8d3d6d00291df26 \
|
||||
--hash=sha256:b835aba863195269ea358cecc21b400276747cc977492319fd7682b8cd2c253d \
|
||||
--hash=sha256:bf1196dcc239e608605b716e7b166eb5faf4bc192f8a44b81e85251e62584bd2 \
|
||||
--hash=sha256:c669391319973e49a7c6230c218a1e3044710bc1ce4c8e6eb71f7e6d43a2c131 \
|
||||
--hash=sha256:c7556bafeaa0a50e2fe7dc86e0382dea349ebcad8f010d5a7dc6ba568eaaa789 \
|
||||
--hash=sha256:c8f253a84dbd2c63c19590fa86a032ef3d8cc18923b8049d91bcdeeb2581fbf6 \
|
||||
--hash=sha256:d18b66fe626ac412d96c2ab536306c736c66cf2a31c243a45025156cc190dc8a \
|
||||
--hash=sha256:d5291d98cd3ad9a562883468c690a2a238c4a6388ab3bd155b0c75dd55ece858 \
|
||||
--hash=sha256:d5c31fe855c77cad679b302aabc42d724ed87c043b1432d457f4976add1c2c3e \
|
||||
--hash=sha256:d6e427c7378c7f1b2bef6a344c925b8b63623d3321c09a237b7cc0e77dd98ceb \
|
||||
--hash=sha256:dac1ebf6983148b45b5fa48593950f90ed6d1d26300604f321c74a9ca1609f8e \
|
||||
--hash=sha256:de8153a7aae3835484ac168a9a9bdaa0c5eee4e0bc595503c95d53b942879c84 \
|
||||
--hash=sha256:e1a0d1924a5013d4f294087e00024ad25668234569289650929ab871231668e7 \
|
||||
--hash=sha256:e7902211afd0af05fbadcc9a312e4cf10f27b779cf1323e78d52377ae4b72bea \
|
||||
--hash=sha256:e888ff76ceb39601c59e219f281466c6d7e66bd375b4ec1ce83bcdc68306796b \
|
||||
--hash=sha256:f06e5a9e99b7df44640767842f414ed5d7bedaaa78cd817ce04bbd6fd86e2dd6 \
|
||||
--hash=sha256:f6be2d708a9d0e9b0054856f07ac7070fbe1754be40ca8525d5adccdbda8f475 \
|
||||
--hash=sha256:f9917691f410a2e0897d1ef99619fd3f7dd503647c8ff2475bf90c3cf222ad74 \
|
||||
--hash=sha256:fc1a75aa8f11b87910ffd98de62b29d6520b6d6e8a3de69a70ca34dea85d2a8a \
|
||||
--hash=sha256:fe8512ed897d5daf089e5bd010c3dc03bb1bdae00b35588c49b98268d4a01e00
|
||||
# via jinja2
|
||||
oauthlib==3.2.2 \
|
||||
--hash=sha256:8139f29aac13e25d502680e9e19963e83f16838d48a0d71c287fe40e7067fbca \
|
||||
|
|
@ -216,9 +216,9 @@ python-dateutil==2.8.2 \
|
|||
--hash=sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86 \
|
||||
--hash=sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9
|
||||
# via kubernetes
|
||||
python-dotenv==1.0.0 \
|
||||
--hash=sha256:a8df96034aae6d2d50a4ebe8216326c61c3eb64836776504fcca410e5937a3ba \
|
||||
--hash=sha256:f5971a9226b701070a4bf2c38c89e5a3f0d64de8debda981d1db98583009122a
|
||||
python-dotenv==1.0.1 \
|
||||
--hash=sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca \
|
||||
--hash=sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a
|
||||
# via -r requirements.in
|
||||
pyyaml==6.0.1 \
|
||||
--hash=sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5 \
|
||||
|
|
@ -250,6 +250,7 @@ pyyaml==6.0.1 \
|
|||
--hash=sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4 \
|
||||
--hash=sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba \
|
||||
--hash=sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8 \
|
||||
--hash=sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef \
|
||||
--hash=sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5 \
|
||||
--hash=sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd \
|
||||
--hash=sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3 \
|
||||
|
|
@ -297,11 +298,10 @@ six==1.16.0 \
|
|||
# via
|
||||
# kubernetes
|
||||
# python-dateutil
|
||||
urllib3==1.26.18 \
|
||||
--hash=sha256:34b97092d7e0a3a8cf7cd10e386f401b3737364026c45e622aa02903dffe0f07 \
|
||||
--hash=sha256:f8ecc1bba5667413457c529ab955bf8c67b45db799d159066261719e328580a0
|
||||
urllib3==2.1.0 \
|
||||
--hash=sha256:55901e917a5896a349ff771be919f8bd99aff50b79fe58fec595eb37bbc56bb3 \
|
||||
--hash=sha256:df7aa8afb0148fa78488e7899b2c59b5f4ffcfa82e6c54ccb9dd37c1d7b52d54
|
||||
# via
|
||||
# -r requirements.in
|
||||
# docker
|
||||
# kubernetes
|
||||
# requests
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ from hashlib import sha512
|
|||
from inspect import getsourcefile
|
||||
from io import BufferedReader
|
||||
from json import dumps, loads
|
||||
from os.path import basename, normpath
|
||||
from os.path import basename
|
||||
from pathlib import Path
|
||||
from sys import _getframe
|
||||
from threading import Lock
|
||||
|
|
@ -28,17 +28,19 @@ def is_cached_file(
|
|||
expire: Union[Literal["hour"], Literal["day"], Literal["week"], Literal["month"]],
|
||||
db=None,
|
||||
) -> bool:
|
||||
if not isinstance(file, Path):
|
||||
file = Path(file)
|
||||
|
||||
is_cached = False
|
||||
cached_file = None
|
||||
try:
|
||||
file = normpath(file)
|
||||
file_path = Path(f"{file}.md")
|
||||
if not file_path.is_file():
|
||||
if not db:
|
||||
return False
|
||||
cached_file = db.get_job_cache_file(
|
||||
basename(getsourcefile(_getframe(1))).replace(".py", ""),
|
||||
basename(file),
|
||||
file.name,
|
||||
with_info=True,
|
||||
)
|
||||
|
||||
|
|
@ -65,16 +67,13 @@ def is_cached_file(
|
|||
is_cached = False
|
||||
|
||||
if is_cached and cached_file:
|
||||
Path(file).write_bytes(cached_file.data)
|
||||
file.write_bytes(cached_file.data)
|
||||
|
||||
return is_cached and cached_file
|
||||
|
||||
|
||||
def get_file_in_db(file: Union[str, Path], db, *, job_name: Optional[str] = None) -> Optional[bytes]:
|
||||
cached_file = db.get_job_cache_file(
|
||||
job_name or basename(getsourcefile(_getframe(1))).replace(".py", ""),
|
||||
normpath(file),
|
||||
)
|
||||
cached_file = db.get_job_cache_file(job_name or basename(getsourcefile(_getframe(1))).replace(".py", ""), file)
|
||||
if not cached_file:
|
||||
return None
|
||||
return cached_file.data
|
||||
|
|
@ -107,10 +106,10 @@ def set_file_in_db(
|
|||
return ret, err
|
||||
|
||||
|
||||
def del_file_in_db(name: str, db) -> Tuple[bool, str]:
|
||||
def del_file_in_db(name: str, db, *, service_id: Optional[str] = None) -> Tuple[bool, str]:
|
||||
ret, err = True, "success"
|
||||
try:
|
||||
db.delete_job_cache(name, job_name=basename(getsourcefile(_getframe(1))).replace(".py", ""))
|
||||
db.delete_job_cache(name, job_name=basename(getsourcefile(_getframe(1))).replace(".py", ""), service_id=service_id)
|
||||
except:
|
||||
return False, f"exception :\n{format_exc()}"
|
||||
return ret, err
|
||||
|
|
@ -118,7 +117,10 @@ def del_file_in_db(name: str, db) -> Tuple[bool, str]:
|
|||
|
||||
def file_hash(file: Union[str, Path]) -> str:
|
||||
_sha512 = sha512()
|
||||
with open(normpath(file), "rb") as f:
|
||||
if not isinstance(file, Path):
|
||||
file = Path(file)
|
||||
|
||||
with file.open("rb") as f:
|
||||
while True:
|
||||
data = f.read(1024)
|
||||
if not data:
|
||||
|
|
@ -139,18 +141,24 @@ def bytes_hash(bio: BufferedReader) -> str:
|
|||
|
||||
|
||||
def cache_hash(cache: Union[str, Path], db=None) -> Optional[str]:
|
||||
checksum = None
|
||||
with suppress(BaseException):
|
||||
return loads(Path(normpath(f"{cache}.md")).read_text(encoding="utf-8")).get("checksum", None)
|
||||
if db:
|
||||
checksum = loads(Path(f"{cache}.md").read_text(encoding="utf-8")).get("checksum", None)
|
||||
|
||||
if not checksum and db:
|
||||
if not isinstance(cache, Path):
|
||||
cache = Path(cache)
|
||||
|
||||
cached_file = db.get_job_cache_file(
|
||||
basename(getsourcefile(_getframe(1))).replace(".py", ""),
|
||||
basename(normpath(cache)),
|
||||
cache.name,
|
||||
with_info=True,
|
||||
with_data=False,
|
||||
)
|
||||
checksum = cached_file.checksum if cached_file else None
|
||||
|
||||
if cached_file:
|
||||
return cached_file.checksum
|
||||
if checksum:
|
||||
return checksum
|
||||
return None
|
||||
|
||||
|
||||
|
|
@ -166,9 +174,9 @@ def cache_file(
|
|||
ret, err = True, "success"
|
||||
try:
|
||||
if not isinstance(file, Path):
|
||||
file = Path(normpath(file))
|
||||
file = Path(file)
|
||||
if not isinstance(cache, Path):
|
||||
cache = Path(normpath(cache))
|
||||
cache = Path(cache)
|
||||
|
||||
content = file.read_bytes()
|
||||
cache.write_bytes(content)
|
||||
|
|
@ -181,7 +189,7 @@ def cache_file(
|
|||
|
||||
if db:
|
||||
return set_file_in_db(
|
||||
basename(str(cache)),
|
||||
cache.name,
|
||||
content,
|
||||
db,
|
||||
job_name=basename(getsourcefile(_getframe(1))).replace(".py", ""),
|
||||
|
|
|
|||
|
|
@ -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,15 +225,15 @@
|
|||
},
|
||||
{
|
||||
"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",
|
||||
"name": "zlib v1.3",
|
||||
"name": "zlib v1.3.1",
|
||||
"url": "https://github.com/madler/zlib.git",
|
||||
"commit": "09155eaa2f9270dc4ed1fa13e2b4b2613e6e4851"
|
||||
"commit": "51b7f2abdade71cd9bb0e7a373ef2610ec6f9daf"
|
||||
},
|
||||
{
|
||||
"id": "lua-resty-redis-connector",
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
10
src/deps/src/libmaxminddb/CMakeLists.txt
vendored
10
src/deps/src/libmaxminddb/CMakeLists.txt
vendored
|
|
@ -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}")
|
||||
|
||||
|
|
|
|||
16
src/deps/src/libmaxminddb/Changes.md
vendored
16
src/deps/src/libmaxminddb/Changes.md
vendored
|
|
@ -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
|
||||
|
|
|
|||
2
src/deps/src/libmaxminddb/configure.ac
vendored
2
src/deps/src/libmaxminddb/configure.ac
vendored
|
|
@ -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])
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
4
src/deps/src/libmaxminddb/src/data-pool.c
vendored
4
src/deps/src/libmaxminddb/src/data-pool.c
vendored
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
1
src/deps/src/libmaxminddb/src/data-pool.h
vendored
1
src/deps/src/libmaxminddb/src/data-pool.h
vendored
|
|
@ -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);
|
||||
|
|
|
|||
33
src/deps/src/libmaxminddb/src/maxminddb.c
vendored
33
src/deps/src/libmaxminddb/src/maxminddb.c
vendored
|
|
@ -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,
|
||||
|
|
|
|||
2
src/deps/src/libmaxminddb/t/libtap
vendored
2
src/deps/src/libmaxminddb/t/libtap
vendored
|
|
@ -1 +1 @@
|
|||
Subproject commit 56e31231e0329b202c978c676e4a897c857c7a1f
|
||||
Subproject commit b53e4ef5257f80e881762b6143834d8aae29da1a
|
||||
60
src/deps/src/lua-nginx-module/.travis.yml
vendored
60
src/deps/src/lua-nginx-module/.travis.yml
vendored
|
|
@ -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
|
||||
|
|
|
|||
76
src/deps/src/lua-nginx-module/README.markdown
vendored
76
src/deps/src/lua-nginx-module/README.markdown
vendored
|
|
@ -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 <file>*
|
||||
|
||||
**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 <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](#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 <file>*
|
||||
|
||||
**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*, 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](#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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 | ------------------------------------
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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: */
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue