mirror of
https://github.com/bunkerity/bunkerweb
synced 2026-05-24 09:28:37 +00:00
Soft merge branch 'dev' into branch '1.6'
This commit is contained in:
commit
d1ca342332
209 changed files with 2571 additions and 1825 deletions
2
.github/workflows/beta.yml
vendored
2
.github/workflows/beta.yml
vendored
|
|
@ -133,7 +133,7 @@ jobs:
|
|||
versionrpm: ${{ steps.getversionrpm.outputs.versionrpm }}
|
||||
steps:
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
- name: Get VERSION
|
||||
id: getversion
|
||||
run: echo "version=$(cat src/VERSION | tr -d '\n')" >> "$GITHUB_OUTPUT"
|
||||
|
|
|
|||
6
.github/workflows/codeql.yml
vendored
6
.github/workflows/codeql.yml
vendored
|
|
@ -19,7 +19,7 @@ jobs:
|
|||
language: ["python", "javascript"]
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
- name: Set up Python 3.9
|
||||
uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0
|
||||
if: matrix.language == 'python'
|
||||
|
|
@ -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@2e230e8fe0ad3a14a340ad0815ddb96d599d2aff # v3.25.8
|
||||
uses: github/codeql-action/init@23acc5c183826b7a8a97bce3cecc52db901f8251 # v3.25.10
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
config-file: ./.github/codeql.yml
|
||||
setup-python-dependencies: false
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@2e230e8fe0ad3a14a340ad0815ddb96d599d2aff # v3.25.8
|
||||
uses: github/codeql-action/analyze@23acc5c183826b7a8a97bce3cecc52db901f8251 # v3.25.10
|
||||
with:
|
||||
category: "/language:${{matrix.language}}"
|
||||
|
|
|
|||
6
.github/workflows/container-build.yml
vendored
6
.github/workflows/container-build.yml
vendored
|
|
@ -45,7 +45,7 @@ jobs:
|
|||
steps:
|
||||
# Prepare
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
- name: Replace VERSION
|
||||
if: inputs.RELEASE == 'testing' || inputs.RELEASE == 'dev'
|
||||
run: ./misc/update-version.sh ${{ inputs.RELEASE }}
|
||||
|
|
@ -92,7 +92,7 @@ jobs:
|
|||
# Build cached image
|
||||
- name: Build image
|
||||
if: inputs.CACHE == true
|
||||
uses: docker/build-push-action@2cdde995de11925a030ce8070c3d77a52ffcf1c0 # v5.3.0
|
||||
uses: docker/build-push-action@ca052bb54ab0790a636c9b5f226502c73d547a25 # v5.4.0
|
||||
with:
|
||||
context: .
|
||||
file: ${{ inputs.DOCKERFILE }}
|
||||
|
|
@ -105,7 +105,7 @@ jobs:
|
|||
# Build non-cached image
|
||||
- name: Build image
|
||||
if: inputs.CACHE != true
|
||||
uses: docker/build-push-action@2cdde995de11925a030ce8070c3d77a52ffcf1c0 # v5.3.0
|
||||
uses: docker/build-push-action@ca052bb54ab0790a636c9b5f226502c73d547a25 # v5.4.0
|
||||
with:
|
||||
context: .
|
||||
file: ${{ inputs.DOCKERFILE }}
|
||||
|
|
|
|||
2
.github/workflows/create-arm.yml
vendored
2
.github/workflows/create-arm.yml
vendored
|
|
@ -33,7 +33,7 @@ jobs:
|
|||
steps:
|
||||
# Prepare
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
- name: Get ARM availabilities
|
||||
id: availabilities
|
||||
uses: scaleway/action-scw@be2696f261325a78354eda14988c80405f33e082
|
||||
|
|
|
|||
2
.github/workflows/dev-update-mmdb.yml
vendored
2
.github/workflows/dev-update-mmdb.yml
vendored
|
|
@ -12,7 +12,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
with:
|
||||
fetch-depth: 0
|
||||
token: ${{ secrets.BUNKERBOT_TOKEN }}
|
||||
|
|
|
|||
4
.github/workflows/dev.yml
vendored
4
.github/workflows/dev.yml
vendored
|
|
@ -80,7 +80,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
- id: set-matrix
|
||||
run: |
|
||||
tests=$(find ./tests/ui/ -name "*_page.py" -type f -printf "%f\n" | jq -c --raw-input --slurp 'split("\n")| .[0:-1]')
|
||||
|
|
@ -113,7 +113,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
- id: set-matrix
|
||||
run: |
|
||||
tests=$(find ./tests/core/ -maxdepth 1 -mindepth 1 -type d -printf "%f\n" | jq -c --raw-input --slurp 'split("\n")| .[0:-1]')
|
||||
|
|
|
|||
2
.github/workflows/doc-to-pdf.yml
vendored
2
.github/workflows/doc-to-pdf.yml
vendored
|
|
@ -13,7 +13,7 @@ jobs:
|
|||
steps:
|
||||
# Prepare
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
- name: Install Python
|
||||
uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0
|
||||
with:
|
||||
|
|
|
|||
8
.github/workflows/linux-build.yml
vendored
8
.github/workflows/linux-build.yml
vendored
|
|
@ -37,7 +37,7 @@ jobs:
|
|||
steps:
|
||||
# Prepare
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
- name: Replace VERSION
|
||||
if: inputs.RELEASE == 'testing' || inputs.RELEASE == 'dev' || inputs.RELEASE == 'ui'
|
||||
run: ./misc/update-version.sh ${{ inputs.RELEASE }}
|
||||
|
|
@ -94,7 +94,7 @@ jobs:
|
|||
# Build testing package image
|
||||
- name: Build package image
|
||||
if: inputs.RELEASE == 'testing' || inputs.RELEASE == 'dev' || inputs.RELEASE == 'ui'
|
||||
uses: docker/build-push-action@2cdde995de11925a030ce8070c3d77a52ffcf1c0 # v5.3.0
|
||||
uses: docker/build-push-action@ca052bb54ab0790a636c9b5f226502c73d547a25 # v5.4.0
|
||||
with:
|
||||
context: .
|
||||
load: true
|
||||
|
|
@ -106,7 +106,7 @@ jobs:
|
|||
# Build non-testing package image
|
||||
- name: Build package image
|
||||
if: inputs.RELEASE != 'testing' && inputs.RELEASE != 'dev'
|
||||
uses: docker/build-push-action@2cdde995de11925a030ce8070c3d77a52ffcf1c0 # v5.3.0
|
||||
uses: docker/build-push-action@ca052bb54ab0790a636c9b5f226502c73d547a25 # v5.4.0
|
||||
with:
|
||||
context: .
|
||||
load: true
|
||||
|
|
@ -142,7 +142,7 @@ jobs:
|
|||
images: ghcr.io/bunkerity/${{ inputs.LINUX }}-tests:${{ inputs.RELEASE }}
|
||||
- name: Build test image
|
||||
if: inputs.TEST == true
|
||||
uses: docker/build-push-action@2cdde995de11925a030ce8070c3d77a52ffcf1c0 # v5.3.0
|
||||
uses: docker/build-push-action@ca052bb54ab0790a636c9b5f226502c73d547a25 # v5.4.0
|
||||
with:
|
||||
context: .
|
||||
file: tests/linux/Dockerfile-${{ inputs.LINUX }}
|
||||
|
|
|
|||
2
.github/workflows/push-doc.yml
vendored
2
.github/workflows/push-doc.yml
vendored
|
|
@ -18,7 +18,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
with:
|
||||
fetch-depth: 0
|
||||
token: ${{ secrets.BUNKERBOT_TOKEN }}
|
||||
|
|
|
|||
4
.github/workflows/push-docker.yml
vendored
4
.github/workflows/push-docker.yml
vendored
|
|
@ -33,7 +33,7 @@ jobs:
|
|||
steps:
|
||||
# Prepare
|
||||
- name: Check out repository code
|
||||
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@0d4c9c5ea7693da7b068278f7b52bda2a190a446 # v3.2.0
|
||||
with:
|
||||
|
|
@ -70,7 +70,7 @@ jobs:
|
|||
images: bunkerity/${{ inputs.IMAGE }}
|
||||
# Build and push
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@2cdde995de11925a030ce8070c3d77a52ffcf1c0 # v5.3.0
|
||||
uses: docker/build-push-action@ca052bb54ab0790a636c9b5f226502c73d547a25 # v5.4.0
|
||||
with:
|
||||
context: .
|
||||
file: ${{ inputs.DOCKERFILE }}
|
||||
|
|
|
|||
2
.github/workflows/push-github.yml
vendored
2
.github/workflows/push-github.yml
vendored
|
|
@ -15,7 +15,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# Checkout
|
||||
- uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
||||
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
# Get PDF doc
|
||||
- name: Get documentation
|
||||
if: inputs.VERSION != 'testing'
|
||||
|
|
|
|||
4
.github/workflows/push-packagecloud.yml
vendored
4
.github/workflows/push-packagecloud.yml
vendored
|
|
@ -40,9 +40,9 @@ jobs:
|
|||
steps:
|
||||
# Prepare
|
||||
- name: Check out repository code
|
||||
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
- name: Install ruby
|
||||
uses: ruby/setup-ruby@d5fb7a202fc07872cb44f00ba8e6197b70cb0c55 # v1.179.0
|
||||
uses: ruby/setup-ruby@ff740bc00a01b3a50fffc55a1071b1060eeae9dc # v1.180.0
|
||||
with:
|
||||
ruby-version: "3.0"
|
||||
- name: Install packagecloud
|
||||
|
|
|
|||
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
|
|
@ -143,7 +143,7 @@ jobs:
|
|||
versionrpm: ${{ steps.getversionrpm.outputs.versionrpm }}
|
||||
steps:
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
- name: Get VERSION
|
||||
id: getversion
|
||||
run: echo "version=$(cat src/VERSION | tr -d '\n')" >> "$GITHUB_OUTPUT"
|
||||
|
|
|
|||
2
.github/workflows/rm-arm.yml
vendored
2
.github/workflows/rm-arm.yml
vendored
|
|
@ -21,7 +21,7 @@ jobs:
|
|||
steps:
|
||||
# Prepare
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
- name: Delete ARM VM
|
||||
uses: scaleway/action-scw@be2696f261325a78354eda14988c80405f33e082
|
||||
with:
|
||||
|
|
|
|||
4
.github/workflows/scorecards-analysis.yml
vendored
4
.github/workflows/scorecards-analysis.yml
vendored
|
|
@ -15,7 +15,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: "Checkout code"
|
||||
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: "Run analysis"
|
||||
|
|
@ -25,6 +25,6 @@ jobs:
|
|||
results_format: sarif
|
||||
publish_results: true
|
||||
- name: "Upload SARIF results to code scanning"
|
||||
uses: github/codeql-action/upload-sarif@2e230e8fe0ad3a14a340ad0815ddb96d599d2aff # v3.25.8
|
||||
uses: github/codeql-action/upload-sarif@23acc5c183826b7a8a97bce3cecc52db901f8251 # v3.25.10
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
|
|
|
|||
2
.github/workflows/staging-create-infra.yml
vendored
2
.github/workflows/staging-create-infra.yml
vendored
|
|
@ -21,7 +21,7 @@ jobs:
|
|||
run: ssh-keygen -b 2048 -t rsa -f ~/.ssh/id_rsa -q -N "" && ssh-keygen -f ~/.ssh/id_rsa -y > ~/.ssh/id_rsa.pub && echo -e "Host *\n StrictHostKeyChecking no" > ~/.ssh/ssh_config
|
||||
if: inputs.TYPE != 'k8s'
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
- name: Install terraform
|
||||
uses: hashicorp/setup-terraform@651471c36a6092792c552e8b1bef71e592b462d8 # v3.1.1
|
||||
- name: Install kubectl
|
||||
|
|
|
|||
2
.github/workflows/staging-delete-infra.yml
vendored
2
.github/workflows/staging-delete-infra.yml
vendored
|
|
@ -20,7 +20,7 @@ jobs:
|
|||
steps:
|
||||
# Prepare
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
- name: Install terraform
|
||||
uses: hashicorp/setup-terraform@651471c36a6092792c552e8b1bef71e592b462d8 # v3.1.1
|
||||
- uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4.1.7
|
||||
|
|
|
|||
2
.github/workflows/staging-tests.yml
vendored
2
.github/workflows/staging-tests.yml
vendored
|
|
@ -25,7 +25,7 @@ jobs:
|
|||
steps:
|
||||
# Prepare
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
- name: Login to ghcr
|
||||
uses: docker/login-action@0d4c9c5ea7693da7b068278f7b52bda2a190a446 # v3.2.0
|
||||
with:
|
||||
|
|
|
|||
4
.github/workflows/staging.yml
vendored
4
.github/workflows/staging.yml
vendored
|
|
@ -91,7 +91,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
- id: set-matrix
|
||||
run: |
|
||||
tests=$(find ./tests/core/ -maxdepth 1 -mindepth 1 -type d -printf "%f\n" | jq -c --raw-input --slurp 'split("\n")| .[0:-1]')
|
||||
|
|
@ -102,7 +102,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
- id: set-matrix
|
||||
run: |
|
||||
tests=$(find ./tests/ui/ -name "*_page.py" -type f -printf "%f\n" | jq -c --raw-input --slurp 'split("\n")| .[0:-1]')
|
||||
|
|
|
|||
2
.github/workflows/test-core-linux.yml
vendored
2
.github/workflows/test-core-linux.yml
vendored
|
|
@ -16,7 +16,7 @@ jobs:
|
|||
steps:
|
||||
# Prepare
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
- name: Set up Python 3.12
|
||||
uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0
|
||||
with:
|
||||
|
|
|
|||
2
.github/workflows/test-core.yml
vendored
2
.github/workflows/test-core.yml
vendored
|
|
@ -16,7 +16,7 @@ jobs:
|
|||
steps:
|
||||
# Prepare
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
- name: Login to ghcr
|
||||
uses: docker/login-action@0d4c9c5ea7693da7b068278f7b52bda2a190a446 # v3.2.0
|
||||
with:
|
||||
|
|
|
|||
2
.github/workflows/tests-ui-linux.yml
vendored
2
.github/workflows/tests-ui-linux.yml
vendored
|
|
@ -16,7 +16,7 @@ jobs:
|
|||
steps:
|
||||
# Prepare
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
- name: Set up Python 3.12
|
||||
uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0
|
||||
with:
|
||||
|
|
|
|||
2
.github/workflows/tests-ui.yml
vendored
2
.github/workflows/tests-ui.yml
vendored
|
|
@ -15,7 +15,7 @@ jobs:
|
|||
steps:
|
||||
# Prepare
|
||||
- name: Checkout source code
|
||||
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
- name: Login to ghcr
|
||||
uses: docker/login-action@0d4c9c5ea7693da7b068278f7b52bda2a190a446 # v3.2.0
|
||||
with:
|
||||
|
|
|
|||
2
.github/workflows/ui.yml
vendored
2
.github/workflows/ui.yml
vendored
|
|
@ -67,7 +67,7 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
- id: set-matrix
|
||||
run: |
|
||||
tests=$(find ./tests/ui/ -name "*_page.py" -type f -printf "%f\n" | jq -c --raw-input --slurp 'split("\n")| .[0:-1]')
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ src/ui/templates/settings_plugins.html:hashicorp-tf-password:297
|
|||
src/ui/templates/settings_plugins.html:hashicorp-tf-password:106
|
||||
src/ui/templates/account.html:hashicorp-tf-password:154
|
||||
src/ui/templates/account.html:hashicorp-tf-password:162
|
||||
src/ui/templates/setup_loading.html:aws-access-token:14
|
||||
src/common/core/errors/files/error.html:aws-access-token:20
|
||||
src/deps/src/nginx/src/event/quic/ngx_event_quic_protection.c:generic-api-key:164
|
||||
src/deps/src/nginx/src/event/quic/ngx_event_quic_protection.c:generic-api-key:165
|
||||
|
|
|
|||
|
|
@ -15,8 +15,10 @@
|
|||
- [FEATURE] Add experimental support of HTTP/3 (QUIC)
|
||||
- [FEATURE] Optimize the way the scheduler handles jobs and the way the jobs are executed
|
||||
- [FEATURE] Optimize the way the cache files are being refreshed from the database
|
||||
- [FEATURE] Add failover logic in case the NGINX configuration is not valid to fallback to the previous configuration and log the error to prevent the service from being stopped
|
||||
- [UI] Force HTTPS on setup wizard
|
||||
- [UI] Fallback to self-signed certificate when UI is installed with setup wizard and let's encrypt is not used
|
||||
- [UI] Force HTTPS even if UI is installed in advanced mode
|
||||
- [UI] Add OVERRIDE_ADMIN_CREDS environment variable to allow overriding the default admin credentials even if an admin user already exists
|
||||
- [UI] Optimize the way the UI handles the requests and the responses
|
||||
- [AUTOCONF] Refactor Autoconf config parsing and saving logic so that it doesn't override the scheduler or UI config every time
|
||||
|
|
|
|||
13
README.md
13
README.md
|
|
@ -86,6 +86,19 @@ Learn more about the core security features in the [security tuning](https://doc
|
|||
|
||||
A demo website protected with BunkerWeb is available at [demo.bunkerweb.io](https://demo.bunkerweb.io/?utm_campaign=self&utm_source=github). Feel free to visit it and perform some security tests.
|
||||
|
||||
## BunkerWeb Cloud
|
||||
|
||||
Don't want to self-host and manage your own BunkerWeb instance(s) ? You might be interested into BunkerWeb Cloud, our fully managed SaaS offer for BunkerWeb.
|
||||
|
||||
Try our [BunkerWeb Cloud beta offer for free](https://panel.bunkerweb.io/order/bunkerweb-cloud/14?utm_source=github&utm_campaign=self) and get access to :
|
||||
|
||||
- Fully managed BunkerWeb instance hosted in our cloud
|
||||
- All BunkerWeb features including PRO ones
|
||||
- Monitoring platform including dashboards and alerts
|
||||
- Technical support to assist you in the configuration
|
||||
|
||||
You will find more information about BunkerWeb Cloud in the [FAQ page](https://panel.bunkerweb.io/knowledgebase/55/BunkerWeb-Cloud?utm_source=github&utm_campaign=self) of the BunkerWeb panel.
|
||||
|
||||
## PRO version
|
||||
|
||||
When using BunkerWeb you have the choice of the version you want to use : open-source or PRO.
|
||||
|
|
|
|||
|
|
@ -59,6 +59,19 @@ To delve deeper into the core security features, we invite you to explore the [s
|
|||
|
||||
A demo website protected with BunkerWeb is available at [demo.bunkerweb.io](https://demo.bunkerweb.io/?utm_campaign=self&utm_source=doc). Feel free to visit it and perform some security tests.
|
||||
|
||||
## BunkerWeb Cloud
|
||||
|
||||
Don't want to self-host and manage your own BunkerWeb instance(s) ? You might be interested into BunkerWeb Cloud, our fully managed SaaS offer for BunkerWeb.
|
||||
|
||||
Try our [BunkerWeb Cloud beta offer for free](https://panel.bunkerweb.io/order/bunkerweb-cloud/14?utm_source=doc&utm_campaign=self) and get access to :
|
||||
|
||||
- Fully managed BunkerWeb instance hosted in our cloud
|
||||
- All BunkerWeb features including PRO ones
|
||||
- Monitoring platform including dashboards and alerts
|
||||
- Technical support to assist you in the configuration
|
||||
|
||||
You will find more information about BunkerWeb Cloud in the [FAQ page](https://panel.bunkerweb.io/knowledgebase/55/BunkerWeb-Cloud?utm_source=doc&utm_campaign=self) of the BunkerWeb panel.
|
||||
|
||||
## PRO version
|
||||
|
||||
When using BunkerWeb you have the choice of the version you want to use : open-source or PRO.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
mike==2.1.1
|
||||
mkdocs-material[imaging]==9.5.26
|
||||
mkdocs-material[imaging]==9.5.27
|
||||
mkdocs-print-site-plugin==2.5.0
|
||||
pytablewriter==1.2.0
|
||||
|
|
|
|||
|
|
@ -317,9 +317,9 @@ mkdocs-get-deps==0.2.0 \
|
|||
--hash=sha256:162b3d129c7fad9b19abfdcb9c1458a651628e4b1dea628ac68790fb3061c60c \
|
||||
--hash=sha256:2bf11d0b133e77a0dd036abeeb06dec8775e46efa526dc70667d8863eefc6134
|
||||
# via mkdocs
|
||||
mkdocs-material==9.5.26 \
|
||||
--hash=sha256:56aeb91d94cffa43b6296fa4fbf0eb7c840136e563eecfd12c2d9e92e50ba326 \
|
||||
--hash=sha256:5d01fb0aa1c7946a1e3ae8689aa2b11a030621ecb54894e35aabb74c21016312
|
||||
mkdocs-material==9.5.27 \
|
||||
--hash=sha256:a7d4a35f6d4a62b0c43a0cfe7e987da0980c13587b5bc3c26e690ad494427ec0 \
|
||||
--hash=sha256:af8cc263fafa98bb79e9e15a8c966204abf15164987569bd1175fd66a7705182
|
||||
# via
|
||||
# -r requirements.in
|
||||
# mkdocs-print-site-plugin
|
||||
|
|
@ -331,9 +331,9 @@ mkdocs-print-site-plugin==2.5.0 \
|
|||
--hash=sha256:48b3d41ae80384de72062b2712fce677f2e46d8364d9fe603ba837b0cf7156a4 \
|
||||
--hash=sha256:95dccc8d5cc8a59da67815a2d3304ef0101b065e363f2b9ac919c23d6196dd24
|
||||
# via -r requirements.in
|
||||
packaging==24.0 \
|
||||
--hash=sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5 \
|
||||
--hash=sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9
|
||||
packaging==24.1 \
|
||||
--hash=sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002 \
|
||||
--hash=sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124
|
||||
# via
|
||||
# mkdocs
|
||||
# typepy
|
||||
|
|
@ -637,9 +637,9 @@ typepy==1.3.2 \
|
|||
# dataproperty
|
||||
# pytablewriter
|
||||
# tabledata
|
||||
urllib3==2.2.1 \
|
||||
--hash=sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d \
|
||||
--hash=sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19
|
||||
urllib3==2.2.2 \
|
||||
--hash=sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472 \
|
||||
--hash=sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168
|
||||
# via requests
|
||||
verspec==0.1.0 \
|
||||
--hash=sha256:741877d5633cc9464c45a469ae2a31e801e6dbbaa85b9675d481cda100f11c31 \
|
||||
|
|
|
|||
|
|
@ -137,7 +137,7 @@ Besides the HTTPS / SSL/TLS configuration, the following settings related to HTT
|
|||
| `AUTO_REDIRECT_HTTP_TO_HTTPS` | `yes` | When set to `yes`, will redirect every HTTP request to HTTPS only if BunkerWeb is configured with HTTPS. |
|
||||
| `SSL_PROTOCOLS` | `TLSv1.2 TLSv1.3` | List of supported SSL/TLS protocols when SSL is enabled. |
|
||||
| `HTTP2` | `yes` | When set to `yes`, will enable HTTP2 protocol support when using HTTPS. |
|
||||
| `HTTP3` | `no` | When set to `yes`, will enable HTTP3 protocol support when using HTTPS. |
|
||||
| `HTTP3` | `no` | When set to `yes`, will enable HTTP3 protocol support when using HTTPS. |
|
||||
| `HTTP3_ALT_SVC_PORT` | `443` | HTTP3 alternate service port. This value will be used as part of the Alt-Svc header. |
|
||||
| `LISTEN_HTTP` | `yes` | When set to `no`, BunkerWeb will not listen for HTTP requests. Useful if you want HTTPS only for example. |
|
||||
|
||||
|
|
@ -330,7 +330,7 @@ Here is the list of related settings :
|
|||
| --------------------------- | ------------ | --------- | -------- | ------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `USE_ANTIBOT` | `no` | multisite | no | Activate antibot feature. |
|
||||
| `ANTIBOT_URI` | `/challenge` | multisite | no | Unused URI that clients will be redirected to to solve the challenge. |
|
||||
| `ANTIBOT_RECAPTCHA_SCORE` | `0.7` | multisite | no | Minimum score required for reCAPTCHA challenge. |
|
||||
| `ANTIBOT_RECAPTCHA_SCORE` | `0.7` | multisite | no | Minimum score required for reCAPTCHA challenge (Only compatible with reCAPTCHA v3). |
|
||||
| `ANTIBOT_RECAPTCHA_SITEKEY` | | multisite | no | Sitekey for reCAPTCHA challenge. |
|
||||
| `ANTIBOT_RECAPTCHA_SECRET` | | multisite | no | Secret for reCAPTCHA challenge. |
|
||||
| `ANTIBOT_HCAPTCHA_SITEKEY` | | multisite | no | Sitekey for hCaptcha challenge. |
|
||||
|
|
@ -354,30 +354,26 @@ STREAM support :warning:
|
|||
|
||||
You can use the following settings to set up blacklisting :
|
||||
|
||||
| Setting | Default | Context | Multiple | Description |
|
||||
| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | --------- | -------- | ------------------------------------------------------------------------------------------------ |
|
||||
| `USE_BLACKLIST` | `yes` | multisite | no | Activate blacklist feature. |
|
||||
| `BLACKLIST_IP` | | multisite | no | List of IP/network, separated with spaces, to block. |
|
||||
| `BLACKLIST_IP_URLS` | `https://www.dan.me.uk/torlist/?exit` | global | no | List of URLs, separated with spaces, containing bad IP/network to block. |
|
||||
| `BLACKLIST_RDNS_GLOBAL` | `yes` | multisite | no | Only perform RDNS blacklist checks on global IP addresses. |
|
||||
| `BLACKLIST_RDNS` | `.shodan.io .censys.io` | multisite | no | List of reverse DNS suffixes, separated with spaces, to block. |
|
||||
| `BLACKLIST_RDNS_URLS` | | global | no | List of URLs, separated with spaces, containing reverse DNS suffixes to block. |
|
||||
| `BLACKLIST_ASN` | | multisite | no | List of ASN numbers, separated with spaces, to block. |
|
||||
| `BLACKLIST_ASN_URLS` | | global | no | List of URLs, separated with spaces, containing ASN to block. |
|
||||
| `BLACKLIST_USER_AGENT` | | multisite | no | List of User-Agent (PCRE regex), separated with spaces, to block. |
|
||||
| `BLACKLIST_USER_AGENT_URLS` | `https://raw.githubusercontent.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker/master/_generator_lists/bad-user-agents.list` | global | no | List of URLs, separated with spaces, containing bad User-Agent to block. |
|
||||
| `BLACKLIST_URI` | | multisite | no | List of URI (PCRE regex), separated with spaces, to block. |
|
||||
| `BLACKLIST_URI_URLS` | | global | no | List of URLs, separated with spaces, containing bad URI to block. |
|
||||
| `BLACKLIST_IGNORE_IP` | | multisite | no | List of IP/network, separated with spaces, to ignore in the blacklist. |
|
||||
| `BLACKLIST_IGNORE_IP_URLS` | | global | no | List of URLs, separated with spaces, containing IP/network to ignore in the blacklist. |
|
||||
| `BLACKLIST_IGNORE_RDNS` | | multisite | no | List of reverse DNS suffixes, separated with spaces, to ignore in the blacklist. |
|
||||
| `BLACKLIST_IGNORE_RDNS_URLS` | | global | no | List of URLs, separated with spaces, containing reverse DNS suffixes to ignore in the blacklist. |
|
||||
| `BLACKLIST_IGNORE_ASN` | | multisite | no | List of ASN numbers, separated with spaces, to ignore in the blacklist. |
|
||||
| `BLACKLIST_IGNORE_ASN_URLS` | | global | no | List of URLs, separated with spaces, containing ASN to ignore in the blacklist. |
|
||||
| `BLACKLIST_IGNORE_USER_AGENT` | | multisite | no | List of User-Agent (PCRE regex), separated with spaces, to ignore in the blacklist. |
|
||||
| `BLACKLIST_IGNORE_USER_AGENT_URLS` | | global | no | List of URLs, separated with spaces, containing User-Agent to ignore in the blacklist. |
|
||||
| `BLACKLIST_IGNORE_URI` | | multisite | no | List of URI (PCRE regex), separated with spaces, to ignore in the blacklist. |
|
||||
| `BLACKLIST_IGNORE_URI_URLS` | | global | no | List of URLs, separated with spaces, containing URI to ignore in the blacklist. |
|
||||
| Setting | Default | Context | Multiple | Description |
|
||||
| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | --------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `USE_BLACKLIST` | `yes` | multisite | no | Activate blacklist feature. |
|
||||
| `BLACKLIST_IP` | | multisite | no | List of IP/network, separated with spaces, to block. |
|
||||
| `BLACKLIST_RDNS_GLOBAL` | `yes` | multisite | no | Only perform RDNS blacklist checks on global IP addresses. |
|
||||
| `BLACKLIST_RDNS` | `.shodan.io .censys.io` | multisite | no | List of reverse DNS suffixes, separated with spaces, to block. |
|
||||
| `BLACKLIST_ASN` | | multisite | no | List of ASN numbers, separated with spaces, to block. |
|
||||
| `BLACKLIST_ASN_URLS` | | global | no | List of URLs, separated with spaces, containing ASN to block. |
|
||||
| `BLACKLIST_USER_AGENT` | | multisite | no | List of User-Agent (PCRE regex), separated with spaces, to block. |
|
||||
| `BLACKLIST_URI` | | multisite | no | List of URI (PCRE regex), separated with spaces, to block. |
|
||||
| `BLACKLIST_IP_URLS` | `https://www.dan.me.uk/torlist/?exit` | global | no | List of URLs, separated with spaces, containing bad IP/network to block. Also supports file:// URLs and and auth basic using http://user:pass@url scheme. |
|
||||
| `BLACKLIST_RDNS_URLS` | | global | no | List of URLs, separated with spaces, containing reverse DNS suffixes to block. Also supports file:// URLs and and auth basic using http://user:pass@url scheme. |
|
||||
| `BLACKLIST_ASN_URLS` | | global | no | List of URLs, separated with spaces, containing ASN to block. Also supports file:// URLs and and auth basic using http://user:pass@url scheme. |
|
||||
| `BLACKLIST_USER_AGENT_URLS` | `https://raw.githubusercontent.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker/master/_generator_lists/bad-user-agents.list` | global | no | List of URLs, separated with spaces, containing bad User-Agent to block. Also supports file:// URLs and and auth basic using http://user:pass@url scheme. |
|
||||
| `BLACKLIST_URI_URLS` | | global | no | List of URLs, separated with spaces, containing bad URI to block. Also supports file:// URLs and and auth basic using http://user:pass@url scheme. |
|
||||
| `BLACKLIST_IGNORE_IP_URLS` | | global | no | List of URLs, separated with spaces, containing IP/network to ignore in the blacklist. Also supports file:// URLs and and auth basic using http://user:pass@url scheme. |
|
||||
| `BLACKLIST_IGNORE_RDNS_URLS` | | global | no | List of URLs, separated with spaces, containing reverse DNS suffixes to ignore in the blacklist. Also supports file:// URLs and and auth basic using http://user:pass@url scheme. |
|
||||
| `BLACKLIST_IGNORE_ASN_URLS` | | global | no | List of URLs, separated with spaces, containing ASN to ignore in the blacklist. Also supports file:// URLs and and auth basic using http://user:pass@url scheme. |
|
||||
| `BLACKLIST_IGNORE_USER_AGENT_URLS` | | global | no | List of URLs, separated with spaces, containing User-Agent to ignore in the blacklist. Also supports file:// URLs and and auth basic using http://user:pass@url scheme. |
|
||||
| `BLACKLIST_IGNORE_URI_URLS` | | global | no | List of URLs, separated with spaces, containing URI to ignore in the blacklist. Also supports file:// URLs and and auth basic using http://user:pass@url scheme. |
|
||||
|
||||
When using stream mode, only IP, RDNS and ASN checks will be done.
|
||||
|
||||
|
|
@ -387,20 +383,20 @@ STREAM support :warning:
|
|||
|
||||
You can use the following settings to set up greylisting :
|
||||
|
||||
| Setting | Default | Context | Multiple | Description |
|
||||
| -------------------------- | ------- | --------- | -------- | ---------------------------------------------------------------------------------------------- |
|
||||
| `USE_GREYLIST` | `no` | multisite | no | Activate greylist feature. |
|
||||
| `GREYLIST_IP` | | multisite | no | List of IP/network, separated with spaces, to put into the greylist. |
|
||||
| `GREYLIST_IP_URLS` | | global | no | List of URLs, separated with spaces, containing good IP/network to put into the greylist. |
|
||||
| `GREYLIST_RDNS_GLOBAL` | `yes` | multisite | no | Only perform RDNS greylist checks on global IP addresses. |
|
||||
| `GREYLIST_RDNS` | | multisite | no | List of reverse DNS suffixes, separated with spaces, to put into the greylist. |
|
||||
| `GREYLIST_RDNS_URLS` | | global | no | List of URLs, separated with spaces, containing reverse DNS suffixes to put into the greylist. |
|
||||
| `GREYLIST_ASN` | | multisite | no | List of ASN numbers, separated with spaces, to put into the greylist. |
|
||||
| `GREYLIST_ASN_URLS` | | global | no | List of URLs, separated with spaces, containing ASN to put into the greylist. |
|
||||
| `GREYLIST_USER_AGENT` | | multisite | no | List of User-Agent (PCRE regex), separated with spaces, to put into the greylist. |
|
||||
| `GREYLIST_USER_AGENT_URLS` | | global | no | List of URLs, separated with spaces, containing good User-Agent to put into the greylist. |
|
||||
| `GREYLIST_URI` | | multisite | no | List of URI (PCRE regex), separated with spaces, to put into the greylist. |
|
||||
| `GREYLIST_URI_URLS` | | global | no | List of URLs, separated with spaces, containing bad URI to put into the greylist. |
|
||||
| Setting | Default | Context | Multiple | Description |
|
||||
| -------------------------- | ------- | --------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `USE_GREYLIST` | `no` | multisite | no | Activate greylist feature. |
|
||||
| `GREYLIST_IP` | | multisite | no | List of IP/network, separated with spaces, to put into the greylist. |
|
||||
| `GREYLIST_RDNS_GLOBAL` | `yes` | multisite | no | Only perform RDNS greylist checks on global IP addresses. |
|
||||
| `GREYLIST_RDNS` | | multisite | no | List of reverse DNS suffixes, separated with spaces, to put into the greylist. |
|
||||
| `GREYLIST_ASN` | | multisite | no | List of ASN numbers, separated with spaces, to put into the greylist. |
|
||||
| `GREYLIST_USER_AGENT` | | multisite | no | List of User-Agent (PCRE regex), separated with spaces, to put into the greylist. |
|
||||
| `GREYLIST_URI` | | multisite | no | List of URI (PCRE regex), separated with spaces, to put into the greylist. |
|
||||
| `GREYLIST_IP_URLS` | | global | no | List of URLs, separated with spaces, containing good IP/network to put into the greylist. Also supports file:// URLs and and auth basic using http://user:pass@url scheme. |
|
||||
| `GREYLIST_RDNS_URLS` | | global | no | List of URLs, separated with spaces, containing reverse DNS suffixes to put into the greylist. Also supports file:// URLs and and auth basic using http://user:pass@url scheme. |
|
||||
| `GREYLIST_ASN_URLS` | | global | no | List of URLs, separated with spaces, containing ASN to put into the greylist. Also supports file:// URLs and and auth basic using http://user:pass@url scheme. |
|
||||
| `GREYLIST_USER_AGENT_URLS` | | global | no | List of URLs, separated with spaces, containing good User-Agent to put into the greylist. Also supports file:// URLs and and auth basic using http://user:pass@url scheme. |
|
||||
| `GREYLIST_URI_URLS` | | global | no | List of URLs, separated with spaces, containing bad URI to put into the greylist. Also supports file:// URLs and and auth basic using http://user:pass@url scheme. |
|
||||
|
||||
When using stream mode, only IP, RDNS and ASN checks will be done.
|
||||
|
||||
|
|
@ -410,20 +406,20 @@ STREAM support :warning:
|
|||
|
||||
You can use the following settings to set up whitelisting :
|
||||
|
||||
| Setting | Default | Context | Multiple | Description |
|
||||
| --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- | -------- | ---------------------------------------------------------------------------------- |
|
||||
| `USE_WHITELIST` | `yes` | multisite | no | Activate whitelist feature. |
|
||||
| `WHITELIST_IP` | `20.191.45.212 40.88.21.235 40.76.173.151 40.76.163.7 20.185.79.47 52.142.26.175 20.185.79.15 52.142.24.149 40.76.162.208 40.76.163.23 40.76.162.191 40.76.162.247 54.208.102.37 107.21.1.8` | multisite | no | List of IP/network, separated with spaces, to put into the whitelist. |
|
||||
| `WHITELIST_IP_URLS` | | global | no | List of URLs, separated with spaces, containing good IP/network to whitelist. |
|
||||
| `WHITELIST_RDNS_GLOBAL` | `yes` | multisite | no | Only perform RDNS whitelist checks on global IP addresses. |
|
||||
| `WHITELIST_RDNS` | `.google.com .googlebot.com .yandex.ru .yandex.net .yandex.com .search.msn.com .baidu.com .baidu.jp .crawl.yahoo.net .fwd.linkedin.com .twitter.com .twttr.com .discord.com` | multisite | no | List of reverse DNS suffixes, separated with spaces, to whitelist. |
|
||||
| `WHITELIST_RDNS_URLS` | | global | no | List of URLs, separated with spaces, containing reverse DNS suffixes to whitelist. |
|
||||
| `WHITELIST_ASN` | `32934` | multisite | no | List of ASN numbers, separated with spaces, to whitelist. |
|
||||
| `WHITELIST_ASN_URLS` | | global | no | List of URLs, separated with spaces, containing ASN to whitelist. |
|
||||
| `WHITELIST_USER_AGENT` | | multisite | no | List of User-Agent (PCRE regex), separated with spaces, to whitelist. |
|
||||
| `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. |
|
||||
| Setting | Default | Context | Multiple | Description |
|
||||
| --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `USE_WHITELIST` | `yes` | multisite | no | Activate whitelist feature. |
|
||||
| `WHITELIST_IP` | `20.191.45.212 40.88.21.235 40.76.173.151 40.76.163.7 20.185.79.47 52.142.26.175 20.185.79.15 52.142.24.149 40.76.162.208 40.76.163.23 40.76.162.191 40.76.162.247 54.208.102.37 107.21.1.8` | multisite | no | List of IP/network, separated with spaces, to put into the whitelist. |
|
||||
| `WHITELIST_RDNS_GLOBAL` | `yes` | multisite | no | Only perform RDNS whitelist checks on global IP addresses. |
|
||||
| `WHITELIST_RDNS` | `.google.com .googlebot.com .yandex.ru .yandex.net .yandex.com .search.msn.com .baidu.com .baidu.jp .crawl.yahoo.net .fwd.linkedin.com .twitter.com .twttr.com .discord.com` | multisite | no | List of reverse DNS suffixes, separated with spaces, to whitelist. |
|
||||
| `WHITELIST_ASN` | `32934` | multisite | no | List of ASN numbers, separated with spaces, to whitelist. |
|
||||
| `WHITELIST_USER_AGENT` | | multisite | no | List of User-Agent (PCRE regex), separated with spaces, to whitelist. |
|
||||
| `WHITELIST_URI` | | multisite | no | List of URI (PCRE regex), separated with spaces, to whitelist. |
|
||||
| `WHITELIST_IP_URLS` | | global | no | List of URLs, separated with spaces, containing good IP/network to whitelist. Also supports file:// URLs and and auth basic using http://user:pass@url scheme. |
|
||||
| `WHITELIST_RDNS_URLS` | | global | no | List of URLs, separated with spaces, containing reverse DNS suffixes to whitelist. Also supports file:// URLs and and auth basic using http://user:pass@url scheme. |
|
||||
| `WHITELIST_ASN_URLS` | | global | no | List of URLs, separated with spaces, containing ASN to whitelist. Also supports file:// URLs and and auth basic using http://user:pass@url scheme. |
|
||||
| `WHITELIST_USER_AGENT_URLS` | | global | no | List of URLs, separated with spaces, containing good User-Agent to whitelist. Also supports file:// URLs and and auth basic using http://user:pass@url scheme. |
|
||||
| `WHITELIST_URI_URLS` | | global | no | List of URLs, separated with spaces, containing bad URI to whitelist. Also supports file:// URLs and and auth basic using http://user:pass@url scheme. |
|
||||
|
||||
When using stream mode, only IP, RDNS and ASN checks will be done.
|
||||
|
||||
|
|
|
|||
122
docs/settings.md
122
docs/settings.md
|
|
@ -65,7 +65,7 @@ Bot detection by using a challenge.
|
|||
|`ANTIBOT_URI` |`/challenge`|multisite|no |Unused URI that clients will be redirected to to solve the challenge. |
|
||||
|`ANTIBOT_TIME_RESOLVE` |`60` |multisite|no |Maximum time (in seconds) clients have to resolve the challenge. Once this time has passed, a new challenge will be generated.|
|
||||
|`ANTIBOT_TIME_VALID` |`86400` |multisite|no |Maximum validity time of solved challenges. Once this time has passed, clients will need to resolve a new one. |
|
||||
|`ANTIBOT_RECAPTCHA_SCORE` |`0.7` |multisite|no |Minimum score required for reCAPTCHA challenge. |
|
||||
|`ANTIBOT_RECAPTCHA_SCORE` |`0.7` |multisite|no |Minimum score required for reCAPTCHA challenge (Only compatible with reCAPTCHA v3). |
|
||||
|`ANTIBOT_RECAPTCHA_SITEKEY`| |multisite|no |Sitekey for reCAPTCHA challenge. |
|
||||
|`ANTIBOT_RECAPTCHA_SECRET` | |multisite|no |Secret for reCAPTCHA challenge. |
|
||||
|`ANTIBOT_HCAPTCHA_SITEKEY` | |multisite|no |Sitekey for hCaptcha challenge. |
|
||||
|
|
@ -140,30 +140,30 @@ STREAM support :warning:
|
|||
|
||||
Deny access based on internal and external IP/network/rDNS/ASN blacklists.
|
||||
|
||||
| Setting | Default | Context |Multiple| Description |
|
||||
|----------------------------------|------------------------------------------------------------------------------------------------------------------------------|---------|--------|------------------------------------------------------------------------------------------------|
|
||||
|`USE_BLACKLIST` |`yes` |multisite|no |Activate blacklist feature. |
|
||||
|`BLACKLIST_IP` | |multisite|no |List of IP/network, separated with spaces, to block. |
|
||||
|`BLACKLIST_RDNS` |`.shodan.io .censys.io` |multisite|no |List of reverse DNS suffixes, separated with spaces, to block. |
|
||||
|`BLACKLIST_RDNS_GLOBAL` |`yes` |multisite|no |Only perform RDNS blacklist checks on global IP addresses. |
|
||||
|`BLACKLIST_ASN` | |multisite|no |List of ASN numbers, separated with spaces, to block. |
|
||||
|`BLACKLIST_USER_AGENT` | |multisite|no |List of User-Agent (PCRE regex), separated with spaces, to block. |
|
||||
|`BLACKLIST_URI` | |multisite|no |List of URI (PCRE regex), separated with spaces, to block. |
|
||||
|`BLACKLIST_IGNORE_IP` | |multisite|no |List of IP/network, separated with spaces, to ignore in the blacklist. |
|
||||
|`BLACKLIST_IGNORE_RDNS` | |multisite|no |List of reverse DNS suffixes, separated with spaces, to ignore in the blacklist. |
|
||||
|`BLACKLIST_IGNORE_ASN` | |multisite|no |List of ASN numbers, separated with spaces, to ignore in the blacklist. |
|
||||
|`BLACKLIST_IGNORE_USER_AGENT` | |multisite|no |List of User-Agent (PCRE regex), separated with spaces, to ignore in the blacklist. |
|
||||
|`BLACKLIST_IGNORE_URI` | |multisite|no |List of URI (PCRE regex), separated with spaces, to ignore in the blacklist. |
|
||||
|`BLACKLIST_IP_URLS` |`https://www.dan.me.uk/torlist/?exit` |global |no |List of URLs, separated with spaces, containing bad IP/network to block. |
|
||||
|`BLACKLIST_RDNS_URLS` | |global |no |List of URLs, separated with spaces, containing reverse DNS suffixes to block. |
|
||||
|`BLACKLIST_ASN_URLS` | |global |no |List of URLs, separated with spaces, containing ASN to block. |
|
||||
|`BLACKLIST_USER_AGENT_URLS` |`https://raw.githubusercontent.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker/master/_generator_lists/bad-user-agents.list`|global |no |List of URLs, separated with spaces, containing bad User-Agent to block. |
|
||||
|`BLACKLIST_URI_URLS` | |global |no |List of URLs, separated with spaces, containing bad URI to block. |
|
||||
|`BLACKLIST_IGNORE_IP_URLS` | |global |no |List of URLs, separated with spaces, containing IP/network to ignore in the blacklist. |
|
||||
|`BLACKLIST_IGNORE_RDNS_URLS` | |global |no |List of URLs, separated with spaces, containing reverse DNS suffixes to ignore in the blacklist.|
|
||||
|`BLACKLIST_IGNORE_ASN_URLS` | |global |no |List of URLs, separated with spaces, containing ASN to ignore in the blacklist. |
|
||||
|`BLACKLIST_IGNORE_USER_AGENT_URLS`| |global |no |List of URLs, separated with spaces, containing User-Agent to ignore in the blacklist. |
|
||||
|`BLACKLIST_IGNORE_URI_URLS` | |global |no |List of URLs, separated with spaces, containing URI to ignore in the blacklist. |
|
||||
| Setting | Default | Context |Multiple| Description |
|
||||
|----------------------------------|------------------------------------------------------------------------------------------------------------------------------|---------|--------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
|`USE_BLACKLIST` |`yes` |multisite|no |Activate blacklist feature. |
|
||||
|`BLACKLIST_IP` | |multisite|no |List of IP/network, separated with spaces, to block. |
|
||||
|`BLACKLIST_RDNS` |`.shodan.io .censys.io` |multisite|no |List of reverse DNS suffixes, separated with spaces, to block. |
|
||||
|`BLACKLIST_RDNS_GLOBAL` |`yes` |multisite|no |Only perform RDNS blacklist checks on global IP addresses. |
|
||||
|`BLACKLIST_ASN` | |multisite|no |List of ASN numbers, separated with spaces, to block. |
|
||||
|`BLACKLIST_USER_AGENT` | |multisite|no |List of User-Agent (PCRE regex), separated with spaces, to block. |
|
||||
|`BLACKLIST_URI` | |multisite|no |List of URI (PCRE regex), separated with spaces, to block. |
|
||||
|`BLACKLIST_IGNORE_IP` | |multisite|no |List of IP/network, separated with spaces, to ignore in the blacklist. |
|
||||
|`BLACKLIST_IGNORE_RDNS` | |multisite|no |List of reverse DNS suffixes, separated with spaces, to ignore in the blacklist. |
|
||||
|`BLACKLIST_IGNORE_ASN` | |multisite|no |List of ASN numbers, separated with spaces, to ignore in the blacklist. |
|
||||
|`BLACKLIST_IGNORE_USER_AGENT` | |multisite|no |List of User-Agent (PCRE regex), separated with spaces, to ignore in the blacklist. |
|
||||
|`BLACKLIST_IGNORE_URI` | |multisite|no |List of URI (PCRE regex), separated with spaces, to ignore in the blacklist. |
|
||||
|`BLACKLIST_IP_URLS` |`https://www.dan.me.uk/torlist/?exit` |global |no |List of URLs, separated with spaces, containing bad IP/network to block. Also supports file:// URLs and and auth basic using http://user:pass@url scheme. |
|
||||
|`BLACKLIST_RDNS_URLS` | |global |no |List of URLs, separated with spaces, containing reverse DNS suffixes to block. Also supports file:// URLs and and auth basic using http://user:pass@url scheme. |
|
||||
|`BLACKLIST_ASN_URLS` | |global |no |List of URLs, separated with spaces, containing ASN to block. Also supports file:// URLs and and auth basic using http://user:pass@url scheme. |
|
||||
|`BLACKLIST_USER_AGENT_URLS` |`https://raw.githubusercontent.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker/master/_generator_lists/bad-user-agents.list`|global |no |List of URLs, separated with spaces, containing bad User-Agent to block. Also supports file:// URLs and and auth basic using http://user:pass@url scheme. |
|
||||
|`BLACKLIST_URI_URLS` | |global |no |List of URLs, separated with spaces, containing bad URI to block. Also supports file:// URLs and and auth basic using http://user:pass@url scheme. |
|
||||
|`BLACKLIST_IGNORE_IP_URLS` | |global |no |List of URLs, separated with spaces, containing IP/network to ignore in the blacklist. Also supports file:// URLs and and auth basic using http://user:pass@url scheme. |
|
||||
|`BLACKLIST_IGNORE_RDNS_URLS` | |global |no |List of URLs, separated with spaces, containing reverse DNS suffixes to ignore in the blacklist. Also supports file:// URLs and and auth basic using http://user:pass@url scheme.|
|
||||
|`BLACKLIST_IGNORE_ASN_URLS` | |global |no |List of URLs, separated with spaces, containing ASN to ignore in the blacklist. Also supports file:// URLs and and auth basic using http://user:pass@url scheme. |
|
||||
|`BLACKLIST_IGNORE_USER_AGENT_URLS`| |global |no |List of URLs, separated with spaces, containing User-Agent to ignore in the blacklist. Also supports file:// URLs and and auth basic using http://user:pass@url scheme. |
|
||||
|`BLACKLIST_IGNORE_URI_URLS` | |global |no |List of URLs, separated with spaces, containing URI to ignore in the blacklist. Also supports file:// URLs and and auth basic using http://user:pass@url scheme. |
|
||||
|
||||
## Brotli
|
||||
|
||||
|
|
@ -287,20 +287,20 @@ STREAM support :warning:
|
|||
|
||||
Allow access while keeping security features based on internal and external IP/network/rDNS/ASN greylists.
|
||||
|
||||
| Setting |Default| Context |Multiple| Description |
|
||||
|--------------------------|-------|---------|--------|----------------------------------------------------------------------------------------------|
|
||||
|`USE_GREYLIST` |`no` |multisite|no |Activate greylist feature. |
|
||||
|`GREYLIST_IP` | |multisite|no |List of IP/network, separated with spaces, to put into the greylist. |
|
||||
|`GREYLIST_RDNS` | |multisite|no |List of reverse DNS suffixes, separated with spaces, to put into the greylist. |
|
||||
|`GREYLIST_RDNS_GLOBAL` |`yes` |multisite|no |Only perform RDNS greylist checks on global IP addresses. |
|
||||
|`GREYLIST_ASN` | |multisite|no |List of ASN numbers, separated with spaces, to put into the greylist. |
|
||||
|`GREYLIST_USER_AGENT` | |multisite|no |List of User-Agent (PCRE regex), separated with spaces, to put into the greylist. |
|
||||
|`GREYLIST_URI` | |multisite|no |List of URI (PCRE regex), separated with spaces, to put into the greylist. |
|
||||
|`GREYLIST_IP_URLS` | |global |no |List of URLs, separated with spaces, containing good IP/network to put into the greylist. |
|
||||
|`GREYLIST_RDNS_URLS` | |global |no |List of URLs, separated with spaces, containing reverse DNS suffixes to put into the greylist.|
|
||||
|`GREYLIST_ASN_URLS` | |global |no |List of URLs, separated with spaces, containing ASN to put into the greylist. |
|
||||
|`GREYLIST_USER_AGENT_URLS`| |global |no |List of URLs, separated with spaces, containing good User-Agent to put into the greylist. |
|
||||
|`GREYLIST_URI_URLS` | |global |no |List of URLs, separated with spaces, containing bad URI to put into the greylist. |
|
||||
| Setting |Default| Context |Multiple| Description |
|
||||
|--------------------------|-------|---------|--------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
|`USE_GREYLIST` |`no` |multisite|no |Activate greylist feature. |
|
||||
|`GREYLIST_IP` | |multisite|no |List of IP/network, separated with spaces, to put into the greylist. |
|
||||
|`GREYLIST_RDNS` | |multisite|no |List of reverse DNS suffixes, separated with spaces, to put into the greylist. |
|
||||
|`GREYLIST_RDNS_GLOBAL` |`yes` |multisite|no |Only perform RDNS greylist checks on global IP addresses. |
|
||||
|`GREYLIST_ASN` | |multisite|no |List of ASN numbers, separated with spaces, to put into the greylist. |
|
||||
|`GREYLIST_USER_AGENT` | |multisite|no |List of User-Agent (PCRE regex), separated with spaces, to put into the greylist. |
|
||||
|`GREYLIST_URI` | |multisite|no |List of URI (PCRE regex), separated with spaces, to put into the greylist. |
|
||||
|`GREYLIST_IP_URLS` | |global |no |List of URLs, separated with spaces, containing good IP/network to put into the greylist. Also supports file:// URLs and and auth basic using http://user:pass@url scheme. |
|
||||
|`GREYLIST_RDNS_URLS` | |global |no |List of URLs, separated with spaces, containing reverse DNS suffixes to put into the greylist. Also supports file:// URLs and and auth basic using http://user:pass@url scheme.|
|
||||
|`GREYLIST_ASN_URLS` | |global |no |List of URLs, separated with spaces, containing ASN to put into the greylist. Also supports file:// URLs and and auth basic using http://user:pass@url scheme. |
|
||||
|`GREYLIST_USER_AGENT_URLS`| |global |no |List of URLs, separated with spaces, containing good User-Agent to put into the greylist. Also supports file:// URLs and and auth basic using http://user:pass@url scheme. |
|
||||
|`GREYLIST_URI_URLS` | |global |no |List of URLs, separated with spaces, containing bad URI to put into the greylist. Also supports file:// URLs and and auth basic using http://user:pass@url scheme. |
|
||||
|
||||
## Gzip
|
||||
|
||||
|
|
@ -516,14 +516,14 @@ STREAM support :warning:
|
|||
|
||||
Get real IP of clients when BunkerWeb is behind a reverse proxy / load balancer.
|
||||
|
||||
| Setting | Default | Context |Multiple| Description |
|
||||
|--------------------|-----------------------------------------|---------|--------|--------------------------------------------------------------------------------------------------------|
|
||||
|`USE_REAL_IP` |`no` |multisite|no |Retrieve the real IP of client. |
|
||||
|`USE_PROXY_PROTOCOL`|`no` |multisite|no |Enable PROXY protocol communication. |
|
||||
|`REAL_IP_FROM` |`192.168.0.0/16 172.16.0.0/12 10.0.0.0/8`|multisite|no |List of trusted IPs / networks, separated with spaces, where proxied requests come from. |
|
||||
|`REAL_IP_HEADER` |`X-Forwarded-For` |multisite|no |HTTP header containing the real IP or special value proxy_protocol for PROXY protocol. |
|
||||
|`REAL_IP_RECURSIVE` |`yes` |multisite|no |Perform a recursive search in the header container IP address. |
|
||||
|`REAL_IP_FROM_URLS` | |global |no |List of URLs containing trusted IPs / networks, separated with spaces, where proxied requests come from.|
|
||||
| Setting | Default | Context |Multiple| Description |
|
||||
|--------------------|-----------------------------------------|---------|--------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
|`USE_REAL_IP` |`no` |multisite|no |Retrieve the real IP of client. |
|
||||
|`USE_PROXY_PROTOCOL`|`no` |multisite|no |Enable PROXY protocol communication. |
|
||||
|`REAL_IP_FROM` |`192.168.0.0/16 172.16.0.0/12 10.0.0.0/8`|multisite|no |List of trusted IPs / networks, separated with spaces, where proxied requests come from. |
|
||||
|`REAL_IP_HEADER` |`X-Forwarded-For` |multisite|no |HTTP header containing the real IP or special value proxy_protocol for PROXY protocol. |
|
||||
|`REAL_IP_RECURSIVE` |`yes` |multisite|no |Perform a recursive search in the header container IP address. |
|
||||
|`REAL_IP_FROM_URLS` | |global |no |List of URLs containing trusted IPs / networks, separated with spaces, where proxied requests come from. Also supports file:// URLs and and auth basic using http://user:pass@url scheme.|
|
||||
|
||||
## Redirect
|
||||
|
||||
|
|
@ -676,17 +676,17 @@ STREAM support :warning:
|
|||
|
||||
Allow access based on internal and external IP/network/rDNS/ASN whitelists.
|
||||
|
||||
| Setting | Default | Context |Multiple| Description |
|
||||
|---------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|--------|----------------------------------------------------------------------------------|
|
||||
|`USE_WHITELIST` |`yes` |multisite|no |Activate whitelist feature. |
|
||||
|`WHITELIST_IP` |`20.191.45.212 40.88.21.235 40.76.173.151 40.76.163.7 20.185.79.47 52.142.26.175 20.185.79.15 52.142.24.149 40.76.162.208 40.76.163.23 40.76.162.191 40.76.162.247` |multisite|no |List of IP/network, separated with spaces, to put into the whitelist. |
|
||||
|`WHITELIST_RDNS` |`.google.com .googlebot.com .yandex.ru .yandex.net .yandex.com .search.msn.com .baidu.com .baidu.jp .crawl.yahoo.net .fwd.linkedin.com .twitter.com .twttr.com .discord.com`|multisite|no |List of reverse DNS suffixes, separated with spaces, to whitelist. |
|
||||
|`WHITELIST_RDNS_GLOBAL` |`yes` |multisite|no |Only perform RDNS whitelist checks on global IP addresses. |
|
||||
|`WHITELIST_ASN` |`32934` |multisite|no |List of ASN numbers, separated with spaces, to whitelist. |
|
||||
|`WHITELIST_USER_AGENT` | |multisite|no |List of User-Agent (PCRE regex), separated with spaces, to whitelist. |
|
||||
|`WHITELIST_URI` | |multisite|no |List of URI (PCRE regex), separated with spaces, to whitelist. |
|
||||
|`WHITELIST_IP_URLS` | |global |no |List of URLs, separated with spaces, containing good IP/network to whitelist. |
|
||||
|`WHITELIST_RDNS_URLS` | |global |no |List of URLs, separated with spaces, containing reverse DNS suffixes to whitelist.|
|
||||
|`WHITELIST_ASN_URLS` | |global |no |List of URLs, separated with spaces, containing ASN to whitelist. |
|
||||
|`WHITELIST_USER_AGENT_URLS`| |global |no |List of URLs, separated with spaces, containing good User-Agent to whitelist. |
|
||||
|`WHITELIST_URI_URLS` | |global |no |List of URLs, separated with spaces, containing bad URI to whitelist. |
|
||||
| Setting | Default | Context |Multiple| Description |
|
||||
|---------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|--------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
|`USE_WHITELIST` |`yes` |multisite|no |Activate whitelist feature. |
|
||||
|`WHITELIST_IP` |`20.191.45.212 40.88.21.235 40.76.173.151 40.76.163.7 20.185.79.47 52.142.26.175 20.185.79.15 52.142.24.149 40.76.162.208 40.76.163.23 40.76.162.191 40.76.162.247` |multisite|no |List of IP/network, separated with spaces, to put into the whitelist. |
|
||||
|`WHITELIST_RDNS` |`.google.com .googlebot.com .yandex.ru .yandex.net .yandex.com .search.msn.com .baidu.com .baidu.jp .crawl.yahoo.net .fwd.linkedin.com .twitter.com .twttr.com .discord.com`|multisite|no |List of reverse DNS suffixes, separated with spaces, to whitelist. |
|
||||
|`WHITELIST_RDNS_GLOBAL` |`yes` |multisite|no |Only perform RDNS whitelist checks on global IP addresses. |
|
||||
|`WHITELIST_ASN` |`32934` |multisite|no |List of ASN numbers, separated with spaces, to whitelist. |
|
||||
|`WHITELIST_USER_AGENT` | |multisite|no |List of User-Agent (PCRE regex), separated with spaces, to whitelist. |
|
||||
|`WHITELIST_URI` | |multisite|no |List of URI (PCRE regex), separated with spaces, to whitelist. |
|
||||
|`WHITELIST_IP_URLS` | |global |no |List of URLs, separated with spaces, containing good IP/network to whitelist. Also supports file:// URLs and and auth basic using http://user:pass@url scheme. |
|
||||
|`WHITELIST_RDNS_URLS` | |global |no |List of URLs, separated with spaces, containing reverse DNS suffixes to whitelist. Also supports file:// URLs and and auth basic using http://user:pass@url scheme.|
|
||||
|`WHITELIST_ASN_URLS` | |global |no |List of URLs, separated with spaces, containing ASN to whitelist. Also supports file:// URLs and and auth basic using http://user:pass@url scheme. |
|
||||
|`WHITELIST_USER_AGENT_URLS`| |global |no |List of URLs, separated with spaces, containing good User-Agent to whitelist. Also supports file:// URLs and and auth basic using http://user:pass@url scheme. |
|
||||
|`WHITELIST_URI_URLS` | |global |no |List of URLs, separated with spaces, containing bad URI to whitelist. Also supports file:// URLs and and auth basic using http://user:pass@url scheme. |
|
||||
|
|
|
|||
|
|
@ -31,6 +31,8 @@ Because the web UI is a web application, the recommended installation procedure
|
|||
* Do not open the web UI on the Internet without any further restrictions
|
||||
* Apply settings listed in the [security tuning section](security-tuning.md) of the documentation
|
||||
|
||||
**Please note that using HTTPS in front the web UI is mandatory since version 1.5.8 of BunkerWeb.**
|
||||
|
||||
!!! info "Multisite mode"
|
||||
|
||||
The usage of the web UI implies enabling the [multisite mode](concepts.md#multisite-mode).
|
||||
|
|
@ -39,7 +41,7 @@ Because the web UI is a web application, the recommended installation procedure
|
|||
|
||||
!!! 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 (`https://hostname-of-web-ui:7000`) and browse the `/setup` URI of your server to access the 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.
|
||||
|
||||
<figure markdown>
|
||||
{ align=center, width="350" }
|
||||
|
|
@ -70,7 +72,7 @@ Review your final BunkerWeb UI URL and then click on the `Setup` button. Once th
|
|||
|
||||
!!! tip "Accessing the setup wizard"
|
||||
|
||||
You can access the setup wizard by browsing the `https://your-ip-address/setup` URI of your server.
|
||||
You can access the setup wizard by browsing the `https://your-ip-address-or-fqdn/setup` URI of your server.
|
||||
|
||||
|
||||
Here is the docker-compose boilerplate that you can use (don't forget to edit the `changeme` data) :
|
||||
|
|
@ -162,7 +164,7 @@ Review your final BunkerWeb UI URL and then click on the `Setup` button. Once th
|
|||
|
||||
!!! tip "Accessing the setup wizard"
|
||||
|
||||
You can access the setup wizard by browsing the `https://your-ip-address/setup` URI of your server.
|
||||
You can access the setup wizard by browsing the `https://your-ip-address-or-fqdn/setup` URI of your server.
|
||||
|
||||
Here is the docker-compose boilerplate that you can use (don't forget to edit the `changeme` data) :
|
||||
|
||||
|
|
@ -269,7 +271,7 @@ Review your final BunkerWeb UI URL and then click on the `Setup` button. Once th
|
|||
|
||||
!!! tip "Accessing the setup wizard"
|
||||
|
||||
You can access the setup wizard by browsing the `https://your-ip-address/setup` URI of your server.
|
||||
You can access the setup wizard by browsing the `https://your-ip-address-or-fqdn/setup` URI of your server.
|
||||
|
||||
Here is the stack boilerplate that you can use (don't forget to edit the `changeme` data) :
|
||||
|
||||
|
|
@ -399,7 +401,7 @@ Review your final BunkerWeb UI URL and then click on the `Setup` button. Once th
|
|||
|
||||
!!! tip "Accessing the setup wizard"
|
||||
|
||||
You can access the setup wizard by browsing the `https://your-ip-address/setup` URI of your server.
|
||||
You can access the setup wizard by browsing the `https://your-ip-address-or-fqdn/setup` URI of your server.
|
||||
|
||||
Here is the yaml boilerplate that you can use (don't forget to edit the `changeme` data) :
|
||||
|
||||
|
|
@ -832,6 +834,7 @@ After a successful login/password combination, you will be prompted to enter you
|
|||
|
||||
- `ADMIN_USERNAME` : username to access the web UI
|
||||
- `ADMIN_PASSWORD` : password to access the web UI
|
||||
- `OVERRIDE_ADMIN_CREDS` : force override the admin credentials even if we already have a user in the database (default = `no`)
|
||||
|
||||
Accessing the web UI through BunkerWeb is a classical [reverse proxy setup](quickstart-guide.md#protect-http-applications). We recommend you to connect BunkerWeb and web UI using a dedicated network (like `bw-universe` also used by the scheduler) so it won't be on the same network of your web services for obvious security reasons. Please note that the web UI container is listening on the `7000` port.
|
||||
|
||||
|
|
@ -953,6 +956,7 @@ After a successful login/password combination, you will be prompted to enter you
|
|||
|
||||
- `ADMIN_USERNAME` : username to access the web UI
|
||||
- `ADMIN_PASSWORD` : password to access the web UI
|
||||
- `OVERRIDE_ADMIN_CREDS` : force override the admin credentials even if we already have a user in the database (default = `no`)
|
||||
|
||||
Accessing the web UI through BunkerWeb is a classical [reverse proxy setup](quickstart-guide.md#protect-http-applications). We recommend you to connect BunkerWeb and web UI using a dedicated network (like `bw-universe` also used by the scheduler and autoconf) so it won't be on the same network of your web services for obvious security reasons. Please note that the web UI container is listening on the `7000` port.
|
||||
|
||||
|
|
@ -1088,6 +1092,7 @@ After a successful login/password combination, you will be prompted to enter you
|
|||
|
||||
- `ADMIN_USERNAME` : username to access the web UI
|
||||
- `ADMIN_PASSWORD` : password to access the web UI
|
||||
- `OVERRIDE_ADMIN_CREDS` : force override the admin credentials even if we already have a user in the database (default = `no`)
|
||||
|
||||
Accessing the web UI through BunkerWeb is a classical [reverse proxy setup](quickstart-guide.md#protect-http-applications). We recommend you to connect BunkerWeb and web UI using a dedicated network (like `bw-universe` also used by the scheduler and autoconf) so it won't be on the same network of your web services for obvious security reasons. Please note that the web UI container is listening on the `7000` port.
|
||||
|
||||
|
|
@ -1236,6 +1241,7 @@ After a successful login/password combination, you will be prompted to enter you
|
|||
|
||||
- `ADMIN_USERNAME` : username to access the web UI
|
||||
- `ADMIN_PASSWORD` : password to access the web UI
|
||||
- `OVERRIDE_ADMIN_CREDS` : force override the admin credentials even if we already have a user in the database (default = `no`)
|
||||
|
||||
Accessing the web UI through BunkerWeb is a classical [reverse proxy setup](quickstart-guide.md#protect-http-applications). Network segmentation between web UI and web services is not covered in this documentation. Please note that the web UI container is listening on the `7000` port.
|
||||
|
||||
|
|
@ -1590,6 +1596,7 @@ After a successful login/password combination, you will be prompted to enter you
|
|||
```conf
|
||||
ADMIN_USERNAME=changeme
|
||||
ADMIN_PASSWORD=changeme
|
||||
OVERRIDE_ADMIN_CREDS=no
|
||||
```
|
||||
|
||||
Each time you edit the `/etc/bunkerweb/ui.env` file, you will need to restart the service :
|
||||
|
|
|
|||
|
|
@ -113,6 +113,8 @@ services:
|
|||
- "bunkerweb.REVERSE_PROXY_URL=/admin"
|
||||
- "bunkerweb.REVERSE_PROXY_HOST=http://bw-ui:7000"
|
||||
- "bunkerweb.INTERCEPTED_ERROR_CODES=400 404 405 413 429 500 501 502 503 504"
|
||||
- "bunkerweb.GENERATE_SELF_SIGNED_SSL=yes"
|
||||
- bunkerweb.CUSTOM_CONF_MODSEC_CRS_ip-host=SecRuleRemoveById 920350
|
||||
|
||||
bw-db:
|
||||
image: mariadb:11
|
||||
|
|
|
|||
|
|
@ -110,6 +110,7 @@ services:
|
|||
- "bunkerweb.REVERSE_PROXY_URL=/admin"
|
||||
- "bunkerweb.REVERSE_PROXY_HOST=http://bw-ui:7000"
|
||||
- "bunkerweb.INTERCEPTED_ERROR_CODES=400 404 405 413 429 500 501 502 503 504"
|
||||
- "bunkerweb.GENERATE_SELF_SIGNED_SSL=yes"
|
||||
|
||||
bw-db:
|
||||
image: mariadb:11
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ services:
|
|||
www.example.com_REVERSE_PROXY_URL: "/admin"
|
||||
www.example.com_REVERSE_PROXY_HOST: "http://bw-ui:7000"
|
||||
www.example.com_INTERCEPTED_ERROR_CODES: "400 404 405 413 429 500 501 502 503 504"
|
||||
www.example.com_GENERATE_SELF_SIGNED_SSL: "yes"
|
||||
app1.example.com_USE_REVERSE_PROXY: "yes"
|
||||
app1.example.com_REVERSE_PROXY_URL: "/"
|
||||
app1.example.com_REVERSE_PROXY_HOST: "http://app1:8080"
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ services:
|
|||
www.example.com_REVERSE_PROXY_URL: "/admin"
|
||||
www.example.com_REVERSE_PROXY_HOST: "http://bw-ui:7000"
|
||||
www.example.com_INTERCEPTED_ERROR_CODES: "400 404 405 413 429 500 501 502 503 504"
|
||||
www.example.com_GENERATE_SELF_SIGNED_SSL: "yes"
|
||||
app1.example.com_USE_REVERSE_PROXY: "yes"
|
||||
app1.example.com_REVERSE_PROXY_URL: "/"
|
||||
app1.example.com_REVERSE_PROXY_HOST: "http://app1:8080"
|
||||
|
|
|
|||
|
|
@ -17,3 +17,4 @@ www.example.com_USE_REVERSE_PROXY=yes
|
|||
www.example.com_REVERSE_PROXY_URL=/admin
|
||||
www.example.com_REVERSE_PROXY_HOST=http://127.0.0.1:7000
|
||||
www.example.com_INTERCEPTED_ERROR_CODES=400 404 405 413 429 500 501 502 503 504
|
||||
www.example.com_GENERATE_SELF_SIGNED_SSL=yes
|
||||
|
|
|
|||
|
|
@ -18,4 +18,5 @@ www.example.com_USE_REVERSE_PROXY=yes
|
|||
www.example.com_REVERSE_PROXY_URL=/admin
|
||||
www.example.com_REVERSE_PROXY_HOST=http://127.0.0.1:7000
|
||||
www.example.com_INTERCEPTED_ERROR_CODES=400 404 405 413 429 500 501 502 503 504
|
||||
www.example.com_GENERATE_SELF_SIGNED_SSL=yes
|
||||
EXTERNAL_PLUGIN_URLS=https://github.com/bunkerity/bunkerweb-plugins/archive/refs/heads/dev.zip
|
||||
|
|
|
|||
|
|
@ -46,8 +46,12 @@ class Config:
|
|||
if not server_name:
|
||||
continue
|
||||
for variable, value in service.items():
|
||||
if self._db.is_setting(variable, multisite=True):
|
||||
config[f"{server_name}_{variable}"] = value
|
||||
if variable.startswith("CUSTOM_CONF") or not variable.isupper():
|
||||
continue
|
||||
if not self._db.is_setting(variable, multisite=True):
|
||||
self.__logger.warning(f"Variable {variable}: {value} is not a valid multisite setting, ignoring it")
|
||||
continue
|
||||
config[f"{server_name}_{variable}"] = value
|
||||
config["SERVER_NAME"] += f" {server_name}"
|
||||
config["SERVER_NAME"] = config["SERVER_NAME"].strip()
|
||||
return config
|
||||
|
|
@ -143,6 +147,7 @@ class Config:
|
|||
|
||||
# update instances in database
|
||||
if "instances" in changes:
|
||||
self.__logger.debug(f"Updating instances in database: {self.__instances}")
|
||||
err = self._db.update_instances(self.__instances, "autoconf", changed=False)
|
||||
if err:
|
||||
self.__logger.error(f"Failed to update instances: {err}")
|
||||
|
|
@ -150,6 +155,7 @@ class Config:
|
|||
# save config to database
|
||||
changed_plugins = []
|
||||
if "config" in changes:
|
||||
self.__logger.debug(f"Saving config in database: {self.__config}")
|
||||
err = self._db.save_config(self.__config, "autoconf", changed=False)
|
||||
if isinstance(err, str):
|
||||
success = False
|
||||
|
|
@ -158,6 +164,7 @@ class Config:
|
|||
|
||||
# save custom configs to database
|
||||
if "custom_configs" in changes:
|
||||
self.__logger.debug(f"Saving custom configs in database: {custom_configs}")
|
||||
err = self._db.save_custom_configs(custom_configs, "autoconf", changed=False)
|
||||
if err:
|
||||
success = False
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
FROM python:3.12.3-alpine3.19@sha256:ef097620baf1272e38264207003b0982285da3236a20ed829bf6bbf1e85fe3cb as builder
|
||||
FROM python:3.12.4-alpine3.19@sha256:ef3397d09070efd36583e83d2619cf8006158641e5b6b629d4d92a9778f5aa1c as builder
|
||||
|
||||
# Export var for specific actions on linux/arm/v7
|
||||
ARG TARGETPLATFORM
|
||||
|
|
@ -31,7 +31,7 @@ COPY src/common/helpers helpers
|
|||
COPY src/common/settings.json settings.json
|
||||
COPY src/common/utils utils
|
||||
|
||||
FROM python:3.12.3-alpine3.19@sha256:ef097620baf1272e38264207003b0982285da3236a20ed829bf6bbf1e85fe3cb
|
||||
FROM python:3.12.4-alpine3.19@sha256:ef3397d09070efd36583e83d2619cf8006158641e5b6b629d4d92a9778f5aa1c
|
||||
|
||||
# Set default umask to prevent huge recursive chmod increasing the final image size
|
||||
RUN umask 027
|
||||
|
|
|
|||
|
|
@ -216,9 +216,9 @@ six==1.16.0 \
|
|||
# via
|
||||
# kubernetes
|
||||
# python-dateutil
|
||||
urllib3==2.2.1 \
|
||||
--hash=sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d \
|
||||
--hash=sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19
|
||||
urllib3==2.2.2 \
|
||||
--hash=sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472 \
|
||||
--hash=sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168
|
||||
# via
|
||||
# docker
|
||||
# kubernetes
|
||||
|
|
|
|||
|
|
@ -256,6 +256,15 @@
|
|||
</div>
|
||||
<!-- text -->
|
||||
|
||||
{-raw-}
|
||||
<script nonce="{{ nonce_script }}">
|
||||
// Automatically refresh the page after 2 seconds
|
||||
setTimeout(() => {
|
||||
location.reload();
|
||||
}, 2000);
|
||||
</script>
|
||||
{-raw-}
|
||||
|
||||
<footer class="fixed bottom-1.5 lg:bottom-2">
|
||||
<div class="flex justify-center pb-2">
|
||||
<img
|
||||
|
|
|
|||
|
|
@ -67,18 +67,22 @@ server {
|
|||
end
|
||||
|
||||
local nonce_style = rand(16)
|
||||
local nonce_script = rand(16)
|
||||
|
||||
-- Override CSP header
|
||||
ngx.header["Content-Security-Policy"] = "default-src 'none'; form-action 'self'; img-src 'self' data:; style-src 'self' 'nonce-"
|
||||
ngx.header["Content-Security-Policy"] = "default-src 'none'; script-src http: https: 'unsafe-inline' 'strict-dynamic' 'nonce-"
|
||||
.. nonce_script
|
||||
.. "'; style-src 'nonce-"
|
||||
.. nonce_style
|
||||
.. "'; font-src 'self' data:; base-uri 'self'; require-trusted-types-for 'script';"
|
||||
.. "'; base-uri 'none'; img-src 'self' data:; font-src 'self' data:; require-trusted-types-for 'script';"
|
||||
|
||||
-- Remove server header
|
||||
ngx.header["Server"] = nil
|
||||
|
||||
-- Render template
|
||||
render("index.html", {
|
||||
nonce_style = nonce_style
|
||||
nonce_style = nonce_style,
|
||||
nonce_script = nonce_script
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,42 +60,36 @@ function antibot:header()
|
|||
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
|
||||
-- Override CSP header
|
||||
local csp_directives = {
|
||||
["default-src"] = "'none'",
|
||||
["base-uri"] = "'none'",
|
||||
["img-src"] = "'self' data:",
|
||||
["font-src"] = "'self' data:",
|
||||
["script-src"] = "http: https: 'unsafe-inline' 'strict-dynamic' 'nonce-"
|
||||
.. self.ctx.bw.antibot_nonce_script
|
||||
.. "'",
|
||||
["style-src"] = "'self' 'nonce-" .. self.ctx.bw.antibot_nonce_style .. "'",
|
||||
["require-trusted-types-for"] = "'script'",
|
||||
}
|
||||
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
|
||||
.. "' https://www.google.com/recaptcha/ https://www.gstatic.com/recaptcha/ 'unsafe-inline' http: https:;"
|
||||
.. " img-src https://www.gstatic.com/recaptcha/ 'self' data:; "
|
||||
.. " frame-src https://www.google.com/recaptcha/ https://recaptcha.google.com/recaptcha/;"
|
||||
.. " style-src 'self' 'nonce-"
|
||||
.. self.session_data.nonce_style
|
||||
.. "'; font-src 'self' https://fonts.gstatic.com data:; base-uri 'self';"
|
||||
csp_directives["script-src"] = csp_directives["script-src"]
|
||||
.. " https://www.google.com/recaptcha/ https://www.gstatic.com/recaptcha/"
|
||||
csp_directives["frame-src"] = "https://www.google.com/recaptcha/ https://recaptcha.google.com/recaptcha/"
|
||||
elseif self.session_data.type == "hcaptcha" then
|
||||
ngx.header[header] = "default-src 'none'; form-action 'self'; script-src 'strict-dynamic' 'nonce-"
|
||||
.. self.session_data.nonce_script
|
||||
.. "' https://hcaptcha.com https://*.hcaptcha.com 'unsafe-inline' http: https:; img-src 'self' data:;"
|
||||
.. " frame-src https://hcaptcha.com https://*.hcaptcha.com; style-src 'self' 'nonce-"
|
||||
.. self.session_data.nonce_style
|
||||
.. "' https://hcaptcha.com https://*.hcaptcha.com; connect-src https://hcaptcha.com https://*.hcaptcha.com; "
|
||||
.. " font-src 'self' data:; base-uri 'self';"
|
||||
csp_directives["script-src"] = csp_directives["script-src"] .. " https://hcaptcha.com https://*.hcaptcha.com"
|
||||
csp_directives["frame-src"] = "https://hcaptcha.com https://*.hcaptcha.com"
|
||||
csp_directives["style-src"] = csp_directives["style-src"] .. " https://hcaptcha.com https://*.hcaptcha.com"
|
||||
csp_directives["connect-src"] = "https://hcaptcha.com https://*.hcaptcha.com"
|
||||
elseif self.session_data.type == "turnstile" then
|
||||
ngx.header[header] = "default-src 'none'; form-action 'self'; script-src 'strict-dynamic' 'nonce-"
|
||||
.. self.session_data.nonce_script
|
||||
.. "' https://challenges.cloudflare.com 'unsafe-inline' http: https:; img-src 'self' data:;"
|
||||
.. " frame-src https://challenges.cloudflare.com; style-src 'self' 'nonce-"
|
||||
.. self.session_data.nonce_style
|
||||
.. "'; font-src 'self' data:; base-uri 'self';"
|
||||
else
|
||||
ngx.header[header] = "default-src 'none'; form-action 'self'; script-src 'strict-dynamic' 'nonce-"
|
||||
.. self.session_data.nonce_script
|
||||
.. "' 'unsafe-inline' http: https:; img-src 'self' data:; style-src 'self' 'nonce-"
|
||||
.. self.session_data.nonce_style
|
||||
.. "'; font-src 'self' data:; base-uri 'self';"
|
||||
csp_directives["script-src"] = csp_directives["script-src"] .. " https://challenges.cloudflare.com"
|
||||
csp_directives["frame-src"] = "https://challenges.cloudflare.com"
|
||||
end
|
||||
local csp_content = ""
|
||||
for directive, value in pairs(csp_directives) do
|
||||
csp_content = csp_content .. directive .. " " .. value .. "; "
|
||||
end
|
||||
ngx.header["Content-Security-Policy"] = csp_content
|
||||
return self:ret(true, "successfully overridden CSP header")
|
||||
end
|
||||
|
||||
|
|
@ -192,6 +186,9 @@ function antibot:content()
|
|||
return self:ret(true, "no session", nil, "/")
|
||||
end
|
||||
|
||||
self.ctx.bw.antibot_nonce_script = rand(32)
|
||||
self.ctx.bw.antibot_nonce_style = rand(32)
|
||||
|
||||
-- Display content
|
||||
local ok, err = self:display_challenge()
|
||||
if not ok then
|
||||
|
|
@ -242,8 +239,6 @@ function antibot:prepare_challenge()
|
|||
self.session_data.type = self.variables["USE_ANTIBOT"]
|
||||
self.session_data.resolved = false
|
||||
self.session_data.original_uri = self.ctx.bw.request_uri
|
||||
self.session_data.nonce_script = rand(16)
|
||||
self.session_data.nonce_style = rand(16)
|
||||
if self.ctx.bw.uri == self.variables["ANTIBOT_URI"] then
|
||||
self.session_data.original_uri = "/"
|
||||
end
|
||||
|
|
@ -268,8 +263,8 @@ function antibot:display_challenge()
|
|||
-- Common variables for templates
|
||||
local template_vars = {
|
||||
antibot_uri = self.variables["ANTIBOT_URI"],
|
||||
nonce_script = self.session_data.nonce_script,
|
||||
nonce_style = self.session_data.nonce_style,
|
||||
nonce_script = self.ctx.bw.antibot_nonce_script,
|
||||
nonce_style = self.ctx.bw.antibot_nonce_style,
|
||||
}
|
||||
|
||||
-- Javascript case
|
||||
|
|
@ -387,7 +382,10 @@ function antibot:check_challenge()
|
|||
if not ok then
|
||||
return nil, "error while decoding JSON from reCAPTCHA API : " .. rdata, nil
|
||||
end
|
||||
if not rdata.success or rdata.score < tonumber(self.variables["ANTIBOT_RECAPTCHA_SCORE"]) then
|
||||
if not rdata.success then
|
||||
return false, "client failed challenge", nil
|
||||
end
|
||||
if rdata.score and rdata.score < tonumber(self.variables["ANTIBOT_RECAPTCHA_SCORE"]) then
|
||||
return false, "client failed challenge with score " .. tostring(rdata.score), nil
|
||||
end
|
||||
self.session_data.resolved = true
|
||||
|
|
|
|||
113
src/common/core/antibot/files/recaptcha.html
vendored
113
src/common/core/antibot/files/recaptcha.html
vendored
|
|
@ -22,6 +22,65 @@
|
|||
margin-top: 1rem
|
||||
}
|
||||
</style>
|
||||
{-raw-}
|
||||
<script
|
||||
src="https://www.google.com/recaptcha/api.js?onload=onv3Callback&render={*recaptcha_sitekey*}&trustedtypes=true"
|
||||
nonce="{*nonce_script*}"
|
||||
></script>
|
||||
<script
|
||||
defer
|
||||
src="https://www.google.com/recaptcha/api.js?onload=onv2Callback&trustedtypes=true"
|
||||
nonce="{*nonce_script*}"
|
||||
></script>
|
||||
<script type="text/javascript" nonce="{*nonce_script*}">
|
||||
var onSubmit = function (token) {
|
||||
document.getElementById("token").value = token;
|
||||
document.getElementById("form").submit();
|
||||
};
|
||||
|
||||
var usedVersion = "v2";
|
||||
|
||||
var onv2Callback = function () {
|
||||
if (usedVersion === "invisible") {
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove the v3 button
|
||||
document.getElementById("recaptcha-verify").remove();
|
||||
|
||||
// Insert the v2 div
|
||||
var recaptchaDiv = document.createElement("div");
|
||||
recaptchaDiv.id = "recaptcha-v2-verify";
|
||||
recaptchaDiv.className = "g-recaptcha";
|
||||
recaptchaDiv.setAttribute("data-sitekey", "{*recaptcha_sitekey*}");
|
||||
recaptchaDiv.setAttribute("data-callback", "onSubmit");
|
||||
recaptchaDiv.setAttribute("data-action", "submit");
|
||||
document
|
||||
.getElementById("recaptcha-container")
|
||||
.appendChild(recaptchaDiv);
|
||||
|
||||
grecaptcha.ready(function () {
|
||||
grecaptcha.render("recaptcha-v2-verify", {
|
||||
sitekey: "{*recaptcha_sitekey*}",
|
||||
callback: onSubmit,
|
||||
action: "submit",
|
||||
});
|
||||
document.querySelector(".grecaptcha-badge").remove();
|
||||
});
|
||||
};
|
||||
|
||||
var onv3Callback = function () {
|
||||
usedVersion = "invisible";
|
||||
grecaptcha.ready(function () {
|
||||
document
|
||||
.getElementById("recaptcha-verify")
|
||||
.addEventListener("click", function () {
|
||||
grecaptcha.execute();
|
||||
});
|
||||
});
|
||||
};
|
||||
</script>
|
||||
{-raw-}
|
||||
</head>
|
||||
<body
|
||||
class="bg-gradient-to-r from-[#075577] to-[#116D70] w-screen h-screen overflow-hidden"
|
||||
|
|
@ -255,14 +314,19 @@
|
|||
<form class="hidden" method="POST" action="{*antibot_uri*}" id="form">
|
||||
<input type="hidden" name="token" id="token" />
|
||||
</form>
|
||||
{-raw-}
|
||||
<div class="mt-8 flex flex-col justify-center items-center">
|
||||
<button
|
||||
id="recaptcha-verify"
|
||||
class="text-sm xs:text-base mb-2.5 hover:brightness-90 mt-2 rounded-lg bg-secondary px-6 py-2 text-white font-bold"
|
||||
>
|
||||
I'm not a robot
|
||||
</button>
|
||||
<div id="recaptcha-container">
|
||||
<button
|
||||
id="recaptcha-verify"
|
||||
class="g-recaptcha text-sm xs:text-base mb-2.5 hover:brightness-90 mt-2 rounded-lg bg-secondary px-6 py-2 text-white font-bold"
|
||||
data-sitekey="{*recaptcha_sitekey*}"
|
||||
data-callback="onSubmit"
|
||||
data-action="submit"
|
||||
>
|
||||
I'm not a robot
|
||||
</button>
|
||||
</div>
|
||||
{-raw-}
|
||||
<p
|
||||
id="recaptcha-terms"
|
||||
class="text-gray-100 text-center text-xs sm:text-sm"
|
||||
|
|
@ -284,41 +348,6 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{-raw-}
|
||||
<script nonce="{*nonce_script*}">
|
||||
// recaptcha
|
||||
const check_robot = function () {
|
||||
grecaptcha.ready(function () {
|
||||
grecaptcha
|
||||
.execute("{*recaptcha_sitekey*}", { action: "recaptcha" })
|
||||
.then(function (token) {
|
||||
document.getElementById("token").value = token;
|
||||
document.getElementById("form").submit();
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
var cooldown = false;
|
||||
|
||||
document
|
||||
.getElementById("recaptcha-verify")
|
||||
.addEventListener("click", (e) => {
|
||||
e.preventDefault();
|
||||
if (cooldown) return;
|
||||
cooldown = true;
|
||||
check_robot();
|
||||
setTimeout(() => {
|
||||
cooldown = false;
|
||||
}, 1500);
|
||||
});
|
||||
</script>
|
||||
<script
|
||||
async
|
||||
src="https://www.google.com/recaptcha/api.js?render={*recaptcha_sitekey*}"
|
||||
nonce="{*nonce_script*}"
|
||||
></script>
|
||||
{-raw-}
|
||||
|
||||
<!-- text -->
|
||||
<footer class="fixed bottom-1.5 lg:bottom-2">
|
||||
<div class="flex justify-center pb-2">
|
||||
|
|
|
|||
1
src/common/core/antibot/files/turnstile.html
vendored
1
src/common/core/antibot/files/turnstile.html
vendored
|
|
@ -22,7 +22,6 @@
|
|||
</style>
|
||||
{-raw-}
|
||||
<script
|
||||
async
|
||||
defer
|
||||
src="https://challenges.cloudflare.com/turnstile/v0/api.js"
|
||||
nonce="{*nonce_script*}"
|
||||
|
|
|
|||
|
|
@ -53,9 +53,9 @@
|
|||
"ANTIBOT_RECAPTCHA_SCORE": {
|
||||
"context": "multisite",
|
||||
"default": "0.7",
|
||||
"help": "Minimum score required for reCAPTCHA challenge.",
|
||||
"help": "Minimum score required for reCAPTCHA challenge (Only compatible with reCAPTCHA v3).",
|
||||
"id": "antibot-recaptcha-score",
|
||||
"label": "reCAPTCHA score",
|
||||
"label": "reCAPTCHA v3 score",
|
||||
"regex": "^(0\\.[1-9]|1\\.0)$",
|
||||
"type": "text"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@
|
|||
"BLACKLIST_IP_URLS": {
|
||||
"context": "global",
|
||||
"default": "https://www.dan.me.uk/torlist/?exit",
|
||||
"help": "List of URLs, separated with spaces, containing bad IP/network to block.",
|
||||
"help": "List of URLs, separated with spaces, containing bad IP/network to block. Also supports file:// URLs and and auth basic using http://user:pass@url scheme.",
|
||||
"id": "blacklist-ip-urls",
|
||||
"label": "Blacklist IP/network URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
|
|
@ -125,7 +125,7 @@
|
|||
"BLACKLIST_RDNS_URLS": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
"help": "List of URLs, separated with spaces, containing reverse DNS suffixes to block.",
|
||||
"help": "List of URLs, separated with spaces, containing reverse DNS suffixes to block. Also supports file:// URLs and and auth basic using http://user:pass@url scheme.",
|
||||
"id": "blacklist-rdns-urls",
|
||||
"label": "Blacklist reverse DNS URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
|
|
@ -134,7 +134,7 @@
|
|||
"BLACKLIST_ASN_URLS": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
"help": "List of URLs, separated with spaces, containing ASN to block.",
|
||||
"help": "List of URLs, separated with spaces, containing ASN to block. Also supports file:// URLs and and auth basic using http://user:pass@url scheme.",
|
||||
"id": "blacklist-asn-urls",
|
||||
"label": "Blacklist ASN URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
|
|
@ -143,7 +143,7 @@
|
|||
"BLACKLIST_USER_AGENT_URLS": {
|
||||
"context": "global",
|
||||
"default": "https://raw.githubusercontent.com/mitchellkrogza/nginx-ultimate-bad-bot-blocker/master/_generator_lists/bad-user-agents.list",
|
||||
"help": "List of URLs, separated with spaces, containing bad User-Agent to block.",
|
||||
"help": "List of URLs, separated with spaces, containing bad User-Agent to block. Also supports file:// URLs and and auth basic using http://user:pass@url scheme.",
|
||||
"id": "blacklist-user-agent-urls",
|
||||
"label": "Blacklist User-Agent URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
|
|
@ -152,7 +152,7 @@
|
|||
"BLACKLIST_URI_URLS": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
"help": "List of URLs, separated with spaces, containing bad URI to block.",
|
||||
"help": "List of URLs, separated with spaces, containing bad URI to block. Also supports file:// URLs and and auth basic using http://user:pass@url scheme.",
|
||||
"id": "blacklist-uri-urls",
|
||||
"label": "Blacklist URI URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
|
|
@ -161,7 +161,7 @@
|
|||
"BLACKLIST_IGNORE_IP_URLS": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
"help": "List of URLs, separated with spaces, containing IP/network to ignore in the blacklist.",
|
||||
"help": "List of URLs, separated with spaces, containing IP/network to ignore in the blacklist. Also supports file:// URLs and and auth basic using http://user:pass@url scheme.",
|
||||
"id": "blacklist-ignore-ip-urls",
|
||||
"label": "Blacklist ignore IP/network URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
|
|
@ -170,7 +170,7 @@
|
|||
"BLACKLIST_IGNORE_RDNS_URLS": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
"help": "List of URLs, separated with spaces, containing reverse DNS suffixes to ignore in the blacklist.",
|
||||
"help": "List of URLs, separated with spaces, containing reverse DNS suffixes to ignore in the blacklist. Also supports file:// URLs and and auth basic using http://user:pass@url scheme.",
|
||||
"id": "blacklist-ignore-rdns-urls",
|
||||
"label": "Blacklist ignore reverse DNS URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
|
|
@ -179,7 +179,7 @@
|
|||
"BLACKLIST_IGNORE_ASN_URLS": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
"help": "List of URLs, separated with spaces, containing ASN to ignore in the blacklist.",
|
||||
"help": "List of URLs, separated with spaces, containing ASN to ignore in the blacklist. Also supports file:// URLs and and auth basic using http://user:pass@url scheme.",
|
||||
"id": "blacklist-ignore-asn-urls",
|
||||
"label": "Blacklist ignore ASN URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
|
|
@ -188,7 +188,7 @@
|
|||
"BLACKLIST_IGNORE_USER_AGENT_URLS": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
"help": "List of URLs, separated with spaces, containing User-Agent to ignore in the blacklist.",
|
||||
"help": "List of URLs, separated with spaces, containing User-Agent to ignore in the blacklist. Also supports file:// URLs and and auth basic using http://user:pass@url scheme.",
|
||||
"id": "blacklist-ignore-user-agent-urls",
|
||||
"label": "Blacklist ignore User-Agent URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
|
|
@ -197,7 +197,7 @@
|
|||
"BLACKLIST_IGNORE_URI_URLS": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
"help": "List of URLs, separated with spaces, containing URI to ignore in the blacklist.",
|
||||
"help": "List of URLs, separated with spaces, containing URI to ignore in the blacklist. Also supports file:// URLs and and auth basic using http://user:pass@url scheme.",
|
||||
"id": "blacklist-ignore-uri-urls",
|
||||
"label": "Blacklist ignore URI URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from contextlib import suppress
|
||||
from os import getenv, sep
|
||||
from os.path import join
|
||||
from pathlib import Path
|
||||
|
|
@ -21,8 +20,8 @@ LOGGER = setup_logger("CUSTOM-CERT", getenv("LOG_LEVEL", "INFO"))
|
|||
JOB = Job(LOGGER)
|
||||
|
||||
|
||||
def check_cert(cert_file: Union[Path, bytes], key_file: Union[Path, bytes], first_server: str) -> Tuple[bool, str]:
|
||||
with suppress(BaseException):
|
||||
def check_cert(cert_file: Union[Path, bytes], key_file: Union[Path, bytes], first_server: str) -> Tuple[bool, Union[str, BaseException]]:
|
||||
try:
|
||||
ret = False
|
||||
if not cert_file or not key_file:
|
||||
return False, "Both variables CUSTOM_SSL_CERT and CUSTOM_SSL_KEY have to be set to use custom certificates"
|
||||
|
|
@ -54,7 +53,8 @@ def check_cert(cert_file: Union[Path, bytes], key_file: Union[Path, bytes], firs
|
|||
LOGGER.error(f"Error while caching custom-key key.pem file : {err}")
|
||||
|
||||
return ret, ""
|
||||
return False, "exception"
|
||||
except BaseException as e:
|
||||
return False, e
|
||||
|
||||
|
||||
status = 0
|
||||
|
|
@ -112,8 +112,8 @@ try:
|
|||
|
||||
LOGGER.info(f"Checking certificate for {first_server} ...")
|
||||
need_reload, err = check_cert(cert_file, key_file, first_server)
|
||||
if err == "exception":
|
||||
LOGGER.exception(f"Exception while checking {first_server}'s certificate, skipping ...")
|
||||
if isinstance(err, BaseException):
|
||||
LOGGER.error(f"Exception while checking {first_server}'s certificate, skipping ... \n{err}")
|
||||
skipped_servers.append(first_server)
|
||||
continue
|
||||
elif err:
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@
|
|||
"GREYLIST_IP_URLS": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
"help": "List of URLs, separated with spaces, containing good IP/network to put into the greylist.",
|
||||
"help": "List of URLs, separated with spaces, containing good IP/network to put into the greylist. Also supports file:// URLs and and auth basic using http://user:pass@url scheme.",
|
||||
"id": "greylist-ip-urls",
|
||||
"label": "Greylist IP/network URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
|
|
@ -80,7 +80,7 @@
|
|||
"GREYLIST_RDNS_URLS": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
"help": "List of URLs, separated with spaces, containing reverse DNS suffixes to put into the greylist.",
|
||||
"help": "List of URLs, separated with spaces, containing reverse DNS suffixes to put into the greylist. Also supports file:// URLs and and auth basic using http://user:pass@url scheme.",
|
||||
"id": "greylist-rdns-urls",
|
||||
"label": "Greylist reverse DNS URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
|
|
@ -89,7 +89,7 @@
|
|||
"GREYLIST_ASN_URLS": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
"help": "List of URLs, separated with spaces, containing ASN to put into the greylist.",
|
||||
"help": "List of URLs, separated with spaces, containing ASN to put into the greylist. Also supports file:// URLs and and auth basic using http://user:pass@url scheme.",
|
||||
"id": "greylist-asn-urls",
|
||||
"label": "Greylist ASN URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
|
|
@ -98,7 +98,7 @@
|
|||
"GREYLIST_USER_AGENT_URLS": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
"help": "List of URLs, separated with spaces, containing good User-Agent to put into the greylist.",
|
||||
"help": "List of URLs, separated with spaces, containing good User-Agent to put into the greylist. Also supports file:// URLs and and auth basic using http://user:pass@url scheme.",
|
||||
"id": "greylist-user-agent-urls",
|
||||
"label": "Greylist User-Agent URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
|
|
@ -107,7 +107,7 @@
|
|||
"GREYLIST_URI_URLS": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
"help": "List of URLs, separated with spaces, containing bad URI to put into the greylist.",
|
||||
"help": "List of URLs, separated with spaces, containing bad URI to put into the greylist. Also supports file:// URLs and and auth basic using http://user:pass@url scheme.",
|
||||
"id": "greylist-uri-urls",
|
||||
"label": "Greylist URI URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
|
|
|
|||
25
src/common/core/jobs/jobs/failover-backup.py
Normal file
25
src/common/core/jobs/jobs/failover-backup.py
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from os import getenv, sep
|
||||
from os.path import join
|
||||
from sys import exit as sys_exit, path as sys_path
|
||||
from traceback import format_exc
|
||||
|
||||
for deps_path in [join(sep, "usr", "share", "bunkerweb", *paths) for paths in (("deps", "python"), ("utils",), ("db",))]:
|
||||
if deps_path not in sys_path:
|
||||
sys_path.append(deps_path)
|
||||
|
||||
from jobs import Job # type: ignore
|
||||
from logger import setup_logger # type: ignore
|
||||
|
||||
LOGGER = setup_logger("FAILOVER-BACKUP", getenv("LOG_LEVEL", "INFO"))
|
||||
status = 0
|
||||
|
||||
try:
|
||||
# Restoring the backup failover configuration
|
||||
JOB = Job(LOGGER)
|
||||
except:
|
||||
status = 2
|
||||
LOGGER.error(f"Exception while running failover-backup.py :\n{format_exc()}")
|
||||
|
||||
sys_exit(status)
|
||||
|
|
@ -82,8 +82,8 @@ try:
|
|||
for chunk in resp.iter_content(chunk_size=4 * 1024):
|
||||
if chunk:
|
||||
file_content.write(chunk)
|
||||
except RequestException:
|
||||
LOGGER.error(f"Error while downloading mmdb file from {mmdb_url}")
|
||||
except RequestException as e:
|
||||
LOGGER.error(f"Error while downloading mmdb file from {mmdb_url}: {e}")
|
||||
sys_exit(2)
|
||||
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -82,8 +82,8 @@ try:
|
|||
for chunk in resp.iter_content(chunk_size=4 * 1024):
|
||||
if chunk:
|
||||
file_content.write(chunk)
|
||||
except RequestException:
|
||||
LOGGER.error(f"Error while downloading mmdb file from {mmdb_url}")
|
||||
except RequestException as e:
|
||||
LOGGER.error(f"Error while downloading mmdb file from {mmdb_url}: {e}")
|
||||
sys_exit(2)
|
||||
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -23,6 +23,12 @@
|
|||
"file": "update-check.py",
|
||||
"every": "day",
|
||||
"reload": false
|
||||
},
|
||||
{
|
||||
"name": "failover-backup",
|
||||
"file": "failover-backup.py",
|
||||
"every": "once",
|
||||
"reload": false
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ try:
|
|||
if key not in ("version", "integration", "database_version", "is_pro"):
|
||||
data.pop(key, None)
|
||||
|
||||
db_config = JOB.db.get_config(methods=True, with_drafts=True)
|
||||
db_config = JOB.db.get_non_default_settings(methods=True, with_drafts=True)
|
||||
services = db_config.get("SERVER_NAME", {"value": ""})["value"].split(" ")
|
||||
multisite = db_config.get("MULTISITE", {"value": "no"})["value"] == "yes"
|
||||
|
||||
|
|
@ -85,7 +85,7 @@ try:
|
|||
|
||||
data["non_default_settings"] = {}
|
||||
for setting, setting_data in db_config.items():
|
||||
if isinstance(setting_data, dict) and setting_data["method"] != "default":
|
||||
if isinstance(setting_data, dict):
|
||||
for server in services:
|
||||
if setting.startswith(server + "_"):
|
||||
setting = setting[len(server) + 1 :] # noqa: E203
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
"letsencrypt",
|
||||
"selfsigned"
|
||||
],
|
||||
"set": ["sessions", "whitelist", "letsencrypt", "customcert", "selfsigned"],
|
||||
"set": ["sessions", "whitelist", "letsencrypt", "customcert", "selfsigned", "ui"],
|
||||
"ssl_certificate": ["customcert", "letsencrypt", "selfsigned"],
|
||||
"access": [
|
||||
"whitelist",
|
||||
|
|
|
|||
|
|
@ -95,7 +95,6 @@ def install_plugin(plugin_path: Path, db, preview: bool = True) -> bool:
|
|||
try:
|
||||
db = Database(LOGGER, sqlalchemy_string=getenv("DATABASE_URI"))
|
||||
db_metadata = db.get_metadata()
|
||||
db_config = db.get_config()
|
||||
current_date = datetime.now()
|
||||
pro_license_key = getenv("PRO_LICENSE_KEY", "").strip()
|
||||
|
||||
|
|
@ -110,6 +109,7 @@ try:
|
|||
headers = {"User-Agent": f"BunkerWeb/{data['version']}"}
|
||||
default_metadata = {
|
||||
"is_pro": False,
|
||||
"pro_license": pro_license_key,
|
||||
"pro_expire": None,
|
||||
"pro_status": "invalid",
|
||||
"pro_overlapped": False,
|
||||
|
|
@ -157,7 +157,7 @@ try:
|
|||
|
||||
# ? If we already checked today, skip the check and if the metadata is the same, skip the check
|
||||
if (
|
||||
pro_license_key == db_config["PRO_LICENSE_KEY"]
|
||||
pro_license_key == db_metadata.get("pro_license", "")
|
||||
and metadata.get("is_pro", False) == db_metadata["is_pro"]
|
||||
and db_metadata["last_pro_check"]
|
||||
and current_date.replace(hour=0, minute=0, second=0, microsecond=0) == db_metadata["last_pro_check"].replace(hour=0, minute=0, second=0, microsecond=0)
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@
|
|||
"REAL_IP_FROM_URLS": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
"help": "List of URLs containing trusted IPs / networks, separated with spaces, where proxied requests come from.",
|
||||
"help": "List of URLs containing trusted IPs / networks, separated with spaces, where proxied requests come from. Also supports file:// URLs and and auth basic using http://user:pass@url scheme.",
|
||||
"id": "real-ip-from-urls",
|
||||
"label": "Real IP from URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
|
|
|
|||
|
|
@ -38,7 +38,27 @@ location /setup/check {
|
|||
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
|
||||
default_type 'text/plain';
|
||||
content_by_lua_block {
|
||||
ngx.say("ok")
|
||||
local logger = require "bunkerweb.logger":new("UI")
|
||||
local args, err = ngx.req.get_uri_args(1)
|
||||
if err == "truncated" or not args["server_name"] or args["server_name"] == "" then
|
||||
logger:log(ngx.NOTICE, "Received standard server name check")
|
||||
ngx.print("ok")
|
||||
else
|
||||
logger:log(ngx.NOTICE, "Received remote server name check for " .. args["server_name"])
|
||||
local http = require "resty.http".new()
|
||||
local res, err = http:request_uri("https://" .. args["server_name"] .. "/setup/check", {ssl_verify = false})
|
||||
if not res then
|
||||
ngx.print("ko")
|
||||
logger:log(ngx.ERR, "Server name check failed : " .. err)
|
||||
return
|
||||
end
|
||||
if res.status == 200 and res.body == "ok" then
|
||||
ngx.print("ok")
|
||||
return
|
||||
end
|
||||
logger:log(ngx.ERR, "Server name check failed : status = " .. tostring(res.status) .. " and body != ok")
|
||||
ngx.print("ko")
|
||||
end
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
19
src/common/core/ui/ui.lua
Normal file
19
src/common/core/ui/ui.lua
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
local class = require "middleclass"
|
||||
local plugin = require "bunkerweb.plugin"
|
||||
|
||||
local ui = class("ui", plugin)
|
||||
|
||||
function ui:initialize(ctx)
|
||||
-- Call parent initialize
|
||||
plugin.initialize(self, "ui", ctx)
|
||||
end
|
||||
|
||||
function ui:set()
|
||||
local https_configured = self.variables["USE_UI"]
|
||||
if https_configured == "yes" then
|
||||
self.ctx.bw.https_configured = "yes"
|
||||
end
|
||||
return self:ret(true, "set https_configured to " .. https_configured)
|
||||
end
|
||||
|
||||
return ui
|
||||
|
|
@ -71,7 +71,7 @@
|
|||
"WHITELIST_IP_URLS": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
"help": "List of URLs, separated with spaces, containing good IP/network to whitelist.",
|
||||
"help": "List of URLs, separated with spaces, containing good IP/network to whitelist. Also supports file:// URLs and and auth basic using http://user:pass@url scheme.",
|
||||
"id": "whitelist-ip-urls",
|
||||
"label": "Whitelist IP/network URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
|
|
@ -80,7 +80,7 @@
|
|||
"WHITELIST_RDNS_URLS": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
"help": "List of URLs, separated with spaces, containing reverse DNS suffixes to whitelist.",
|
||||
"help": "List of URLs, separated with spaces, containing reverse DNS suffixes to whitelist. Also supports file:// URLs and and auth basic using http://user:pass@url scheme.",
|
||||
"id": "whitelist-rdns-urls",
|
||||
"label": "Whitelist reverse DNS URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
|
|
@ -89,7 +89,7 @@
|
|||
"WHITELIST_ASN_URLS": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
"help": "List of URLs, separated with spaces, containing ASN to whitelist.",
|
||||
"help": "List of URLs, separated with spaces, containing ASN to whitelist. Also supports file:// URLs and and auth basic using http://user:pass@url scheme.",
|
||||
"id": "whitelist-asn-urls",
|
||||
"label": "Whitelist ASN URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
|
|
@ -98,7 +98,7 @@
|
|||
"WHITELIST_USER_AGENT_URLS": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
"help": "List of URLs, separated with spaces, containing good User-Agent to whitelist.",
|
||||
"help": "List of URLs, separated with spaces, containing good User-Agent to whitelist. Also supports file:// URLs and and auth basic using http://user:pass@url scheme.",
|
||||
"id": "whitelist-user-agent-urls",
|
||||
"label": "Whitelist User-Agent URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
|
|
@ -107,7 +107,7 @@
|
|||
"WHITELIST_URI_URLS": {
|
||||
"context": "global",
|
||||
"default": "",
|
||||
"help": "List of URLs, separated with spaces, containing bad URI to whitelist.",
|
||||
"help": "List of URLs, separated with spaces, containing bad URI to whitelist. Also supports file:// URLs and and auth basic using http://user:pass@url scheme.",
|
||||
"id": "whitelist-uri-urls",
|
||||
"label": "Whitelist URI URLs",
|
||||
"regex": "^( *((https?:\\/\\/|file:\\/\\/\\/)[\\-\\w@:%.+~#=]+[\\-\\w\\(\\)!@:%+.~#?&\\/=$]*)(?!.*\\2(?!.)) *)*$",
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@ from datetime import datetime
|
|||
from io import BytesIO
|
||||
from logging import Logger
|
||||
from os import _exit, getenv, listdir, sep
|
||||
from os.path import join
|
||||
from os.path import join as os_join
|
||||
from pathlib import Path
|
||||
from re import compile as re_compile
|
||||
from re import compile as re_compile, escape, search
|
||||
from sys import argv, path as sys_path
|
||||
from threading import Lock
|
||||
from typing import Any, Dict, List, Literal, Optional, Set, Tuple, Union
|
||||
|
|
@ -34,14 +34,14 @@ from model import (
|
|||
Metadata,
|
||||
)
|
||||
|
||||
for deps_path in [join(sep, "usr", "share", "bunkerweb", *paths) for paths in (("deps", "python"), ("utils",))]:
|
||||
for deps_path in [os_join(sep, "usr", "share", "bunkerweb", *paths) for paths in (("deps", "python"), ("utils",))]:
|
||||
if deps_path not in sys_path:
|
||||
sys_path.append(deps_path)
|
||||
|
||||
from common_utils import bytes_hash # type: ignore
|
||||
|
||||
from pymysql import install_as_MySQLdb
|
||||
from sqlalchemy import create_engine, event, MetaData as sql_metadata, text, inspect
|
||||
from sqlalchemy import create_engine, event, MetaData as sql_metadata, join, select as db_select, text, inspect
|
||||
from sqlalchemy.engine import Engine
|
||||
from sqlalchemy.exc import (
|
||||
ArgumentError,
|
||||
|
|
@ -304,12 +304,42 @@ class Database:
|
|||
"""Check if the setting exists in the database and optionally if it's multisite"""
|
||||
with self.__db_session() as session:
|
||||
try:
|
||||
if multisite:
|
||||
return session.query(Settings).filter_by(id=setting, context="multisite").first() is not None
|
||||
return session.query(Settings).filter_by(id=setting).first() is not None
|
||||
multiple = False
|
||||
if self.suffix_rx.search(setting):
|
||||
setting = setting.rsplit("_", 1)[0]
|
||||
multiple = True
|
||||
|
||||
db_setting = session.query(Settings).filter_by(id=setting).first()
|
||||
|
||||
if not db_setting:
|
||||
return False
|
||||
elif multisite and db_setting.context != "multisite":
|
||||
return False
|
||||
elif multiple and db_setting.multiple is None:
|
||||
return False
|
||||
return True
|
||||
except (ProgrammingError, OperationalError):
|
||||
return False
|
||||
|
||||
def set_failover(self, value: bool = True) -> str:
|
||||
"""Set the failover value"""
|
||||
with self.__db_session() as session:
|
||||
if self.readonly:
|
||||
return "The database is read-only, the changes will not be saved"
|
||||
|
||||
try:
|
||||
metadata = session.query(Metadata).get(1)
|
||||
|
||||
if not metadata:
|
||||
return "The metadata are not set yet, try again"
|
||||
|
||||
metadata.failover = value
|
||||
session.commit()
|
||||
except BaseException as e:
|
||||
return str(e)
|
||||
|
||||
return ""
|
||||
|
||||
def initialize_db(self, version: str, integration: str = "Unknown") -> str:
|
||||
"""Initialize the database"""
|
||||
with self.__db_session() as session:
|
||||
|
|
@ -338,16 +368,18 @@ class Database:
|
|||
|
||||
return ""
|
||||
|
||||
def get_metadata(self) -> Dict[str, str]:
|
||||
def get_metadata(self) -> Dict[str, Any]:
|
||||
"""Get the metadata from the database"""
|
||||
data = {
|
||||
"is_initialized": False,
|
||||
"is_pro": "no",
|
||||
"pro_license": "",
|
||||
"pro_expire": None,
|
||||
"pro_status": "invalid",
|
||||
"pro_services": 0,
|
||||
"pro_overlapped": False,
|
||||
"last_pro_check": None,
|
||||
"failover": False,
|
||||
"first_config_saved": False,
|
||||
"autoconf_loaded": False,
|
||||
"scheduler_first_start": True,
|
||||
|
|
@ -1367,12 +1399,124 @@ class Database:
|
|||
|
||||
return message
|
||||
|
||||
def get_config(self, global_only: bool = False, methods: bool = False, with_drafts: bool = False) -> Dict[str, Any]:
|
||||
def get_non_default_settings(
|
||||
self,
|
||||
global_only: bool = False,
|
||||
methods: bool = False,
|
||||
with_drafts: bool = False,
|
||||
filtered_settings: Optional[Union[List[str], Set[str], Tuple[str]]] = None,
|
||||
*,
|
||||
original_config: Optional[Dict[str, Any]] = None,
|
||||
original_multisite: Optional[Set[str]] = None,
|
||||
) -> Dict[str, Any]:
|
||||
"""Get the config from the database"""
|
||||
filtered_settings = set(filtered_settings or [])
|
||||
|
||||
if filtered_settings and not global_only:
|
||||
filtered_settings.update(("SERVER_NAME", "MULTISITE"))
|
||||
|
||||
with self.__db_session() as session:
|
||||
config = original_config or {}
|
||||
multisite = original_multisite or set()
|
||||
|
||||
# Define the join operation
|
||||
j = join(Settings, Global_values, Settings.id == Global_values.setting_id)
|
||||
|
||||
# Define the select statement
|
||||
stmt = (
|
||||
db_select(Settings.id.label("setting_id"), Settings.context, Settings.multiple, Global_values.value, Global_values.suffix, Global_values.method)
|
||||
.select_from(j)
|
||||
.order_by(Settings.order)
|
||||
)
|
||||
|
||||
if filtered_settings:
|
||||
stmt = stmt.where(Settings.id.in_(filtered_settings))
|
||||
|
||||
# Execute the query and fetch all results
|
||||
results = session.execute(stmt).fetchall()
|
||||
|
||||
for global_value in results:
|
||||
setting_id = global_value.setting_id + (f"_{global_value.suffix}" if global_value.multiple and global_value.suffix > 0 else "")
|
||||
config[setting_id] = global_value.value if not methods else {"value": global_value.value, "global": True, "method": global_value.method}
|
||||
if global_value.context == "multisite":
|
||||
multisite.add(setting_id)
|
||||
|
||||
is_multisite = config.get("MULTISITE", {"value": "no"})["value"] == "yes" if methods else config.get("MULTISITE", "no") == "yes"
|
||||
|
||||
services = session.query(Services).with_entities(Services.id, Services.is_draft)
|
||||
|
||||
if not with_drafts:
|
||||
services = services.filter_by(is_draft=False)
|
||||
|
||||
if not global_only and is_multisite:
|
||||
servers = ""
|
||||
for service in services:
|
||||
config[f"{service.id}_IS_DRAFT"] = "yes" if service.is_draft else "no"
|
||||
if methods:
|
||||
config[f"{service.id}_IS_DRAFT"] = {"value": config[f"{service.id}_IS_DRAFT"], "global": False, "method": "default"}
|
||||
for key in multisite:
|
||||
config[f"{service.id}_{key}"] = config[key]
|
||||
servers += f"{service.id} "
|
||||
servers = servers.strip()
|
||||
|
||||
# Define the join operation
|
||||
j = join(Services, Services_settings, Services.id == Services_settings.service_id)
|
||||
j = j.join(Settings, Settings.id == Services_settings.setting_id)
|
||||
|
||||
# Define the select statement
|
||||
stmt = (
|
||||
db_select(
|
||||
Services.id.label("service_id"),
|
||||
Settings.id.label("setting_id"),
|
||||
Settings.multiple,
|
||||
Services_settings.value,
|
||||
Services_settings.suffix,
|
||||
Services_settings.method,
|
||||
)
|
||||
.select_from(j)
|
||||
.order_by(Services.id, Settings.order)
|
||||
)
|
||||
|
||||
if not with_drafts:
|
||||
stmt = stmt.where(Services.is_draft == False) # noqa: E712
|
||||
|
||||
if filtered_settings:
|
||||
stmt = stmt.where(Settings.id.in_(filtered_settings))
|
||||
|
||||
# Execute the query and fetch all results
|
||||
results = session.execute(stmt).fetchall()
|
||||
|
||||
for result in results:
|
||||
value = result.value
|
||||
|
||||
if result.setting_id == "SERVER_NAME" and not search(r"^" + escape(result.service_id) + r"( |$)", value):
|
||||
split = set(value.split(" "))
|
||||
split.discard(result.service_id)
|
||||
value = result.service_id + " " + " ".join(split)
|
||||
|
||||
config[f"{result.service_id}_{result.setting_id}" + (f"_{result.suffix}" if result.multiple and result.suffix else "")] = (
|
||||
value if not methods else {"value": value, "global": False, "method": result.method}
|
||||
)
|
||||
else:
|
||||
servers = " ".join(service.id for service in services)
|
||||
|
||||
config["SERVER_NAME"] = servers if not methods else {"value": servers, "global": True, "method": "default"}
|
||||
|
||||
return config
|
||||
|
||||
def get_config(
|
||||
self,
|
||||
global_only: bool = False,
|
||||
methods: bool = False,
|
||||
with_drafts: bool = False,
|
||||
filtered_settings: Optional[Union[List[str], Set[str], Tuple[str]]] = None,
|
||||
) -> Dict[str, Any]:
|
||||
"""Get the config from the database"""
|
||||
with self.__db_session() as session:
|
||||
config = {}
|
||||
multisite = []
|
||||
for setting in (
|
||||
multisite = set()
|
||||
|
||||
query = (
|
||||
session.query(Settings)
|
||||
.with_entities(
|
||||
Settings.id,
|
||||
|
|
@ -1381,81 +1525,25 @@ class Database:
|
|||
Settings.multiple,
|
||||
)
|
||||
.order_by(Settings.order)
|
||||
):
|
||||
)
|
||||
|
||||
if filtered_settings:
|
||||
query = query.filter(Settings.id.in_(filtered_settings))
|
||||
|
||||
for setting in query:
|
||||
default = setting.default or ""
|
||||
config[setting.id] = default if not methods else {"value": default, "global": True, "method": "default"}
|
||||
|
||||
for global_value in (
|
||||
session.query(Global_values).with_entities(Global_values.value, Global_values.suffix, Global_values.method).filter_by(setting_id=setting.id)
|
||||
):
|
||||
config[setting.id + (f"_{global_value.suffix}" if setting.multiple and global_value.suffix > 0 else "")] = (
|
||||
global_value.value
|
||||
if not methods
|
||||
else {
|
||||
"value": global_value.value,
|
||||
"global": True,
|
||||
"method": global_value.method,
|
||||
}
|
||||
)
|
||||
|
||||
if setting.context == "multisite":
|
||||
multisite.append(setting.id)
|
||||
multisite.add(setting.id)
|
||||
|
||||
is_multisite = config.get("MULTISITE", {"value": "no"})["value"] == "yes" if methods else config.get("MULTISITE", "no") == "yes"
|
||||
|
||||
services = session.query(Services).with_entities(Services.id, Services.is_draft)
|
||||
if not with_drafts:
|
||||
services = services.filter_by(is_draft=False)
|
||||
|
||||
if not global_only and is_multisite:
|
||||
for service in services:
|
||||
config[f"{service.id}_IS_DRAFT"] = "yes" if service.is_draft else "no"
|
||||
if methods:
|
||||
config[f"{service.id}_IS_DRAFT"] = {"value": config[f"{service.id}_IS_DRAFT"], "global": False, "method": "default"}
|
||||
|
||||
checked_settings = []
|
||||
for key, value in config.copy().items():
|
||||
original_key = key
|
||||
if self.suffix_rx.search(key):
|
||||
key = key[: -len(str(key.split("_")[-1])) - 1]
|
||||
|
||||
if key not in multisite:
|
||||
continue
|
||||
elif f"{service.id}_{original_key}" not in config:
|
||||
config[f"{service.id}_{original_key}"] = value
|
||||
|
||||
if original_key not in checked_settings:
|
||||
checked_settings.append(original_key)
|
||||
else:
|
||||
continue
|
||||
|
||||
for service_setting in (
|
||||
session.query(Services_settings)
|
||||
.with_entities(
|
||||
Services_settings.value,
|
||||
Services_settings.suffix,
|
||||
Services_settings.method,
|
||||
)
|
||||
.filter_by(service_id=service.id, setting_id=key)
|
||||
):
|
||||
value = service_setting.value
|
||||
if key == "SERVER_NAME" and service.id not in value.split(" "):
|
||||
value = f"{service.id} {value}".strip()
|
||||
|
||||
config[f"{service.id}_{key}" + (f"_{service_setting.suffix}" if service_setting.suffix > 0 else "")] = (
|
||||
value
|
||||
if not methods
|
||||
else {
|
||||
"value": value,
|
||||
"global": False,
|
||||
"method": service_setting.method,
|
||||
}
|
||||
)
|
||||
|
||||
servers = " ".join(service.id for service in services)
|
||||
config["SERVER_NAME"] = servers if not methods else {"value": servers, "global": True, "method": "default"}
|
||||
|
||||
return config
|
||||
return self.get_non_default_settings(
|
||||
global_only=global_only,
|
||||
methods=methods,
|
||||
with_drafts=with_drafts,
|
||||
filtered_settings=filtered_settings,
|
||||
original_config=config,
|
||||
original_multisite=multisite,
|
||||
)
|
||||
|
||||
def get_custom_configs(self) -> List[Dict[str, Any]]:
|
||||
"""Get the custom configs from the database"""
|
||||
|
|
|
|||
|
|
@ -235,6 +235,7 @@ class Metadata(Base):
|
|||
id = Column(Integer, primary_key=True, default=1)
|
||||
is_initialized = Column(Boolean, nullable=False)
|
||||
is_pro = Column(Boolean, default=False, nullable=False)
|
||||
pro_license = Column(String(128), default="", nullable=True)
|
||||
pro_expire = Column(DateTime, nullable=True)
|
||||
pro_status = Column(PRO_STATUS_ENUM, default="invalid", nullable=False)
|
||||
pro_services = Column(Integer, default=0, nullable=False)
|
||||
|
|
@ -251,5 +252,6 @@ class Metadata(Base):
|
|||
last_pro_plugins_change = Column(DateTime, nullable=True)
|
||||
instances_changed = Column(Boolean, default=False, nullable=True)
|
||||
last_instances_change = Column(DateTime, nullable=True)
|
||||
failover = Column(Boolean, default=None, nullable=True)
|
||||
integration = Column(INTEGRATIONS_ENUM, default="Unknown", nullable=False)
|
||||
version = Column(String(32), default="1.5.8", nullable=False)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
jinja2==3.1.4
|
||||
python-dotenv==1.0.1
|
||||
redis==5.0.5
|
||||
redis==5.0.6
|
||||
requests==2.32.3
|
||||
|
|
|
|||
|
|
@ -178,15 +178,15 @@ python-dotenv==1.0.1 \
|
|||
--hash=sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca \
|
||||
--hash=sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a
|
||||
# via -r requirements.in
|
||||
redis==5.0.5 \
|
||||
--hash=sha256:30b47d4ebb6b7a0b9b40c1275a19b87bb6f46b3bed82a89012cf56dea4024ada \
|
||||
--hash=sha256:3417688621acf6ee368dec4a04dd95881be24efd34c79f00d31f62bb528800ae
|
||||
redis==5.0.6 \
|
||||
--hash=sha256:38473cd7c6389ad3e44a91f4c3eaf6bcb8a9f746007f29bf4fb20824ff0b2197 \
|
||||
--hash=sha256:c0d6d990850c627bbf7be01c5c4cbaadf67b48593e913bb71c9819c30df37eee
|
||||
# via -r requirements.in
|
||||
requests==2.32.3 \
|
||||
--hash=sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760 \
|
||||
--hash=sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6
|
||||
# via -r requirements.in
|
||||
urllib3==2.2.1 \
|
||||
--hash=sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d \
|
||||
--hash=sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19
|
||||
urllib3==2.2.2 \
|
||||
--hash=sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472 \
|
||||
--hash=sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168
|
||||
# via requests
|
||||
|
|
|
|||
|
|
@ -71,15 +71,15 @@
|
|||
},
|
||||
{
|
||||
"id": "libmaxminddb",
|
||||
"name": "libmaxminddb v1.9.1",
|
||||
"name": "libmaxminddb v1.10.0",
|
||||
"url": "https://github.com/maxmind/libmaxminddb.git",
|
||||
"commit": "e26013e1d2b57eff0ed22b7364270358adb72205"
|
||||
"commit": "7acfe43a72a5043d01cc3dd6429005acdf812cb3"
|
||||
},
|
||||
{
|
||||
"id": "lua-cjson",
|
||||
"name": "lua-cjson v2.1.0.12",
|
||||
"name": "lua-cjson v2.1.0.14",
|
||||
"url": "https://github.com/openresty/lua-cjson.git",
|
||||
"commit": "881accc8fadca5ec02aa34d364df2a1aa25cd2f9"
|
||||
"commit": "f95cd9ea1e39221a36818772eb85f05b4164bbb1"
|
||||
},
|
||||
{
|
||||
"id": "lua-ffi-zlib",
|
||||
|
|
|
|||
|
|
@ -125,9 +125,9 @@ importlib-metadata==7.1.0 \
|
|||
--hash=sha256:30962b96c0c223483ed6cc7280e7f0199feb01a0e40cfae4d4450fc6fab1f570 \
|
||||
--hash=sha256:b78938b926ee8d5f020fc4772d487045805a55ddbad2ecf21c6d60938dc7fcd2
|
||||
# via build
|
||||
packaging==24.0 \
|
||||
--hash=sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5 \
|
||||
--hash=sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9
|
||||
packaging==24.1 \
|
||||
--hash=sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002 \
|
||||
--hash=sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124
|
||||
# via importlib-metadata
|
||||
|
||||
# The following packages are considered to be unsafe in a requirements file:
|
||||
|
|
@ -182,9 +182,9 @@ toposort==1.10 \
|
|||
--hash=sha256:bfbb479c53d0a696ea7402601f4e693c97b0367837c8898bc6471adfca37a6bd \
|
||||
--hash=sha256:cbdbc0d0bee4d2695ab2ceec97fe0679e9c10eab4b2a87a9372b929e70563a87
|
||||
# via pip-compile-multi
|
||||
urllib3==2.2.1 \
|
||||
--hash=sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d \
|
||||
--hash=sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19
|
||||
urllib3==2.2.2 \
|
||||
--hash=sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472 \
|
||||
--hash=sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168
|
||||
# via requests
|
||||
wheel==0.43.0 \
|
||||
--hash=sha256:465ef92c69fa5c5da2d1cf8ac40559a8c940886afcef87dcf14b9470862f1d85 \
|
||||
|
|
|
|||
|
|
@ -16,9 +16,9 @@ importlib-metadata==7.1.0 \
|
|||
--hash=sha256:30962b96c0c223483ed6cc7280e7f0199feb01a0e40cfae4d4450fc6fab1f570 \
|
||||
--hash=sha256:b78938b926ee8d5f020fc4772d487045805a55ddbad2ecf21c6d60938dc7fcd2
|
||||
# via build
|
||||
packaging==24.0 \
|
||||
--hash=sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5 \
|
||||
--hash=sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9
|
||||
packaging==24.1 \
|
||||
--hash=sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002 \
|
||||
--hash=sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124
|
||||
# via importlib-metadata
|
||||
|
||||
# The following packages are considered to be unsafe in a requirements file:
|
||||
|
|
|
|||
43
src/deps/src/libmaxminddb/CMakeLists.txt
vendored
43
src/deps/src/libmaxminddb/CMakeLists.txt
vendored
|
|
@ -2,7 +2,7 @@ cmake_minimum_required (VERSION 3.9)
|
|||
|
||||
project(maxminddb
|
||||
LANGUAGES C
|
||||
VERSION 1.9.1
|
||||
VERSION 1.10.0
|
||||
)
|
||||
set(MAXMINDDB_SOVERSION 0.0.7)
|
||||
set(CMAKE_C_STANDARD 99)
|
||||
|
|
@ -13,6 +13,8 @@ if (WIN32)
|
|||
endif()
|
||||
option(BUILD_SHARED_LIBS "Build shared libraries (.dll/.so) instead of static ones (.lib/.a)" OFF)
|
||||
option(BUILD_TESTING "Build test programs" ON)
|
||||
option(MAXMINDDB_BUILD_BINARIES "Build binaries" ON)
|
||||
option(MAXMINDDB_INSTALL "Generate the install target" ON)
|
||||
|
||||
include(GNUInstallDirs)
|
||||
|
||||
|
|
@ -90,17 +92,20 @@ set(MAXMINDB_HEADERS
|
|||
)
|
||||
set_target_properties(maxminddb PROPERTIES PUBLIC_HEADER "${MAXMINDB_HEADERS}")
|
||||
|
||||
install(TARGETS maxminddb
|
||||
EXPORT maxminddb)
|
||||
if (MAXMINDDB_INSTALL)
|
||||
install(TARGETS maxminddb
|
||||
EXPORT maxminddb)
|
||||
|
||||
# This is required to work with FetchContent
|
||||
install(EXPORT maxminddb
|
||||
FILE maxminddb-config.cmake
|
||||
NAMESPACE maxminddb::
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/maxminddb)
|
||||
# This is required to work with FetchContent
|
||||
install(EXPORT maxminddb
|
||||
FILE maxminddb-config.cmake
|
||||
NAMESPACE maxminddb::
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/maxminddb)
|
||||
endif()
|
||||
|
||||
# We always want to build mmdblookup
|
||||
add_subdirectory(bin)
|
||||
if (MAXMINDDB_BUILD_BINARIES)
|
||||
add_subdirectory(bin)
|
||||
endif()
|
||||
|
||||
if (BUILD_TESTING)
|
||||
enable_testing()
|
||||
|
|
@ -110,14 +115,16 @@ endif()
|
|||
# Generate libmaxminddb.pc file for pkg-config
|
||||
# Set the required variables as same with autotools
|
||||
set(prefix ${CMAKE_INSTALL_PREFIX})
|
||||
set(exec_prefix \${prefix})
|
||||
set(libdir \${exec_prefix}/lib)
|
||||
set(includedir \${prefix}/include)
|
||||
set(exec_prefix ${CMAKE_INSTALL_PREFIX})
|
||||
set(libdir ${CMAKE_INSTALL_LIBDIR})
|
||||
set(includedir ${CMAKE_INSTALL_INCLUDEDIR})
|
||||
set(PACKAGE_VERSION ${maxminddb_VERSION})
|
||||
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/libmaxminddb.pc.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/src/libmaxminddb.pc
|
||||
@ONLY)
|
||||
if (MAXMINDDB_INSTALL)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/libmaxminddb.pc.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/src/libmaxminddb.pc
|
||||
@ONLY)
|
||||
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/src/libmaxminddb.pc
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/src/libmaxminddb.pc
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
|
||||
endif()
|
||||
|
|
|
|||
14
src/deps/src/libmaxminddb/Changes.md
vendored
14
src/deps/src/libmaxminddb/Changes.md
vendored
|
|
@ -1,3 +1,15 @@
|
|||
## 1.10.0 - 2024-06-10
|
||||
|
||||
* When building with CMake, it is now possible to disable the building
|
||||
of binaries (e.g., `mmdblookup`) with the `MAXMINDDB_BUILD_BINARIES`
|
||||
option and the install target generation with the `MAXMINDDB_INSTALL`
|
||||
option. Pull request by Seena Fallah. GitHub #342.
|
||||
* CMake now makes greater use of GNUInstallDirs. Pull request by Maximilian
|
||||
Downey Twiss. GitHub #346.
|
||||
* The reader can now lookup records on a database with a search tree
|
||||
that is greater than 4 gigabytes without sometimes returning erroneous
|
||||
results due to an integer overflow.
|
||||
|
||||
## 1.9.1 - 2024-01-09
|
||||
|
||||
* `SSIZE_MAX` is now defined conditionally on Windows. The 1.9.0
|
||||
|
|
@ -230,7 +242,7 @@
|
|||
code to think it had found valid metadata when none existed. In addition,
|
||||
this could lead to an attempt to read past the end of the database
|
||||
entirely. Finally, if there are multiple metadata markers in the database,
|
||||
we treat the final one as the start of the metdata, instead of the first.
|
||||
we treat the final one as the start of the metadata, instead of the first.
|
||||
Implemented by Tobias Stoeckmann. GitHub #102.
|
||||
* Don't attempt to mmap a file that is too large to be mmapped on the
|
||||
system. Implemented by Tobias Stoeckmann. GitHub #101.
|
||||
|
|
|
|||
10
src/deps/src/libmaxminddb/bin/CMakeLists.txt
vendored
10
src/deps/src/libmaxminddb/bin/CMakeLists.txt
vendored
|
|
@ -15,8 +15,10 @@ if(NOT MSVC)
|
|||
|
||||
target_link_libraries(mmdblookup maxminddb pthread)
|
||||
|
||||
install(
|
||||
TARGETS mmdblookup
|
||||
DESTINATION bin
|
||||
)
|
||||
if (MAXMINDDB_INSTALL)
|
||||
install(
|
||||
TARGETS mmdblookup
|
||||
DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
|
|
|||
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.9.1], [support@maxmind.com])
|
||||
AC_INIT([libmaxminddb], [1.10.0], [support@maxmind.com])
|
||||
AC_CONFIG_SRCDIR([include/maxminddb.h])
|
||||
AC_CONFIG_HEADERS([config.h include/maxminddb_config.h])
|
||||
|
||||
|
|
|
|||
6
src/deps/src/libmaxminddb/doc/mmdblookup.md
vendored
6
src/deps/src/libmaxminddb/doc/mmdblookup.md
vendored
|
|
@ -9,8 +9,10 @@ mmdblookup --file [FILE PATH] --ip [IP ADDRESS] [DATA PATH]
|
|||
# DESCRIPTION
|
||||
|
||||
`mmdblookup` looks up an IP address in the specified MaxMind DB file. The
|
||||
record for the IP address is displayed in a JSON-like structure with type
|
||||
annotations.
|
||||
record for the IP address is displayed with `{}` to denote maps and `[]` to
|
||||
denote arrays. The values are followed by type annotations. This output is
|
||||
_not_ JSON and is not intended to be used as such. If you need JSON, please
|
||||
see [`mmdbinspect`](https://github.com/maxmind/mmdbinspect).
|
||||
|
||||
If an IP's data entry resolves to a map or array, you can provide a lookup
|
||||
path to only show part of that data.
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
#define MAXMINDDB_CONFIG_H
|
||||
|
||||
#ifndef MMDB_UINT128_USING_MODE
|
||||
/* Define as 1 if we use unsigned int __atribute__ ((__mode__(TI))) for uint128 values */
|
||||
/* Define as 1 if we use unsigned int __attribute__ ((__mode__(TI))) for uint128 values */
|
||||
#cmakedefine MMDB_UINT128_USING_MODE @MMDB_UINT128_USING_MODE@
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
#define MAXMINDDB_CONFIG_H
|
||||
|
||||
#ifndef MMDB_UINT128_USING_MODE
|
||||
/* Define as 1 if we use unsigned int __atribute__ ((__mode__(TI))) for uint128 values */
|
||||
/* Define as 1 if we use unsigned int __attribute__ ((__mode__(TI))) for uint128 values */
|
||||
#define MMDB_UINT128_USING_MODE 0
|
||||
#endif
|
||||
|
||||
|
|
|
|||
3
src/deps/src/libmaxminddb/src/maxminddb.c
vendored
3
src/deps/src/libmaxminddb/src/maxminddb.c
vendored
|
|
@ -947,7 +947,7 @@ static int find_address_in_search_tree(const MMDB_s *const mmdb,
|
|||
return MMDB_UNKNOWN_DATABASE_FORMAT_ERROR;
|
||||
}
|
||||
|
||||
uint32_t value = 0;
|
||||
uint64_t value = 0;
|
||||
uint16_t current_bit = 0;
|
||||
if (mmdb->metadata.ip_version == 6 && address_family == AF_INET) {
|
||||
value = mmdb->ipv4_start_node.node_value;
|
||||
|
|
@ -961,6 +961,7 @@ static int find_address_in_search_tree(const MMDB_s *const mmdb,
|
|||
uint8_t bit =
|
||||
1U & (address[current_bit >> 3] >> (7 - (current_bit % 8)));
|
||||
|
||||
// Note that value*record_info.record_length can be larger than 2**32
|
||||
record_pointer = &search_tree[value * record_info.record_length];
|
||||
if (record_pointer + record_info.record_length > mmdb->data_section) {
|
||||
return MMDB_CORRUPT_SEARCH_TREE_ERROR;
|
||||
|
|
|
|||
2
src/deps/src/libmaxminddb/t/maxmind-db
vendored
2
src/deps/src/libmaxminddb/t/maxmind-db
vendored
|
|
@ -1 +1 @@
|
|||
Subproject commit 31a33b3c09ac53028216e82f3d8a6d33749a8df5
|
||||
Subproject commit 880f6b4b5eb6c12ea9d5c70dd201dec2cb5639a2
|
||||
6
src/deps/src/libmaxminddb/t/metadata_t.c
vendored
6
src/deps/src/libmaxminddb/t/metadata_t.c
vendored
|
|
@ -3,8 +3,8 @@
|
|||
void test_metadata(MMDB_s *mmdb, const char *mode_desc) {
|
||||
cmp_ok(mmdb->metadata.node_count,
|
||||
"==",
|
||||
37,
|
||||
"node_count is 37 - %s",
|
||||
163,
|
||||
"node_count is 163 - %s",
|
||||
mode_desc);
|
||||
cmp_ok(mmdb->metadata.record_size,
|
||||
"==",
|
||||
|
|
@ -197,7 +197,7 @@ void test_metadata_as_data_entry_list(MMDB_s *mmdb, const char *mode_desc) {
|
|||
if (strcmp(key_name, "node_count") == 0) {
|
||||
MMDB_entry_data_list_s *value = entry_data_list =
|
||||
entry_data_list->next;
|
||||
cmp_ok(value->entry_data.uint32, "==", 37, "node_count == 37");
|
||||
cmp_ok(value->entry_data.uint32, "==", 163, "node_count == 163");
|
||||
} else if (strcmp(key_name, "record_size") == 0) {
|
||||
MMDB_entry_data_list_s *value = entry_data_list =
|
||||
entry_data_list->next;
|
||||
|
|
|
|||
279
src/deps/src/libmaxminddb/t/read_node_t.c
vendored
279
src/deps/src/libmaxminddb/t/read_node_t.c
vendored
|
|
@ -74,50 +74,55 @@ void run_24_bit_record_tests(int mode, const char *mode_desc) {
|
|||
MMDB_s *mmdb = open_ok(path, mode, mode_desc);
|
||||
free(path);
|
||||
|
||||
const uint32_t tests[7][5] = {
|
||||
{0, 1, MMDB_RECORD_TYPE_SEARCH_NODE, 242, MMDB_RECORD_TYPE_EMPTY},
|
||||
{
|
||||
80,
|
||||
81,
|
||||
MMDB_RECORD_TYPE_SEARCH_NODE,
|
||||
197,
|
||||
MMDB_RECORD_TYPE_SEARCH_NODE,
|
||||
},
|
||||
{
|
||||
96,
|
||||
97,
|
||||
MMDB_RECORD_TYPE_SEARCH_NODE,
|
||||
242,
|
||||
MMDB_RECORD_TYPE_EMPTY,
|
||||
},
|
||||
{
|
||||
103,
|
||||
242,
|
||||
MMDB_RECORD_TYPE_EMPTY,
|
||||
104,
|
||||
MMDB_RECORD_TYPE_SEARCH_NODE,
|
||||
},
|
||||
{
|
||||
127,
|
||||
242,
|
||||
MMDB_RECORD_TYPE_EMPTY,
|
||||
315,
|
||||
MMDB_RECORD_TYPE_DATA,
|
||||
},
|
||||
{
|
||||
132,
|
||||
329,
|
||||
MMDB_RECORD_TYPE_DATA,
|
||||
242,
|
||||
MMDB_RECORD_TYPE_EMPTY,
|
||||
},
|
||||
{
|
||||
241,
|
||||
96,
|
||||
MMDB_RECORD_TYPE_SEARCH_NODE,
|
||||
242,
|
||||
MMDB_RECORD_TYPE_EMPTY,
|
||||
}};
|
||||
const uint32_t tests[7][5] = {{
|
||||
0,
|
||||
1,
|
||||
MMDB_RECORD_TYPE_SEARCH_NODE,
|
||||
435,
|
||||
MMDB_RECORD_TYPE_SEARCH_NODE,
|
||||
},
|
||||
{
|
||||
80,
|
||||
81,
|
||||
MMDB_RECORD_TYPE_SEARCH_NODE,
|
||||
323,
|
||||
MMDB_RECORD_TYPE_SEARCH_NODE,
|
||||
},
|
||||
{
|
||||
96,
|
||||
97,
|
||||
MMDB_RECORD_TYPE_SEARCH_NODE,
|
||||
148,
|
||||
MMDB_RECORD_TYPE_SEARCH_NODE,
|
||||
},
|
||||
{
|
||||
103,
|
||||
444,
|
||||
MMDB_RECORD_TYPE_EMPTY,
|
||||
104,
|
||||
MMDB_RECORD_TYPE_SEARCH_NODE,
|
||||
},
|
||||
{
|
||||
127,
|
||||
444,
|
||||
MMDB_RECORD_TYPE_EMPTY,
|
||||
514,
|
||||
MMDB_RECORD_TYPE_DATA,
|
||||
},
|
||||
{
|
||||
132,
|
||||
527,
|
||||
MMDB_RECORD_TYPE_DATA,
|
||||
444,
|
||||
MMDB_RECORD_TYPE_EMPTY,
|
||||
},
|
||||
{
|
||||
241,
|
||||
444,
|
||||
MMDB_RECORD_TYPE_EMPTY,
|
||||
242,
|
||||
MMDB_RECORD_TYPE_SEARCH_NODE,
|
||||
}};
|
||||
run_read_node_tests(mmdb, tests, 7, 24);
|
||||
|
||||
MMDB_close(mmdb);
|
||||
|
|
@ -130,50 +135,55 @@ void run_28_bit_record_tests(int mode, const char *mode_desc) {
|
|||
MMDB_s *mmdb = open_ok(path, mode, mode_desc);
|
||||
free(path);
|
||||
|
||||
const uint32_t tests[7][5] = {
|
||||
{0, 1, MMDB_RECORD_TYPE_SEARCH_NODE, 242, MMDB_RECORD_TYPE_EMPTY},
|
||||
{
|
||||
80,
|
||||
81,
|
||||
MMDB_RECORD_TYPE_SEARCH_NODE,
|
||||
197,
|
||||
MMDB_RECORD_TYPE_SEARCH_NODE,
|
||||
},
|
||||
{
|
||||
96,
|
||||
97,
|
||||
MMDB_RECORD_TYPE_SEARCH_NODE,
|
||||
242,
|
||||
MMDB_RECORD_TYPE_EMPTY,
|
||||
},
|
||||
{
|
||||
103,
|
||||
242,
|
||||
MMDB_RECORD_TYPE_EMPTY,
|
||||
104,
|
||||
MMDB_RECORD_TYPE_SEARCH_NODE,
|
||||
},
|
||||
{
|
||||
127,
|
||||
242,
|
||||
MMDB_RECORD_TYPE_EMPTY,
|
||||
315,
|
||||
MMDB_RECORD_TYPE_DATA,
|
||||
},
|
||||
{
|
||||
132,
|
||||
329,
|
||||
MMDB_RECORD_TYPE_DATA,
|
||||
242,
|
||||
MMDB_RECORD_TYPE_EMPTY,
|
||||
},
|
||||
{
|
||||
241,
|
||||
96,
|
||||
MMDB_RECORD_TYPE_SEARCH_NODE,
|
||||
242,
|
||||
MMDB_RECORD_TYPE_EMPTY,
|
||||
}};
|
||||
const uint32_t tests[7][5] = {{
|
||||
0,
|
||||
1,
|
||||
MMDB_RECORD_TYPE_SEARCH_NODE,
|
||||
435,
|
||||
MMDB_RECORD_TYPE_SEARCH_NODE,
|
||||
},
|
||||
{
|
||||
80,
|
||||
81,
|
||||
MMDB_RECORD_TYPE_SEARCH_NODE,
|
||||
323,
|
||||
MMDB_RECORD_TYPE_SEARCH_NODE,
|
||||
},
|
||||
{
|
||||
96,
|
||||
97,
|
||||
MMDB_RECORD_TYPE_SEARCH_NODE,
|
||||
148,
|
||||
MMDB_RECORD_TYPE_SEARCH_NODE,
|
||||
},
|
||||
{
|
||||
103,
|
||||
444,
|
||||
MMDB_RECORD_TYPE_EMPTY,
|
||||
104,
|
||||
MMDB_RECORD_TYPE_SEARCH_NODE,
|
||||
},
|
||||
{
|
||||
127,
|
||||
444,
|
||||
MMDB_RECORD_TYPE_EMPTY,
|
||||
514,
|
||||
MMDB_RECORD_TYPE_DATA,
|
||||
},
|
||||
{
|
||||
132,
|
||||
527,
|
||||
MMDB_RECORD_TYPE_DATA,
|
||||
444,
|
||||
MMDB_RECORD_TYPE_EMPTY,
|
||||
},
|
||||
{
|
||||
241,
|
||||
444,
|
||||
MMDB_RECORD_TYPE_EMPTY,
|
||||
242,
|
||||
MMDB_RECORD_TYPE_SEARCH_NODE,
|
||||
}};
|
||||
run_read_node_tests(mmdb, tests, 7, 28);
|
||||
|
||||
MMDB_close(mmdb);
|
||||
|
|
@ -186,50 +196,55 @@ void run_32_bit_record_tests(int mode, const char *mode_desc) {
|
|||
MMDB_s *mmdb = open_ok(path, mode, mode_desc);
|
||||
free(path);
|
||||
|
||||
const uint32_t tests[7][5] = {
|
||||
{0, 1, MMDB_RECORD_TYPE_SEARCH_NODE, 242, MMDB_RECORD_TYPE_EMPTY},
|
||||
{
|
||||
80,
|
||||
81,
|
||||
MMDB_RECORD_TYPE_SEARCH_NODE,
|
||||
197,
|
||||
MMDB_RECORD_TYPE_SEARCH_NODE,
|
||||
},
|
||||
{
|
||||
96,
|
||||
97,
|
||||
MMDB_RECORD_TYPE_SEARCH_NODE,
|
||||
242,
|
||||
MMDB_RECORD_TYPE_EMPTY,
|
||||
},
|
||||
{
|
||||
103,
|
||||
242,
|
||||
MMDB_RECORD_TYPE_EMPTY,
|
||||
104,
|
||||
MMDB_RECORD_TYPE_SEARCH_NODE,
|
||||
},
|
||||
{
|
||||
127,
|
||||
242,
|
||||
MMDB_RECORD_TYPE_EMPTY,
|
||||
315,
|
||||
MMDB_RECORD_TYPE_DATA,
|
||||
},
|
||||
{
|
||||
132,
|
||||
329,
|
||||
MMDB_RECORD_TYPE_DATA,
|
||||
242,
|
||||
MMDB_RECORD_TYPE_EMPTY,
|
||||
},
|
||||
{
|
||||
241,
|
||||
96,
|
||||
MMDB_RECORD_TYPE_SEARCH_NODE,
|
||||
242,
|
||||
MMDB_RECORD_TYPE_EMPTY,
|
||||
}};
|
||||
const uint32_t tests[7][5] = {{
|
||||
0,
|
||||
1,
|
||||
MMDB_RECORD_TYPE_SEARCH_NODE,
|
||||
435,
|
||||
MMDB_RECORD_TYPE_SEARCH_NODE,
|
||||
},
|
||||
{
|
||||
80,
|
||||
81,
|
||||
MMDB_RECORD_TYPE_SEARCH_NODE,
|
||||
323,
|
||||
MMDB_RECORD_TYPE_SEARCH_NODE,
|
||||
},
|
||||
{
|
||||
96,
|
||||
97,
|
||||
MMDB_RECORD_TYPE_SEARCH_NODE,
|
||||
148,
|
||||
MMDB_RECORD_TYPE_SEARCH_NODE,
|
||||
},
|
||||
{
|
||||
103,
|
||||
444,
|
||||
MMDB_RECORD_TYPE_EMPTY,
|
||||
104,
|
||||
MMDB_RECORD_TYPE_SEARCH_NODE,
|
||||
},
|
||||
{
|
||||
127,
|
||||
444,
|
||||
MMDB_RECORD_TYPE_EMPTY,
|
||||
514,
|
||||
MMDB_RECORD_TYPE_DATA,
|
||||
},
|
||||
{
|
||||
132,
|
||||
527,
|
||||
MMDB_RECORD_TYPE_DATA,
|
||||
444,
|
||||
MMDB_RECORD_TYPE_EMPTY,
|
||||
},
|
||||
{
|
||||
241,
|
||||
444,
|
||||
MMDB_RECORD_TYPE_EMPTY,
|
||||
242,
|
||||
MMDB_RECORD_TYPE_SEARCH_NODE,
|
||||
}};
|
||||
|
||||
run_read_node_tests(mmdb, tests, 7, 32);
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ jobs:
|
|||
runtestArgs: "LUA_INCLUDE_DIR=.lua/include/luajit-2.1"
|
||||
runtestEnv: "SKIP_CMAKE=1"
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-24.04
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
|
|
@ -47,7 +47,7 @@ jobs:
|
|||
sudo cpanm --notest Test::Base Test::LongString
|
||||
|
||||
- name: cppcheck
|
||||
run: cppcheck -i .lua/ -i .install/ -i dtoa.c --force --error-exitcode=1 --enable=warning .
|
||||
run: cppcheck -i .lua/ -i .install/ -i dtoa.c --force --error-exitcode=1 --enable=warning --inline-suppr .
|
||||
|
||||
- name: prove
|
||||
run: LUA_BIN=lua prove -Itests tests
|
||||
|
|
|
|||
1
src/deps/src/lua-cjson/.gitignore
vendored
1
src/deps/src/lua-cjson/.gitignore
vendored
|
|
@ -1,6 +1,7 @@
|
|||
*.html
|
||||
*.o
|
||||
*.so
|
||||
*.a
|
||||
notes
|
||||
packages
|
||||
tags
|
||||
|
|
|
|||
2
src/deps/src/lua-cjson/.travis.yml
vendored
2
src/deps/src/lua-cjson/.travis.yml
vendored
|
|
@ -27,7 +27,7 @@ env:
|
|||
- JOBS=3
|
||||
- LUAROCKS_VER=2.4.2
|
||||
matrix:
|
||||
#- LUA=1 LUA_DIR=/usr LUA_INCLUDE_DIR=$LUA_DIR/include/lua5.1
|
||||
#- LUA=1 LUA_DIR=/usr LUA_INCLUDE_DIR=$LUA_DIR/include/lua5.1
|
||||
- LUAJIT=1 LUA_DIR=/usr/local LUA_INCLUDE_DIR=$LUA_DIR/include/luajit-2.1 LUA_SUFFIX=--lua-suffix=jit
|
||||
|
||||
install:
|
||||
|
|
|
|||
7
src/deps/src/lua-cjson/CMakeLists.txt
vendored
7
src/deps/src/lua-cjson/CMakeLists.txt
vendored
|
|
@ -68,6 +68,13 @@ else()
|
|||
set(_lua_module_dir "${_lua_lib_dir}/lua/5.1")
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
||||
add_definitions(-Dinline=__inline)
|
||||
add_definitions(-Dsnprintf=_snprintf)
|
||||
add_definitions(-Dstrncasecmp=_strnicmp)
|
||||
endif()
|
||||
|
||||
add_library(cjson MODULE lua_cjson.c strbuf.c ${FPCONV_SOURCES})
|
||||
set_target_properties(cjson PROPERTIES PREFIX "")
|
||||
target_link_libraries(cjson ${_MODULE_LINK})
|
||||
|
|
|
|||
8
src/deps/src/lua-cjson/Makefile
vendored
8
src/deps/src/lua-cjson/Makefile
vendored
|
|
@ -23,6 +23,8 @@ LUA_CMODULE_DIR ?= $(PREFIX)/lib/lua/$(LUA_VERSION)
|
|||
LUA_MODULE_DIR ?= $(PREFIX)/share/lua/$(LUA_VERSION)
|
||||
LUA_BIN_DIR ?= $(PREFIX)/bin
|
||||
|
||||
AR= $(CC) -o
|
||||
|
||||
##### Platform overrides #####
|
||||
##
|
||||
## Tweak one of the platform sections below to suit your situation.
|
||||
|
|
@ -84,12 +86,12 @@ OBJS = lua_cjson.o strbuf.o $(FPCONV_OBJS)
|
|||
|
||||
.PHONY: all clean install install-extra doc
|
||||
|
||||
.SUFFIXES: .html .txt
|
||||
.SUFFIXES: .html .adoc
|
||||
|
||||
.c.o:
|
||||
$(CC) -c $(CFLAGS) $(CPPFLAGS) $(BUILD_CFLAGS) -o $@ $<
|
||||
|
||||
.txt.html:
|
||||
.adoc.html:
|
||||
$(ASCIIDOC) -n -a toc $<
|
||||
|
||||
all: $(TARGET)
|
||||
|
|
@ -97,7 +99,7 @@ all: $(TARGET)
|
|||
doc: manual.html performance.html
|
||||
|
||||
$(TARGET): $(OBJS)
|
||||
$(CC) $(LDFLAGS) $(CJSON_LDFLAGS) -o $@ $(OBJS)
|
||||
$(AR) $@ $(LDFLAGS) $(CJSON_LDFLAGS) $(OBJS)
|
||||
|
||||
install: $(TARGET)
|
||||
mkdir -p $(DESTDIR)$(LUA_CMODULE_DIR)
|
||||
|
|
|
|||
2
src/deps/src/lua-cjson/build-packages.sh
vendored
2
src/deps/src/lua-cjson/build-packages.sh
vendored
|
|
@ -5,7 +5,7 @@
|
|||
# Build packages. Use current checked out version, or a specific tag/commit.
|
||||
|
||||
# Files requiring a version bump
|
||||
VERSION_FILES="lua-cjson-2.1devel-1.rockspec lua-cjson.spec lua_cjson.c manual.txt runtests.sh tests/test.lua"
|
||||
VERSION_FILES="lua-cjson-2.1devel-1.rockspec lua-cjson.spec lua_cjson.c manual.adoc runtests.sh tests/test.lua"
|
||||
|
||||
[ "$1" ] && BRANCH="$1" || BRANCH="`git describe --match '[1-3].[0-9]*'`"
|
||||
VERSION="`git describe --match '[1-3].[0-9]*' $BRANCH`"
|
||||
|
|
|
|||
115
src/deps/src/lua-cjson/dtoa.c
vendored
115
src/deps/src/lua-cjson/dtoa.c
vendored
|
|
@ -1,3 +1,7 @@
|
|||
/* The code comes from https://portal.ampl.com/~dmg/netlib/fp/dtoa.c
|
||||
* Go to https://portal.ampl.com/~dmg/netlib/fp/changes for the detailed changes.
|
||||
*/
|
||||
|
||||
/****************************************************************
|
||||
*
|
||||
* The author of this software is David M. Gay.
|
||||
|
|
@ -1533,12 +1537,18 @@ ThInfo {
|
|||
set_max_dtoa_threads(unsigned int n)
|
||||
{
|
||||
size_t L;
|
||||
ThInfo *newTI1;
|
||||
|
||||
if (n > maxthreads) {
|
||||
L = n*sizeof(ThInfo);
|
||||
if (TI1) {
|
||||
TI1 = (ThInfo*)REALLOC(TI1, L);
|
||||
memset(TI1 + maxthreads, 0, (n-maxthreads)*sizeof(ThInfo));
|
||||
newTI1 = (ThInfo*)REALLOC(TI1, L);
|
||||
if (newTI1) {
|
||||
TI1 = newTI1;
|
||||
memset(TI1 + maxthreads, 0, (n-maxthreads)*sizeof(ThInfo));
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
else {
|
||||
TI1 = (ThInfo*)MALLOC(L);
|
||||
|
|
@ -1871,7 +1881,7 @@ mult(Bigint *a, Bigint *b MTd)
|
|||
#else
|
||||
#ifdef Pack_32
|
||||
for(; xb < xbe; xb++, xc0++) {
|
||||
if (y = *xb & 0xffff) {
|
||||
if ((y = *xb & 0xffff)) {
|
||||
x = xa;
|
||||
xc = xc0;
|
||||
carry = 0;
|
||||
|
|
@ -1885,7 +1895,7 @@ mult(Bigint *a, Bigint *b MTd)
|
|||
while(x < xae);
|
||||
*xc = carry;
|
||||
}
|
||||
if (y = *xb >> 16) {
|
||||
if ((y = *xb >> 16)) {
|
||||
x = xa;
|
||||
xc = xc0;
|
||||
carry = 0;
|
||||
|
|
@ -2718,13 +2728,14 @@ enum { /* rounding values: same as FLT_ROUNDS */
|
|||
};
|
||||
|
||||
void
|
||||
gethex( const char **sp, U *rvp, int rounding, int sign MTd)
|
||||
gethex(const char **sp, U *rvp, int rounding, int sign MTd)
|
||||
{
|
||||
Bigint *b;
|
||||
char d;
|
||||
const unsigned char *decpt, *s0, *s, *s1;
|
||||
Long e, e1;
|
||||
ULong L, lostbits, *x;
|
||||
int big, denorm, esign, havedig, k, n, nbits, up, zret;
|
||||
int big, denorm, esign, havedig, k, n, nb, nbits, nz, up, zret;
|
||||
#ifdef IBM
|
||||
int j;
|
||||
#endif
|
||||
|
|
@ -2742,6 +2753,9 @@ gethex( const char **sp, U *rvp, int rounding, int sign MTd)
|
|||
#endif
|
||||
#endif /*}}*/
|
||||
};
|
||||
#ifdef IEEE_Arith
|
||||
int check_denorm = 0;
|
||||
#endif
|
||||
#ifdef USE_LOCALE
|
||||
int i;
|
||||
#ifdef NO_LOCALE_CACHE
|
||||
|
|
@ -2893,7 +2907,7 @@ gethex( const char **sp, U *rvp, int rounding, int sign MTd)
|
|||
k++;
|
||||
b = Balloc(k MTa);
|
||||
x = b->x;
|
||||
n = 0;
|
||||
havedig = n = nz = 0;
|
||||
L = 0;
|
||||
#ifdef USE_LOCALE
|
||||
for(i = 0; decimalpoint[i+1]; ++i);
|
||||
|
|
@ -2908,22 +2922,28 @@ gethex( const char **sp, U *rvp, int rounding, int sign MTd)
|
|||
if (*--s1 == '.')
|
||||
continue;
|
||||
#endif
|
||||
if ((d = hexdig[*s1]))
|
||||
havedig = 1;
|
||||
else if (!havedig) {
|
||||
e += 4;
|
||||
continue;
|
||||
}
|
||||
if (n == ULbits) {
|
||||
*x++ = L;
|
||||
L = 0;
|
||||
n = 0;
|
||||
}
|
||||
L |= (hexdig[*s1] & 0x0f) << n;
|
||||
L |= (d & 0x0f) << n;
|
||||
n += 4;
|
||||
}
|
||||
*x++ = L;
|
||||
b->wds = n = x - b->x;
|
||||
n = ULbits*n - hi0bits(L);
|
||||
nb = ULbits*n - hi0bits(L);
|
||||
nbits = Nbits;
|
||||
lostbits = 0;
|
||||
x = b->x;
|
||||
if (n > nbits) {
|
||||
n -= nbits;
|
||||
if (nb > nbits) {
|
||||
n = nb - nbits;
|
||||
if (any_on(b,n)) {
|
||||
lostbits = 1;
|
||||
k = n - 1;
|
||||
|
|
@ -2936,8 +2956,8 @@ gethex( const char **sp, U *rvp, int rounding, int sign MTd)
|
|||
rshift(b, n);
|
||||
e += n;
|
||||
}
|
||||
else if (n < nbits) {
|
||||
n = nbits - n;
|
||||
else if (nb < nbits) {
|
||||
n = nbits - nb;
|
||||
b = lshift(b, n MTa);
|
||||
e -= n;
|
||||
x = b->x;
|
||||
|
|
@ -2992,12 +3012,49 @@ gethex( const char **sp, U *rvp, int rounding, int sign MTd)
|
|||
return;
|
||||
}
|
||||
k = n - 1;
|
||||
#ifdef IEEE_Arith
|
||||
if (!k) {
|
||||
switch(rounding) {
|
||||
case Round_near:
|
||||
if (((b->x[0] & 3) == 3) || (lostbits && (b->x[0] & 1))) {
|
||||
multadd(b, 1, 1 MTa);
|
||||
emin_check:
|
||||
if (b->x[1] == (1 << (Exp_shift + 1))) {
|
||||
rshift(b,1);
|
||||
e = emin;
|
||||
goto normal;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Round_up:
|
||||
if (!sign && (lostbits || (b->x[0] & 1))) {
|
||||
incr_denorm:
|
||||
multadd(b, 1, 2 MTa);
|
||||
check_denorm = 1;
|
||||
lostbits = 0;
|
||||
goto emin_check;
|
||||
}
|
||||
break;
|
||||
case Round_down:
|
||||
if (sign && (lostbits || (b->x[0] & 1)))
|
||||
goto incr_denorm;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (lostbits)
|
||||
lostbits = 1;
|
||||
else if (k > 0)
|
||||
lostbits = any_on(b,k);
|
||||
#ifdef IEEE_Arith
|
||||
else if (check_denorm)
|
||||
goto no_lostbits;
|
||||
#endif
|
||||
if (x[k>>kshift] & 1 << (k & kmask))
|
||||
lostbits |= 2;
|
||||
#ifdef IEEE_Arith
|
||||
no_lostbits:
|
||||
#endif
|
||||
nbits -= n;
|
||||
rshift(b,n);
|
||||
e = emin;
|
||||
|
|
@ -3022,16 +3079,9 @@ gethex( const char **sp, U *rvp, int rounding, int sign MTd)
|
|||
k = b->wds;
|
||||
b = increment(b MTa);
|
||||
x = b->x;
|
||||
if (denorm) {
|
||||
#if 0
|
||||
if (nbits == Nbits - 1
|
||||
&& x[nbits >> kshift] & 1 << (nbits & kmask))
|
||||
denorm = 0; /* not currently used */
|
||||
#endif
|
||||
}
|
||||
else if (b->wds > k
|
||||
if (!denorm && (b->wds > k
|
||||
|| ((n = nbits & kmask) !=0
|
||||
&& hi0bits(x[k-1]) < 32-n)) {
|
||||
&& hi0bits(x[k-1]) < 32-n))) {
|
||||
rshift(b,1);
|
||||
if (++e > Emax)
|
||||
goto ovfl;
|
||||
|
|
@ -3041,8 +3091,10 @@ gethex( const char **sp, U *rvp, int rounding, int sign MTd)
|
|||
#ifdef IEEE_Arith
|
||||
if (denorm)
|
||||
word0(rvp) = b->wds > 1 ? b->x[1] & ~0x100000 : 0;
|
||||
else
|
||||
else {
|
||||
normal:
|
||||
word0(rvp) = (b->x[1] & ~0x100000) | ((e + 0x3ff + 52) << 20);
|
||||
}
|
||||
word1(rvp) = b->x[0];
|
||||
#endif
|
||||
#ifdef IBM
|
||||
|
|
@ -3409,6 +3461,7 @@ retlow1:
|
|||
if ((j = ((word0(rv) & Exp_mask) >> Exp_shift) - bc->scale) <= 0) {
|
||||
i = 1 - j;
|
||||
if (i <= 31) {
|
||||
/* cppcheck-suppress integerOverflowCond */
|
||||
if (word1(rv) & (0x1 << i))
|
||||
goto odd;
|
||||
}
|
||||
|
|
@ -3619,10 +3672,11 @@ fpconv_strtod(const char *s00, char **se)
|
|||
c = *++s;
|
||||
if (c > '0' && c <= '9') {
|
||||
L = c - '0';
|
||||
s1 = s;
|
||||
while((c = *++s) >= '0' && c <= '9')
|
||||
L = 10*L + c - '0';
|
||||
if (s - s1 > 8 || L > 19999)
|
||||
while((c = *++s) >= '0' && c <= '9') {
|
||||
if (L <= 19999)
|
||||
L = 10*L + c - '0';
|
||||
}
|
||||
if (L > 19999)
|
||||
/* Avoid confusion from exponents
|
||||
* so large that e might overflow.
|
||||
*/
|
||||
|
|
@ -4884,6 +4938,7 @@ nrv_alloc(const char *s, char *s0, size_t s0len, char **rve, int n MTd)
|
|||
s0 = rv_alloc(n MTa);
|
||||
else if (s0len <= n) {
|
||||
rv = 0;
|
||||
/* cppcheck-suppress nullPointerArithmetic */
|
||||
t = rv + n;
|
||||
goto rve_chk;
|
||||
}
|
||||
|
|
@ -5237,9 +5292,11 @@ dtoa_r(double dd, int mode, int ndigits, int *decpt, int *sign, char **rve, char
|
|||
#ifndef SET_INEXACT
|
||||
#ifdef Check_FLT_ROUNDS
|
||||
try_quick = Rounding == 1;
|
||||
#else
|
||||
try_quick = 1;
|
||||
#endif
|
||||
#endif /*SET_INEXACT*/
|
||||
#endif
|
||||
#endif /*USE_BF96*/
|
||||
|
||||
if (mode > 5) {
|
||||
mode -= 4;
|
||||
|
|
@ -5281,6 +5338,7 @@ dtoa_r(double dd, int mode, int ndigits, int *decpt, int *sign, char **rve, char
|
|||
else if (blen <= i) {
|
||||
buf = 0;
|
||||
if (rve)
|
||||
/* cppcheck-suppress nullPointerArithmetic */
|
||||
*rve = buf + i;
|
||||
return buf;
|
||||
}
|
||||
|
|
@ -5469,6 +5527,7 @@ dtoa_r(double dd, int mode, int ndigits, int *decpt, int *sign, char **rve, char
|
|||
res3 = p10->b1 * dbhi + (tv3 & 0xffffffffull);
|
||||
res = p10->b0 * dbhi + (tv3>>32) + (res3>>32);
|
||||
be += p10->e - 0x3fe;
|
||||
/* cppcheck-suppress integerOverflowCond */
|
||||
eulp = j1 = be - 54 + ulpadj;
|
||||
if (!(res & 0x8000000000000000ull)) {
|
||||
--be;
|
||||
|
|
|
|||
2
src/deps/src/lua-cjson/fpconv.c
vendored
2
src/deps/src/lua-cjson/fpconv.c
vendored
|
|
@ -130,7 +130,7 @@ double fpconv_strtod(const char *nptr, char **endptr)
|
|||
/* Duplicate number into buffer */
|
||||
if (buflen >= FPCONV_G_FMT_BUFSIZE) {
|
||||
/* Handle unusually large numbers */
|
||||
buf = malloc(buflen + 1);
|
||||
buf = (char *)malloc(buflen + 1);
|
||||
if (!buf) {
|
||||
fprintf(stderr, "Out of memory");
|
||||
abort();
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
package = "lua-cjson"
|
||||
version = "2.1.0.11-1"
|
||||
version = "2.1.0.14-1"
|
||||
|
||||
source = {
|
||||
url = "git+https://github.com/openresty/lua-cjson",
|
||||
tag = "2.1.0.11",
|
||||
tag = "2.1.0.14",
|
||||
}
|
||||
|
||||
description = {
|
||||
2
src/deps/src/lua-cjson/lua-cjson.spec
vendored
2
src/deps/src/lua-cjson/lua-cjson.spec
vendored
|
|
@ -50,7 +50,7 @@ rm -rf "$RPM_BUILD_ROOT"
|
|||
|
||||
%files
|
||||
%defattr(-,root,root,-)
|
||||
%doc LICENSE NEWS performance.html performance.txt manual.html manual.txt rfc4627.txt THANKS
|
||||
%doc LICENSE NEWS performance.html performance.adoc manual.html manual.adoc rfc4627.txt THANKS
|
||||
%{lualibdir}/*
|
||||
%{luadatadir}/*
|
||||
%{_bindir}/*
|
||||
|
|
|
|||
117
src/deps/src/lua-cjson/lua_cjson.c
vendored
117
src/deps/src/lua-cjson/lua_cjson.c
vendored
|
|
@ -40,6 +40,7 @@
|
|||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include <limits.h>
|
||||
#include <lua.h>
|
||||
#include <lauxlib.h>
|
||||
|
|
@ -65,6 +66,13 @@
|
|||
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define CJSON_EXPORT __declspec(dllexport)
|
||||
#define strncasecmp(x,y,z) _strnicmp(x,y,z)
|
||||
#else
|
||||
#define CJSON_EXPORT extern
|
||||
#endif
|
||||
|
||||
/* Workaround for Solaris platforms missing isinf() */
|
||||
#if !defined(isinf) && (defined(USE_INTERNAL_ISINF) || defined(MISSING_ISINF))
|
||||
#define isinf(x) (!isnan(x) && isnan((x) - (x)))
|
||||
|
|
@ -103,8 +111,8 @@
|
|||
#define json_lightudata_mask(ludata) (ludata)
|
||||
#endif
|
||||
|
||||
#if LUA_VERSION_NUM > 501
|
||||
#define lua_objlen(L,i) lua_rawlen(L, (i))
|
||||
#if LUA_VERSION_NUM >= 502
|
||||
#define lua_objlen(L,i) luaL_len(L, (i))
|
||||
#endif
|
||||
|
||||
static const char * const *json_empty_array;
|
||||
|
|
@ -117,6 +125,7 @@ typedef enum {
|
|||
T_ARR_END,
|
||||
T_STRING,
|
||||
T_NUMBER,
|
||||
T_INTEGER,
|
||||
T_BOOLEAN,
|
||||
T_NULL,
|
||||
T_COLON,
|
||||
|
|
@ -134,6 +143,7 @@ static const char *json_token_type_name[] = {
|
|||
"T_ARR_END",
|
||||
"T_STRING",
|
||||
"T_NUMBER",
|
||||
"T_INTEGER",
|
||||
"T_BOOLEAN",
|
||||
"T_NULL",
|
||||
"T_COLON",
|
||||
|
|
@ -179,13 +189,14 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
json_token_type_t type;
|
||||
int index;
|
||||
size_t index;
|
||||
union {
|
||||
const char *string;
|
||||
double number;
|
||||
lua_Integer integer;
|
||||
int boolean;
|
||||
} value;
|
||||
int string_len;
|
||||
size_t string_len;
|
||||
} json_token_t;
|
||||
|
||||
static const char *char2escape[256] = {
|
||||
|
|
@ -233,7 +244,7 @@ static json_config_t *json_fetch_config(lua_State *l)
|
|||
{
|
||||
json_config_t *cfg;
|
||||
|
||||
cfg = lua_touserdata(l, lua_upvalueindex(1));
|
||||
cfg = (json_config_t *)lua_touserdata(l, lua_upvalueindex(1));
|
||||
if (!cfg)
|
||||
luaL_error(l, "BUG: Unable to fetch CJSON configuration");
|
||||
|
||||
|
|
@ -442,7 +453,7 @@ static int json_destroy_config(lua_State *l)
|
|||
{
|
||||
json_config_t *cfg;
|
||||
|
||||
cfg = lua_touserdata(l, 1);
|
||||
cfg = (json_config_t *)lua_touserdata(l, 1);
|
||||
if (cfg)
|
||||
strbuf_free(&cfg->encode_buf);
|
||||
cfg = NULL;
|
||||
|
|
@ -455,7 +466,11 @@ static void json_create_config(lua_State *l)
|
|||
json_config_t *cfg;
|
||||
int i;
|
||||
|
||||
cfg = lua_newuserdata(l, sizeof(*cfg));
|
||||
cfg = (json_config_t *)lua_newuserdata(l, sizeof(*cfg));
|
||||
if (!cfg)
|
||||
abort();
|
||||
|
||||
memset(cfg, 0, sizeof(*cfg));
|
||||
|
||||
/* Create GC method to clean up strbuf */
|
||||
lua_newtable(l);
|
||||
|
|
@ -547,9 +562,9 @@ static void json_encode_exception(lua_State *l, json_config_t *cfg, strbuf_t *js
|
|||
static void json_append_string(lua_State *l, strbuf_t *json, int lindex)
|
||||
{
|
||||
const char *escstr;
|
||||
unsigned i;
|
||||
const char *str;
|
||||
size_t len;
|
||||
size_t i;
|
||||
|
||||
str = lua_tolstring(l, lindex, &len);
|
||||
|
||||
|
|
@ -557,6 +572,8 @@ static void json_append_string(lua_State *l, strbuf_t *json, int lindex)
|
|||
* This buffer is reused constantly for small strings
|
||||
* If there are any excess pages, they won't be hit anyway.
|
||||
* This gains ~5% speedup. */
|
||||
if (len > SIZE_MAX / 6 - 3)
|
||||
abort(); /* Overflow check */
|
||||
strbuf_ensure_empty_length(json, len * 6 + 2);
|
||||
|
||||
strbuf_append_char_unsafe(json, '\"');
|
||||
|
|
@ -646,9 +663,9 @@ static int json_append_data(lua_State *l, json_config_t *cfg,
|
|||
/* json_append_array args:
|
||||
* - lua_State
|
||||
* - JSON strbuf
|
||||
* - Size of passwd Lua array (top of stack) */
|
||||
* - Size of passed Lua array (top of stack) */
|
||||
static void json_append_array(lua_State *l, json_config_t *cfg, int current_depth,
|
||||
strbuf_t *json, int array_length)
|
||||
strbuf_t *json, int array_length, int raw)
|
||||
{
|
||||
int comma, i, json_pos, err;
|
||||
|
||||
|
|
@ -660,7 +677,17 @@ static void json_append_array(lua_State *l, json_config_t *cfg, int current_dept
|
|||
if (comma++ > 0)
|
||||
strbuf_append_char(json, ',');
|
||||
|
||||
lua_rawgeti(l, -1, i);
|
||||
if (raw) {
|
||||
lua_rawgeti(l, -1, i);
|
||||
} else {
|
||||
#if LUA_VERSION_NUM >= 503
|
||||
lua_geti(l, -1, i);
|
||||
#else
|
||||
lua_pushinteger(l, i);
|
||||
lua_gettable(l, -2);
|
||||
#endif
|
||||
}
|
||||
|
||||
err = json_append_data(l, cfg, current_depth, json);
|
||||
if (err) {
|
||||
strbuf_set_length(json, json_pos);
|
||||
|
|
@ -677,8 +704,17 @@ static void json_append_array(lua_State *l, json_config_t *cfg, int current_dept
|
|||
static void json_append_number(lua_State *l, json_config_t *cfg,
|
||||
strbuf_t *json, int lindex)
|
||||
{
|
||||
double num = lua_tonumber(l, lindex);
|
||||
int len;
|
||||
#if LUA_VERSION_NUM >= 503
|
||||
if (lua_isinteger(l, lindex)) {
|
||||
lua_Integer num = lua_tointeger(l, lindex);
|
||||
strbuf_ensure_empty_length(json, FPCONV_G_FMT_BUFSIZE); /* max length of int64 is 19 */
|
||||
len = sprintf(strbuf_empty_ptr(json), LUA_INTEGER_FMT, num);
|
||||
strbuf_extend_length(json, len);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
double num = lua_tonumber(l, lindex);
|
||||
|
||||
if (cfg->encode_invalid_numbers == 0) {
|
||||
/* Prevent encoding invalid numbers */
|
||||
|
|
@ -766,6 +802,7 @@ static int json_append_data(lua_State *l, json_config_t *cfg,
|
|||
int len;
|
||||
int as_array = 0;
|
||||
int has_metatable;
|
||||
int raw = 1;
|
||||
|
||||
switch (lua_type(l, -1)) {
|
||||
case LUA_TSTRING:
|
||||
|
|
@ -790,17 +827,30 @@ static int json_append_data(lua_State *l, json_config_t *cfg,
|
|||
lua_pushlightuserdata(l, json_lightudata_mask(&json_array));
|
||||
lua_rawget(l, LUA_REGISTRYINDEX);
|
||||
as_array = lua_rawequal(l, -1, -2);
|
||||
lua_pop(l, 2);
|
||||
if (as_array) {
|
||||
raw = 1;
|
||||
lua_pop(l, 2);
|
||||
len = lua_objlen(l, -1);
|
||||
} else {
|
||||
raw = 0;
|
||||
lua_pop(l, 2);
|
||||
if (luaL_getmetafield(l, -1, "__len")) {
|
||||
lua_pushvalue(l, -2);
|
||||
lua_call(l, 1, 1);
|
||||
len = lua_tonumber(l, -1);
|
||||
lua_pop(l, 1);
|
||||
as_array = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (as_array) {
|
||||
len = lua_objlen(l, -1);
|
||||
json_append_array(l, cfg, current_depth, json, len);
|
||||
json_append_array(l, cfg, current_depth, json, len, raw);
|
||||
} else {
|
||||
len = lua_array_length(l, cfg, json);
|
||||
|
||||
if (len > 0 || (len == 0 && !cfg->encode_empty_table_as_object)) {
|
||||
json_append_array(l, cfg, current_depth, json, len);
|
||||
json_append_array(l, cfg, current_depth, json, len, raw);
|
||||
} else {
|
||||
if (has_metatable) {
|
||||
lua_getmetatable(l, -1);
|
||||
|
|
@ -810,7 +860,9 @@ static int json_append_data(lua_State *l, json_config_t *cfg,
|
|||
as_array = lua_rawequal(l, -1, -2);
|
||||
lua_pop(l, 2); /* pop pointer + metatable */
|
||||
if (as_array) {
|
||||
json_append_array(l, cfg, current_depth, json, 0);
|
||||
len = lua_objlen(l, -1);
|
||||
raw = 1;
|
||||
json_append_array(l, cfg, current_depth, json, len, raw);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -825,7 +877,7 @@ static int json_append_data(lua_State *l, json_config_t *cfg,
|
|||
if (lua_touserdata(l, -1) == NULL) {
|
||||
strbuf_append_mem(json, "null", 4);
|
||||
} else if (lua_touserdata(l, -1) == json_lightudata_mask(&json_array)) {
|
||||
json_append_array(l, cfg, current_depth, json, 0);
|
||||
json_append_array(l, cfg, current_depth, json, 0, 1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
@ -848,7 +900,7 @@ static int json_encode(lua_State *l)
|
|||
strbuf_t local_encode_buf;
|
||||
strbuf_t *encode_buf;
|
||||
char *json;
|
||||
int len;
|
||||
size_t len;
|
||||
|
||||
luaL_argcheck(l, lua_gettop(l) == 1, 1, "expected 1 argument");
|
||||
|
||||
|
|
@ -1138,13 +1190,19 @@ static int json_is_invalid_number(json_parse_t *json)
|
|||
static void json_next_number_token(json_parse_t *json, json_token_t *token)
|
||||
{
|
||||
char *endptr;
|
||||
|
||||
token->type = T_NUMBER;
|
||||
token->value.number = fpconv_strtod(json->ptr, &endptr);
|
||||
if (json->ptr == endptr)
|
||||
json_set_token_error(token, json, "invalid number");
|
||||
else
|
||||
json->ptr = endptr; /* Skip the processed number */
|
||||
token->value.integer = strtoll(json->ptr, &endptr, 10);
|
||||
if (json->ptr == endptr || *endptr == '.' || *endptr == 'e' ||
|
||||
*endptr == 'E' || *endptr == 'x') {
|
||||
token->type = T_NUMBER;
|
||||
token->value.number = fpconv_strtod(json->ptr, &endptr);
|
||||
if (json->ptr == endptr) {
|
||||
json_set_token_error(token, json, "invalid number");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
token->type = T_INTEGER;
|
||||
}
|
||||
json->ptr = endptr; /* Skip the processed number */
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
@ -1380,6 +1438,9 @@ static void json_process_value(lua_State *l, json_parse_t *json,
|
|||
case T_NUMBER:
|
||||
lua_pushnumber(l, token->value.number);
|
||||
break;;
|
||||
case T_INTEGER:
|
||||
lua_pushinteger(l, token->value.integer);
|
||||
break;;
|
||||
case T_BOOLEAN:
|
||||
lua_pushboolean(l, token->value.boolean);
|
||||
break;;
|
||||
|
|
@ -1595,7 +1656,7 @@ static int lua_cjson_safe_new(lua_State *l)
|
|||
return 1;
|
||||
}
|
||||
|
||||
int luaopen_cjson(lua_State *l)
|
||||
CJSON_EXPORT int luaopen_cjson(lua_State *l)
|
||||
{
|
||||
lua_cjson_new(l);
|
||||
|
||||
|
|
@ -1609,7 +1670,7 @@ int luaopen_cjson(lua_State *l)
|
|||
return 1;
|
||||
}
|
||||
|
||||
int luaopen_cjson_safe(lua_State *l)
|
||||
CJSON_EXPORT int luaopen_cjson_safe(lua_State *l)
|
||||
{
|
||||
lua_cjson_safe_new(l);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
= Lua CJSON 2.1devel Manual =
|
||||
Mark Pulford <mark@kyne.com.au>
|
||||
:revdate: 1st March 2012
|
||||
:revdate: August 2016
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
|
@ -20,7 +20,7 @@ The Lua CJSON module provides JSON support for Lua.
|
|||
Lua CJSON is covered by the MIT license. Review the file +LICENSE+ for
|
||||
details.
|
||||
|
||||
The latest version of this software is available from the
|
||||
The current stable version of this software is available from the
|
||||
http://www.kyne.com.au/%7Emark/software/lua-cjson.php[Lua CJSON website].
|
||||
|
||||
Feel free to email me if you have any patches, suggestions, or comments.
|
||||
|
|
@ -29,8 +29,8 @@ Feel free to email me if you have any patches, suggestions, or comments.
|
|||
Installation
|
||||
------------
|
||||
|
||||
Lua CJSON requires either http://www.lua.org[Lua] 5.1, Lua 5.2, or
|
||||
http://www.luajit.org[LuaJIT] to build.
|
||||
Lua CJSON requires either http://www.lua.org[Lua] 5.1, Lua 5.2, Lua 5.3,
|
||||
or http://www.luajit.org[LuaJIT] to build.
|
||||
|
||||
The build method can be selected from 4 options:
|
||||
|
||||
|
|
@ -203,8 +203,8 @@ Import Lua CJSON via the Lua +require+ function. Lua CJSON does not
|
|||
register a global module table.
|
||||
|
||||
The +cjson+ module will throw an error during JSON conversion if any
|
||||
invalid data is encountered. Refer to <<cjson_encode,+cjson.encode+>>
|
||||
and <<cjson_decode,+cjson.decode+>> for details.
|
||||
invalid data is encountered. Refer to <<encode,+cjson.encode+>> and
|
||||
<<decode,+cjson.decode+>> for details.
|
||||
|
||||
The +cjson.safe+ module behaves identically to the +cjson+ module,
|
||||
except when errors are encountered during JSON conversion. On error, the
|
||||
|
|
@ -238,6 +238,7 @@ workaround if required. Lua CJSON should be reinitialised via
|
|||
different locale per thread is not supported.
|
||||
|
||||
|
||||
[[decode]]
|
||||
decode
|
||||
~~~~~~
|
||||
|
||||
|
|
@ -26,7 +26,7 @@ http://chiselapp.com/user/dhkolf/repository/dkjson/[DKJSON 2.1]::
|
|||
https://github.com/brimworks/lua-yajl[Lua YAJL 2.0]::
|
||||
- C wrapper for the YAJL library
|
||||
|
||||
http://www.kyne.com.au/%7Emark/software/lua-cjson.php[Lua CSJON 2.0.0]::
|
||||
http://www.kyne.com.au/%7Emark/software/lua-cjson.php[Lua CJSON 2.0.0]::
|
||||
- C implementation with no dependencies on other libraries
|
||||
|
||||
|
||||
116
src/deps/src/lua-cjson/strbuf.c
vendored
116
src/deps/src/lua-cjson/strbuf.c
vendored
|
|
@ -26,6 +26,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "strbuf.h"
|
||||
|
||||
|
|
@ -38,38 +39,38 @@ static void die(const char *fmt, ...)
|
|||
va_end(arg);
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
exit(-1);
|
||||
abort();
|
||||
}
|
||||
|
||||
void strbuf_init(strbuf_t *s, int len)
|
||||
void strbuf_init(strbuf_t *s, size_t len)
|
||||
{
|
||||
int size;
|
||||
size_t size;
|
||||
|
||||
if (len <= 0)
|
||||
if (!len)
|
||||
size = STRBUF_DEFAULT_SIZE;
|
||||
else
|
||||
size = len + 1; /* \0 terminator */
|
||||
|
||||
size = len + 1;
|
||||
if (size < len)
|
||||
die("Overflow, len: %zu", len);
|
||||
s->buf = NULL;
|
||||
s->size = size;
|
||||
s->length = 0;
|
||||
s->increment = STRBUF_DEFAULT_INCREMENT;
|
||||
s->dynamic = 0;
|
||||
s->reallocs = 0;
|
||||
s->debug = 0;
|
||||
|
||||
s->buf = malloc(size);
|
||||
s->buf = (char *)malloc(size);
|
||||
if (!s->buf)
|
||||
die("Out of memory");
|
||||
|
||||
strbuf_ensure_null(s);
|
||||
}
|
||||
|
||||
strbuf_t *strbuf_new(int len)
|
||||
strbuf_t *strbuf_new(size_t len)
|
||||
{
|
||||
strbuf_t *s;
|
||||
|
||||
s = malloc(sizeof(strbuf_t));
|
||||
s = (strbuf_t*)malloc(sizeof(strbuf_t));
|
||||
if (!s)
|
||||
die("Out of memory");
|
||||
|
||||
|
|
@ -81,20 +82,10 @@ strbuf_t *strbuf_new(int len)
|
|||
return s;
|
||||
}
|
||||
|
||||
void strbuf_set_increment(strbuf_t *s, int increment)
|
||||
{
|
||||
/* Increment > 0: Linear buffer growth rate
|
||||
* Increment < -1: Exponential buffer growth rate */
|
||||
if (increment == 0 || increment == -1)
|
||||
die("BUG: Invalid string increment");
|
||||
|
||||
s->increment = increment;
|
||||
}
|
||||
|
||||
static inline void debug_stats(strbuf_t *s)
|
||||
{
|
||||
if (s->debug) {
|
||||
fprintf(stderr, "strbuf(%lx) reallocs: %d, length: %d, size: %d\n",
|
||||
fprintf(stderr, "strbuf(%lx) reallocs: %d, length: %zd, size: %zd\n",
|
||||
(long)s, s->reallocs, s->length, s->size);
|
||||
}
|
||||
}
|
||||
|
|
@ -113,7 +104,7 @@ void strbuf_free(strbuf_t *s)
|
|||
free(s);
|
||||
}
|
||||
|
||||
char *strbuf_free_to_string(strbuf_t *s, int *len)
|
||||
char *strbuf_free_to_string(strbuf_t *s, size_t *len)
|
||||
{
|
||||
char *buf;
|
||||
|
||||
|
|
@ -131,57 +122,63 @@ char *strbuf_free_to_string(strbuf_t *s, int *len)
|
|||
return buf;
|
||||
}
|
||||
|
||||
static int calculate_new_size(strbuf_t *s, int len)
|
||||
static size_t calculate_new_size(strbuf_t *s, size_t len)
|
||||
{
|
||||
int reqsize, newsize;
|
||||
size_t reqsize, newsize;
|
||||
|
||||
if (len <= 0)
|
||||
die("BUG: Invalid strbuf length requested");
|
||||
|
||||
/* Ensure there is room for optional NULL termination */
|
||||
reqsize = len + 1;
|
||||
if (reqsize < len)
|
||||
die("Overflow, len: %zu", len);
|
||||
|
||||
/* If the user has requested to shrink the buffer, do it exactly */
|
||||
if (s->size > reqsize)
|
||||
return reqsize;
|
||||
|
||||
newsize = s->size;
|
||||
if (s->increment < 0) {
|
||||
if (reqsize >= SIZE_MAX / 2) {
|
||||
newsize = reqsize;
|
||||
} else {
|
||||
/* Exponential sizing */
|
||||
while (newsize < reqsize)
|
||||
newsize *= -s->increment;
|
||||
} else if (s->increment != 0) {
|
||||
/* Linear sizing */
|
||||
newsize = ((newsize + s->increment - 1) / s->increment) * s->increment;
|
||||
newsize *= 2;
|
||||
}
|
||||
|
||||
if (newsize < reqsize)
|
||||
die("BUG: strbuf length would overflow, len: %zu", len);
|
||||
|
||||
|
||||
return newsize;
|
||||
}
|
||||
|
||||
|
||||
/* Ensure strbuf can handle a string length bytes long (ignoring NULL
|
||||
* optional termination). */
|
||||
void strbuf_resize(strbuf_t *s, int len)
|
||||
void strbuf_resize(strbuf_t *s, size_t len)
|
||||
{
|
||||
int newsize;
|
||||
size_t newsize;
|
||||
|
||||
newsize = calculate_new_size(s, len);
|
||||
|
||||
if (s->debug > 1) {
|
||||
fprintf(stderr, "strbuf(%lx) resize: %d => %d\n",
|
||||
fprintf(stderr, "strbuf(%lx) resize: %zd => %zd\n",
|
||||
(long)s, s->size, newsize);
|
||||
}
|
||||
|
||||
s->size = newsize;
|
||||
s->buf = realloc(s->buf, s->size);
|
||||
s->buf = (char *)realloc(s->buf, s->size);
|
||||
if (!s->buf)
|
||||
die("Out of memory");
|
||||
die("Out of memory, len: %zu", len);
|
||||
s->reallocs++;
|
||||
}
|
||||
|
||||
void strbuf_append_string(strbuf_t *s, const char *str)
|
||||
{
|
||||
int space, i;
|
||||
int i;
|
||||
size_t space;
|
||||
|
||||
space = strbuf_empty_length(s);
|
||||
|
||||
|
|
@ -197,55 +194,6 @@ void strbuf_append_string(strbuf_t *s, const char *str)
|
|||
}
|
||||
}
|
||||
|
||||
/* strbuf_append_fmt() should only be used when an upper bound
|
||||
* is known for the output string. */
|
||||
void strbuf_append_fmt(strbuf_t *s, int len, const char *fmt, ...)
|
||||
{
|
||||
va_list arg;
|
||||
int fmt_len;
|
||||
|
||||
strbuf_ensure_empty_length(s, len);
|
||||
|
||||
va_start(arg, fmt);
|
||||
fmt_len = vsnprintf(s->buf + s->length, len, fmt, arg);
|
||||
va_end(arg);
|
||||
|
||||
if (fmt_len < 0)
|
||||
die("BUG: Unable to convert number"); /* This should never happen.. */
|
||||
|
||||
s->length += fmt_len;
|
||||
}
|
||||
|
||||
/* strbuf_append_fmt_retry() can be used when the there is no known
|
||||
* upper bound for the output string. */
|
||||
void strbuf_append_fmt_retry(strbuf_t *s, const char *fmt, ...)
|
||||
{
|
||||
va_list arg;
|
||||
int fmt_len, try;
|
||||
int empty_len;
|
||||
|
||||
/* If the first attempt to append fails, resize the buffer appropriately
|
||||
* and try again */
|
||||
for (try = 0; ; try++) {
|
||||
va_start(arg, fmt);
|
||||
/* Append the new formatted string */
|
||||
/* fmt_len is the length of the string required, excluding the
|
||||
* trailing NULL */
|
||||
empty_len = strbuf_empty_length(s);
|
||||
/* Add 1 since there is also space to store the terminating NULL. */
|
||||
fmt_len = vsnprintf(s->buf + s->length, empty_len + 1, fmt, arg);
|
||||
va_end(arg);
|
||||
|
||||
if (fmt_len <= empty_len)
|
||||
break; /* SUCCESS */
|
||||
if (try > 0)
|
||||
die("BUG: length of formatted string changed");
|
||||
|
||||
strbuf_resize(s, s->length + fmt_len);
|
||||
}
|
||||
|
||||
s->length += fmt_len;
|
||||
}
|
||||
|
||||
/* vi:ai et sw=4 ts=4:
|
||||
*/
|
||||
|
|
|
|||
46
src/deps/src/lua-cjson/strbuf.h
vendored
46
src/deps/src/lua-cjson/strbuf.h
vendored
|
|
@ -32,15 +32,13 @@
|
|||
|
||||
/* Size: Total bytes allocated to *buf
|
||||
* Length: String length, excluding optional NULL terminator.
|
||||
* Increment: Allocation increments when resizing the string buffer.
|
||||
* Dynamic: True if created via strbuf_new()
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
char *buf;
|
||||
int size;
|
||||
int length;
|
||||
int increment;
|
||||
size_t size;
|
||||
size_t length;
|
||||
int dynamic;
|
||||
int reallocs;
|
||||
int debug;
|
||||
|
|
@ -49,33 +47,27 @@ typedef struct {
|
|||
#ifndef STRBUF_DEFAULT_SIZE
|
||||
#define STRBUF_DEFAULT_SIZE 1023
|
||||
#endif
|
||||
#ifndef STRBUF_DEFAULT_INCREMENT
|
||||
#define STRBUF_DEFAULT_INCREMENT -2
|
||||
#endif
|
||||
|
||||
/* Initialise */
|
||||
extern strbuf_t *strbuf_new(int len);
|
||||
extern void strbuf_init(strbuf_t *s, int len);
|
||||
extern void strbuf_set_increment(strbuf_t *s, int increment);
|
||||
extern strbuf_t *strbuf_new(size_t len);
|
||||
extern void strbuf_init(strbuf_t *s, size_t len);
|
||||
|
||||
/* Release */
|
||||
extern void strbuf_free(strbuf_t *s);
|
||||
extern char *strbuf_free_to_string(strbuf_t *s, int *len);
|
||||
extern char *strbuf_free_to_string(strbuf_t *s, size_t *len);
|
||||
|
||||
/* Management */
|
||||
extern void strbuf_resize(strbuf_t *s, int len);
|
||||
static int strbuf_empty_length(strbuf_t *s);
|
||||
static int strbuf_length(strbuf_t *s);
|
||||
static char *strbuf_string(strbuf_t *s, int *len);
|
||||
static void strbuf_ensure_empty_length(strbuf_t *s, int len);
|
||||
extern void strbuf_resize(strbuf_t *s, size_t len);
|
||||
static size_t strbuf_empty_length(strbuf_t *s);
|
||||
static size_t strbuf_length(strbuf_t *s);
|
||||
static char *strbuf_string(strbuf_t *s, size_t *len);
|
||||
static void strbuf_ensure_empty_length(strbuf_t *s, size_t len);
|
||||
static char *strbuf_empty_ptr(strbuf_t *s);
|
||||
static void strbuf_extend_length(strbuf_t *s, int len);
|
||||
static void strbuf_extend_length(strbuf_t *s, size_t len);
|
||||
static void strbuf_set_length(strbuf_t *s, int len);
|
||||
|
||||
/* Update */
|
||||
extern void strbuf_append_fmt(strbuf_t *s, int len, const char *fmt, ...);
|
||||
extern void strbuf_append_fmt_retry(strbuf_t *s, const char *format, ...);
|
||||
static void strbuf_append_mem(strbuf_t *s, const char *c, int len);
|
||||
static void strbuf_append_mem(strbuf_t *s, const char *c, size_t len);
|
||||
extern void strbuf_append_string(strbuf_t *s, const char *str);
|
||||
static void strbuf_append_char(strbuf_t *s, const char c);
|
||||
static void strbuf_ensure_null(strbuf_t *s);
|
||||
|
|
@ -93,12 +85,12 @@ static inline int strbuf_allocated(strbuf_t *s)
|
|||
|
||||
/* Return bytes remaining in the string buffer
|
||||
* Ensure there is space for a NULL terminator. */
|
||||
static inline int strbuf_empty_length(strbuf_t *s)
|
||||
static inline size_t strbuf_empty_length(strbuf_t *s)
|
||||
{
|
||||
return s->size - s->length - 1;
|
||||
}
|
||||
|
||||
static inline void strbuf_ensure_empty_length(strbuf_t *s, int len)
|
||||
static inline void strbuf_ensure_empty_length(strbuf_t *s, size_t len)
|
||||
{
|
||||
if (len > strbuf_empty_length(s))
|
||||
strbuf_resize(s, s->length + len);
|
||||
|
|
@ -114,12 +106,12 @@ static inline void strbuf_set_length(strbuf_t *s, int len)
|
|||
s->length = len;
|
||||
}
|
||||
|
||||
static inline void strbuf_extend_length(strbuf_t *s, int len)
|
||||
static inline void strbuf_extend_length(strbuf_t *s, size_t len)
|
||||
{
|
||||
s->length += len;
|
||||
}
|
||||
|
||||
static inline int strbuf_length(strbuf_t *s)
|
||||
static inline size_t strbuf_length(strbuf_t *s)
|
||||
{
|
||||
return s->length;
|
||||
}
|
||||
|
|
@ -135,14 +127,14 @@ static inline void strbuf_append_char_unsafe(strbuf_t *s, const char c)
|
|||
s->buf[s->length++] = c;
|
||||
}
|
||||
|
||||
static inline void strbuf_append_mem(strbuf_t *s, const char *c, int len)
|
||||
static inline void strbuf_append_mem(strbuf_t *s, const char *c, size_t len)
|
||||
{
|
||||
strbuf_ensure_empty_length(s, len);
|
||||
memcpy(s->buf + s->length, c, len);
|
||||
s->length += len;
|
||||
}
|
||||
|
||||
static inline void strbuf_append_mem_unsafe(strbuf_t *s, const char *c, int len)
|
||||
static inline void strbuf_append_mem_unsafe(strbuf_t *s, const char *c, size_t len)
|
||||
{
|
||||
memcpy(s->buf + s->length, c, len);
|
||||
s->length += len;
|
||||
|
|
@ -153,7 +145,7 @@ static inline void strbuf_ensure_null(strbuf_t *s)
|
|||
s->buf[s->length] = 0;
|
||||
}
|
||||
|
||||
static inline char *strbuf_string(strbuf_t *s, int *len)
|
||||
static inline char *strbuf_string(strbuf_t *s, size_t *len)
|
||||
{
|
||||
if (len)
|
||||
*len = s->length;
|
||||
|
|
|
|||
42
src/deps/src/lua-cjson/tests/agentzh.t
vendored
42
src/deps/src/lua-cjson/tests/agentzh.t
vendored
|
|
@ -332,3 +332,45 @@ Cannot serialise function: type not supported
|
|||
|
||||
{"valid":"valid"}
|
||||
["one","two","three"]
|
||||
|
||||
|
||||
|
||||
=== TEST 23: array-like proxy object with __len and __index
|
||||
--- lua
|
||||
local cjson = require "cjson"
|
||||
local real_array = {"foo", "bar", "baz"}
|
||||
local proxy_array = {}
|
||||
setmetatable(proxy_array, {
|
||||
__len = function() return 3 end,
|
||||
__index = function(t, k)
|
||||
return real_array[k]
|
||||
end,
|
||||
})
|
||||
|
||||
print(cjson.encode(proxy_array))
|
||||
--- out
|
||||
["foo","bar","baz"]
|
||||
|
||||
|
||||
|
||||
=== TEST 24: check that integers are handled correctly on Lua 5.3+
|
||||
--- lua
|
||||
local lv = tonumber((_VERSION):match("Lua 5%.([0-9]+)"))
|
||||
|
||||
if lv >= 3 then
|
||||
local cjson = require "cjson"
|
||||
local array = cjson.decode [[ [10, 10.0, 3.5] ]]
|
||||
for i = 1, 4 do
|
||||
print(tostring(i) .. ": " .. tostring(math.type(array[i])))
|
||||
end
|
||||
else
|
||||
print("1: integer")
|
||||
print("2: float")
|
||||
print("3: float")
|
||||
print("4: nil")
|
||||
end
|
||||
--- out
|
||||
1: integer
|
||||
2: float
|
||||
3: float
|
||||
4: nil
|
||||
|
|
|
|||
1
src/deps/src/lua-cjson/tests/genutf8.pl
vendored
1
src/deps/src/lua-cjson/tests/genutf8.pl
vendored
|
|
@ -6,6 +6,7 @@
|
|||
# cff03b039d850f370a7362f3313e5268
|
||||
|
||||
use strict;
|
||||
no warnings 'nonchar';
|
||||
|
||||
# 0xD800 - 0xDFFF are used to encode supplementary codepoints
|
||||
# 0x10000 - 0x10FFFF are supplementary codepoints
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
FROM redhat/ubi9:9.4@sha256:d31d3e5e92c0c47277c5011c0326b285ab7ae627eff036133be1dccc4208004d as builder
|
||||
FROM redhat/ubi9:9.4@sha256:d98fdae16212df566150ac975cab860cd8d2cb1b322ed9966d09a13e219112e9 as builder
|
||||
|
||||
ENV OS=rhel
|
||||
ENV NGINX_VERSION 1.26.1
|
||||
|
|
@ -68,7 +68,7 @@ COPY src/scheduler scheduler
|
|||
COPY src/ui ui
|
||||
COPY src/VERSION VERSION
|
||||
|
||||
FROM redhat/ubi9:9.4@sha256:d31d3e5e92c0c47277c5011c0326b285ab7ae627eff036133be1dccc4208004d
|
||||
FROM redhat/ubi9:9.4@sha256:d98fdae16212df566150ac975cab860cd8d2cb1b322ed9966d09a13e219112e9
|
||||
|
||||
# Set default umask to prevent huge recursive chmod increasing the final image size
|
||||
RUN umask 027
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
FROM python:3.12.3-alpine3.19@sha256:ef097620baf1272e38264207003b0982285da3236a20ed829bf6bbf1e85fe3cb as builder
|
||||
FROM python:3.12.4-alpine3.19@sha256:ef3397d09070efd36583e83d2619cf8006158641e5b6b629d4d92a9778f5aa1c as builder
|
||||
|
||||
# Export var for specific actions on linux/arm/v7
|
||||
ARG TARGETPLATFORM
|
||||
|
|
@ -35,7 +35,7 @@ COPY src/common/utils utils
|
|||
COPY src/scheduler scheduler
|
||||
COPY src/VERSION VERSION
|
||||
|
||||
FROM python:3.12.3-alpine3.19@sha256:ef097620baf1272e38264207003b0982285da3236a20ed829bf6bbf1e85fe3cb
|
||||
FROM python:3.12.4-alpine3.19@sha256:ef3397d09070efd36583e83d2619cf8006158641e5b6b629d4d92a9778f5aa1c
|
||||
|
||||
# Set default umask to prevent huge recursive chmod increasing the final image size
|
||||
RUN umask 027
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ from json import load as json_load
|
|||
from os import _exit, environ, getenv, getpid, sep
|
||||
from os.path import join
|
||||
from pathlib import Path
|
||||
from shutil import copy, rmtree
|
||||
from shutil import copy, rmtree, copytree
|
||||
from signal import SIGINT, SIGTERM, signal, SIGHUP
|
||||
from stat import S_IEXEC
|
||||
from subprocess import run as subprocess_run, DEVNULL, STDOUT, PIPE
|
||||
|
|
@ -31,14 +31,16 @@ from common_utils import bytes_hash, dict_to_frozenset, get_integration # type:
|
|||
from logger import setup_logger # type: ignore
|
||||
from Database import Database # type: ignore
|
||||
from JobScheduler import JobScheduler
|
||||
from jobs import Job # type: ignore
|
||||
from API import API # type: ignore
|
||||
from ApiCaller import ApiCaller # type: ignore
|
||||
from ApiCaller import ApiCaller # type: ignore # type: ignore
|
||||
|
||||
APPLYING_CHANGES = Event()
|
||||
RUN = True
|
||||
SCHEDULER: Optional[JobScheduler] = None
|
||||
|
||||
CACHE_PATH = join(sep, "var", "cache", "bunkerweb")
|
||||
Path(CACHE_PATH).mkdir(parents=True, exist_ok=True)
|
||||
CACHE_PATH = Path(sep, "var", "cache", "bunkerweb")
|
||||
CACHE_PATH.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
CUSTOM_CONFIGS_PATH = Path(sep, "etc", "bunkerweb", "configs")
|
||||
CUSTOM_CONFIGS_PATH.mkdir(parents=True, exist_ok=True)
|
||||
|
|
@ -56,6 +58,8 @@ CUSTOM_CONFIGS_DIRS = (
|
|||
for custom_config_dir in CUSTOM_CONFIGS_DIRS:
|
||||
CUSTOM_CONFIGS_PATH.joinpath(custom_config_dir).mkdir(parents=True, exist_ok=True)
|
||||
|
||||
CONFIG_PATH = Path(sep, "etc", "nginx")
|
||||
|
||||
EXTERNAL_PLUGINS_PATH = Path(sep, "etc", "bunkerweb", "plugins")
|
||||
EXTERNAL_PLUGINS_PATH.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
|
|
@ -65,6 +69,9 @@ PRO_PLUGINS_PATH.mkdir(parents=True, exist_ok=True)
|
|||
TMP_PATH = Path(sep, "var", "tmp", "bunkerweb")
|
||||
TMP_PATH.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
FAILOVER_PATH = TMP_PATH.joinpath("failover")
|
||||
FAILOVER_PATH.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
HEALTHY_PATH = TMP_PATH.joinpath("scheduler.healthy")
|
||||
|
||||
SCHEDULER_TMP_ENV_PATH = TMP_PATH.joinpath("scheduler.env")
|
||||
|
|
@ -87,6 +94,14 @@ MASTER_MODE = getenv("MASTER_MODE", "no") == "yes"
|
|||
|
||||
|
||||
def handle_stop(signum, frame):
|
||||
current_time = datetime.now()
|
||||
while APPLYING_CHANGES.is_set() and (datetime.now() - current_time).seconds < 30:
|
||||
LOGGER.warning("Waiting for the changes to be applied before stopping ...")
|
||||
sleep(1)
|
||||
|
||||
if APPLYING_CHANGES.is_set():
|
||||
LOGGER.warning("Timeout reached, stopping without waiting for the changes to be applied ...")
|
||||
|
||||
if SCHEDULER is not None:
|
||||
SCHEDULER.clear()
|
||||
stop(0)
|
||||
|
|
@ -135,6 +150,41 @@ def stop(status):
|
|||
_exit(status)
|
||||
|
||||
|
||||
def send_nginx_configs(sent_path: Path = CONFIG_PATH):
|
||||
assert SCHEDULER is not None, "SCHEDULER is not defined"
|
||||
LOGGER.info(f"Sending {sent_path} folder ...")
|
||||
ret = SCHEDULER.send_files(sent_path.as_posix(), "/confs")
|
||||
if not ret:
|
||||
LOGGER.error("Sending nginx configs failed, configuration will not work as expected...")
|
||||
|
||||
|
||||
def send_nginx_cache(sent_path: Path = CACHE_PATH):
|
||||
assert SCHEDULER is not None, "SCHEDULER is not defined"
|
||||
LOGGER.info(f"Sending {sent_path} folder ...")
|
||||
if not SCHEDULER.send_files(sent_path.as_posix(), "/cache"):
|
||||
LOGGER.error(f"Error while sending {sent_path} folder")
|
||||
else:
|
||||
LOGGER.info(f"Successfully sent {sent_path} folder")
|
||||
|
||||
|
||||
def send_nginx_custom_configs(sent_path: Path = CUSTOM_CONFIGS_PATH):
|
||||
assert SCHEDULER is not None, "SCHEDULER is not defined"
|
||||
LOGGER.info(f"Sending {sent_path} folder ...")
|
||||
if not SCHEDULER.send_files(sent_path.as_posix(), "/custom_configs"):
|
||||
LOGGER.error(f"Error while sending {sent_path} folder")
|
||||
else:
|
||||
LOGGER.info(f"Successfully sent {sent_path} folder")
|
||||
|
||||
|
||||
def send_nginx_external_plugins(sent_path: Path = EXTERNAL_PLUGINS_PATH):
|
||||
assert SCHEDULER is not None, "SCHEDULER is not defined"
|
||||
LOGGER.info(f"Sending {sent_path} folder ...")
|
||||
if not SCHEDULER.send_files(sent_path.as_posix(), "/pro_plugins" if sent_path.as_posix().endswith("/pro/plugins") else "/plugins"):
|
||||
LOGGER.error(f"Error while sending {sent_path} folder")
|
||||
else:
|
||||
LOGGER.info(f"Successfully sent {sent_path} folder")
|
||||
|
||||
|
||||
def generate_custom_configs(configs: Optional[List[Dict[str, Any]]] = None, *, original_path: Union[Path, str] = CUSTOM_CONFIGS_PATH):
|
||||
if not isinstance(original_path, Path):
|
||||
original_path = Path(original_path)
|
||||
|
|
@ -179,22 +229,17 @@ def generate_custom_configs(configs: Optional[List[Dict[str, Any]]] = None, *, o
|
|||
)
|
||||
|
||||
if SCHEDULER and SCHEDULER.apis:
|
||||
LOGGER.info("Sending custom configs to BunkerWeb")
|
||||
ret = SCHEDULER.send_files(original_path, "/custom_configs")
|
||||
|
||||
if not ret:
|
||||
LOGGER.error("Sending custom configs failed, configuration will not work as expected...")
|
||||
send_nginx_custom_configs(original_path)
|
||||
|
||||
|
||||
def generate_external_plugins(plugins: Optional[List[Dict[str, Any]]] = None, *, original_path: Union[Path, str] = EXTERNAL_PLUGINS_PATH):
|
||||
def generate_external_plugins(original_path: Union[Path, str] = EXTERNAL_PLUGINS_PATH):
|
||||
if not isinstance(original_path, Path):
|
||||
original_path = Path(original_path)
|
||||
pro = "pro" in original_path.parts
|
||||
pro = original_path.as_posix().endswith("/pro/plugins")
|
||||
|
||||
if not plugins:
|
||||
assert SCHEDULER is not None
|
||||
plugins = SCHEDULER.db.get_plugins(_type="pro" if pro else "external", with_data=True)
|
||||
assert plugins is not None, "Couldn't get plugins from database"
|
||||
assert SCHEDULER is not None
|
||||
plugins = SCHEDULER.db.get_plugins(_type="pro" if pro else "external", with_data=True)
|
||||
assert plugins is not None, "Couldn't get plugins from database"
|
||||
|
||||
# Remove old external/pro plugins files
|
||||
LOGGER.info(f"Removing old/changed {'pro ' if pro else ''}external plugins files ...")
|
||||
|
|
@ -249,10 +294,7 @@ def generate_external_plugins(plugins: Optional[List[Dict[str, Any]]] = None, *,
|
|||
|
||||
if SCHEDULER and SCHEDULER.apis:
|
||||
LOGGER.info(f"Sending {'pro ' if pro else ''}external plugins to BunkerWeb")
|
||||
ret = SCHEDULER.send_files(original_path, "/pro_plugins" if original_path.as_posix().endswith("/pro/plugins") else "/plugins")
|
||||
|
||||
if not ret:
|
||||
LOGGER.error(f"Sending {'pro ' if pro else ''}external plugins failed, configuration will not work as expected...")
|
||||
send_nginx_external_plugins(original_path)
|
||||
|
||||
|
||||
def generate_caches():
|
||||
|
|
@ -334,7 +376,7 @@ def run_in_slave_mode(): # TODO: Refactor this feature
|
|||
threads = [
|
||||
Thread(target=generate_custom_configs),
|
||||
Thread(target=generate_external_plugins),
|
||||
Thread(target=generate_external_plugins, kwargs={"original_path": PRO_PLUGINS_PATH}),
|
||||
Thread(target=generate_external_plugins, args=(PRO_PLUGINS_PATH,)),
|
||||
Thread(target=generate_caches),
|
||||
]
|
||||
|
||||
|
|
@ -358,7 +400,7 @@ def run_in_slave_mode(): # TODO: Refactor this feature
|
|||
"--templates",
|
||||
join(sep, "usr", "share", "bunkerweb", "confs"),
|
||||
"--output",
|
||||
join(sep, "etc", "nginx"),
|
||||
CONFIG_PATH.as_posix(),
|
||||
"--variables",
|
||||
str(SCHEDULER_TMP_ENV_PATH),
|
||||
],
|
||||
|
|
@ -456,11 +498,13 @@ if __name__ == "__main__":
|
|||
|
||||
INTEGRATION = get_integration()
|
||||
tmp_variables_path = Path(args.variables or join(sep, "var", "tmp", "bunkerweb", "variables.env"))
|
||||
nginx_variables_path = Path(sep, "etc", "nginx", "variables.env")
|
||||
nginx_variables_path = CONFIG_PATH.joinpath("variables.env")
|
||||
dotenv_env = dotenv_values(str(tmp_variables_path))
|
||||
|
||||
SCHEDULER = JobScheduler(environ, LOGGER, INTEGRATION, db=Database(LOGGER, sqlalchemy_string=dotenv_env.get("DATABASE_URI", getenv("DATABASE_URI", None)))) # type: ignore
|
||||
|
||||
JOB = Job(LOGGER, SCHEDULER.db)
|
||||
|
||||
if SLAVE_MODE:
|
||||
run_in_slave_mode()
|
||||
stop(1)
|
||||
|
|
@ -469,6 +513,8 @@ if __name__ == "__main__":
|
|||
|
||||
db_metadata = SCHEDULER.db.get_metadata()
|
||||
|
||||
APPLYING_CHANGES.set()
|
||||
|
||||
if (
|
||||
isinstance(db_metadata, str)
|
||||
or (db_metadata["is_initialized"] and SCHEDULER.db.get_config() != dotenv_env)
|
||||
|
|
@ -523,6 +569,7 @@ if __name__ == "__main__":
|
|||
|
||||
def check_configs_changes():
|
||||
# Checking if any custom config has been created by the user
|
||||
assert SCHEDULER is not None, "SCHEDULER is not defined"
|
||||
LOGGER.info("Checking if there are any changes in custom configs ...")
|
||||
custom_configs = []
|
||||
db_configs = SCHEDULER.db.get_custom_configs()
|
||||
|
|
@ -564,6 +611,7 @@ if __name__ == "__main__":
|
|||
|
||||
def check_plugin_changes(_type: Literal["external", "pro"] = "external"):
|
||||
# Check if any external or pro plugin has been added by the user
|
||||
assert SCHEDULER is not None, "SCHEDULER is not defined"
|
||||
LOGGER.info(f"Checking if there are any changes in {_type} plugins ...")
|
||||
plugin_path = EXTERNAL_PLUGINS_PATH if _type == "external" else PRO_PLUGINS_PATH
|
||||
db_plugins = SCHEDULER.db.get_plugins(_type=_type)
|
||||
|
|
@ -603,6 +651,7 @@ if __name__ == "__main__":
|
|||
| ({"jobs": jobs} if jobs else {})
|
||||
)
|
||||
|
||||
changes = False
|
||||
if tmp_external_plugins:
|
||||
changes = {hash(dict_to_frozenset(d)) for d in tmp_external_plugins} != {hash(dict_to_frozenset(d)) for d in db_plugins}
|
||||
|
||||
|
|
@ -613,8 +662,10 @@ if __name__ == "__main__":
|
|||
LOGGER.error(f"Couldn't save some manually added {_type} plugins to database: {err}")
|
||||
except BaseException as e:
|
||||
LOGGER.error(f"Error while saving {_type} plugins to database: {e}")
|
||||
else:
|
||||
return send_nginx_external_plugins(plugin_path)
|
||||
|
||||
generate_external_plugins(SCHEDULER.db.get_plugins(_type=_type, with_data=True), original_path=plugin_path)
|
||||
generate_external_plugins(plugin_path)
|
||||
|
||||
threads.extend([Thread(target=check_plugin_changes, args=("external",)), Thread(target=check_plugin_changes, args=("pro",))])
|
||||
|
||||
|
|
@ -638,7 +689,7 @@ if __name__ == "__main__":
|
|||
threads.clear()
|
||||
|
||||
if db_metadata["pro_plugins_changed"]:
|
||||
threads.append(Thread(target=generate_external_plugins, kwargs={"original_path": PRO_PLUGINS_PATH}))
|
||||
threads.append(Thread(target=generate_external_plugins, args=(PRO_PLUGINS_PATH,)))
|
||||
if db_metadata["external_plugins_changed"]:
|
||||
threads.append(Thread(target=generate_external_plugins))
|
||||
|
||||
|
|
@ -679,19 +730,6 @@ if __name__ == "__main__":
|
|||
RUN_JOBS_ONCE = True
|
||||
CHANGES = []
|
||||
|
||||
def send_nginx_configs():
|
||||
LOGGER.info(f"Sending {join(sep, 'etc', 'nginx')} folder ...")
|
||||
ret = SCHEDULER.send_files(join(sep, "etc", "nginx"), "/confs")
|
||||
if not ret:
|
||||
LOGGER.error("Sending nginx configs failed, configuration will not work as expected...")
|
||||
|
||||
def send_nginx_cache():
|
||||
LOGGER.info(f"Sending {CACHE_PATH} folder ...")
|
||||
if not SCHEDULER.send_files(CACHE_PATH, "/cache"):
|
||||
LOGGER.error(f"Error while sending {CACHE_PATH} folder")
|
||||
else:
|
||||
LOGGER.info(f"Successfully sent {CACHE_PATH} folder")
|
||||
|
||||
changed_plugins = []
|
||||
old_changes = {}
|
||||
|
||||
|
|
@ -722,7 +760,7 @@ if __name__ == "__main__":
|
|||
"--templates",
|
||||
join(sep, "usr", "share", "bunkerweb", "confs"),
|
||||
"--output",
|
||||
join(sep, "etc", "nginx"),
|
||||
CONFIG_PATH.as_posix(),
|
||||
"--variables",
|
||||
str(SCHEDULER_TMP_ENV_PATH),
|
||||
]
|
||||
|
|
@ -746,6 +784,7 @@ if __name__ == "__main__":
|
|||
LOGGER.warning("No BunkerWeb instance found, skipping nginx configs sending ...")
|
||||
|
||||
try:
|
||||
failed = False
|
||||
if SCHEDULER.apis:
|
||||
# send cache
|
||||
thread = Thread(target=send_nginx_cache)
|
||||
|
|
@ -755,10 +794,7 @@ if __name__ == "__main__":
|
|||
for thread in threads:
|
||||
thread.join()
|
||||
|
||||
if SCHEDULER.send_to_apis("POST", "/reload"):
|
||||
LOGGER.info("Successfully reloaded nginx")
|
||||
else:
|
||||
LOGGER.error("Error while reloading nginx")
|
||||
failed = not SCHEDULER.send_to_apis("POST", "/reload")
|
||||
elif INTEGRATION == "Linux":
|
||||
# Reload nginx
|
||||
LOGGER.info("Reloading nginx ...")
|
||||
|
|
@ -770,14 +806,47 @@ if __name__ == "__main__":
|
|||
check=False,
|
||||
stdout=PIPE,
|
||||
)
|
||||
if proc.returncode == 0:
|
||||
LOGGER.info("Successfully sent reload signal to nginx")
|
||||
else:
|
||||
LOGGER.error(
|
||||
f"Error while reloading nginx - returncode: {proc.returncode} - error: {proc.stdout.decode('utf-8') if proc.stdout else 'no output'}"
|
||||
)
|
||||
failed = proc.returncode != 0
|
||||
else:
|
||||
LOGGER.warning("No BunkerWeb instance found, skipping nginx reload ...")
|
||||
LOGGER.warning("No BunkerWeb instance found, skipping bunkerweb reload ...")
|
||||
|
||||
try:
|
||||
SCHEDULER.db.set_failover(failed)
|
||||
except BaseException as e:
|
||||
LOGGER.error(f"Error while setting failover to true in the database: {e}")
|
||||
|
||||
if failed:
|
||||
LOGGER.error("Error while reloading bunkerweb, failing over to last working configuration ...")
|
||||
if (
|
||||
not FAILOVER_PATH.joinpath("config").is_dir()
|
||||
or not FAILOVER_PATH.joinpath("custom_configs").is_dir()
|
||||
or not FAILOVER_PATH.joinpath("cache").is_dir()
|
||||
):
|
||||
LOGGER.error("No failover configuration found, ignoring failover ...")
|
||||
else:
|
||||
# Failover to last working configuration
|
||||
if SCHEDULER.apis:
|
||||
tmp_threads = [
|
||||
Thread(target=send_nginx_configs, args=(FAILOVER_PATH.joinpath("config"),)),
|
||||
Thread(target=send_nginx_cache, args=(FAILOVER_PATH.joinpath("cache"),)),
|
||||
Thread(target=send_nginx_custom_configs, args=(FAILOVER_PATH.joinpath("custom_configs"),)),
|
||||
]
|
||||
for thread in tmp_threads:
|
||||
thread.start()
|
||||
|
||||
for thread in tmp_threads:
|
||||
thread.join()
|
||||
|
||||
SCHEDULER.send_to_apis("POST", "/reload")
|
||||
else:
|
||||
LOGGER.info("Successfully reloaded bunkerweb")
|
||||
# Update the failover path with the working configuration
|
||||
rmtree(FAILOVER_PATH, ignore_errors=True)
|
||||
FAILOVER_PATH.mkdir(parents=True, exist_ok=True)
|
||||
copytree(CONFIG_PATH, FAILOVER_PATH.joinpath("config"))
|
||||
copytree(CUSTOM_CONFIGS_PATH, FAILOVER_PATH.joinpath("custom_configs"))
|
||||
copytree(CACHE_PATH, FAILOVER_PATH.joinpath("cache"))
|
||||
Thread(target=JOB.cache_dir, args=(FAILOVER_PATH,), kwargs={"job_name": "failover-backup"}).start()
|
||||
except:
|
||||
LOGGER.error(f"Exception while reloading after running jobs once scheduling : {format_exc()}")
|
||||
|
||||
|
|
@ -813,6 +882,8 @@ if __name__ == "__main__":
|
|||
if not HEALTHY_PATH.is_file():
|
||||
HEALTHY_PATH.write_text(datetime.now().isoformat(), encoding="utf-8")
|
||||
|
||||
APPLYING_CHANGES.clear()
|
||||
|
||||
# infinite schedule for the jobs
|
||||
LOGGER.info("Executing job scheduler ...")
|
||||
errors = 0
|
||||
|
|
@ -922,6 +993,7 @@ if __name__ == "__main__":
|
|||
sleep(5)
|
||||
|
||||
if NEED_RELOAD:
|
||||
APPLYING_CHANGES.set()
|
||||
LOGGER.debug(f"Changes: {changes}")
|
||||
SCHEDULER.try_database_readonly(force=True)
|
||||
CHANGES.clear()
|
||||
|
|
@ -938,12 +1010,12 @@ if __name__ == "__main__":
|
|||
|
||||
if PLUGINS_NEED_GENERATION:
|
||||
CHANGES.append("external_plugins")
|
||||
generate_external_plugins(SCHEDULER.db.get_plugins(_type="external", with_data=True))
|
||||
generate_external_plugins()
|
||||
SCHEDULER.update_jobs()
|
||||
|
||||
if PRO_PLUGINS_NEED_GENERATION:
|
||||
CHANGES.append("pro_plugins")
|
||||
generate_external_plugins(SCHEDULER.db.get_plugins(_type="pro", with_data=True), original_path=PRO_PLUGINS_PATH)
|
||||
generate_external_plugins(PRO_PLUGINS_PATH)
|
||||
SCHEDULER.update_jobs()
|
||||
|
||||
if CONFIG_NEED_GENERATION:
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue