Compare commits
21 Commits
v1.6.1
...
feat/frank
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
79e3a98a11 | ||
|
|
afc4463ab3 | ||
|
|
6749ddbde5 | ||
|
|
82ba882a4e | ||
|
|
4b1679e70f | ||
|
|
75ce2e22c2 | ||
|
|
5a43e9f4de | ||
|
|
5542044376 | ||
|
|
52b65311c2 | ||
|
|
2dc8048ad2 | ||
|
|
a59b649dac | ||
|
|
68a4548bf4 | ||
|
|
6f049f9a9c | ||
|
|
340b1fd1c2 | ||
|
|
c9329bd717 | ||
|
|
f54a1fa85e | ||
|
|
b4115ca9a2 | ||
|
|
14469d4a0a | ||
|
|
ee394756b1 | ||
|
|
5a260c430a | ||
|
|
b6fcab5a95 |
@@ -6,6 +6,6 @@
|
||||
.idea/
|
||||
.vscode/
|
||||
__debug_bin
|
||||
frankenphp.test
|
||||
frankenphp.dev.test
|
||||
caddy/frankenphp/Build
|
||||
*.log
|
||||
|
||||
5
.github/dependabot.yaml
vendored
@@ -17,11 +17,6 @@ updates:
|
||||
interval: weekly
|
||||
commit-message:
|
||||
prefix: chore(caddy)
|
||||
# These packages must be in sync with versions
|
||||
# used by github.com/caddyserver/caddy/v2
|
||||
ignore:
|
||||
- dependency-name: github.com/google/cel-go
|
||||
- dependency-name: github.com/quic-go/*
|
||||
groups:
|
||||
go-modules:
|
||||
patterns:
|
||||
|
||||
4
.github/workflows/docker.yaml
vendored
@@ -134,7 +134,7 @@ jobs:
|
||||
platforms: ${{ matrix.platform }}
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v3
|
||||
if: github.event.pull_request.head.repo.full_name == github.repository
|
||||
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
|
||||
with:
|
||||
username: ${{ secrets.REGISTRY_USERNAME }}
|
||||
password: ${{ secrets.REGISTRY_PASSWORD }}
|
||||
@@ -223,7 +223,7 @@ jobs:
|
||||
uses: docker/setup-buildx-action@v3
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v3
|
||||
if: github.event.pull_request.head.repo.full_name == github.repository
|
||||
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
|
||||
with:
|
||||
username: ${{ secrets.REGISTRY_USERNAME }}
|
||||
password: ${{ secrets.REGISTRY_PASSWORD }}
|
||||
|
||||
2
.github/workflows/lint.yaml
vendored
@@ -23,8 +23,6 @@ jobs:
|
||||
- name: Lint Code Base
|
||||
uses: super-linter/super-linter/slim@v7.4.0
|
||||
env:
|
||||
VALIDATE_ALL_CODEBASE: true
|
||||
DEFAULT_BRANCH: main
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
LINTER_RULES_PATH: /
|
||||
MARKDOWN_CONFIG_FILE: .markdown-lint.yaml
|
||||
|
||||
2
.github/workflows/sanitizers.yaml
vendored
@@ -101,4 +101,4 @@ jobs:
|
||||
- name: Compile tests
|
||||
run: go test ${{ matrix.sanitizer == 'msan' && '-tags=nowatcher' || '' }} -${{ matrix.sanitizer }} -v -x -c
|
||||
- name: Run tests
|
||||
run: ./frankenphp.test -test.v
|
||||
run: ./frankenphp.dev.test -test.v
|
||||
|
||||
6
.github/workflows/static.yaml
vendored
@@ -101,7 +101,7 @@ jobs:
|
||||
platforms: ${{ matrix.platform }}
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v3
|
||||
if: github.event.pull_request.head.repo.full_name == github.repository
|
||||
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
|
||||
with:
|
||||
username: ${{ secrets.REGISTRY_USERNAME }}
|
||||
password: ${{ secrets.REGISTRY_PASSWORD }}
|
||||
@@ -205,7 +205,7 @@ jobs:
|
||||
platforms: ${{ matrix.platform }}
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v3
|
||||
if: github.event.pull_request.head.repo.full_name == github.repository
|
||||
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
|
||||
with:
|
||||
username: ${{ secrets.REGISTRY_USERNAME }}
|
||||
password: ${{ secrets.REGISTRY_PASSWORD }}
|
||||
@@ -315,7 +315,7 @@ jobs:
|
||||
uses: docker/setup-buildx-action@v3
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v3
|
||||
if: github.event.pull_request.head.repo.full_name == github.repository
|
||||
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository
|
||||
with:
|
||||
username: ${{ secrets.REGISTRY_USERNAME }}
|
||||
password: ${{ secrets.REGISTRY_PASSWORD }}
|
||||
|
||||
5
.github/workflows/tests.yaml
vendored
@@ -15,6 +15,7 @@ permissions:
|
||||
contents: read
|
||||
env:
|
||||
GOTOOLCHAIN: local
|
||||
GOEXPERIMENT: cgocheck2
|
||||
jobs:
|
||||
tests-linux:
|
||||
name: Tests (Linux, PHP ${{ matrix.php-versions }})
|
||||
@@ -24,7 +25,6 @@ jobs:
|
||||
matrix:
|
||||
php-versions: ["8.2", "8.3", "8.4"]
|
||||
env:
|
||||
GOEXPERIMENT: cgocheck2
|
||||
GOMAXPROCS: 10
|
||||
LIBRARY_PATH: ${{ github.workspace }}/watcher/target/lib
|
||||
steps:
|
||||
@@ -46,7 +46,7 @@ jobs:
|
||||
debug: true
|
||||
- name: Install e-dant/watcher
|
||||
uses: ./.github/actions/watcher
|
||||
- name: Set Set CGO flags
|
||||
- name: Set CGO flags
|
||||
run: echo "CGO_CFLAGS=-I${PWD}/watcher/target/include $(php-config --includes)" >> "${GITHUB_ENV}"
|
||||
- name: Build
|
||||
run: go build
|
||||
@@ -78,7 +78,6 @@ jobs:
|
||||
name: Tests (macOS, PHP 8.4)
|
||||
runs-on: macos-latest
|
||||
env:
|
||||
GOEXPERIMENT: cgocheck2
|
||||
HOMEBREW_NO_AUTO_UPDATE: 1
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
2
.gitignore
vendored
@@ -6,7 +6,7 @@
|
||||
.idea/
|
||||
.vscode/
|
||||
__debug_bin
|
||||
frankenphp.test
|
||||
frankenphp.dev.test
|
||||
caddy/frankenphp/Build
|
||||
package/etc/php.ini
|
||||
*.log
|
||||
|
||||
7
.golangci.yaml
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
version: "2"
|
||||
run:
|
||||
build-tags:
|
||||
- nobadger
|
||||
- nomysql
|
||||
- nopgx
|
||||
@@ -176,7 +176,7 @@ docker buildx bake -f docker-bake.hcl --pull --no-cache --push
|
||||
|
||||
```console
|
||||
go test -tags watcher -c -ldflags=-w
|
||||
gdb --args frankenphp.test -test.run ^MyTest$
|
||||
gdb --args frankenphp.dev.test -test.run ^MyTest$
|
||||
```
|
||||
|
||||
9. When the bug is fixed, revert all these changes
|
||||
@@ -214,6 +214,6 @@ follow these steps:
|
||||
3. Copy the `README.md` and `CONTRIBUTING.md` files from the root directory to the new directory
|
||||
4. Translate the content of the files, but don't change the filenames, also don't translate strings starting with `> [!` (it's special markup for GitHub)
|
||||
5. Create a Pull Request with the translations
|
||||
6. In the [site repository](https://github.com/dunglas/frankenphp-website/tree/main), copy and translate the translation files in the `content/`, `data/` and `i18n/` directories
|
||||
6. In the [site repository](https://github.com/dunglas/frankenphp-website), copy and translate the translation files in the `content/`, `data/` and `i18n/` directories
|
||||
7. Translate the values in the created YAML file
|
||||
8. Open a Pull Request on the site repository
|
||||
|
||||
@@ -43,12 +43,6 @@ You can also run command-line scripts with:
|
||||
frankenphp php-cli /path/to/your/script.php
|
||||
```
|
||||
|
||||
> [!WARNING]
|
||||
>
|
||||
> In production, prefer using [the Docker images](#docker), [the Brew package](#homebrew)
|
||||
> or [compiling FrankenPHP from sources](https://frankenphp.dev/docs/compile/).
|
||||
> The standalone binary is provided for development and testing purposes.
|
||||
|
||||
### Docker
|
||||
|
||||
Alternatively, [Docker images](https://frankenphp.dev/docs/docker/) are available:
|
||||
@@ -100,7 +94,7 @@ frankenphp php-server
|
||||
- [Laravel integration](https://frankenphp.dev/docs/laravel/)
|
||||
- [Known issues](https://frankenphp.dev/docs/known-issues/)
|
||||
- [Demo app (Symfony) and benchmarks](https://github.com/dunglas/frankenphp-demo)
|
||||
- [Go library documentation](https://pkg.go.dev/github.com/dunglas/frankenphp)
|
||||
- [Go library documentation](https://pkg.go.dev/frankenphp.dev)
|
||||
- [Contributing and debugging](https://frankenphp.dev/docs/contributing/)
|
||||
|
||||
## Examples and Skeletons
|
||||
|
||||
@@ -31,30 +31,14 @@ if [ ! -f "dist/$bin" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "${FRANKENPHP_VERSION}" ]; then
|
||||
FRANKENPHP_VERSION="$(git rev-parse --verify HEAD)"
|
||||
export FRANKENPHP_VERSION
|
||||
elif [ -d ".git/" ]; then
|
||||
CURRENT_REF="$(git rev-parse --abbrev-ref HEAD)"
|
||||
export CURRENT_REF
|
||||
version_output="$(dist/"$bin" version)"
|
||||
frankenphp_version=$(echo "$version_output" | grep -oP 'FrankenPHP\s+\K[^ ]+' || true)
|
||||
frankenphp_version=${frankenphp_version#v}
|
||||
|
||||
if echo "${FRANKENPHP_VERSION}" | grep -F -q "."; then
|
||||
# Tag
|
||||
|
||||
# Trim "v" prefix if any
|
||||
FRANKENPHP_VERSION=${FRANKENPHP_VERSION#v}
|
||||
export FRANKENPHP_VERSION
|
||||
|
||||
git checkout "v${FRANKENPHP_VERSION}"
|
||||
else
|
||||
git checkout "${FRANKENPHP_VERSION}"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ ! "${FRANKENPHP_VERSION}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
||||
echo "Warning: FRANKENPHP_VERSION must be set to X.Y.Z (e.g. 1.5.1), got '${FRANKENPHP_VERSION}'"
|
||||
if [[ ! "${frankenphp_version}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
||||
echo "Warning: frankenphp_version must be set to X.Y.Z (e.g. 1.5.1), got '${frankenphp_version}'"
|
||||
echo "Falling back to non-release version 0.0.0"
|
||||
FRANKENPHP_VERSION=0.0.0
|
||||
frankenphp_version=0.0.0
|
||||
fi
|
||||
|
||||
group_preexists=0
|
||||
@@ -87,7 +71,7 @@ iteration=1
|
||||
glibc_version=$(ldd -v "$bin" | awk '/GLIBC_/ {gsub(/[()]/, "", $2); print $2}' | grep -v GLIBC_PRIVATE | sort -V | tail -n1)
|
||||
cxxabi_version=$(strings "$bin" | grep -oP 'CXXABI_\d+\.\d+(\.\d+)?' | sort -V | tail -n1)
|
||||
|
||||
fpm -s dir -t rpm -n frankenphp -v "${FRANKENPHP_VERSION}" \
|
||||
fpm -s dir -t rpm -n frankenphp -v "${frankenphp_version}" \
|
||||
--config-files /etc/frankenphp/Caddyfile \
|
||||
--config-files /etc/frankenphp/php.ini \
|
||||
--depends "libc.so.6(${glibc_version})(64bit)" \
|
||||
@@ -110,7 +94,7 @@ fpm -s dir -t rpm -n frankenphp -v "${FRANKENPHP_VERSION}" \
|
||||
glibc_version=$(ldd -v "$bin" | awk '/GLIBC_/ {gsub(/[()]/, "", $2); print $2}' | grep -v GLIBC_PRIVATE | sed 's/GLIBC_//' | sort -V | tail -n1)
|
||||
cxxabi_version=$(strings "$bin" | grep -oP 'CXXABI_\d+\.\d+(\.\d+)?' | sed 's/CXXABI_//' | sort -V | tail -n1)
|
||||
|
||||
fpm -s dir -t deb -n frankenphp -v "${FRANKENPHP_VERSION}" \
|
||||
fpm -s dir -t deb -n frankenphp -v "${frankenphp_version}" \
|
||||
--config-files /etc/frankenphp/Caddyfile \
|
||||
--config-files /etc/frankenphp/php.ini \
|
||||
--depends "libc6 (>= ${glibc_version})" \
|
||||
|
||||
@@ -330,8 +330,8 @@ CGO_ENABLED=1 \
|
||||
${XCADDY_COMMAND} build \
|
||||
--output "../dist/${bin}" \
|
||||
${XCADDY_ARGS} \
|
||||
--with github.com/dunglas/frankenphp=.. \
|
||||
--with github.com/dunglas/frankenphp/caddy=.
|
||||
--with frankenphp.dev=.. \
|
||||
--with frankenphp.dev/caddy=.
|
||||
cd ..
|
||||
|
||||
if [ -d "${EMBED}" ]; then
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/caddyserver/caddy/v2"
|
||||
"github.com/dunglas/frankenphp"
|
||||
"frankenphp.dev"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
|
||||
@@ -4,14 +4,14 @@ import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/dunglas/frankenphp/internal/fastabs"
|
||||
"io"
|
||||
"net/http"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"frankenphp.dev"
|
||||
"frankenphp.dev/internal/fastabs"
|
||||
"github.com/caddyserver/caddy/v2/caddytest"
|
||||
"github.com/dunglas/frankenphp"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
@@ -225,8 +225,6 @@ func TestAddModuleWorkerViaAdminApi(t *testing.T) {
|
||||
skip_install_trust
|
||||
admin localhost:2999
|
||||
http_port `+testPort+`
|
||||
|
||||
frankenphp
|
||||
}
|
||||
|
||||
localhost:`+testPort+` {
|
||||
@@ -252,8 +250,6 @@ func TestAddModuleWorkerViaAdminApi(t *testing.T) {
|
||||
skip_install_trust
|
||||
admin localhost:2999
|
||||
http_port ` + testPort + `
|
||||
|
||||
frankenphp
|
||||
}
|
||||
|
||||
localhost:` + testPort + ` {
|
||||
|
||||
105
caddy/caddy.go
@@ -14,7 +14,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/dunglas/frankenphp/internal/fastabs"
|
||||
"frankenphp.dev/internal/fastabs"
|
||||
|
||||
"github.com/caddyserver/caddy/v2"
|
||||
"github.com/caddyserver/caddy/v2/caddyconfig"
|
||||
@@ -23,7 +23,7 @@ import (
|
||||
"github.com/caddyserver/caddy/v2/modules/caddyhttp"
|
||||
"github.com/caddyserver/caddy/v2/modules/caddyhttp/fileserver"
|
||||
"github.com/caddyserver/caddy/v2/modules/caddyhttp/rewrite"
|
||||
"github.com/dunglas/frankenphp"
|
||||
"frankenphp.dev"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -33,10 +33,6 @@ const (
|
||||
|
||||
var iniError = errors.New("'php_ini' must be in the format: php_ini \"<key>\" \"<value>\"")
|
||||
|
||||
// FrankenPHPModule instances register their workers, and FrankenPHPApp reads them at Start() time.
|
||||
// FrankenPHPApp.Workers may be set by JSON config, so keep them separate.
|
||||
var moduleWorkerConfigs []workerConfig
|
||||
|
||||
func init() {
|
||||
caddy.RegisterModule(FrankenPHPApp{})
|
||||
caddy.RegisterModule(FrankenPHPModule{})
|
||||
@@ -104,6 +100,40 @@ func (f *FrankenPHPApp) Provision(ctx caddy.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *FrankenPHPApp) generateUniqueModuleWorkerName(filepath string) string {
|
||||
var i uint
|
||||
filepath, _ = fastabs.FastAbs(filepath)
|
||||
name := "m#" + filepath
|
||||
|
||||
retry:
|
||||
for _, wc := range f.Workers {
|
||||
if wc.Name == name {
|
||||
name = fmt.Sprintf("m#%s_%d", filepath, i)
|
||||
i++
|
||||
|
||||
goto retry
|
||||
}
|
||||
}
|
||||
|
||||
return name
|
||||
}
|
||||
|
||||
func (f *FrankenPHPApp) addModuleWorkers(workers ...workerConfig) ([]workerConfig, error) {
|
||||
for i := range workers {
|
||||
w := &workers[i]
|
||||
if frankenphp.EmbeddedAppPath != "" && filepath.IsLocal(w.FileName) {
|
||||
w.FileName = filepath.Join(frankenphp.EmbeddedAppPath, w.FileName)
|
||||
}
|
||||
if w.Name == "" {
|
||||
w.Name = f.generateUniqueModuleWorkerName(w.FileName)
|
||||
} else if !strings.HasPrefix(w.Name, "m#") {
|
||||
w.Name = "m#" + w.Name
|
||||
}
|
||||
f.Workers = append(f.Workers, *w)
|
||||
}
|
||||
return workers, nil
|
||||
}
|
||||
|
||||
func (f *FrankenPHPApp) Start() error {
|
||||
repl := caddy.NewReplacer()
|
||||
|
||||
@@ -115,9 +145,7 @@ func (f *FrankenPHPApp) Start() error {
|
||||
frankenphp.WithPhpIni(f.PhpIni),
|
||||
frankenphp.WithMaxWaitTime(f.MaxWaitTime),
|
||||
}
|
||||
// Add workers from FrankenPHPApp and FrankenPHPModule configurations
|
||||
// f.Workers may have been set by JSON config, so keep them separate
|
||||
for _, w := range append(f.Workers, moduleWorkerConfigs...) {
|
||||
for _, w := range append(f.Workers) {
|
||||
opts = append(opts, frankenphp.WithWorkers(w.Name, repl.ReplaceKnown(w.FileName, ""), w.Num, w.Env, w.Watch))
|
||||
}
|
||||
|
||||
@@ -143,7 +171,6 @@ func (f *FrankenPHPApp) Stop() error {
|
||||
f.Workers = nil
|
||||
f.NumThreads = 0
|
||||
f.MaxWaitTime = 0
|
||||
moduleWorkerConfigs = nil
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -316,14 +343,6 @@ func (f *FrankenPHPApp) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
|
||||
if frankenphp.EmbeddedAppPath != "" && filepath.IsLocal(wc.FileName) {
|
||||
wc.FileName = filepath.Join(frankenphp.EmbeddedAppPath, wc.FileName)
|
||||
}
|
||||
if wc.Name == "" {
|
||||
// let worker initialization validate if the FileName is valid or not
|
||||
name, _ := fastabs.FastAbs(wc.FileName)
|
||||
if name == "" {
|
||||
name = wc.FileName
|
||||
}
|
||||
wc.Name = name
|
||||
}
|
||||
if strings.HasPrefix(wc.Name, "m#") {
|
||||
return fmt.Errorf(`global worker names must not start with "m#": %q`, wc.Name)
|
||||
}
|
||||
@@ -391,6 +410,23 @@ func (FrankenPHPModule) CaddyModule() caddy.ModuleInfo {
|
||||
// Provision sets up the module.
|
||||
func (f *FrankenPHPModule) Provision(ctx caddy.Context) error {
|
||||
f.logger = ctx.Slogger()
|
||||
app, err := ctx.App("frankenphp")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fapp, ok := app.(*FrankenPHPApp)
|
||||
if !ok {
|
||||
return fmt.Errorf(`expected ctx.App("frankenphp") to return *FrankenPHPApp, got %T`, app)
|
||||
}
|
||||
if fapp == nil {
|
||||
return fmt.Errorf(`expected ctx.App("frankenphp") to return *FrankenPHPApp, got nil`)
|
||||
}
|
||||
|
||||
workers, err := fapp.addModuleWorkers(f.Workers...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
f.Workers = workers
|
||||
|
||||
if f.Root == "" {
|
||||
if frankenphp.EmbeddedAppPath == "" {
|
||||
@@ -504,25 +540,6 @@ func (f *FrankenPHPModule) ServeHTTP(w http.ResponseWriter, r *http.Request, _ c
|
||||
return nil
|
||||
}
|
||||
|
||||
func generateUniqueModuleWorkerName(filepath string) string {
|
||||
var i uint
|
||||
name := "m#" + filepath
|
||||
|
||||
outer:
|
||||
for {
|
||||
for _, wc := range moduleWorkerConfigs {
|
||||
if wc.Name == name {
|
||||
name = fmt.Sprintf("m#%s_%d", filepath, i)
|
||||
i++
|
||||
|
||||
continue outer
|
||||
}
|
||||
}
|
||||
|
||||
return name
|
||||
}
|
||||
}
|
||||
|
||||
// UnmarshalCaddyfile implements caddyfile.Unmarshaler.
|
||||
func (f *FrankenPHPModule) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
|
||||
// First pass: Parse all directives except "worker"
|
||||
@@ -608,28 +625,14 @@ func (f *FrankenPHPModule) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
|
||||
}
|
||||
}
|
||||
|
||||
if wc.Name == "" {
|
||||
wc.Name = generateUniqueModuleWorkerName(wc.FileName)
|
||||
}
|
||||
if !strings.HasPrefix(wc.Name, "m#") {
|
||||
wc.Name = "m#" + wc.Name
|
||||
}
|
||||
|
||||
// Check if a worker with this filename already exists in this module
|
||||
for _, existingWorker := range f.Workers {
|
||||
if existingWorker.FileName == wc.FileName {
|
||||
return fmt.Errorf(`workers in a single "php_server" block must not have duplicate filenames: %q`, wc.FileName)
|
||||
}
|
||||
}
|
||||
// Check if a worker with this name and a different environment or filename already exists
|
||||
for _, existingWorker := range moduleWorkerConfigs {
|
||||
if existingWorker.Name == wc.Name {
|
||||
return fmt.Errorf("workers must not have duplicate names: %q", wc.Name)
|
||||
}
|
||||
}
|
||||
|
||||
f.Workers = append(f.Workers, wc)
|
||||
moduleWorkerConfigs = append(moduleWorkerConfigs, wc)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,8 +14,8 @@ import (
|
||||
|
||||
"github.com/caddyserver/caddy/v2"
|
||||
"github.com/caddyserver/caddy/v2/caddytest"
|
||||
"github.com/dunglas/frankenphp"
|
||||
"github.com/dunglas/frankenphp/internal/fastabs"
|
||||
"frankenphp.dev"
|
||||
"frankenphp.dev/internal/fastabs"
|
||||
"github.com/prometheus/client_golang/prometheus/testutil"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
@@ -31,8 +31,6 @@ func TestPHP(t *testing.T) {
|
||||
admin localhost:2999
|
||||
http_port `+testPort+`
|
||||
https_port 9443
|
||||
|
||||
frankenphp
|
||||
}
|
||||
|
||||
localhost:`+testPort+` {
|
||||
@@ -63,8 +61,6 @@ func TestLargeRequest(t *testing.T) {
|
||||
admin localhost:2999
|
||||
http_port `+testPort+`
|
||||
https_port 9443
|
||||
|
||||
frankenphp
|
||||
}
|
||||
|
||||
localhost:`+testPort+` {
|
||||
@@ -182,8 +178,6 @@ func TestNamedModuleWorkers(t *testing.T) {
|
||||
{
|
||||
skip_install_trust
|
||||
admin localhost:2999
|
||||
|
||||
frankenphp
|
||||
}
|
||||
|
||||
http://localhost:`+testPort+` {
|
||||
@@ -383,8 +377,6 @@ func TestPHPServerDirective(t *testing.T) {
|
||||
admin localhost:2999
|
||||
http_port `+testPort+`
|
||||
https_port 9443
|
||||
|
||||
frankenphp
|
||||
}
|
||||
|
||||
localhost:`+testPort+` {
|
||||
@@ -406,8 +398,6 @@ func TestPHPServerDirectiveDisableFileServer(t *testing.T) {
|
||||
admin localhost:2999
|
||||
http_port `+testPort+`
|
||||
https_port 9443
|
||||
|
||||
frankenphp
|
||||
order php_server before respond
|
||||
}
|
||||
|
||||
@@ -434,8 +424,6 @@ func TestMetrics(t *testing.T) {
|
||||
http_port `+testPort+`
|
||||
https_port 9443
|
||||
metrics
|
||||
|
||||
frankenphp
|
||||
}
|
||||
|
||||
localhost:`+testPort+` {
|
||||
@@ -800,7 +788,6 @@ func TestAllDefinedServerVars(t *testing.T) {
|
||||
skip_install_trust
|
||||
admin localhost:2999
|
||||
http_port `+testPort+`
|
||||
frankenphp
|
||||
}
|
||||
localhost:`+testPort+` {
|
||||
route {
|
||||
|
||||
@@ -7,11 +7,6 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// resetModuleWorkers resets the moduleWorkerConfigs slice for testing
|
||||
func resetModuleWorkers() {
|
||||
moduleWorkerConfigs = make([]workerConfig, 0)
|
||||
}
|
||||
|
||||
func TestModuleWorkerDuplicateFilenamesFail(t *testing.T) {
|
||||
// Create a test configuration with duplicate worker filenames
|
||||
configWithDuplicateFilenames := `
|
||||
@@ -38,53 +33,6 @@ func TestModuleWorkerDuplicateFilenamesFail(t *testing.T) {
|
||||
// Verify that an error was returned
|
||||
require.Error(t, err, "Expected an error when two workers in the same module have the same filename")
|
||||
require.Contains(t, err.Error(), "must not have duplicate filenames", "Error message should mention duplicate filenames")
|
||||
resetModuleWorkers()
|
||||
}
|
||||
|
||||
func TestModuleWorkersDuplicateNameFail(t *testing.T) {
|
||||
// Create a test configuration with a worker name
|
||||
configWithWorkerName1 := `
|
||||
{
|
||||
php_server {
|
||||
worker {
|
||||
name test-worker
|
||||
file ../testdata/worker-with-env.php
|
||||
num 1
|
||||
}
|
||||
}
|
||||
}`
|
||||
|
||||
// Parse the first configuration
|
||||
d1 := caddyfile.NewTestDispenser(configWithWorkerName1)
|
||||
module1 := &FrankenPHPModule{}
|
||||
|
||||
// Unmarshal the first configuration
|
||||
err := module1.UnmarshalCaddyfile(d1)
|
||||
require.NoError(t, err, "First module should be configured without errors")
|
||||
|
||||
// Create a second test configuration with the same worker name
|
||||
configWithWorkerName2 := `
|
||||
{
|
||||
php_server {
|
||||
worker {
|
||||
name test-worker
|
||||
file ../testdata/worker-with-env.php
|
||||
num 1
|
||||
}
|
||||
}
|
||||
}`
|
||||
|
||||
// Parse the second configuration
|
||||
d2 := caddyfile.NewTestDispenser(configWithWorkerName2)
|
||||
module2 := &FrankenPHPModule{}
|
||||
|
||||
// Unmarshal the second configuration
|
||||
err = module2.UnmarshalCaddyfile(d2)
|
||||
|
||||
// Verify that an error was returned
|
||||
require.Error(t, err, "Expected an error when two workers have the same name, but different environments")
|
||||
require.Contains(t, err.Error(), "must not have duplicate names", "Error message should mention duplicate names")
|
||||
resetModuleWorkers()
|
||||
}
|
||||
|
||||
func TestModuleWorkersWithDifferentFilenames(t *testing.T) {
|
||||
@@ -111,8 +59,6 @@ func TestModuleWorkersWithDifferentFilenames(t *testing.T) {
|
||||
require.Len(t, module.Workers, 2, "Expected two workers to be added to the module")
|
||||
require.Equal(t, "../testdata/worker-with-env.php", module.Workers[0].FileName, "First worker should have the correct filename")
|
||||
require.Equal(t, "../testdata/worker-with-counter.php", module.Workers[1].FileName, "Second worker should have the correct filename")
|
||||
|
||||
resetModuleWorkers()
|
||||
}
|
||||
|
||||
func TestModuleWorkersDifferentNamesSucceed(t *testing.T) {
|
||||
@@ -130,6 +76,7 @@ func TestModuleWorkersDifferentNamesSucceed(t *testing.T) {
|
||||
|
||||
// Parse the first configuration
|
||||
d1 := caddyfile.NewTestDispenser(configWithWorkerName1)
|
||||
app := &FrankenPHPApp{}
|
||||
module1 := &FrankenPHPModule{}
|
||||
|
||||
// Unmarshal the first configuration
|
||||
@@ -158,12 +105,15 @@ func TestModuleWorkersDifferentNamesSucceed(t *testing.T) {
|
||||
// Verify that no error was returned
|
||||
require.NoError(t, err, "Expected no error when two workers have different names")
|
||||
|
||||
// Verify that both workers were added to moduleWorkerConfigs
|
||||
require.Len(t, moduleWorkerConfigs, 2, "Expected two workers to be added to moduleWorkerConfigs")
|
||||
require.Equal(t, "m#test-worker-1", moduleWorkerConfigs[0].Name, "First worker should have the correct name")
|
||||
require.Equal(t, "m#test-worker-2", moduleWorkerConfigs[1].Name, "Second worker should have the correct name")
|
||||
_, err = app.addModuleWorkers(module1.Workers...)
|
||||
require.NoError(t, err, "Expected no error when adding the first module workers")
|
||||
_, err = app.addModuleWorkers(module2.Workers...)
|
||||
require.NoError(t, err, "Expected no error when adding the second module workers")
|
||||
|
||||
resetModuleWorkers()
|
||||
// Verify that both workers were added
|
||||
require.Len(t, app.Workers, 2, "Expected two workers in the app")
|
||||
require.Equal(t, "m#test-worker-1", app.Workers[0].Name, "First worker should have the correct name")
|
||||
require.Equal(t, "m#test-worker-2", app.Workers[1].Name, "Second worker should have the correct name")
|
||||
}
|
||||
|
||||
func TestModuleWorkerWithEnvironmentVariables(t *testing.T) {
|
||||
@@ -198,8 +148,6 @@ func TestModuleWorkerWithEnvironmentVariables(t *testing.T) {
|
||||
require.Len(t, module.Workers[0].Env, 2, "Expected two environment variables")
|
||||
require.Equal(t, "production", module.Workers[0].Env["APP_ENV"], "APP_ENV should be set to production")
|
||||
require.Equal(t, "true", module.Workers[0].Env["DEBUG"], "DEBUG should be set to true")
|
||||
|
||||
resetModuleWorkers()
|
||||
}
|
||||
|
||||
func TestModuleWorkerWithWatchConfiguration(t *testing.T) {
|
||||
@@ -236,8 +184,6 @@ func TestModuleWorkerWithWatchConfiguration(t *testing.T) {
|
||||
require.Equal(t, "./**/*.{php,yaml,yml,twig,env}", module.Workers[0].Watch[0], "First watch pattern should be the default")
|
||||
require.Equal(t, "./src/**/*.php", module.Workers[0].Watch[1], "Second watch pattern should match the configuration")
|
||||
require.Equal(t, "./config/**/*.yaml", module.Workers[0].Watch[2], "Third watch pattern should match the configuration")
|
||||
|
||||
resetModuleWorkers()
|
||||
}
|
||||
|
||||
func TestModuleWorkerWithCustomName(t *testing.T) {
|
||||
@@ -256,6 +202,7 @@ func TestModuleWorkerWithCustomName(t *testing.T) {
|
||||
// Parse the configuration
|
||||
d := caddyfile.NewTestDispenser(configWithCustomName)
|
||||
module := &FrankenPHPModule{}
|
||||
app := &FrankenPHPApp{}
|
||||
|
||||
// Unmarshal the configuration
|
||||
err := module.UnmarshalCaddyfile(d)
|
||||
@@ -267,8 +214,9 @@ func TestModuleWorkerWithCustomName(t *testing.T) {
|
||||
require.Len(t, module.Workers, 1, "Expected one worker to be added to the module")
|
||||
require.Equal(t, "../testdata/worker-with-env.php", module.Workers[0].FileName, "Worker should have the correct filename")
|
||||
|
||||
// Verify that the worker was added to moduleWorkerConfigs with the m# prefix
|
||||
require.Equal(t, "m#custom-worker-name", module.Workers[0].Name, "Worker should have the custom name")
|
||||
|
||||
resetModuleWorkers()
|
||||
// Verify that the worker was added to app.Workers with the m# prefix
|
||||
module.Workers, err = app.addModuleWorkers(module.Workers...)
|
||||
require.NoError(t, err, "Expected no error when adding the worker to the app")
|
||||
require.Equal(t, "m#custom-worker-name", module.Workers[0].Name, "Worker should have the custom name, prefixed with m#")
|
||||
require.Equal(t, "m#custom-worker-name", app.Workers[0].Name, "Worker should have the custom name, prefixed with m#")
|
||||
}
|
||||
|
||||
@@ -4,10 +4,11 @@
|
||||
# https://caddyserver.com/docs/caddyfile
|
||||
{
|
||||
skip_install_trust
|
||||
|
||||
{$CADDY_GLOBAL_OPTIONS}
|
||||
|
||||
frankenphp {
|
||||
{$FRANKENPHP_CONFIG}
|
||||
{$FRANKENPHP_CONFIG}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +47,9 @@
|
||||
{$CADDY_SERVER_EXTRA_DIRECTIVES}
|
||||
|
||||
php_server {
|
||||
}
|
||||
#worker /path/to/your/worker.php
|
||||
}
|
||||
}
|
||||
|
||||
# As an alternative to editing the above site block, you can add your own site
|
||||
# block files in the Caddyfile.d directory, and they will be included as long
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
// plug in Caddy modules here.
|
||||
_ "github.com/caddyserver/caddy/v2/modules/standard"
|
||||
_ "github.com/dunglas/caddy-cbrotli"
|
||||
_ "github.com/dunglas/frankenphp/caddy"
|
||||
_ "frankenphp.dev/caddy"
|
||||
_ "github.com/dunglas/mercure/caddy"
|
||||
_ "github.com/dunglas/vulcain/caddy"
|
||||
)
|
||||
|
||||
38
caddy/go.mod
@@ -1,8 +1,8 @@
|
||||
module github.com/dunglas/frankenphp/caddy
|
||||
module frankenphp.dev/caddy
|
||||
|
||||
go 1.24.0
|
||||
|
||||
replace github.com/dunglas/frankenphp => ../
|
||||
replace frankenphp.dev => ../
|
||||
|
||||
retract v1.0.0-rc.1 // Human error
|
||||
|
||||
@@ -10,7 +10,7 @@ require (
|
||||
github.com/caddyserver/caddy/v2 v2.10.0
|
||||
github.com/caddyserver/certmagic v0.23.0
|
||||
github.com/dunglas/caddy-cbrotli v1.0.0
|
||||
github.com/dunglas/frankenphp v1.6.1
|
||||
frankenphp.dev v1.7.0
|
||||
github.com/dunglas/mercure/caddy v0.19.2
|
||||
github.com/dunglas/vulcain/caddy v1.2.0
|
||||
github.com/prometheus/client_golang v1.22.0
|
||||
@@ -18,7 +18,7 @@ require (
|
||||
github.com/stretchr/testify v1.10.0
|
||||
)
|
||||
|
||||
require github.com/smallstep/go-attestation v0.4.4-0.20240109183208-413678f90935 // indirect
|
||||
require github.com/smallstep/go-attestation v0.4.4-0.20241119153605-2306d5b464ca // indirect
|
||||
|
||||
require (
|
||||
cel.dev/expr v0.24.0 // indirect
|
||||
@@ -31,11 +31,11 @@ require (
|
||||
github.com/Masterminds/semver/v3 v3.3.1 // indirect
|
||||
github.com/Masterminds/sprig/v3 v3.3.0 // indirect
|
||||
github.com/MauriceGit/skiplist v0.0.0-20211105230623-77f5c8d3e145 // indirect
|
||||
github.com/MicahParks/jwkset v0.9.5 // indirect
|
||||
github.com/MicahParks/keyfunc/v3 v3.3.11 // indirect
|
||||
github.com/MicahParks/jwkset v0.9.6 // indirect
|
||||
github.com/MicahParks/keyfunc/v3 v3.4.0 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.2 // indirect
|
||||
github.com/RoaringBitmap/roaring v1.9.4 // indirect
|
||||
github.com/alecthomas/chroma/v2 v2.17.2 // indirect
|
||||
github.com/alecthomas/chroma/v2 v2.18.0 // indirect
|
||||
github.com/antlr4-go/antlr/v4 v4.13.1 // indirect
|
||||
github.com/aryann/difflib v0.0.0-20210328193216-ff5ff6dc229b // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
@@ -85,7 +85,7 @@ require (
|
||||
github.com/google/certificate-transparency-go v1.3.1 // indirect
|
||||
github.com/google/go-tpm v0.9.5 // indirect
|
||||
github.com/google/go-tspi v0.3.0 // indirect
|
||||
github.com/google/pprof v0.0.0-20250501235452-c0086092b71a // indirect
|
||||
github.com/google/pprof v0.0.0-20250602020802-c6617b811d0e // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/gorilla/handlers v1.5.2 // indirect
|
||||
github.com/gorilla/mux v1.8.1 // indirect
|
||||
@@ -95,14 +95,14 @@ require (
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
|
||||
github.com/jackc/pgx/v5 v5.7.4 // indirect
|
||||
github.com/jackc/pgx/v5 v5.7.5 // indirect
|
||||
github.com/jackc/puddle/v2 v2.2.2 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/kevburnsjr/skipfilter v0.0.1 // indirect
|
||||
github.com/klauspost/compress v1.18.0 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.10 // indirect
|
||||
github.com/kylelemons/godebug v1.1.0 // indirect
|
||||
github.com/libdns/libdns v1.0.0 // indirect
|
||||
github.com/libdns/libdns v1.1.0 // indirect
|
||||
github.com/mailru/easyjson v0.9.0 // indirect
|
||||
github.com/manifoldco/promptui v0.9.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||
@@ -130,7 +130,7 @@ require (
|
||||
github.com/prometheus/common v0.64.0 // indirect
|
||||
github.com/prometheus/procfs v0.16.1 // indirect
|
||||
github.com/quic-go/qpack v0.5.1 // indirect
|
||||
github.com/quic-go/quic-go v0.51.0 // indirect
|
||||
github.com/quic-go/quic-go v0.52.0 // indirect
|
||||
github.com/rs/xid v1.6.0 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/sagikazarmark/locafero v0.9.0 // indirect
|
||||
@@ -147,7 +147,7 @@ require (
|
||||
github.com/smallstep/truststore v0.13.0 // indirect
|
||||
github.com/sourcegraph/conc v0.3.0 // indirect
|
||||
github.com/spf13/afero v1.14.0 // indirect
|
||||
github.com/spf13/cast v1.8.0 // indirect
|
||||
github.com/spf13/cast v1.9.2 // indirect
|
||||
github.com/spf13/pflag v1.0.6 // indirect
|
||||
github.com/spf13/viper v1.20.1 // indirect
|
||||
github.com/stoewer/go-strcase v1.3.0 // indirect
|
||||
@@ -161,7 +161,7 @@ require (
|
||||
github.com/urfave/cli v1.22.16 // indirect
|
||||
github.com/x448/float16 v0.8.4 // indirect
|
||||
github.com/yosida95/uritemplate/v3 v3.0.2 // indirect
|
||||
github.com/yuin/goldmark v1.7.11 // indirect
|
||||
github.com/yuin/goldmark v1.7.12 // indirect
|
||||
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc // indirect
|
||||
github.com/zeebo/blake3 v0.2.4 // indirect
|
||||
go.etcd.io/bbolt v1.4.0 // indirect
|
||||
@@ -179,15 +179,15 @@ require (
|
||||
go.opentelemetry.io/otel/sdk v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.35.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.6.0 // indirect
|
||||
go.step.sm/crypto v0.63.0 // indirect
|
||||
go.step.sm/crypto v0.66.0 // indirect
|
||||
go.uber.org/automaxprocs v1.6.0 // indirect
|
||||
go.uber.org/mock v0.5.2 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.27.0 // indirect
|
||||
go.uber.org/zap/exp v0.3.0 // indirect
|
||||
golang.org/x/crypto v0.38.0 // indirect
|
||||
golang.org/x/crypto/x509roots/fallback v0.0.0-20250512184618-9dbbcf002b5c // indirect
|
||||
golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 // indirect
|
||||
golang.org/x/crypto/x509roots/fallback v0.0.0-20250531095911-4f9f0ca9fcfb // indirect
|
||||
golang.org/x/exp v0.0.0-20250531010427-b6e5de432a8b // indirect
|
||||
golang.org/x/mod v0.24.0 // indirect
|
||||
golang.org/x/net v0.40.0 // indirect
|
||||
golang.org/x/oauth2 v0.30.0 // indirect
|
||||
@@ -197,9 +197,9 @@ require (
|
||||
golang.org/x/text v0.25.0 // indirect
|
||||
golang.org/x/time v0.11.0 // indirect
|
||||
golang.org/x/tools v0.33.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250512202823-5a2f75b736a9 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250512202823-5a2f75b736a9 // indirect
|
||||
google.golang.org/grpc v1.72.1 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250528174236-200df99c418a // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a // indirect
|
||||
google.golang.org/grpc v1.72.2 // indirect
|
||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1 // indirect
|
||||
google.golang.org/protobuf v1.36.6 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
|
||||
|
||||
97
caddy/go.sum
@@ -6,18 +6,18 @@ cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT
|
||||
cloud.google.com/go v0.37.0/go.mod h1:TS1dMSSfndXH133OKGwekG838Om/cQT0BUHV3HcBgoo=
|
||||
cloud.google.com/go v0.120.0 h1:wc6bgG9DHyKqF5/vQvX1CiZrtHnxJjBlKUyF9nP6meA=
|
||||
cloud.google.com/go v0.120.0/go.mod h1:/beW32s8/pGRuj4IILWQNd4uuebeT4dkOhKmkfit64Q=
|
||||
cloud.google.com/go/auth v0.16.0 h1:Pd8P1s9WkcrBE2n/PhAwKsdrR35V3Sg2II9B+ndM3CU=
|
||||
cloud.google.com/go/auth v0.16.0/go.mod h1:1howDHJ5IETh/LwYs3ZxvlkXF48aSqqJUM+5o02dNOI=
|
||||
cloud.google.com/go/auth v0.16.1 h1:XrXauHMd30LhQYVRHLGvJiYeczweKQXZxsTbV9TiguU=
|
||||
cloud.google.com/go/auth v0.16.1/go.mod h1:1howDHJ5IETh/LwYs3ZxvlkXF48aSqqJUM+5o02dNOI=
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc=
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c=
|
||||
cloud.google.com/go/compute/metadata v0.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4j01OwKxG9I=
|
||||
cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg=
|
||||
cloud.google.com/go/iam v1.5.0 h1:QlLcVMhbLGOjRcGe6VTGGTyQib8dRLK2B/kYNV0+2xs=
|
||||
cloud.google.com/go/iam v1.5.0/go.mod h1:U+DOtKQltF/LxPEtcDLoobcsZMilSRwR7mgNL7knOpo=
|
||||
cloud.google.com/go/kms v1.21.2 h1:c/PRUSMNQ8zXrc1sdAUnsenWWaNXN+PzTXfXOcSFdoE=
|
||||
cloud.google.com/go/kms v1.21.2/go.mod h1:8wkMtHV/9Z8mLXEXr1GK7xPSBdi6knuLXIhqjuWcI6w=
|
||||
cloud.google.com/go/longrunning v0.6.6 h1:XJNDo5MUfMM05xK3ewpbSdmt7R2Zw+aQEMbdQR65Rbw=
|
||||
cloud.google.com/go/longrunning v0.6.6/go.mod h1:hyeGJUrPHcx0u2Uu1UFSoYZLn4lkMrccJig0t4FI7yw=
|
||||
cloud.google.com/go/compute/metadata v0.7.0 h1:PBWF+iiAerVNe8UCHxdOt6eHLVc3ydFeOCw78U8ytSU=
|
||||
cloud.google.com/go/compute/metadata v0.7.0/go.mod h1:j5MvL9PprKL39t166CoB1uVHfQMs4tFQZZcKwksXUjo=
|
||||
cloud.google.com/go/iam v1.5.2 h1:qgFRAGEmd8z6dJ/qyEchAuL9jpswyODjA2lS+w234g8=
|
||||
cloud.google.com/go/iam v1.5.2/go.mod h1:SE1vg0N81zQqLzQEwxL2WI6yhetBdbNQuTvIKCSkUHE=
|
||||
cloud.google.com/go/kms v1.22.0 h1:dBRIj7+GDeeEvatJeTB19oYZNV0aj6wEqSIT/7gLqtk=
|
||||
cloud.google.com/go/kms v1.22.0/go.mod h1:U7mf8Sva5jpOb4bxYZdtw/9zsbIjrklYwPcvMk34AL8=
|
||||
cloud.google.com/go/longrunning v0.6.7 h1:IGtfDWHhQCgCjwQjV9iiLnUta9LBCo8R9QmAFsS/PrE=
|
||||
cloud.google.com/go/longrunning v0.6.7/go.mod h1:EAFV3IZAKmM56TyiE6VAP3VoTzhZzySwI/YI1s/nRsY=
|
||||
dario.cat/mergo v1.0.2 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8=
|
||||
dario.cat/mergo v1.0.2/go.mod h1:E/hbnu0NxMFBjpMIE34DRGLWqDy0g5FuKDhCb31ngxA=
|
||||
dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU=
|
||||
@@ -44,10 +44,10 @@ github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSC
|
||||
github.com/MauriceGit/skiplist v0.0.0-20191117202105-643e379adb62/go.mod h1:877WBceefKn14QwVVn4xRFUsHsZb9clICgdeTj4XsUg=
|
||||
github.com/MauriceGit/skiplist v0.0.0-20211105230623-77f5c8d3e145 h1:1yw6O62BReQ+uA1oyk9XaQTvLhcoHWmoQAgXmDFXpIY=
|
||||
github.com/MauriceGit/skiplist v0.0.0-20211105230623-77f5c8d3e145/go.mod h1:877WBceefKn14QwVVn4xRFUsHsZb9clICgdeTj4XsUg=
|
||||
github.com/MicahParks/jwkset v0.9.5 h1:/baA2n7RhO7nRIe1rx4ZX1Opeq+mwDuuWi2myDZwqnA=
|
||||
github.com/MicahParks/jwkset v0.9.5/go.mod h1:U2oRhRaLgDCLjtpGL2GseNKGmZtLs/3O7p+OZaL5vo0=
|
||||
github.com/MicahParks/keyfunc/v3 v3.3.11 h1:eA6wNltwdSRX2gtpTwZseBCC9nGeBkI9KxHtTyZbDbo=
|
||||
github.com/MicahParks/keyfunc/v3 v3.3.11/go.mod h1:y6Ed3dMgNKTcpxbaQHD8mmrYDUZWJAxteddA6OQj+ag=
|
||||
github.com/MicahParks/jwkset v0.9.6 h1:Tf8l2/MOby5Kh3IkrqzThPQKfLytMERoAsGZKlyYZxg=
|
||||
github.com/MicahParks/jwkset v0.9.6/go.mod h1:U2oRhRaLgDCLjtpGL2GseNKGmZtLs/3O7p+OZaL5vo0=
|
||||
github.com/MicahParks/keyfunc/v3 v3.4.0 h1:g03TXq6NjhZyO/UkODl//abm4KiLLNRi0VhW7vGOHyg=
|
||||
github.com/MicahParks/keyfunc/v3 v3.4.0/go.mod h1:y6Ed3dMgNKTcpxbaQHD8mmrYDUZWJAxteddA6OQj+ag=
|
||||
github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE=
|
||||
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
|
||||
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
||||
@@ -59,8 +59,8 @@ github.com/RoaringBitmap/roaring v1.9.4/go.mod h1:6AXUsoIEzDTFFQCe1RbGA6uFONMhve
|
||||
github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0=
|
||||
github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k=
|
||||
github.com/alecthomas/chroma/v2 v2.2.0/go.mod h1:vf4zrexSH54oEjJ7EdB65tGNHmH3pGZmVkgTP5RHvAs=
|
||||
github.com/alecthomas/chroma/v2 v2.17.2 h1:Rm81SCZ2mPoH+Q8ZCc/9YvzPUN/E7HgPiPJD8SLV6GI=
|
||||
github.com/alecthomas/chroma/v2 v2.17.2/go.mod h1:RVX6AvYm4VfYe/zsk7mjHueLDZor3aWCNE14TFlepBk=
|
||||
github.com/alecthomas/chroma/v2 v2.18.0 h1:6h53Q4hW83SuF+jcsp7CVhLsMozzvQvO8HBbKQW+gn4=
|
||||
github.com/alecthomas/chroma/v2 v2.18.0/go.mod h1:RVX6AvYm4VfYe/zsk7mjHueLDZor3aWCNE14TFlepBk=
|
||||
github.com/alecthomas/repr v0.0.0-20220113201626-b1b626ac65ae/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8=
|
||||
github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc=
|
||||
github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
|
||||
@@ -167,6 +167,7 @@ github.com/dolthub/maphash v0.1.0 h1:bsQ7JsF4FkkWyrP3oCnFJgrCUAFbFf3kOl4L/QxPDyQ
|
||||
github.com/dolthub/maphash v0.1.0/go.mod h1:gkg4Ch4CdCDu5h6PMriVLawB7koZ+5ijb9puGMV50a4=
|
||||
github.com/dunglas/caddy-cbrotli v1.0.0 h1:+WNqXBkWyMcIpXB2rVZ3nwcElUbuAzf0kPxNXU4D+u0=
|
||||
github.com/dunglas/caddy-cbrotli v1.0.0/go.mod h1:KZsUu3fnQBgO0o3YDoQuO3Z61dFgUncr1F8rg8acwQw=
|
||||
github.com/dunglas/frankenphp v1.7.0/go.mod h1:BaPr7WO5PmAkMtJvRUhRcmdWNAuEIK1zWLC++c8GhE0=
|
||||
github.com/dunglas/httpsfv v1.1.0 h1:Jw76nAyKWKZKFrpMMcL76y35tOpYHqQPzHQiwDvpe54=
|
||||
github.com/dunglas/httpsfv v1.1.0/go.mod h1:zID2mqw9mFsnt7YC3vYQ9/cjq30q41W+1AnDwH8TiMg=
|
||||
github.com/dunglas/mercure v0.19.2 h1:eBMQhxvzJTenIffL+jlqtWO+TPevCjOQ+DQJb8iB6+s=
|
||||
@@ -263,8 +264,8 @@ github.com/google/go-tspi v0.3.0 h1:ADtq8RKfP+jrTyIWIZDIYcKOMecRqNJFOew2IT0Inus=
|
||||
github.com/google/go-tspi v0.3.0/go.mod h1:xfMGI3G0PhxCdNVcYr1C4C+EizojDg/TXuX5by8CiHI=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20250501235452-c0086092b71a h1:rDA3FfmxwXR+BVKKdz55WwMJ1pD2hJQNW31d+l3mPk4=
|
||||
github.com/google/pprof v0.0.0-20250501235452-c0086092b71a/go.mod h1:5hDyRhoBCxViHszMt12TnOpEI4VVi+U8Gm9iphldiMA=
|
||||
github.com/google/pprof v0.0.0-20250602020802-c6617b811d0e h1:FJta/0WsADCe1r9vQjdHbd3KuiLPu7Y9WlyLGwMUNyE=
|
||||
github.com/google/pprof v0.0.0-20250602020802-c6617b811d0e/go.mod h1:5hDyRhoBCxViHszMt12TnOpEI4VVi+U8Gm9iphldiMA=
|
||||
github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0=
|
||||
github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
@@ -274,8 +275,8 @@ github.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7
|
||||
github.com/googleapis/gax-go v2.0.0+incompatible h1:j0GKcs05QVmm7yesiZq2+9cxHkNK9YM6zKx4D2qucQU=
|
||||
github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
|
||||
github.com/googleapis/gax-go/v2 v2.0.3/go.mod h1:LLvjysVCY1JZeum8Z6l8qUty8fiNwE08qbEPm1M08qg=
|
||||
github.com/googleapis/gax-go/v2 v2.14.1 h1:hb0FFeiPaQskmvakKu5EbCbpntQn48jyHuvrkurSS/Q=
|
||||
github.com/googleapis/gax-go/v2 v2.14.1/go.mod h1:Hb/NubMaVM88SrNkvl8X/o8XWwDJEPqouaLeN2IUxoA=
|
||||
github.com/googleapis/gax-go/v2 v2.14.2 h1:eBLnkZ9635krYIPD+ag1USrOAI0Nr0QYF3+/3GqO0k0=
|
||||
github.com/googleapis/gax-go/v2 v2.14.2/go.mod h1:ON64QhlJkhVtSqp4v1uaK92VyZ2gmvDQsweuyLV+8+w=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE=
|
||||
github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w=
|
||||
@@ -300,8 +301,8 @@ github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsI
|
||||
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo=
|
||||
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||
github.com/jackc/pgx/v5 v5.7.4 h1:9wKznZrhWa2QiHL+NjTSPP6yjl3451BX3imWDnokYlg=
|
||||
github.com/jackc/pgx/v5 v5.7.4/go.mod h1:ncY89UGWxg82EykZUwSpUKEfccBGGYq1xjrOpsbsfGQ=
|
||||
github.com/jackc/pgx/v5 v5.7.5 h1:JHGfMnQY+IEtGM63d+NGMjoRpysB2JBwDr5fsngwmJs=
|
||||
github.com/jackc/pgx/v5 v5.7.5/go.mod h1:aruU7o91Tc2q2cFp5h4uP3f6ztExVpyVv88Xl/8Vl8M=
|
||||
github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo=
|
||||
github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
||||
github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU=
|
||||
@@ -329,8 +330,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/libdns/libdns v1.0.0 h1:IvYaz07JNz6jUQ4h/fv2R4sVnRnm77J/aOuC9B+TQTA=
|
||||
github.com/libdns/libdns v1.0.0/go.mod h1:4Bj9+5CQiNMVGf87wjX4CY3HQJypUHRuLvlsfsZqLWQ=
|
||||
github.com/libdns/libdns v1.1.0 h1:9ze/tWvt7Df6sbhOJRB8jT33GHEHpEQXdtkE3hPthbU=
|
||||
github.com/libdns/libdns v1.1.0/go.mod h1:4Bj9+5CQiNMVGf87wjX4CY3HQJypUHRuLvlsfsZqLWQ=
|
||||
github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
@@ -412,8 +413,8 @@ github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzM
|
||||
github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is=
|
||||
github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI=
|
||||
github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg=
|
||||
github.com/quic-go/quic-go v0.51.0 h1:K8exxe9zXxeRKxaXxi/GpUqYiTrtdiWP8bo1KFya6Wc=
|
||||
github.com/quic-go/quic-go v0.51.0/go.mod h1:MFlGGpcpJqRAfmYi6NC2cptDPSxRWTOGNuP4wqrWmzQ=
|
||||
github.com/quic-go/quic-go v0.52.0 h1:/SlHrCRElyaU6MaEPKqKr9z83sBg2v4FLLvWM+Z47pA=
|
||||
github.com/quic-go/quic-go v0.52.0/go.mod h1:MFlGGpcpJqRAfmYi6NC2cptDPSxRWTOGNuP4wqrWmzQ=
|
||||
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
|
||||
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
|
||||
github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU=
|
||||
@@ -463,8 +464,8 @@ github.com/smallstep/certificates v0.28.3 h1:rcMh1TAs8m2emP3aDJxKLkE9jriAtcFtCuj
|
||||
github.com/smallstep/certificates v0.28.3/go.mod h1:P/IjGTvRCem3YZ7d1XtUxpvK/8dfFsJn7gaVLpMXbJw=
|
||||
github.com/smallstep/cli-utils v0.12.1 h1:D9QvfbFqiKq3snGZ2xDcXEFrdFJ1mQfPHZMq/leerpE=
|
||||
github.com/smallstep/cli-utils v0.12.1/go.mod h1:skV2Neg8qjiKPu2fphM89H9bIxNpKiiRTnX9Q6Lc+20=
|
||||
github.com/smallstep/go-attestation v0.4.4-0.20240109183208-413678f90935 h1:kjYvkvS/Wdy0PVRDUAA0gGJIVSEZYhiAJtfwYgOYoGA=
|
||||
github.com/smallstep/go-attestation v0.4.4-0.20240109183208-413678f90935/go.mod h1:vNAduivU014fubg6ewygkAvQC0IQVXqdc8vaGl/0er4=
|
||||
github.com/smallstep/go-attestation v0.4.4-0.20241119153605-2306d5b464ca h1:VX8L0r8vybH0bPeaIxh4NQzafKQiqvlOn8pmOXbFLO4=
|
||||
github.com/smallstep/go-attestation v0.4.4-0.20241119153605-2306d5b464ca/go.mod h1:vNAduivU014fubg6ewygkAvQC0IQVXqdc8vaGl/0er4=
|
||||
github.com/smallstep/linkedca v0.23.0 h1:5W/7EudlK1HcCIdZM68dJlZ7orqCCCyv6bm2l/0JmLU=
|
||||
github.com/smallstep/linkedca v0.23.0/go.mod h1:7cyRM9soAYySg9ag65QwytcgGOM+4gOlkJ/YA58A9E8=
|
||||
github.com/smallstep/nosql v0.7.0 h1:YiWC9ZAHcrLCrayfaF+QJUv16I2bZ7KdLC3RpJcnAnE=
|
||||
@@ -486,8 +487,8 @@ github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B
|
||||
github.com/spf13/afero v1.14.0 h1:9tH6MapGnn/j0eb0yIXiLjERO8RB6xIVZRDCX7PtqWA=
|
||||
github.com/spf13/afero v1.14.0/go.mod h1:acJQ8t0ohCGuMN3O+Pv0V0hgMxNYDlvdk+VTfyZmbYo=
|
||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cast v1.8.0 h1:gEN9K4b8Xws4EX0+a0reLmhq8moKn7ntRlQYgjPeCDk=
|
||||
github.com/spf13/cast v1.8.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
|
||||
github.com/spf13/cast v1.9.2 h1:SsGfm7M8QOFtEzumm7UZrZdLLquNdzFYfIbEXntcFbE=
|
||||
github.com/spf13/cast v1.9.2/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo=
|
||||
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
|
||||
github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
|
||||
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
|
||||
@@ -546,8 +547,8 @@ github.com/yosida95/uritemplate/v3 v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zI
|
||||
github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT040gmv5BQTMR2HP4=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/yuin/goldmark v1.4.15/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/yuin/goldmark v1.7.11 h1:ZCxLyDMtz0nT2HFfsYG8WZ47Trip2+JyLysKcMYE5bo=
|
||||
github.com/yuin/goldmark v1.7.11/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg=
|
||||
github.com/yuin/goldmark v1.7.12 h1:YwGP/rrea2/CnCtUHgjuolG/PnMxdQtPMO5PvaE2/nY=
|
||||
github.com/yuin/goldmark v1.7.12/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg=
|
||||
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc h1:+IAOyRda+RLrxa1WC7umKOZRsGq4QrFFMYApOeHzQwQ=
|
||||
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc/go.mod h1:ovIvrum6DQJA4QsJSovrkC4saKHQVs7TvcaeO8AIl5I=
|
||||
github.com/zeebo/assert v1.1.0 h1:hU1L1vLTHsnO8x8c9KAR5GmM5QscxHg5RNU5z5qbUWY=
|
||||
@@ -591,8 +592,8 @@ go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt
|
||||
go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc=
|
||||
go.opentelemetry.io/proto/otlp v1.6.0 h1:jQjP+AQyTf+Fe7OKj/MfkDrmK4MNVtw2NpXsf9fefDI=
|
||||
go.opentelemetry.io/proto/otlp v1.6.0/go.mod h1:cicgGehlFuNdgZkcALOCh3VE6K/u2tAjzlRhDwmVpZc=
|
||||
go.step.sm/crypto v0.63.0 h1:U1QGELQqJ85oDfeNFE2V52cow1rvy0m3MekG3wFmyXY=
|
||||
go.step.sm/crypto v0.63.0/go.mod h1:aj3LETmCZeSil1DMq3BlbhDBcN86+mmKrHZtXWyc0L4=
|
||||
go.step.sm/crypto v0.66.0 h1:9TW6BEguOtcS9NIjja9bDQ+j8OjhenU/F6lJfHjbXNU=
|
||||
go.step.sm/crypto v0.66.0/go.mod h1:anqGyvO/Px05D1mznHq4/a9wwP1I1DmMZvk+TWX5Dzo=
|
||||
go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
|
||||
go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
@@ -618,11 +619,11 @@ golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v
|
||||
golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
|
||||
golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8=
|
||||
golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw=
|
||||
golang.org/x/crypto/x509roots/fallback v0.0.0-20250512184618-9dbbcf002b5c h1:i8SXR9IEBPRl+jdkkgjldNlHiUFpO5pUejfO9igtrHs=
|
||||
golang.org/x/crypto/x509roots/fallback v0.0.0-20250512184618-9dbbcf002b5c/go.mod h1:lxN5T34bK4Z/i6cMaU7frUU57VkDXFD4Kamfl/cp9oU=
|
||||
golang.org/x/crypto/x509roots/fallback v0.0.0-20250531095911-4f9f0ca9fcfb h1:Qr7HsIdEUI8QBvEohd2cTYzTErkEkUXafR9qx9D6QEo=
|
||||
golang.org/x/crypto/x509roots/fallback v0.0.0-20250531095911-4f9f0ca9fcfb/go.mod h1:lxN5T34bK4Z/i6cMaU7frUU57VkDXFD4Kamfl/cp9oU=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 h1:y5zboxd6LQAqYIhHnB48p0ByQ/GnQx2BE33L8BOHQkI=
|
||||
golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6/go.mod h1:U6Lno4MTRCDY+Ba7aCcauB9T60gsv5s4ralQzP72ZoQ=
|
||||
golang.org/x/exp v0.0.0-20250531010427-b6e5de432a8b h1:QoALfVG9rhQ/M7vYDScfPdWjGL9dlsVVM5VGh7aKoAA=
|
||||
golang.org/x/exp v0.0.0-20250531010427-b6e5de432a8b/go.mod h1:U6Lno4MTRCDY+Ba7aCcauB9T60gsv5s4ralQzP72ZoQ=
|
||||
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
@@ -738,8 +739,8 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
|
||||
google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||
google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||
google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y=
|
||||
google.golang.org/api v0.230.0 h1:2u1hni3E+UXAXrONrrkfWpi/V6cyKVAbfGVeGtC3OxM=
|
||||
google.golang.org/api v0.230.0/go.mod h1:aqvtoMk7YkiXx+6U12arQFExiRV9D/ekvMCwCd/TksQ=
|
||||
google.golang.org/api v0.234.0 h1:d3sAmYq3E9gdr2mpmiWGbm9pHsA/KJmyiLkwKfHBqU4=
|
||||
google.golang.org/api v0.234.0/go.mod h1:QpeJkemzkFKe5VCE/PMv7GsUfn9ZF+u+q1Q7w6ckxTg=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
@@ -749,18 +750,18 @@ google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoA
|
||||
google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20181202183823-bd91e49a0898/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg=
|
||||
google.golang.org/genproto v0.0.0-20190306203927-b5d61aea6440/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb h1:ITgPrl429bc6+2ZraNSzMDk3I95nmQln2fuPstKwFDE=
|
||||
google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:sAo5UzpjUwgFBCzupwhcLcxHVDK7vG5IqI30YnwX2eE=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250512202823-5a2f75b736a9 h1:WvBuA5rjZx9SNIzgcU53OohgZy6lKSus++uY4xLaWKc=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250512202823-5a2f75b736a9/go.mod h1:W3S/3np0/dPWsWLi1h/UymYctGXaGBM2StwzD0y140U=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250512202823-5a2f75b736a9 h1:IkAfh6J/yllPtpYFU0zZN1hUPYdT0ogkBT/9hMxHjvg=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250512202823-5a2f75b736a9/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
|
||||
google.golang.org/genproto v0.0.0-20250505200425-f936aa4a68b2 h1:1tXaIXCracvtsRxSBsYDiSBN0cuJvM7QYW+MrpIRY78=
|
||||
google.golang.org/genproto v0.0.0-20250505200425-f936aa4a68b2/go.mod h1:49MsLSx0oWMOZqcpB3uL8ZOkAh1+TndpJ8ONoCBWiZk=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250528174236-200df99c418a h1:SGktgSolFCo75dnHJF2yMvnns6jCmHFJ0vE4Vn2JKvQ=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250528174236-200df99c418a/go.mod h1:a77HrdMjoeKbnd2jmgcWdaS++ZLZAEq3orIOAEIKiVw=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a h1:v2PbRU4K3llS09c7zodFpNePeamkAwG3mPrAery9VeE=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
|
||||
google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||
google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio=
|
||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.72.1 h1:HR03wO6eyZ7lknl75XlxABNVLLFc2PAb6mHlYh756mA=
|
||||
google.golang.org/grpc v1.72.1/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM=
|
||||
google.golang.org/grpc v1.72.2 h1:TdbGzwb82ty4OusHWepvFWGLgIbNo1/SUynEN0ssqv8=
|
||||
google.golang.org/grpc v1.72.2/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM=
|
||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1 h1:F29+wU6Ee6qgu9TddPgooOdaqsxTMunOoj8KA5yuS5A=
|
||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1/go.mod h1:5KF+wpkbTSbGcR9zteSqZV6fqFOWBl4Yde8En8MryZA=
|
||||
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"path/filepath"
|
||||
|
||||
caddycmd "github.com/caddyserver/caddy/v2/cmd"
|
||||
"github.com/dunglas/frankenphp"
|
||||
"frankenphp.dev"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
@@ -20,15 +20,14 @@ import (
|
||||
"github.com/caddyserver/caddy/v2/modules/caddyhttp/fileserver"
|
||||
"github.com/caddyserver/caddy/v2/modules/caddyhttp/rewrite"
|
||||
"github.com/caddyserver/certmagic"
|
||||
"github.com/dunglas/frankenphp"
|
||||
|
||||
"frankenphp.dev"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func init() {
|
||||
caddycmd.RegisterCommand(caddycmd.Command{
|
||||
Name: "php-server",
|
||||
Usage: "[--domain <example.com>] [--root <path>] [--listen <addr>] [--worker /path/to/worker.php<,nb-workers>] [--watch <paths...>] [--access-log] [--debug] [--no-compress] [--mercure]",
|
||||
Usage: "[--domain=<example.com>] [--root=<path>] [--listen=<addr>] [--worker=/path/to/worker.php<,nb-workers>] [--watch[=<glob-pattern>]]... [--access-log] [--debug] [--no-compress] [--mercure]",
|
||||
Short: "Spins up a production-ready PHP server",
|
||||
Long: `
|
||||
A simple but production-ready PHP server. Useful for quick deployments,
|
||||
@@ -47,11 +46,14 @@ For more advanced use cases, see https://github.com/dunglas/frankenphp/blob/main
|
||||
cmd.Flags().StringP("root", "r", "", "The path to the root of the site")
|
||||
cmd.Flags().StringP("listen", "l", "", "The address to which to bind the listener")
|
||||
cmd.Flags().StringArrayP("worker", "w", []string{}, "Worker script")
|
||||
cmd.Flags().StringArrayP("watch", "", []string{}, "Directory to watch for file changes")
|
||||
cmd.Flags().StringArray("watch", []string{}, "Glob pattern of directories and files to watch for changes")
|
||||
cmd.Flags().BoolP("access-log", "a", false, "Enable the access log")
|
||||
cmd.Flags().BoolP("debug", "v", false, "Enable verbose debug logs")
|
||||
cmd.Flags().BoolP("mercure", "m", false, "Enable the built-in Mercure.rocks hub")
|
||||
cmd.Flags().BoolP("no-compress", "", false, "Disable Zstandard, Brotli and Gzip compression")
|
||||
cmd.Flags().Bool("no-compress", false, "Disable Zstandard, Brotli and Gzip compression")
|
||||
|
||||
cmd.Flags().Lookup("watch").NoOptDefVal = defaultWatchPattern
|
||||
|
||||
cmd.RunE = caddycmd.WrapCommandFuncForCobra(cmdPHPServer)
|
||||
},
|
||||
})
|
||||
|
||||
2
cgi.go
@@ -18,7 +18,7 @@ import (
|
||||
"strings"
|
||||
"unsafe"
|
||||
|
||||
"github.com/dunglas/frankenphp/internal/phpheaders"
|
||||
"frankenphp.dev/internal/phpheaders"
|
||||
)
|
||||
|
||||
var knownServerKeys = []string{
|
||||
|
||||
@@ -176,7 +176,7 @@ docker buildx bake -f docker-bake.hcl --pull --no-cache --push
|
||||
|
||||
```console
|
||||
go test -tags watcher -c -ldflags=-w
|
||||
gdb --args frankenphp.test -test.run ^MyTest$
|
||||
gdb --args frankenphp.dev.test -test.run ^MyTest$
|
||||
```
|
||||
|
||||
9. 当错误修复后,恢复所有这些更改
|
||||
|
||||
@@ -80,7 +80,7 @@ CGO_ENABLED=1 \
|
||||
XCADDY_GO_BUILD_FLAGS="-ldflags '-w -s'" \
|
||||
xcaddy build \
|
||||
--output frankenphp \
|
||||
--with github.com/dunglas/frankenphp/caddy \
|
||||
--with frankenphp.dev/caddy \
|
||||
--with github.com/dunglas/caddy-cbrotli \
|
||||
--with github.com/dunglas/mercure/caddy \
|
||||
--with github.com/dunglas/vulcain/caddy
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# 配置
|
||||
# 配置
|
||||
|
||||
FrankenPHP,Caddy 以及 Mercure 和 Vulcain 模块可以使用 [Caddy 支持的格式](https://caddyserver.com/docs/getting-started#your-first-config) 进行配置。
|
||||
|
||||
@@ -39,16 +39,11 @@ FrankenPHP 安装 (.rpm 或 .deb):
|
||||
|
||||
## Caddyfile 配置
|
||||
|
||||
要注册 FrankenPHP 执行器,必须设置 `frankenphp` [全局选项](https://caddyserver.com/docs/caddyfile/concepts#global-options),然后可以在站点块中使用 `php_server` 或 `php` [HTTP 指令](https://caddyserver.com/docs/caddyfile/concepts#directives) 来为您的 PHP 应用程序提供服务。
|
||||
可以在站点块中使用 `php_server` 或 `php` [HTTP 指令](https://caddyserver.com/docs/caddyfile/concepts#directives) 来为您的 PHP 应用程序提供服务。
|
||||
|
||||
最小示例:
|
||||
|
||||
```caddyfile
|
||||
{
|
||||
# 启用 FrankenPHP
|
||||
frankenphp
|
||||
}
|
||||
|
||||
localhost {
|
||||
# 启用压缩(可选)
|
||||
encode zstd br gzip
|
||||
@@ -57,7 +52,8 @@ localhost {
|
||||
}
|
||||
```
|
||||
|
||||
或者,可以在全局选项下指定要创建的线程数和要从服务器启动的 [worker 脚本](worker.md)。
|
||||
您也可以使用全局选项显式配置 FrankenPHP:
|
||||
`frankenphp` [全局选项](https://caddyserver.com/docs/caddyfile/concepts#global-options) 可用于配置 FrankenPHP。
|
||||
|
||||
```caddyfile
|
||||
{
|
||||
@@ -89,21 +85,18 @@ localhost {
|
||||
如果在同一服务器上运行多个应用,还可以定义多个 worker:
|
||||
|
||||
```caddyfile
|
||||
{
|
||||
frankenphp {
|
||||
worker /path/to/app/public/index.php <num>
|
||||
worker /path/to/other/public/index.php <num>
|
||||
app.example.com {
|
||||
php_server {
|
||||
root /path/to/app/public
|
||||
worker index.php <num>
|
||||
}
|
||||
}
|
||||
|
||||
app.example.com {
|
||||
root /path/to/app/public
|
||||
php_server
|
||||
}
|
||||
|
||||
other.example.com {
|
||||
root /path/to/other/public
|
||||
php_server
|
||||
php_server {
|
||||
root /path/to/other/public
|
||||
worker index.php <num>
|
||||
}
|
||||
}
|
||||
# ...
|
||||
```
|
||||
@@ -139,9 +132,18 @@ route {
|
||||
```caddyfile
|
||||
php_server [<matcher>] {
|
||||
root <directory> # 设置站点的根目录。默认值:`root` 指令。
|
||||
split_path <delim...> # 设置用于将 URI 拆分为两部分的子字符串。第一个匹配的子字符串将用于从路径中拆分“路径信息”。第一个部分以匹配的子字符串为后缀,并将假定为实际资源(CGI 脚本)名称。第二部分将设置为PATH_INFO,供脚本使用。默认值:`.php`
|
||||
split_path <delim...> # 设置用于将 URI 拆分为两部分的子字符串。第一个匹配的子字符串将用于从路径中拆分"路径信息"。第一个部分以匹配的子字符串为后缀,并将假定为实际资源(CGI 脚本)名称。第二部分将设置为PATH_INFO,供脚本使用。默认值:`.php`
|
||||
resolve_root_symlink false # 禁用将 `root` 目录在符号链接时将其解析为实际值(默认启用)。
|
||||
env <key> <value> # 设置额外的环境变量,可以设置多个环境变量。
|
||||
file_server off # 禁用内置的 file_server 指令。
|
||||
worker { # 创建特定于此服务器的 worker。可以为多个 worker 多次指定。
|
||||
file <path> # 设置 worker 脚本的路径,可以相对于 php_server 根目录
|
||||
num <num> # 设置要启动的 PHP 线程数,默认为可用 CPU 数的 2 倍
|
||||
name <name> # 为 worker 设置名称,用于日志和指标。默认值:worker 文件的绝对路径。在 php_server 块中定义时始终以 m# 开头。
|
||||
watch <path> # 设置要监视文件更改的路径。可以为多个路径多次指定。
|
||||
env <key> <value> # 将额外的环境变量设置为给定值。可以为多个环境变量多次指定。此 worker 的环境变量也从 php_server 父级继承,但可以在此处覆盖。
|
||||
}
|
||||
worker <other_file> <num> # 也可以像在全局 frankenphp 块中一样使用简短形式。
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -57,8 +57,8 @@ RUN CGO_ENABLED=1 \
|
||||
CGO_LDFLAGS="$(php-config --ldflags) $(php-config --libs)" \
|
||||
xcaddy build \
|
||||
--output /usr/local/bin/frankenphp \
|
||||
--with github.com/dunglas/frankenphp=./ \
|
||||
--with github.com/dunglas/frankenphp/caddy=./caddy/ \
|
||||
--with frankenphp.dev=./ \
|
||||
--with frankenphp.dev/caddy=./caddy/ \
|
||||
--with github.com/dunglas/caddy-cbrotli \
|
||||
# Mercure 和 Vulcain 包含在官方版本中,如果不需要你可以删除它们
|
||||
--with github.com/dunglas/mercure/caddy \
|
||||
|
||||
@@ -3,13 +3,30 @@
|
||||
This document explains how to create a FrankenPHP binary that will load PHP as a dynamic library.
|
||||
This is the recommended method.
|
||||
|
||||
Alternatively, [static builds](static.md) can also be created.
|
||||
Alternatively, [fully and mostly static builds](static.md) can also be created.
|
||||
|
||||
## Install PHP
|
||||
|
||||
FrankenPHP is compatible with PHP 8.2 and superior.
|
||||
|
||||
First, [get the PHP sources](https://www.php.net/downloads.php) and extract them:
|
||||
### With Homebrew (Linux and Mac)
|
||||
|
||||
The easiest way to install a version of libphp compatible with FrankenPHP is to use the ZTS packages provided by [Homebrew PHP](https://github.com/shivammathur/homebrew-php).
|
||||
|
||||
First, if not already done, install [Homebrew](https://brew.sh).
|
||||
|
||||
Then, install the ZTS variant of PHP, Brotli (optional, for compression support) and watcher (optional, for file change detection):
|
||||
|
||||
```console
|
||||
brew install shivammathur/php/php-zts brotli watcher
|
||||
brew link --overwrite --force shivammathur/php/php-zts
|
||||
```
|
||||
|
||||
### By Compiling PHP
|
||||
|
||||
Alternatively, you can compile PHP from sources with the options needed by FrankenPHP by following these steps.
|
||||
~~
|
||||
~~First, [get the PHP sources](https://www.php.net/downloads.php) and extract them:
|
||||
|
||||
```console
|
||||
tar xf php-*
|
||||
@@ -19,7 +36,7 @@ cd php-*/
|
||||
Then, run the `configure` script with the options needed for your platform.
|
||||
The following `./configure` flags are mandatory, but you can add others, for example, to compile extensions or additional features.
|
||||
|
||||
### Linux
|
||||
#### Linux
|
||||
|
||||
```console
|
||||
./configure \
|
||||
@@ -29,13 +46,12 @@ The following `./configure` flags are mandatory, but you can add others, for exa
|
||||
--enable-zend-max-execution-timers
|
||||
```
|
||||
|
||||
### Mac
|
||||
#### Mac
|
||||
|
||||
Use the [Homebrew](https://brew.sh/) package manager to install
|
||||
`libiconv`, `bison`, `re2c` and `pkg-config`:
|
||||
Use the [Homebrew](https://brew.sh/) package manager to install the required and optional dependencies:
|
||||
|
||||
```console
|
||||
brew install libiconv bison brotli re2c pkg-config
|
||||
brew install libiconv bison brotli re2c pkg-config watcher
|
||||
echo 'export PATH="/opt/homebrew/opt/bison/bin:$PATH"' >> ~/.zshrc
|
||||
```
|
||||
|
||||
@@ -43,16 +59,13 @@ Then run the configure script:
|
||||
|
||||
```console
|
||||
./configure \
|
||||
--enable-embed=static \
|
||||
--enable-embed \
|
||||
--enable-zts \
|
||||
--disable-zend-signals \
|
||||
--disable-opcache-jit \
|
||||
--enable-static \
|
||||
--enable-shared=no \
|
||||
--with-iconv=/opt/homebrew/opt/libiconv/
|
||||
```
|
||||
|
||||
## Compile PHP
|
||||
#### Compile PHP
|
||||
|
||||
Finally, compile and install PHP:
|
||||
|
||||
@@ -67,23 +80,18 @@ Some FrankenPHP features depend on optional system dependencies that must be ins
|
||||
Alternatively, these features can be disabled by passing build tags to the Go compiler.
|
||||
|
||||
| Feature | Dependency | Build tag to disable it |
|
||||
| ------------------------------ | --------------------------------------------------------------------- | ----------------------- |
|
||||
|--------------------------------|-----------------------------------------------------------------------|-------------------------|
|
||||
| Brotli compression | [Brotli](https://github.com/google/brotli) | nobrotli |
|
||||
| Restart workers on file change | [Watcher C](https://github.com/e-dant/watcher/tree/release/watcher-c) | nowatcher |
|
||||
|
||||
## Compile the Go App
|
||||
|
||||
You can now build the final binary:
|
||||
|
||||
```console
|
||||
curl -L https://github.com/dunglas/frankenphp/archive/refs/heads/main.tar.gz | tar xz
|
||||
cd frankenphp-main/caddy/frankenphp
|
||||
CGO_CFLAGS=$(php-config --includes) CGO_LDFLAGS="$(php-config --ldflags) $(php-config --libs)" go build -tags=nobadger,nomysql,nopgx
|
||||
```
|
||||
You can now build the final binary.
|
||||
|
||||
### Using xcaddy
|
||||
|
||||
Alternatively, use [xcaddy](https://github.com/caddyserver/xcaddy) to compile FrankenPHP with [custom Caddy modules](https://caddyserver.com/docs/modules/):
|
||||
The recommended way is to use [xcaddy](https://github.com/caddyserver/xcaddy) to compile FrankenPHP.
|
||||
`xcaddy` also allows to easily add [custom Caddy modules](https://caddyserver.com/docs/modules/) and FrankenPHP extensions:
|
||||
|
||||
```console
|
||||
CGO_ENABLED=1 \
|
||||
@@ -92,10 +100,10 @@ CGO_CFLAGS=$(php-config --includes) \
|
||||
CGO_LDFLAGS="$(php-config --ldflags) $(php-config --libs)" \
|
||||
xcaddy build \
|
||||
--output frankenphp \
|
||||
--with github.com/dunglas/frankenphp/caddy \
|
||||
--with frankenphp.dev/caddy \
|
||||
--with github.com/dunglas/mercure/caddy \
|
||||
--with github.com/dunglas/vulcain/caddy
|
||||
# Add extra Caddy modules here
|
||||
# Add extra Caddy modules and FrankenPHP extensions here
|
||||
```
|
||||
|
||||
> [!TIP]
|
||||
@@ -107,3 +115,13 @@ xcaddy build \
|
||||
> To do so, change the `XCADDY_GO_BUILD_FLAGS` environment variable to something like
|
||||
> `XCADDY_GO_BUILD_FLAGS=$'-ldflags "-w -s -extldflags \'-Wl,-z,stack-size=0x80000\'"'`
|
||||
> (change the stack size value according to your app needs).
|
||||
|
||||
### Without xcaddy
|
||||
|
||||
Alternatively, it's possible to compile FrankenPHP without `xcaddy` by using the `go` command directly:
|
||||
|
||||
```console
|
||||
curl -L https://github.com/dunglas/frankenphp/archive/refs/heads/main.tar.gz | tar xz
|
||||
cd frankenphp-main/caddy/frankenphp
|
||||
CGO_CFLAGS=$(php-config --includes) CGO_LDFLAGS="$(php-config --ldflags) $(php-config --libs)" go build -tags=nobadger,nomysql,nopgx
|
||||
```
|
||||
|
||||
@@ -42,16 +42,11 @@ RUN cp $PHP_INI_DIR/php.ini-development $PHP_INI_DIR/php.ini
|
||||
|
||||
## Caddyfile Config
|
||||
|
||||
To register the FrankenPHP executor, the `frankenphp` [global option](https://caddyserver.com/docs/caddyfile/concepts#global-options) must be set, then the `php_server` or the `php` [HTTP directives](https://caddyserver.com/docs/caddyfile/concepts#directives) may be used within the site blocks to serve your PHP app.
|
||||
The `php_server` or the `php` [HTTP directives](https://caddyserver.com/docs/caddyfile/concepts#directives) may be used within the site blocks to serve your PHP app.
|
||||
|
||||
Minimal example:
|
||||
|
||||
```caddyfile
|
||||
{
|
||||
# Enable FrankenPHP
|
||||
frankenphp
|
||||
}
|
||||
|
||||
localhost {
|
||||
# Enable compression (optional)
|
||||
encode zstd br gzip
|
||||
@@ -60,7 +55,8 @@ localhost {
|
||||
}
|
||||
```
|
||||
|
||||
Optionally, the number of threads to create and [worker scripts](worker.md) to start with the server can be specified under the global option.
|
||||
You can also explicitly configure FrankenPHP using the global option:
|
||||
The `frankenphp` [global option](https://caddyserver.com/docs/caddyfile/concepts#global-options) can be used to configure FrankenPHP.
|
||||
|
||||
```caddyfile
|
||||
{
|
||||
@@ -97,21 +93,18 @@ Alternatively, you may use the one-line short form of the `worker` option:
|
||||
You can also define multiple workers if you serve multiple apps on the same server:
|
||||
|
||||
```caddyfile
|
||||
{
|
||||
frankenphp {
|
||||
worker /path/to/app/public/index.php <num>
|
||||
worker /path/to/other/public/index.php <num>
|
||||
app.example.com {
|
||||
php_server {
|
||||
root /path/to/app/public
|
||||
worker index.php <num>
|
||||
}
|
||||
}
|
||||
|
||||
app.example.com {
|
||||
root /path/to/app/public
|
||||
php_server
|
||||
}
|
||||
|
||||
other.example.com {
|
||||
root /path/to/other/public
|
||||
php_server
|
||||
php_server {
|
||||
root /path/to/other/public
|
||||
worker index.php <num>
|
||||
}
|
||||
}
|
||||
|
||||
# ...
|
||||
@@ -154,6 +147,14 @@ php_server [<matcher>] {
|
||||
resolve_root_symlink false # Disables resolving the `root` directory to its actual value by evaluating a symbolic link, if one exists (enabled by default).
|
||||
env <key> <value> # Sets an extra environment variable to the given value. Can be specified more than once for multiple environment variables.
|
||||
file_server off # Disables the built-in file_server directive.
|
||||
worker { # Creates a worker specific to this server. Can be specified more than once for multiple workers.
|
||||
file <path> # Sets the path to the worker script, can be relative to the php_server root
|
||||
num <num> # Sets the number of PHP threads to start, defaults to 2x the number of available
|
||||
name <name> # Sets the name for the worker, used in logs and metrics. Default: absolute path of worker file. Always starts with m# when defined in a php_server block.
|
||||
watch <path> # Sets the path to watch for file changes. Can be specified more than once for multiple paths.
|
||||
env <key> <value> # Sets an extra environment variable to the given value. Can be specified more than once for multiple environment variables. Environment variables for this worker are also inherited from the php_server parent, but can be overwritten here.
|
||||
}
|
||||
worker <other_file> <num> # Can also use the short form like in the global frankenphp block.
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 126 KiB After Width: | Height: | Size: 73 KiB |
|
Before Width: | Height: | Size: 159 KiB After Width: | Height: | Size: 87 KiB |
@@ -65,8 +65,8 @@ RUN CGO_ENABLED=1 \
|
||||
CGO_LDFLAGS="$(php-config --ldflags) $(php-config --libs)" \
|
||||
xcaddy build \
|
||||
--output /usr/local/bin/frankenphp \
|
||||
--with github.com/dunglas/frankenphp=./ \
|
||||
--with github.com/dunglas/frankenphp/caddy=./caddy/ \
|
||||
--with frankenphp.dev=./ \
|
||||
--with frankenphp.dev/caddy=./caddy/ \
|
||||
--with github.com/dunglas/caddy-cbrotli \
|
||||
# Mercure and Vulcain are included in the official build, but feel free to remove them
|
||||
--with github.com/dunglas/mercure/caddy \
|
||||
|
||||
@@ -177,7 +177,7 @@ docker buildx bake -f docker-bake.hcl --pull --no-cache --push
|
||||
|
||||
```console
|
||||
go test -tags watcher -c -ldflags=-w
|
||||
gdb --args frankenphp.test -test.run ^MyTest$
|
||||
gdb --args frankenphp.dev.test -test.run ^MyTest$
|
||||
```
|
||||
|
||||
9. Quand le bug est corrigé, annulez tous les changements.
|
||||
|
||||
@@ -42,12 +42,6 @@ Vous pouvez également exécuter des scripts en ligne de commande avec :
|
||||
frankenphp php-cli /path/to/your/script.php
|
||||
```
|
||||
|
||||
> [!WARNING]
|
||||
>
|
||||
> En production, préférez utiliser [les images Docker](#docker), [le paquet Brew](#homebrew)
|
||||
> ou [compiler FrankenPHP à partir des sources](https://frankenphp.dev/docs/fr/compile/).
|
||||
> Le binaire autonome est fourni à des fins de développement et de test.
|
||||
|
||||
### Docker
|
||||
|
||||
Des [images Docker](https://frankenphp.dev/docs/fr/docker/) sont également disponibles :
|
||||
|
||||
@@ -9,6 +9,23 @@ Alternativement, il est aussi possible de [créer des builds statiques](static.m
|
||||
|
||||
FrankenPHP est compatible avec PHP 8.2 et versions ultérieures.
|
||||
|
||||
### Avec Homebrew (Linux et Mac)
|
||||
|
||||
La manière la plus simple d'installer une version de libphp compatible avec FrankenPHP est d'utiliser les paquets ZTS fournis par [Homebrew PHP](https://github.com/shivammathur/homebrew-php).
|
||||
|
||||
Tout d'abord, si ce n'est déjà fait, installez [Homebrew](https://brew.sh).
|
||||
|
||||
Ensuite, installez la variante ZTS de PHP, Brotli (facultatif, pour la prise en charge de la compression) et watcher (facultatif, pour la détection des modifications de fichiers) :
|
||||
|
||||
```console
|
||||
brew install shivammathur/php/php-zts brotli watcher
|
||||
brew link --overwrite --force shivammathur/php/php-zts
|
||||
```
|
||||
|
||||
### En compilant PHP
|
||||
|
||||
Vous pouvez également compiler PHP à partir des sources avec les options requises par FrankenPHP en suivant ces étapes.
|
||||
|
||||
Tout d'abord, [téléchargez les sources de PHP](https://www.php.net/downloads.php) et extrayez-les :
|
||||
|
||||
```console
|
||||
@@ -32,10 +49,10 @@ Les options de configuration suivantes sont nécessaires pour la compilation, ma
|
||||
|
||||
### Mac
|
||||
|
||||
Utilisez le gestionnaire de paquets [Homebrew](https://brew.sh/) pour installer `libiconv`, `bison`, `re2c` et `pkg-config` :
|
||||
Utilisez le gestionnaire de paquets [Homebrew](https://brew.sh/) pour installer les dépendances obligatoires et optionnelles :
|
||||
|
||||
```console
|
||||
brew install libiconv bison brotli re2c pkg-config
|
||||
brew install libiconv bison brotli re2c pkg-config watcher
|
||||
echo 'export PATH="/opt/homebrew/opt/bison/bin:$PATH"' >> ~/.zshrc
|
||||
```
|
||||
|
||||
@@ -43,16 +60,14 @@ Puis exécutez le script de configuration :
|
||||
|
||||
```console
|
||||
./configure \
|
||||
--enable-embed=static \
|
||||
--enable-embed \
|
||||
--enable-zts \
|
||||
--disable-zend-signals \
|
||||
--disable-opcache-jit \
|
||||
--enable-static \
|
||||
--enable-shared=no \
|
||||
--with-iconv=/opt/homebrew/opt/libiconv/
|
||||
```
|
||||
|
||||
## Compilez PHP
|
||||
### Compilez PHP
|
||||
|
||||
Finalement, compilez et installez PHP :
|
||||
|
||||
@@ -64,26 +79,19 @@ sudo make install
|
||||
## Installez les dépendances optionnelles
|
||||
|
||||
Certaines fonctionnalités de FrankenPHP nécessitent des dépendances optionnelles qui doivent être installées.
|
||||
Ces fonctionnalités peuvent également être désactivées en passant des balises de compilation au compilateur Go.
|
||||
Ces fonctionnalités peuvent également être désactivées en passant des tags de compilation au compilateur Go.
|
||||
|
||||
| Fonctionnalité | Dépendance | Balise de compilation pour la désactiver |
|
||||
| ------------------------------------------------------- | --------------------------------------------------------------------- | ---------------------------------------- |
|
||||
| Compression Brotli | [Brotli](https://github.com/google/brotli) | nobrotli |
|
||||
| Redémarrage des workers en cas de changement de fichier | [Watcher C](https://github.com/e-dant/watcher/tree/release/watcher-c) | nowatcher |
|
||||
| Fonctionnalité | Dépendance | Tag de compilation pour la désactiver |
|
||||
|---------------------------------------------------------|-----------------------------------------------------------------------|---------------------------------------|
|
||||
| Compression Brotli | [Brotli](https://github.com/google/brotli) | nobrotli |
|
||||
| Redémarrage des workers en cas de changement de fichier | [Watcher C](https://github.com/e-dant/watcher/tree/release/watcher-c) | nowatcher |
|
||||
|
||||
## Compiler l'application Go
|
||||
|
||||
Vous pouvez maintenant compiler FrankenPHP :
|
||||
|
||||
```console
|
||||
curl -L https://github.com/dunglas/frankenphp/archive/refs/heads/main.tar.gz | tar xz
|
||||
cd frankenphp-main/caddy/frankenphp
|
||||
CGO_CFLAGS=$(php-config --includes) CGO_LDFLAGS="$(php-config --ldflags) $(php-config --libs)" go build -tags=nobadger,nomysql,nopgx
|
||||
```
|
||||
|
||||
### Utiliser xcaddy
|
||||
|
||||
Alternativement, vous pouvez utiliser [xcaddy](https://github.com/caddyserver/xcaddy) pour compiler FrankenPHP avec [des modules Caddy additionnels](https://caddyserver.com/docs/modules/) :
|
||||
La méthode recommandée consiste à utiliser [xcaddy](https://github.com/caddyserver/xcaddy) pour compiler FrankenPHP.
|
||||
`xcaddy` permet également d'ajouter facilement des [modules Caddy personnalisés](https://caddyserver.com/docs/modules/) et des extensions FrankenPHP :
|
||||
|
||||
```console
|
||||
CGO_ENABLED=1 \
|
||||
@@ -92,11 +100,11 @@ CGO_CFLAGS=$(php-config --includes) \
|
||||
CGO_LDFLAGS="$(php-config --ldflags) $(php-config --libs)" \
|
||||
xcaddy build \
|
||||
--output frankenphp \
|
||||
--with github.com/dunglas/frankenphp/caddy \
|
||||
--with frankenphp.dev/caddy \
|
||||
--with github.com/dunglas/caddy-cbrotli \
|
||||
--with github.com/dunglas/mercure/caddy \
|
||||
--with github.com/dunglas/vulcain/caddy
|
||||
# Add extra Caddy modules here
|
||||
# Ajoutez les modules Caddy supplémentaires et les extensions FrankenPHP ici
|
||||
```
|
||||
|
||||
> [!TIP]
|
||||
@@ -108,3 +116,13 @@ xcaddy build \
|
||||
> Pour ce faire, modifiez la variable d'environnement `XCADDY_GO_BUILD_FLAGS` en quelque chose comme
|
||||
> `XCADDY_GO_BUILD_FLAGS=$'-ldflags "-w -s -extldflags \'-Wl,-z,stack-size=0x80000\'"'`
|
||||
> (modifiez la valeur de la taille de la pile selon les besoins de votre application).
|
||||
|
||||
### Sans xcaddy
|
||||
|
||||
Il est également possible de compiler FrankenPHP sans `xcaddy` en utilisant directement la commande `go` :
|
||||
|
||||
```console
|
||||
curl -L https://github.com/dunglas/frankenphp/archive/refs/heads/main.tar.gz | tar xz
|
||||
cd frankenphp-main/caddy/frankenphp
|
||||
CGO_CFLAGS=$(php-config --includes) CGO_LDFLAGS="$(php-config --ldflags) $(php-config --libs)" go build -tags=nobadger,nomysql,nopgx
|
||||
```
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Configuration
|
||||
# Configuration
|
||||
|
||||
FrankenPHP, Caddy ainsi que les modules Mercure et Vulcain peuvent être configurés en utilisant [les formats pris en charge par Caddy](https://caddyserver.com/docs/getting-started#your-first-config).
|
||||
|
||||
@@ -41,16 +41,11 @@ Binaire statique :
|
||||
|
||||
## Configuration du Caddyfile
|
||||
|
||||
Pour enregistrer l'exécutable de FrankenPHP, l'[option globale](https://caddyserver.com/docs/caddyfile/concepts#global-options) `frankenphp` doit être définie, puis les [directives HTTP](https://caddyserver.com/docs/caddyfile/concepts#directives) `php_server` ou `php` peuvent être utilisées dans les blocs de site pour servir votre application PHP.
|
||||
Les [directives HTTP](https://caddyserver.com/docs/caddyfile/concepts#directives) `php_server` ou `php` peuvent être utilisées dans les blocs de site pour servir votre application PHP.
|
||||
|
||||
Exemple minimal :
|
||||
|
||||
```caddyfile
|
||||
{
|
||||
# Activer FrankenPHP
|
||||
frankenphp
|
||||
}
|
||||
|
||||
localhost {
|
||||
# Activer la compression (optionnel)
|
||||
encode zstd br gzip
|
||||
@@ -59,14 +54,15 @@ localhost {
|
||||
}
|
||||
```
|
||||
|
||||
En option, le nombre de threads à créer et les [workers](worker.md) à démarrer avec le serveur peuvent être spécifiés sous l'option globale.
|
||||
Vous pouvez également configurer explicitement FrankenPHP en utilisant l'option globale :
|
||||
L'[option globale](https://caddyserver.com/docs/caddyfile/concepts#global-options) `frankenphp` peut être utilisée pour configurer FrankenPHP.
|
||||
|
||||
```caddyfile
|
||||
{
|
||||
frankenphp {
|
||||
num_threads <num_threads> # Définit le nombre de threads PHP à démarrer. Par défaut : 2x le nombre de CPUs disponibles.
|
||||
max_threads <num_threads> # Limite le nombre de threads PHP supplémentaires qui peuvent être démarrés au moment de l'exécution. Valeur par défaut : num_threads. Peut être mis à 'auto'.
|
||||
max_wait_time <duration> # Définit le temps maximum pendant lequel une requête peut attendre un thread PHP libre avant d'être interrompue. Valeur par défaut : désactivé.
|
||||
max_wait_time <duration> # Définit le temps maximum pendant lequel une requête peut attendre un thread PHP libre avant d'être interrompue. Valeur par défaut : désactivé.
|
||||
php_ini <key> <value> Définit une directive php.ini. Peut être utilisé plusieurs fois pour définir plusieurs directives.
|
||||
worker {
|
||||
file <path> # Définit le chemin vers le script worker.
|
||||
@@ -96,21 +92,18 @@ Vous pouvez également utiliser la forme courte de l'option worker en une seule
|
||||
Vous pouvez aussi définir plusieurs workers si vous servez plusieurs applications sur le même serveur :
|
||||
|
||||
```caddyfile
|
||||
{
|
||||
frankenphp {
|
||||
worker /path/to/app/public/index.php <num>
|
||||
worker /path/to/other/public/index.php <num>
|
||||
app.example.com {
|
||||
php_server {
|
||||
root /path/to/app/public
|
||||
worker index.php <num>
|
||||
}
|
||||
}
|
||||
|
||||
app.example.com {
|
||||
root /path/to/app/public
|
||||
php_server
|
||||
}
|
||||
|
||||
other.example.com {
|
||||
root /path/to/other/public
|
||||
php_server
|
||||
php_server {
|
||||
root /path/to/other/public
|
||||
worker index.php <num>
|
||||
}
|
||||
}
|
||||
|
||||
# ...
|
||||
@@ -153,6 +146,14 @@ php_server [<matcher>] {
|
||||
resolve_root_symlink false # Désactive la résolution du répertoire `root` vers sa valeur réelle en évaluant un lien symbolique, s'il existe (activé par défaut).
|
||||
env <key> <value> # Définit une variable d'environnement supplémentaire avec la valeur donnée. Peut être spécifié plusieurs fois pour plusieurs variables d'environnement.
|
||||
file_server off # Désactive la directive file_server intégrée.
|
||||
worker { # Crée un worker spécifique à ce serveur. Peut être spécifié plusieurs fois pour plusieurs workers.
|
||||
file <path> # Définit le chemin vers le script worker, peut être relatif à la racine du php_server
|
||||
num <num> # Définit le nombre de threads PHP à démarrer, par défaut 2x le nombre de CPUs disponibles
|
||||
name <name> # Définit le nom du worker, utilisé dans les journaux et les métriques. Défaut : chemin absolu du fichier du worker. Commence toujours par m# lorsqu'il est défini dans un bloc php_server.
|
||||
watch <path> # Définit le chemin d'accès à surveiller pour les modifications de fichiers. Peut être spécifié plusieurs fois pour plusieurs chemins.
|
||||
env <key> <value> # Définit une variable d'environnement supplémentaire avec la valeur donnée. Peut être spécifié plusieurs fois pour plusieurs variables d'environnement. Les variables d'environnement pour ce worker sont également héritées du parent php_server, mais peuvent être écrasées ici.
|
||||
}
|
||||
worker <other_file> <num> # Peut également utiliser la forme courte comme dans le bloc frankenphp global.
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -65,8 +65,8 @@ RUN CGO_ENABLED=1 \
|
||||
CGO_LDFLAGS="$(php-config --ldflags) $(php-config --libs)" \
|
||||
xcaddy build \
|
||||
--output /usr/local/bin/frankenphp \
|
||||
--with github.com/dunglas/frankenphp=./ \
|
||||
--with github.com/dunglas/frankenphp/caddy=./caddy/ \
|
||||
--with frankenphp.dev=./ \
|
||||
--with frankenphp.dev/caddy=./caddy/ \
|
||||
--with github.com/dunglas/caddy-cbrotli \
|
||||
# Mercure et Vulcain sont inclus dans la construction officielle, mais n'hésitez pas à les retirer
|
||||
--with github.com/dunglas/mercure/caddy \
|
||||
|
||||
@@ -74,7 +74,7 @@ La commande `octane:frankenphp` peut prendre les options suivantes :
|
||||
- `--log-level` : Enregistrer les messages au niveau de journalisation spécifié ou au-dessus, en utilisant le logger natif de Caddy
|
||||
|
||||
> [!TIP]
|
||||
> Pour obtenir des logs structurés en JSON logs (utile quand vous utilisez des solutions d'analyse de logs), passez explicitement l'otpion `--log-level`.
|
||||
> Pour obtenir des logs structurés en JSON logs (utile quand vous utilisez des solutions d'analyse de logs), passez explicitement l'option `--log-level`.
|
||||
|
||||
En savoir plus sur Laravel Octane [dans sa documentation officielle](https://laravel.com/docs/octane).
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ Il est également possible de [redémarrer le worker en cas de changement de fic
|
||||
La commande suivante déclenchera un redémarrage si un fichier se terminant par `.php` dans le répertoire `/path/to/your/app/` ou ses sous-répertoires est modifié :
|
||||
|
||||
```console
|
||||
frankenphp php-server --worker /path/to/your/worker/script.php --watch "/path/to/your/app/**/*.php"
|
||||
frankenphp php-server --worker /path/to/your/worker/script.php --watch="/path/to/your/app/**/*.php"
|
||||
```
|
||||
|
||||
## Runtime Symfony
|
||||
|
||||
|
Before Width: | Height: | Size: 1.5 MiB After Width: | Height: | Size: 1009 KiB |
@@ -1,12 +1,15 @@
|
||||
# Real-time
|
||||
|
||||
FrankenPHP comes with a built-in [Mercure](https://mercure.rocks) hub!
|
||||
Mercure allows to push events in real-time to all the connected devices: they will receive a JavaScript event instantly.
|
||||
Mercure allows you to push real-time events to all the connected devices: they will receive a JavaScript event instantly.
|
||||
|
||||
No JS library or SDK required!
|
||||
No JS library or SDK is required!
|
||||
|
||||

|
||||
|
||||
To enable the Mercure hub, update the `Caddyfile` as described [on Mercure's site](https://mercure.rocks/docs/hub/config).
|
||||
|
||||
To push Mercure updates from your code, we recommend the [Symfony Mercure Component](https://symfony.com/components/Mercure) (you don't need the Symfony full stack framework to use it).
|
||||
The path of the Mercure hub is `/.well-known/mercure`.
|
||||
When running FrankenPHP inside Docker, the full send URL would look like `http://php/.well-known/mercure` (with `php` being the container's name running FrankenPHP).
|
||||
|
||||
To push Mercure updates from your code, we recommend the [Symfony Mercure Component](https://symfony.com/components/Mercure) (you don't need the Symfony full-stack framework to use it).
|
||||
|
||||
@@ -176,7 +176,7 @@ docker buildx bake -f docker-bake.hcl --pull --no-cache --push
|
||||
|
||||
```console
|
||||
go test -tags watcher -c -ldflags=-w
|
||||
gdb --args frankenphp.test -test.run ^MyTest$
|
||||
gdb --args frankenphp.dev.test -test.run ^MyTest$
|
||||
```
|
||||
|
||||
9. После исправления ошибки откатите все внесенные изменения.
|
||||
|
||||
@@ -92,7 +92,7 @@ CGO_CFLAGS=$(php-config --includes) \
|
||||
CGO_LDFLAGS="$(php-config --ldflags) $(php-config --libs)" \
|
||||
xcaddy build \
|
||||
--output frankenphp \
|
||||
--with github.com/dunglas/frankenphp/caddy \
|
||||
--with frankenphp.dev/caddy \
|
||||
--with github.com/dunglas/mercure/caddy \
|
||||
--with github.com/dunglas/vulcain/caddy
|
||||
# Добавьте дополнительные модули Caddy здесь
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Конфигурация
|
||||
# Конфигурация
|
||||
|
||||
FrankenPHP, Caddy, а также модули Mercure и Vulcain могут быть настроены с использованием [конфигурационных форматов, поддерживаемых Caddy](https://caddyserver.com/docs/getting-started#your-first-config).
|
||||
|
||||
@@ -41,16 +41,11 @@ RUN cp $PHP_INI_DIR/php.ini-development $PHP_INI_DIR/php.ini
|
||||
|
||||
## Конфигурация Caddyfile
|
||||
|
||||
Для настройки FrankenPHP установите [глобальную опцию](https://caddyserver.com/docs/caddyfile/concepts#global-options) frankenphp. После этого можно использовать [HTTP-директивы](https://caddyserver.com/docs/caddyfile/concepts#directives) `php_server` или `php` для обработки вашего PHP-приложения.
|
||||
[HTTP-директивы](https://caddyserver.com/docs/caddyfile/concepts#directives) `php_server` или `php` могут быть использованы в блоках сайта для обработки вашего PHP-приложения.
|
||||
|
||||
Минимальный пример:
|
||||
|
||||
```caddyfile
|
||||
{
|
||||
# Включить FrankenPHP
|
||||
frankenphp
|
||||
}
|
||||
|
||||
localhost {
|
||||
# Включить сжатие (опционально)
|
||||
encode zstd br gzip
|
||||
@@ -59,7 +54,8 @@ localhost {
|
||||
}
|
||||
```
|
||||
|
||||
Опционально можно указать количество потоков и [worker-скриптов](worker.md), которые запускаются вместе с сервером:
|
||||
Вы также можете явно настроить FrankenPHP с помощью глобальной опции:
|
||||
[Глобальная опция](https://caddyserver.com/docs/caddyfile/concepts#global-options) `frankenphp` может быть использована для настройки FrankenPHP.
|
||||
|
||||
```caddyfile
|
||||
{
|
||||
@@ -92,21 +88,18 @@ localhost {
|
||||
Вы также можете определить несколько workers, если обслуживаете несколько приложений на одном сервере:
|
||||
|
||||
```caddyfile
|
||||
{
|
||||
frankenphp {
|
||||
worker /path/to/app/public/index.php <num>
|
||||
worker /path/to/other/public/index.php <num>
|
||||
app.example.com {
|
||||
php_server {
|
||||
root /path/to/app/public
|
||||
worker index.php <num>
|
||||
}
|
||||
}
|
||||
|
||||
app.example.com {
|
||||
root /path/to/app/public
|
||||
php_server
|
||||
}
|
||||
|
||||
other.example.com {
|
||||
root /path/to/other/public
|
||||
php_server
|
||||
php_server {
|
||||
root /path/to/other/public
|
||||
worker index.php <num>
|
||||
}
|
||||
}
|
||||
|
||||
# ...
|
||||
@@ -146,6 +139,14 @@ php_server [<matcher>] {
|
||||
resolve_root_symlink false # Отключает разрешение символьных ссылок для `root` (включено по умолчанию).
|
||||
env <key> <value> # Устанавливает дополнительные переменные окружения. Можно указать несколько раз для разных переменных.
|
||||
file_server off # Отключает встроенную директиву file_server.
|
||||
worker { # Создает worker, специфичный для этого сервера. Можно указать несколько раз для разных workers.
|
||||
file <path> # Указывает путь к worker-скрипту, может быть относительным к корню php_server
|
||||
num <num> # Указывает количество потоков PHP. По умолчанию: 2x от числа доступных CPU.
|
||||
name <name> # Устанавливает имя для worker, используемое в логах и метриках. По умолчанию: абсолютный путь к файлу worker. Всегда начинается с m# при определении в блоке php_server.
|
||||
watch <path> # Указывает путь для отслеживания изменений файлов. Можно указать несколько раз для разных путей.
|
||||
env <key> <value> # Устанавливает дополнительную переменную окружения. Можно указать несколько раз для разных переменных. Переменные окружения для этого worker также наследуются от родительского php_server, но могут быть переопределены здесь.
|
||||
}
|
||||
worker <other_file> <num> # Также можно использовать краткую форму как в глобальном блоке frankenphp.
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -64,8 +64,8 @@ RUN CGO_ENABLED=1 \
|
||||
CGO_LDFLAGS="$(php-config --ldflags) $(php-config --libs)" \
|
||||
xcaddy build \
|
||||
--output /usr/local/bin/frankenphp \
|
||||
--with github.com/dunglas/frankenphp=./ \
|
||||
--with github.com/dunglas/frankenphp/caddy=./caddy/ \
|
||||
--with frankenphp.dev=./ \
|
||||
--with frankenphp.dev/caddy=./caddy/ \
|
||||
--with github.com/dunglas/caddy-cbrotli \
|
||||
# Mercure и Vulcain включены в официальный билд, но вы можете их удалить
|
||||
--with github.com/dunglas/mercure/caddy \
|
||||
|
||||
@@ -32,7 +32,7 @@ frankenphp php-server --worker /path/to/your/worker/script.php
|
||||
Следующая команда выполнит перезапуск, если будет изменён любой файл с расширением `.php` в директории `/path/to/your/app/` или её поддиректориях:
|
||||
|
||||
```console
|
||||
frankenphp php-server --worker /path/to/your/worker/script.php --watch "/path/to/your/app/**/*.php"
|
||||
frankenphp php-server --worker /path/to/your/worker/script.php --watch="/path/to/your/app/**/*.php"
|
||||
```
|
||||
|
||||
## Symfony Runtime
|
||||
|
||||
@@ -176,7 +176,7 @@ docker buildx bake -f docker-bake.hcl --pull --no-cache --push
|
||||
|
||||
```console
|
||||
go test -tags watcher -c -ldflags=-w
|
||||
gdb --args frankenphp.test -test.run ^MyTest$
|
||||
gdb --args frankenphp.dev.test -test.run ^MyTest$
|
||||
```
|
||||
|
||||
9. Hata düzeltildiğinde, tüm bu değişiklikleri geri alın
|
||||
|
||||
@@ -82,7 +82,7 @@ CGO_ENABLED=1 \
|
||||
XCADDY_GO_BUILD_FLAGS="-ldflags '-w -s'" \
|
||||
xcaddy build \
|
||||
--output frankenphp \
|
||||
--with github.com/dunglas/frankenphp/caddy \
|
||||
--with frankenphp.dev/caddy \
|
||||
--with github.com/dunglas/caddy-cbrotli \
|
||||
--with github.com/dunglas/mercure/caddy \
|
||||
--with github.com/dunglas/vulcain/caddy
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Konfigürasyon
|
||||
# Konfigürasyon
|
||||
|
||||
FrankenPHP, Caddy'nin yanı sıra Mercure ve Vulcain modülleri [Caddy tarafından desteklenen formatlar](https://caddyserver.com/docs/getting-started#your-first-config) kullanılarak yapılandırılabilir.
|
||||
|
||||
@@ -41,16 +41,11 @@ Statik ikili:
|
||||
|
||||
## Caddyfile Konfigürasyonu
|
||||
|
||||
FrankenPHP yürütücüsünü kaydetmek için `frankenphp` [global seçenek](https://caddyserver.com/docs/caddyfile/concepts#global-options) ayarlanmalıdır, ardından PHP uygulamanızı sunmak için site blokları içinde `php_server` veya `php` [HTTP yönergeleri](https://caddyserver.com/docs/caddyfile/concepts#directives) kullanılabilir.
|
||||
PHP uygulamanızı sunmak için site blokları içinde `php_server` veya `php` [HTTP yönergeleri](https://caddyserver.com/docs/caddyfile/concepts#directives) kullanılabilir.
|
||||
|
||||
Minimal örnek:
|
||||
|
||||
```caddyfile
|
||||
{
|
||||
# FrankenPHP'yi aktif et
|
||||
frankenphp
|
||||
}
|
||||
|
||||
localhost {
|
||||
# Sıkıştırmayı etkinleştir (isteğe bağlı)
|
||||
encode zstd br gzip
|
||||
@@ -59,7 +54,8 @@ localhost {
|
||||
}
|
||||
```
|
||||
|
||||
İsteğe bağlı olarak, oluşturulacak iş parçacığı sayısı ve sunucuyla birlikte başlatılacak [işçi betikleri] (worker.md) global seçenek altında belirtilebilir.
|
||||
FrankenPHP'yi global seçenek kullanarak açıkça yapılandırabilirsiniz:
|
||||
`frankenphp` [global seçenek](https://caddyserver.com/docs/caddyfile/concepts#global-options) FrankenPHP'yi yapılandırmak için kullanılabilir.
|
||||
|
||||
```caddyfile
|
||||
{
|
||||
@@ -91,21 +87,18 @@ Alternatif olarak, `worker` seçeneğinin tek satırlık kısa formunu kullanabi
|
||||
Aynı sunucuda birden fazla uygulamaya hizmet veriyorsanız birden fazla işçi de tanımlayabilirsiniz:
|
||||
|
||||
```caddyfile
|
||||
{
|
||||
frankenphp {
|
||||
worker /path/to/app/public/index.php <num>
|
||||
worker /path/to/other/public/index.php <num>
|
||||
app.example.com {
|
||||
php_server {
|
||||
root /path/to/app/public
|
||||
worker index.php <num>
|
||||
}
|
||||
}
|
||||
|
||||
app.example.com {
|
||||
root /path/to/app/public
|
||||
php_server
|
||||
}
|
||||
|
||||
other.example.com {
|
||||
root /path/to/other/public
|
||||
php_server
|
||||
php_server {
|
||||
root /path/to/other/public
|
||||
worker index.php <num>
|
||||
}
|
||||
}
|
||||
|
||||
# ...
|
||||
@@ -145,6 +138,15 @@ php_server [<matcher>] {
|
||||
split_path <delim...> # URI'yi iki parçaya bölmek için alt dizgeleri ayarlar. İlk eşleşen alt dizge "yol bilgisini" yoldan ayırmak için kullanılır. İlk parça eşleşen alt dizeyle sonlandırılır ve gerçek kaynak (CGI betiği) adı olarak kabul edilir. İkinci parça betiğin kullanması için PATH_INFO olarak ayarlanacaktır. Varsayılan: `.php`
|
||||
resolve_root_symlink false # Varsa, sembolik bir bağlantıyı değerlendirerek `root` dizininin gerçek değerine çözümlenmesini devre dışı bırakır (varsayılan olarak etkindir).
|
||||
env <key> <value> # Ek bir ortam değişkenini verilen değere ayarlar. Birden fazla ortam değişkeni için birden fazla kez belirtilebilir.
|
||||
file_server off # Yerleşik file_server yönergesini devre dışı bırakır.
|
||||
worker { # Bu sunucuya özgü bir worker oluşturur. Birden fazla worker için birden fazla kez belirtilebilir.
|
||||
file <path> # Worker betiğinin yolunu ayarlar, php_server köküne göre göreceli olabilir
|
||||
num <num> # Başlatılacak PHP iş parçacığı sayısını ayarlar, varsayılan değer mevcut CPU çekirdek sayısının 2 katıdır
|
||||
name <name> # Worker için günlüklerde ve metriklerde kullanılan bir ad ayarlar. Varsayılan: worker dosyasının mutlak yolu. Bir php_server bloğunda tanımlandığında her zaman m# ile başlar.
|
||||
watch <path> # Dosya değişikliklerini izlemek için yolu ayarlar. Birden fazla yol için birden fazla kez belirtilebilir.
|
||||
env <key> <value> # Ek bir ortam değişkenini verilen değere ayarlar. Birden fazla ortam değişkeni için birden fazla kez belirtilebilir. Bu worker için ortam değişkenleri ayrıca php_server üst öğesinden devralınır, ancak burada geçersiz kılınabilir.
|
||||
}
|
||||
worker <other_file> <num> # Global frankenphp bloğundaki gibi kısa formu da kullanabilirsiniz.
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -58,8 +58,8 @@ RUN CGO_ENABLED=1 \
|
||||
CGO_LDFLAGS="$(php-config --ldflags) $(php-config --libs)" \
|
||||
xcaddy build \
|
||||
--output /usr/local/bin/frankenphp \
|
||||
--with github.com/dunglas/frankenphp=./ \
|
||||
--with github.com/dunglas/frankenphp/caddy=./caddy/ \
|
||||
--with frankenphp.dev=./ \
|
||||
--with frankenphp.dev/caddy=./caddy/ \
|
||||
--with github.com/dunglas/caddy-cbrotli \
|
||||
# Mercure ve Vulcain resmi yapıya dahil edilmiştir, ancak bunları kaldırmaktan çekinmeyin
|
||||
--with github.com/dunglas/mercure/caddy \
|
||||
|
||||
@@ -32,7 +32,7 @@ It's also possible to [restart the worker on file changes](config.md#watching-fo
|
||||
The following command will trigger a restart if any file ending in `.php` in the `/path/to/your/app/` directory or subdirectories is modified:
|
||||
|
||||
```console
|
||||
frankenphp php-server --worker /path/to/your/worker/script.php --watch "/path/to/your/app/**/*.php"
|
||||
frankenphp php-server --worker /path/to/your/worker/script.php --watch="/path/to/your/app/**/*.php"
|
||||
```
|
||||
|
||||
## Symfony Runtime
|
||||
|
||||
@@ -588,6 +588,7 @@ static int frankenphp_send_headers(sapi_headers_struct *sapi_headers) {
|
||||
}
|
||||
|
||||
static void frankenphp_sapi_flush(void *server_context) {
|
||||
sapi_send_headers();
|
||||
if (go_sapi_flush(thread_index)) {
|
||||
php_handle_aborted_connection();
|
||||
}
|
||||
|
||||
@@ -19,9 +19,9 @@ package frankenphp
|
||||
// #cgo CFLAGS: -I/usr/local/include -I/usr/local/include/php -I/usr/local/include/php/main -I/usr/local/include/php/TSRM -I/usr/local/include/php/Zend -I/usr/local/include/php/ext -I/usr/local/include/php/ext/date/lib
|
||||
// #cgo linux CFLAGS: -D_GNU_SOURCE
|
||||
// #cgo darwin CFLAGS: -I/opt/homebrew/include
|
||||
// #cgo LDFLAGS: -L/usr/local/lib -L/usr/lib -lphp -ldl -lm -lutil
|
||||
// #cgo linux LDFLAGS: -lresolv
|
||||
// #cgo darwin LDFLAGS: -Wl,-rpath,/usr/local/lib -L/opt/homebrew/lib -L/opt/homebrew/opt/libiconv/lib -liconv
|
||||
// #cgo LDFLAGS: -L/usr/local/lib -L/usr/lib -lphp -lm -lutil
|
||||
// #cgo linux LDFLAGS: -ldl -lresolv
|
||||
// #cgo darwin LDFLAGS: -Wl,-rpath,/usr/local/lib -L/opt/homebrew/lib -L/opt/homebrew/opt/libiconv/lib -liconv -ldl
|
||||
// #include <stdlib.h>
|
||||
// #include <stdint.h>
|
||||
// #include <php_variables.h>
|
||||
@@ -492,6 +492,10 @@ func addHeader(fc *frankenPHPContext, cString *C.char, length C.int) {
|
||||
func go_write_headers(threadIndex C.uintptr_t, status C.int, headers *C.zend_llist) C.bool {
|
||||
fc := phpThreads[threadIndex].getRequestContext()
|
||||
|
||||
if fc == nil {
|
||||
return C.bool(false)
|
||||
}
|
||||
|
||||
if fc.isDone {
|
||||
return C.bool(false)
|
||||
}
|
||||
|
||||
BIN
frankenphp.png
|
Before Width: | Height: | Size: 176 KiB After Width: | Height: | Size: 116 KiB |
@@ -27,8 +27,8 @@ import (
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"github.com/dunglas/frankenphp"
|
||||
"github.com/dunglas/frankenphp/internal/fastabs"
|
||||
"frankenphp.dev"
|
||||
"frankenphp.dev/internal/fastabs"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/zap/exp/zapslog"
|
||||
@@ -330,7 +330,7 @@ func TestMalformedCookie(t *testing.T) {
|
||||
runTest(t, func(handler func(http.ResponseWriter, *http.Request), _ *httptest.Server, i int) {
|
||||
req := httptest.NewRequest("GET", "http://example.com/cookies.php", nil)
|
||||
req.Header.Add("Cookie", "foo =bar; ===;;==; .dot.=val ;\x00 ; PHPSESSID=1234")
|
||||
// Muliple Cookie header should be joined https://www.rfc-editor.org/rfc/rfc7540#section-8.1.2.5
|
||||
// Multiple Cookie header should be joined https://www.rfc-editor.org/rfc/rfc7540#section-8.1.2.5
|
||||
req.Header.Add("Cookie", "secondCookie=test; secondCookie=overwritten")
|
||||
w := httptest.NewRecorder()
|
||||
handler(w, req)
|
||||
@@ -1023,6 +1023,22 @@ func testRejectInvalidHeaders(t *testing.T, opts *testOptions) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestFlushEmptyResponse_module(t *testing.T) { testFlushEmptyResponse(t, &testOptions{}) }
|
||||
func TestFlushEmptyRespnse_worker(t *testing.T) {
|
||||
testFlushEmptyResponse(t, &testOptions{workerScript: "only-headers.php"})
|
||||
}
|
||||
|
||||
func testFlushEmptyResponse(t *testing.T, opts *testOptions) {
|
||||
runTest(t, func(handler func(http.ResponseWriter, *http.Request), _ *httptest.Server, _ int) {
|
||||
req := httptest.NewRequest("GET", "http://example.com/only-headers.php", nil)
|
||||
w := httptest.NewRecorder()
|
||||
handler(w, req)
|
||||
|
||||
resp := w.Result()
|
||||
assert.Equal(t, 204, resp.StatusCode)
|
||||
}, opts)
|
||||
}
|
||||
|
||||
// Worker mode will clean up unreferenced streams between requests
|
||||
// Make sure referenced streams are not cleaned up
|
||||
func TestFileStreamInWorkerMode(t *testing.T) {
|
||||
|
||||
2
go.mod
@@ -1,4 +1,4 @@
|
||||
module github.com/dunglas/frankenphp
|
||||
module frankenphp.dev
|
||||
|
||||
go 1.24.0
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/dunglas/frankenphp"
|
||||
"frankenphp.dev"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"github.com/dunglas/frankenphp"
|
||||
"frankenphp.dev"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/dunglas/frankenphp/internal/fastabs"
|
||||
"frankenphp.dev/internal/fastabs"
|
||||
)
|
||||
|
||||
type watchPattern struct {
|
||||
|
||||
|
Before Width: | Height: | Size: 5.4 KiB |
|
Before Width: | Height: | Size: 6.2 KiB |
@@ -1,133 +1,731 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Test Page for FrankenPHP</title>
|
||||
<style>
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #FAF5F5;
|
||||
background: #fff;
|
||||
color: #000;
|
||||
font-size: 0.9em;
|
||||
font-family: sans-serif,helvetica;
|
||||
font-family: sans-serif, helvetica;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
}
|
||||
:link, :visited {
|
||||
color: #0B2335;
|
||||
}
|
||||
a:hover {
|
||||
color: #0069DA;
|
||||
}
|
||||
h1 {
|
||||
text-align: center;
|
||||
margin: 0;
|
||||
padding: 0.6em 2em 0.4em;
|
||||
background-color: #0B2335;
|
||||
color: #fff;
|
||||
font-weight: normal;
|
||||
font-size: 1.75em;
|
||||
border-bottom: 2px solid #000;
|
||||
}
|
||||
h1 strong {
|
||||
|
||||
a {
|
||||
color: #390075;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.1em;
|
||||
font-size: 1.5em;
|
||||
font-weight: bold;
|
||||
color: #390075;
|
||||
}
|
||||
hr {
|
||||
display: none;
|
||||
|
||||
main {
|
||||
display: flex;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 1em 5em;
|
||||
}
|
||||
.content-columns {
|
||||
position: relative;
|
||||
padding-top: 1em;
|
||||
}
|
||||
.content-column-left, .content-column-right {
|
||||
width: 47%;
|
||||
float: left;
|
||||
padding-bottom: 2em;
|
||||
}
|
||||
.content-column-left {
|
||||
padding-right: 3%;
|
||||
}
|
||||
.content-column-right {
|
||||
padding-left: 3%;
|
||||
}
|
||||
.logos {
|
||||
text-align: center;
|
||||
margin-top: 2em;
|
||||
}
|
||||
img {
|
||||
border: 2px solid #fff;
|
||||
padding: 2px;
|
||||
margin: 2px;
|
||||
}
|
||||
a:hover img {
|
||||
border: 2px solid #f50;
|
||||
}
|
||||
.footer {
|
||||
clear: both;
|
||||
text-align: center;
|
||||
font-size: xx-small;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
padding: 1.5em 3em;
|
||||
|
||||
section {
|
||||
max-width: 600px;
|
||||
}
|
||||
}
|
||||
|
||||
.runtime-info {
|
||||
background: #efefef;
|
||||
padding: 0.5em;
|
||||
margin-top: 1em;
|
||||
font-size: 0.85em;
|
||||
border-left: 3px solid #0B2335;
|
||||
border-left: 3px solid #390075;
|
||||
}
|
||||
|
||||
.right {
|
||||
overflow: auto;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.left {
|
||||
width: 40%;
|
||||
background: #230143;
|
||||
color: #fff;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
padding-top: 1em;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 1em;
|
||||
|
||||
.logo {
|
||||
width: 80%;
|
||||
max-width: 400px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.franky {
|
||||
width: 80%;
|
||||
max-width: 400px;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
footer {
|
||||
border-top: 1px solid #ccc;
|
||||
font-size: 0.8em;
|
||||
padding: 1em 3em;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1em;
|
||||
|
||||
.logos {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
svg {
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
p {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
main {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.right {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.left {
|
||||
width: 100%;
|
||||
flex-direction: row;
|
||||
padding: 1em;
|
||||
|
||||
.logo {
|
||||
max-width: 250px;
|
||||
}
|
||||
|
||||
.franky {
|
||||
height: 100px;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.logo {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 1em 2em;
|
||||
}
|
||||
|
||||
footer {
|
||||
padding: 1em 2em;
|
||||
text-align: center;
|
||||
margin-top: 1em;
|
||||
|
||||
.logos {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header>
|
||||
<h1>FrankenPHP <strong>Test Page</strong></h1>
|
||||
</header>
|
||||
<main>
|
||||
<div class="left">
|
||||
<h1 class="logo">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" id="logo" viewBox="0 0 699.37 92.29">
|
||||
<defs fill="#000000">
|
||||
<style>
|
||||
.logo_b {
|
||||
fill: #fff;
|
||||
}
|
||||
|
||||
<main class="content">
|
||||
<div class="content-columns">
|
||||
<section class="content-column-left">
|
||||
<h2>If you are a member of the general public:</h2>
|
||||
.c {
|
||||
fill: #b3d133;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<path class="c"
|
||||
d="M22.65,38.71h20.32c3.02,0,5.65,1.1,7.89,3.3,2.24,2.2,3.36,4.85,3.36,7.96s-1.12,5.67-3.36,7.96c-2.24,2.29-4.96,3.43-8.15,3.43H22.65v19.8c0,3.45-1.12,6.17-3.37,8.15-2.24,1.99-4.88,2.98-7.89,2.98s-5.78-.99-8.02-2.98c-2.24-1.98-3.37-4.7-3.37-8.15V20.2c0-3.45,.86-6.64,2.59-9.58,1.72-2.93,4.03-5.26,6.92-6.99,2.89-1.72,6.06-2.59,9.51-2.59h28.86c3.19,0,5.89,1.1,8.09,3.3,2.2,2.2,3.3,4.81,3.3,7.83s-1.14,5.8-3.43,8.09c-2.29,2.29-4.94,3.43-7.96,3.43H22.65v15.01Z"
|
||||
fill="#000000" />
|
||||
<path class="c"
|
||||
d="M118.29,54.76c3.88,2.42,6.66,5.18,8.35,8.28,1.68,3.11,2.52,6.77,2.52,11v6.6c0,3.11-1.08,5.76-3.24,7.96-2.16,2.2-4.75,3.3-7.77,3.3s-5.74-1.12-7.89-3.36c-2.16-2.24-3.24-4.87-3.24-7.89v-6.34l-22.13-26.92v33.26c0,3.11-1.08,5.76-3.24,7.96-2.16,2.2-4.79,3.3-7.89,3.3s-5.89-1.1-8.09-3.3c-2.2-2.2-3.3-4.85-3.3-7.96V12.44c0-3.19,1.1-5.89,3.3-8.09s4.9-3.3,8.09-3.3h25.24c5.09,0,9.62,1.86,13.59,5.57l11,10.61c4.05,4.06,6.08,8.72,6.08,13.98v5.05c0,8.54-3.8,14.71-11.39,18.51Zm-33.39-9.32h22.13V23.7h-22.13v21.74Z"
|
||||
fill="#000000" />
|
||||
<path class="c"
|
||||
d="M270.74,88.54c-2.16,2.24-4.83,3.36-8.02,3.36s-6-1.12-8.15-3.36c-2.16-2.24-3.24-4.96-3.24-8.15V23.57h-20.84v57.07c0,3.19-1.12,5.87-3.37,8.02-2.24,2.16-4.96,3.24-8.15,3.24s-5.76-1.1-7.96-3.3c-2.2-2.2-3.3-4.85-3.3-7.96V12.05c0-3.19,1.12-5.89,3.37-8.09,2.24-2.2,4.87-3.3,7.89-3.3,3.19,0,5.91,1.1,8.15,3.3,2.24,2.2,3.37,4.9,3.37,8.09v3.75c0,.43,.08,.65,.26,.65s.26-.08,.26-.26c1.55-5,4.12-8.8,7.7-11.39,3.58-2.59,7.87-3.88,12.88-3.88,6.47,0,11.82,1.92,16.05,5.76,4.23,3.84,6.34,8.99,6.34,15.47v58.24c0,3.19-1.08,5.91-3.24,8.15Z"
|
||||
fill="#000000" />
|
||||
<path class="c"
|
||||
d="M347.1,80.64c0,3.11-1.14,5.78-3.43,8.02-2.29,2.24-4.98,3.37-8.09,3.37s-5.8-1.12-8.09-3.37c-2.29-2.24-3.43-4.92-3.43-8.02v-24.72l-22.13-.26v24.98c0,3.19-1.1,5.89-3.3,8.09s-4.9,3.3-8.09,3.3-5.89-1.1-8.09-3.3-3.3-4.9-3.3-8.09V11.66c0-3.02,1.1-5.63,3.3-7.83,2.2-2.2,4.9-3.3,8.09-3.3s5.89,1.08,8.09,3.24c2.2,2.16,3.3,4.79,3.3,7.89V53.72l22.13-27.31V11.66c0-3.02,1.14-5.63,3.43-7.83,2.29-2.2,4.94-3.3,7.96-3.3s5.63,1.1,7.83,3.3c2.2,2.2,3.3,4.81,3.3,7.83v15.14c0,4.32-.84,8.05-2.52,11.19-1.68,3.15-4.51,5.98-8.48,8.48,7.68,3.62,11.52,9.79,11.52,18.51v15.66Z"
|
||||
fill="#000000" />
|
||||
<path class="c"
|
||||
d="M374.66,35.6h25.24c3.11,0,5.76,1.1,7.96,3.3,2.2,2.2,3.3,4.9,3.3,8.09,0,3.02-1.12,5.65-3.37,7.89-2.24,2.24-4.88,3.36-7.89,3.36h-25.24v10.87h27.44c3.11,0,5.76,1.1,7.96,3.3,2.2,2.2,3.3,4.9,3.3,8.09,0,3.02-1.1,5.61-3.3,7.77-2.2,2.16-4.85,3.32-7.96,3.49h-31.19c-3.37,0-6.49-.86-9.38-2.59-2.89-1.73-5.2-4.05-6.92-6.99-1.73-2.93-2.59-6.12-2.59-9.58v-6.99c0-5.26,.73-9.55,2.2-12.88,1.47-3.32,4.49-5.76,9.06-7.31-4.32-1.47-7.27-3.77-8.87-6.92-1.6-3.15-2.39-7.23-2.39-12.23v-6.08c0-3.45,.86-6.64,2.59-9.58,1.73-2.93,4.03-5.26,6.92-6.99,2.89-1.72,6.02-2.59,9.38-2.59h31.19c3.11,0,5.76,1.1,7.96,3.3s3.3,4.81,3.3,7.83-1.12,5.8-3.37,8.09c-2.24,2.29-4.88,3.43-7.89,3.43h-27.44v11.91Z"
|
||||
fill="#000000" />
|
||||
<path class="c"
|
||||
d="M480.4,88.54c-2.16,2.24-4.83,3.36-8.02,3.36s-6-1.12-8.15-3.36c-2.16-2.24-3.24-4.96-3.24-8.15V23.57h-20.84v57.07c0,3.19-1.12,5.87-3.37,8.02-2.24,2.16-4.96,3.24-8.15,3.24s-5.76-1.1-7.96-3.3c-2.2-2.2-3.3-4.85-3.3-7.96V12.05c0-3.19,1.12-5.89,3.37-8.09,2.24-2.2,4.87-3.3,7.89-3.3,3.19,0,5.91,1.1,8.15,3.3,2.24,2.2,3.37,4.9,3.37,8.09v3.75c0,.43,.08,.65,.26,.65s.26-.08,.26-.26c1.55-5,4.12-8.8,7.7-11.39,3.58-2.59,7.87-3.88,12.88-3.88,6.47,0,11.82,1.92,16.05,5.76,4.23,3.84,6.34,8.99,6.34,15.47v58.24c0,3.19-1.08,5.91-3.24,8.15Z"
|
||||
fill="#000000" />
|
||||
<path class="logo_b"
|
||||
d="M511.07,80.25c0,3.19-1.06,5.91-3.17,8.15-2.12,2.24-4.72,3.37-7.83,3.37s-5.78-1.12-8.02-3.37c-2.24-2.24-3.37-4.96-3.37-8.15V20.07c0-3.45,.86-6.64,2.59-9.58,1.73-2.93,4.05-5.26,6.99-6.99,2.93-1.72,6.12-2.59,9.58-2.59h17.21c5.09,0,9.53,1.77,13.33,5.31l12.42,12.42c1.81,1.73,3.17,3.97,4.08,6.73,.91,2.76,1.36,5.74,1.36,8.93,0,3.71-.58,7.29-1.75,10.74-1.16,3.45-2.78,6.17-4.85,8.15l-11.26,10.74c-3.62,3.62-8.07,5.44-13.33,5.44h-13.98v10.87Zm21.74-56.69l-21.48-.26v23.42h21.48V23.57Z"
|
||||
fill="#000000" />
|
||||
<path class="logo_b"
|
||||
d="M560.11,11.92c0-3.45,1.12-6.17,3.37-8.15,2.24-1.98,4.92-2.98,8.02-2.98s5.76,.97,7.96,2.91c2.2,1.94,3.3,4.64,3.3,8.09v28.47h21.35V11.92c0-3.45,1.14-6.17,3.43-8.15,2.29-1.98,4.98-2.98,8.09-2.98s5.76,.97,7.96,2.91,3.3,4.64,3.3,8.09V81.16c0,3.45-1.12,6.17-3.37,8.15-2.24,1.99-4.92,2.98-8.02,2.98s-5.78-.99-8.02-2.98c-2.24-1.98-3.37-4.7-3.37-8.15V43.5l-21.35,19.28v18.38c0,3.45-1.12,6.17-3.36,8.15-2.24,1.99-4.88,2.98-7.89,2.98s-5.78-.99-8.02-2.98c-2.24-1.98-3.37-4.7-3.37-8.15V11.92Z"
|
||||
fill="#000000" />
|
||||
<path class="logo_b"
|
||||
d="M654.2,80.25c0,3.19-1.06,5.91-3.17,8.15-2.12,2.24-4.72,3.37-7.83,3.37s-5.78-1.12-8.02-3.37c-2.24-2.24-3.37-4.96-3.37-8.15V20.07c0-3.45,.86-6.64,2.59-9.58,1.73-2.93,4.05-5.26,6.99-6.99,2.93-1.72,6.12-2.59,9.58-2.59h17.21c5.09,0,9.53,1.77,13.33,5.31l12.42,12.42c1.81,1.73,3.17,3.97,4.08,6.73,.91,2.76,1.36,5.74,1.36,8.93,0,3.71-.58,7.29-1.75,10.74-1.16,3.45-2.78,6.17-4.85,8.15l-11.26,10.74c-3.62,3.62-8.07,5.44-13.33,5.44h-13.98v10.87Zm21.74-56.69l-21.48-.26v23.42h21.48V23.57Z"
|
||||
fill="#000000" />
|
||||
<g>
|
||||
<path class="c"
|
||||
d="M142.76,32.66v-3.51c0-1.32,1.04-2.4,2.32-2.4,1.29,0,2.33,1.07,2.33,2.39v3.51l7.92-.02v-3.51c0-1.32,1.04-2.4,2.32-2.4,1.29,0,2.33,1.07,2.33,2.39v3.51h6.64v-3.53c0-1.32,1.03-2.4,2.32-2.4s2.33,1.07,2.33,2.39v3.51h6.83v-3.53c0-1.32,1.03-2.4,2.32-2.4,1.29,0,2.33,1.07,2.33,2.39v3.51l7.69-.02v-3.51c0-1.32,1.03-2.4,2.32-2.4s2.33,1.07,2.33,2.39v3.51h6.89v-.85c-.17-3.02-.89-5.52-2.14-7.51-1.25-1.98-3.22-4.1-5.89-6.34l-16.95-13.85c-3.19-2.67-6.13-4.01-8.8-4.01s-5.61,1.34-9.06,4.01l-16.57,13.85c-2.68,2.33-4.66,4.49-5.95,6.47-1.29,1.99-2.07,4.44-2.33,7.38v.97l8.46-.02Z"
|
||||
fill="#000000" />
|
||||
<path class="c"
|
||||
d="M195.11,37.2v3.5c0,1.32-1.03,2.4-2.32,2.4s-2.33-1.07-2.33-2.39v-3.5l-7.69,.02v3.5c0,1.32-1.03,2.4-2.32,2.4s-2.33-1.07-2.33-2.39v-3.5h-6.83v3.51c0,1.32-1.04,2.4-2.32,2.4-1.29,0-2.33-1.07-2.33-2.39v-3.5h-6.64v3.51c0,1.32-1.03,2.4-2.32,2.4-1.29,0-2.33-1.07-2.33-2.39v-3.5l-7.92,.02v3.5c0,1.32-1.03,2.4-2.32,2.4-1.29,0-2.33-1.07-2.33-2.39v-3.5l-8.47,.02v43.43c0,3.11,1.12,5.74,3.37,7.89,2.24,2.16,4.92,3.24,8.02,3.24s5.76-1.08,7.96-3.24c2.2-2.16,3.3-4.79,3.3-7.89v-31.84l22.52,20.84v11c0,3.11,1.1,5.74,3.3,7.89,2.2,2.16,4.9,3.24,8.09,3.24s5.74-1.08,7.9-3.24,3.24-4.79,3.24-7.89V37.19h-6.88Z"
|
||||
fill="#000000" />
|
||||
</g>
|
||||
</svg>
|
||||
<span>Test page</span>
|
||||
</h1>
|
||||
<svg class="franky" xmlns="http://www.w3.org/2000/svg" id="Calque_1" class="franky"
|
||||
viewBox="0 0 668.77 742.85">
|
||||
<defs>
|
||||
<style>
|
||||
.cls-1 {
|
||||
fill: #010101
|
||||
}
|
||||
|
||||
<p>The fact that you are seeing this page indicates that the website you just visited is either experiencing problems, or is undergoing routine maintenance.</p>
|
||||
.cls-3 {
|
||||
fill: #fff
|
||||
}
|
||||
|
||||
<p>
|
||||
If you would like to let the administrators of this website know that you've seen this page instead of the page you expected, you should send them e-mail.
|
||||
In general, mail sent to the name "webmaster" and directed to the website's domain should reach the appropriate person.
|
||||
</p>
|
||||
.cls-4 {
|
||||
fill: #feffff
|
||||
}
|
||||
|
||||
<p>For example, try contacting <a href="mailto:webmaster@<?php echo $_SERVER['SERVER_NAME'] ?? 'example.com'; ?>">webmaster@<?php echo $_SERVER['SERVER_NAME'] ?? 'example.com'; ?></a>.</p>
|
||||
.cls-7 {
|
||||
fill: #b3cd38
|
||||
}
|
||||
|
||||
<p>Learn more about FrankenPHP at the <a href="https://frankenphp.dev/">official website</a>.</p>
|
||||
</section>
|
||||
.cls-8 {
|
||||
fill: #c3b2d3
|
||||
}
|
||||
|
||||
<section class="content-column-right">
|
||||
<h2>If you are the website administrator:</h2>
|
||||
.cls-9 {
|
||||
fill: #38276b
|
||||
}
|
||||
|
||||
<p>Your server is running and serving requests using FrankenPHP, powered by Caddy</p>
|
||||
.cls-10 {
|
||||
fill: rgba(255, 255, 255, .6)
|
||||
}
|
||||
|
||||
<p>To replace this page, deploy your application files to <code><?php echo getcwd(); ?></code>.</p>
|
||||
.cls-11 {
|
||||
fill: rgba(1, 1, 1, .19)
|
||||
}
|
||||
|
||||
<p>Configuration is handled in your <code>Caddyfile</code>.</p>
|
||||
.cls-12 {
|
||||
opacity: .15
|
||||
}
|
||||
|
||||
<div class="runtime-info">
|
||||
<strong>Served by PHP SAPI: </strong> <?php echo php_sapi_name(); ?><br />
|
||||
</div>
|
||||
.cls-13 {
|
||||
opacity: .19
|
||||
}
|
||||
|
||||
.cls-14,
|
||||
.cls-15 {
|
||||
opacity: .3
|
||||
}
|
||||
|
||||
.cls-20 {
|
||||
opacity: .5
|
||||
}
|
||||
|
||||
.cls-21 {
|
||||
opacity: .7
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<path
|
||||
d="m322.04 433.86-20.02 54.01s-102.75-3.02-160.97-43.78c9.22.24 20.68-2.07 26.69-13.28 10.15-18.96 34.85-56.38 66.66-61.26-1.05 2.76-1.54 5.53-1.32 8.35 2.52 30.64 88.97 55.96 88.97 55.96"
|
||||
class="cls-7" />
|
||||
<path
|
||||
d="M566.16 490.35s-6.54-45.67 23.34-42.26c29.88 3.41 39.28-9.25 39.28-9.25s1.43 54.68-25.6 63.63c-19.28 6.39-31.15-8.29-31.15-8.29"
|
||||
class="cls-9" />
|
||||
<path
|
||||
d="M628.74 443.89c-4.52 6.07-15.63 16.6-37.19 14.14-21.33-2.44-24.11 20.15-23.95 33.27l-1.44-.94s-6.55-45.67 23.33-42.26c29.89 3.4 39.28-9.25 39.28-9.25s.06 1.9-.04 5.05Z"
|
||||
class="cls-3" style="opacity:.35" />
|
||||
<g class="cls-12">
|
||||
<path
|
||||
d="M603.18 502.46c-19.29 6.39-31.15-8.29-31.15-8.29l-5.86-3.82s-1.31-9.19-.08-19.02c3.82 5.08 10.79 11.09 22.42 11.45 18.84.58 32.85-21.94 40.16-37.22-.62 14.88-4.34 49.89-25.49 56.9Z"
|
||||
class="cls-9" />
|
||||
</g>
|
||||
<path
|
||||
d="M593.47 508.95c-15.51 0-24.74-11.15-25.21-11.73-.53-.65-.86-1.39-1-2.16-.14.03-.28.06-.42.08-2.65.39-5.1-1.46-5.47-4.1-.17-1.16-3.91-28.48 8.59-41.34 5.05-5.2 11.83-7.36 20.09-6.41 26.23 2.99 34.81-7.3 34.89-7.4 1.23-1.66 3.35-2.32 5.32-1.7 1.97.62 3.3 2.46 3.35 4.53.06 2.38 1.18 58.39-28.92 68.36-4.03 1.34-7.78 1.88-11.23 1.88Zm-21.45-19.61c1.41 0 2.81.61 3.77 1.8.39.47 10.13 11.94 25.86 6.74 15.92-5.27 20.97-32.15 22.06-49.42-6.77 3.38-17.84 6.38-34.76 4.45-5.21-.6-9.15.56-12.04 3.53-7.55 7.76-6.9 26.26-5.98 33.03.36-.08.73-.13 1.1-.13Z"
|
||||
class="cls-9" />
|
||||
<path
|
||||
d="M260.37 518.13s-82.72-10.58-105.81 55.88c-20.99 60.42 37.01 110.5 37.01 110.5s-26.58 3.88-29.71 22.63c-3.11 18.67 6.99 37.47 87.19 27.57 47.73-5.89 24.18-79.93 24.18-88.84s52.1-15.84 124.98-35.65c12.28-3.34-137.84-92.09-137.84-92.09"
|
||||
class="cls-7" />
|
||||
<path
|
||||
d="M210.7 742.24c-23.85 0-39.54-4.17-47.6-12.58-5.59-5.84-7.62-13.68-6.01-23.32 2.41-14.45 15.73-21.33 24.91-24.4-5.51-5.75-13.69-15.26-20.97-27.58-16.28-27.52-20.1-55.86-11.04-81.95 10.01-28.81 32.48-48.16 65-55.97 24.15-5.8 45.11-3.22 45.99-3.11.65.08 1.28.3 1.84.63.35.21 35.39 20.93 69.83 42.47 72.21 45.16 71.62 49.53 71.05 53.76-.31 2.26-1.92 4.05-4.23 4.67-26.69 7.25-50.78 12.83-70.14 17.31-24.09 5.57-46.9 10.85-51.2 14.49.19 1.49.74 4.32 1.24 6.87 3.27 16.86 10.07 51.93-4.41 71.87-5.8 7.99-14.32 12.73-25.31 14.08-14.8 1.83-27.77 2.74-38.94 2.74Zm37.22-219.89c-7.96 0-19.13.68-30.95 3.55-29.42 7.14-48.89 23.86-57.86 49.68-19.65 56.55 35.05 104.78 35.6 105.26 1.43 1.24 2 3.19 1.47 5.01a4.827 4.827 0 0 1-3.94 3.42c-.22.03-23.14 3.63-25.64 18.65-1.11 6.66-.01 11.44 3.46 15.06 6.49 6.77 25.37 13.48 78.39 6.93 8.34-1.03 14.45-4.36 18.68-10.18 12.02-16.55 5.76-48.84 2.75-64.36-1-5.16-1.48-7.72-1.48-9.52 0-9.09 13.15-12.54 58.75-23.09 17.79-4.12 39.59-9.16 63.68-15.57-15.59-13.32-76.22-51.37-132.02-84.38-1.7-.16-5.58-.47-10.89-.47Z"
|
||||
class="cls-9" />
|
||||
<path
|
||||
d="M194.35 680.56s-.11-.07-.1-.06l.03.03s.02.03.08.06l.25.18c.22.13.4.26.65.39.46.26.98.51 1.51.76 1.08.47 2.21.93 3.4 1.31 2.37.78 4.86 1.45 7.42 1.96 2.55.54 5.15.93 7.78 1.29l3.96.44 3.99.34h.07c1.33.12 2.32 1.29 2.21 2.62a2.414 2.414 0 0 1-2.25 2.21l-4.13.27-4.15.16c-2.77.04-5.57.04-8.39-.13a68.18 68.18 0 0 1-8.54-.94c-1.44-.24-2.9-.58-4.38-.98-.75-.22-1.49-.44-2.27-.73-.38-.13-.79-.31-1.19-.47l-.64-.3c-.1-.04-.24-.12-.36-.19l-.19-.1-.31-.2a4.826 4.826 0 0 1-1.16-6.73 4.826 4.826 0 0 1 6.73-1.16"
|
||||
class="cls-9" />
|
||||
<g class="cls-14">
|
||||
<path
|
||||
d="M394.99 611.86c-71.84 19.52-123.2 26.36-123.2 35.14 0 3.23 3.14 15.15 4.78 29.22 2.79 24.18 1.13 54.69-28.61 58.37-79.06 9.75-89.02-8.79-85.95-27.18.26-1.57.7-3.03 1.27-4.4 3.46 6.68 13.39 18.52 40.32 19.15 45.29 1.08 60.21-9.6 61.7-26.37 1.63-18.18-11.24-54.29-20.85-70.96-15.63-27.09-40.53-49.67-30.69-88.81 1.32-5.21 4.3-9.64 8.52-13.39 20.28-3.67 36.84-1.55 36.84-1.55s147.99 87.49 135.89 90.78"
|
||||
class="cls-1" />
|
||||
</g>
|
||||
<path
|
||||
d="M484.61 526.42s40.06 5.29 63.65-22.27c25.82-30.17 43.37-28.78 44.75-20.41 1.38 8.37-13.05 12.94-25.66 37.79-11.87 23.39-27.73 43.79-64.39 39.02"
|
||||
class="cls-7" />
|
||||
<g class="cls-12">
|
||||
<path
|
||||
d="M567.35 521.54c-11.88 23.4-27.74 43.8-64.4 39.02l-18.35-34.13s2.79.37 7.31.41l1.88 6.4c34.89 12.24 54.62-4.44 71.08-24.86 11.68-14.52 22.29-19.99 28.14-24.57 1.31 8.34-13.09 12.95-25.67 37.74"
|
||||
class="cls-1" />
|
||||
</g>
|
||||
<path
|
||||
d="M513.16 566.07c-3.42 0-7.01-.23-10.82-.73a4.816 4.816 0 0 1-4.16-5.41c.34-2.64 2.77-4.52 5.41-4.16 31.92 4.16 46.85-11.55 59.47-36.42 6.88-13.55 14.16-21.23 19.47-26.84 3.83-4.04 5.99-6.4 5.73-7.98-.04-.23-.11-.65-1.15-.94-4.15-1.16-16.84 2.3-35.16 23.7-25.01 29.22-66.21 24.15-67.95 23.92a4.83 4.83 0 0 1-4.15-5.42c.35-2.64 2.77-4.51 5.41-4.15.38.05 37.8 4.56 59.36-20.62 17.01-19.87 33.86-29.85 45.09-26.72 4.37 1.22 7.39 4.46 8.08 8.67 1.05 6.38-3.05 10.71-8.24 16.19-4.91 5.18-11.63 12.27-17.87 24.57-10.78 21.25-26.18 42.35-58.5 42.35Z"
|
||||
class="cls-9" />
|
||||
<path
|
||||
d="M622.64 301.98c-52 39.58-118.56 71.02-150.03 84.84-11.26 4.95-18.03 7.64-18.03 7.64l-.58-2.45-6.82-28.71-17.11-72.15-1.42-5.99c9.26-2.27 21.56-7.18 35.67-13.53 57.2-25.73 143.96-74.98 176.39-66.94 8.28 2.05 21.03 13.36 22.97 30.74 1.94 17.25-6.76 40.47-41.03 66.55"
|
||||
class="cls-7" />
|
||||
<g class="cls-20">
|
||||
<path
|
||||
d="M663.69 244.42c-.01-.06-.01-.13-.02-.19-1.94-17.38-14.69-28.69-22.97-30.74-39.88-9.88-161.87 66.83-210.08 79.96l-1.97-8.29c46.78-11.49 171.62-90.49 212.05-80.47 8.28 2.05 21.03 13.36 22.97 30.74.33 2.84.35 5.84.02 8.99"
|
||||
class="cls-3" />
|
||||
</g>
|
||||
<g class="cls-14">
|
||||
<path
|
||||
d="M622.64 301.98c-70.6 53.74-168.06 92.48-168.06 92.48l-.58-2.45 4.47-41.31s81.64-5.72 136.45-41.2c40.93-26.51 60.98-53.65 68.75-74.06 1.94 17.25-6.76 40.47-41.03 66.55"
|
||||
class="cls-1" />
|
||||
</g>
|
||||
<path
|
||||
d="M454.58 399.29c-1.92 0-3.74-1.15-4.49-3.05-.98-2.48.23-5.29 2.7-6.27.97-.38 97.69-39.14 166.93-91.83 29.07-22.12 42.79-45.34 38.65-65.36-2.79-13.48-12.88-21.93-18.83-23.41-23.32-5.78-82.61 23.06-130.24 46.22-31.46 15.3-61.17 29.75-79.5 34.25-2.6.64-5.2-.95-5.84-3.54-.64-2.59.95-5.2 3.54-5.84 17.34-4.26 46.6-18.49 77.58-33.56 54.11-26.31 110.07-53.52 136.79-46.91 10.01 2.48 22.51 14.12 25.97 30.82 3.49 16.88-1 43.6-42.26 75-70.31 53.51-168.23 92.73-169.21 93.12-.58.23-1.19.34-1.78.34Z"
|
||||
class="cls-9" />
|
||||
<path
|
||||
d="M481.95 613.06c-33.16 17.95-86.73 25.72-142.28 25.71-26.32 0-84.93-4.73-112.44-65.49-20.27-44.75-.28-76.35 5.02-144.97.04-.48.07-.97.11-1.45 0 0 106.53-124.29 165.69-138.2 13.43-3.16 23.89-1.69 32.01 2.49 27.66 14.17 28.4 59.55 28.4 59.55.12.31.24.63.36.95 4.12 10.69 8.8 22.59 13.78 35.17 15.56 39.21 34.06 85.09 47.55 121.94 14.83 40.57-3.54 85.5-38.21 104.29"
|
||||
class="cls-7" />
|
||||
<path
|
||||
d="M481.95 613.06c-33.16 17.95-86.73 25.72-142.28 25.71-21.85 0-65.95-3.26-96.03-39.12 29.18 21.18 63.4 23.45 82.12 23.45 58.5.01 114.93-8.17 149.84-27.08 29.37-15.9 47.62-49.59 45.54-84.38 12.97 39.79-5.35 83.08-39.2 101.42"
|
||||
class="cls-11" />
|
||||
<path
|
||||
d="M460.72 349.83c13.01 27.24 24.39 55.13 35.49 83.17 5.58 14.01 11.13 28.03 16.59 42.11 2.73 7.04 5.43 14.09 8.09 21.16l3.96 10.62 1.81 5.7c.29.96.63 1.9.87 2.86l.63 2.93c1.9 7.76 2.42 15.82 2.13 23.77-.2 7.99-1.81 15.88-4.09 23.5-2.24 7.66-5.77 14.9-9.94 21.69-4.13 6.84-9.39 12.99-15.27 18.42l-2.24 2.02-1.12 1.01c-.38.33-.8.61-1.19.92l-4.83 3.61c-1.67 1.12-3.42 2.12-5.13 3.18-.86.5-1.71 1.1-2.59 1.51l-2.63 1.33c-3.48 1.86-7.09 3.32-10.66 4.91-3.64 1.36-7.24 2.86-10.93 4.01-14.68 4.94-29.72 8.22-44.83 10.56-15.11 2.35-30.31 3.82-45.51 4.58-7.6.37-15.21.64-22.81.7-7.54.12-15.38.07-23.11-.63-15.49-1.34-30.99-4.86-45.41-11.37-7.19-3.27-14.07-7.29-20.44-12.01-6.39-4.71-12.18-10.22-17.33-16.24-5.15-6.03-9.62-12.6-13.38-19.51-.94-1.73-1.89-3.45-2.7-5.24-.83-1.78-1.75-3.51-2.44-5.37l-2.21-5.5-.55-1.38c-.16-.47-.3-.95-.45-1.42l-.87-2.85-.87-2.85-.43-1.42-.32-1.46-1.24-5.84c-.24-.97-.35-1.96-.46-2.95l-.37-2.96-.36-2.96c-.13-.99-.11-1.98-.17-2.96l-.24-5.93.15-5.89c0-1.97.21-3.9.37-5.84.19-1.93.28-3.89.54-5.8 1.84-15.35 5.01-30.12 7.52-44.87 2.58-14.74 4.62-29.5 5.81-44.35a4.83 4.83 0 0 1 5.2-4.44c2.64.21 4.62 2.51 4.43 5.15-1.08 15.21-3.01 30.36-5.51 45.33-2.47 14.97-5.54 29.72-7.2 44.32-1.59 14.56-1.24 29.03 3.23 42.6l.79 2.55c.14.42.25.85.4 1.27l.51 1.24 2.03 4.98c.62 1.68 1.49 3.27 2.26 4.9.76 1.64 1.63 3.21 2.5 4.79 3.48 6.3 7.53 12.24 12.17 17.67 4.65 5.42 9.85 10.36 15.59 14.59a101.9 101.9 0 0 0 18.47 10.83c13.09 5.9 27.39 9.18 41.9 10.42 7.28.66 14.53.7 22.06.58 7.47-.07 14.92-.33 22.37-.7 14.89-.76 29.74-2.21 44.41-4.49l5.5-.88 5.47-1.01c3.66-.62 7.25-1.48 10.87-2.23 7.18-1.7 14.34-3.51 21.27-5.88 3.51-1.07 6.88-2.47 10.31-3.73 3.32-1.47 6.71-2.81 9.89-4.51l2.42-1.21c.83-.38 1.52-.89 2.29-1.33 1.49-.92 3.03-1.77 4.49-2.75l4.24-3.14c.35-.27.72-.51 1.05-.79l.98-.88 1.97-1.76c5.18-4.75 9.86-10.15 13.54-16.21 3.71-6.01 6.91-12.42 8.91-19.24 2.05-6.77 3.54-13.78 3.73-20.88.27-7.07-.14-14.21-1.81-21.1l-.55-2.6c-.21-.86-.51-1.69-.77-2.54l-1.58-5.08-3.89-10.57c-2.62-7.04-5.28-14.08-7.97-21.1-5.38-14.05-10.86-28.08-16.37-42.09-11.07-28.01-22.26-56.02-30.93-85.03-.38-1.28.35-2.63 1.62-3.01 1.16-.35 2.38.21 2.88 1.27Z"
|
||||
class="cls-9" />
|
||||
<path
|
||||
d="M511.48 499.78c22.09 38.73 74.9 175.05 91.89 181.82 23.59 9.4 58.1 48.69-39.78 55.83-79.01 5.77-96.14-97-132.6-127.66"
|
||||
class="cls-7" />
|
||||
<path
|
||||
d="M563.58 737.44c-79 5.77-96.12-96.99-132.6-127.66 0 0 21.51 4.44 50.19 51.58 18.31 30.09 51.97 58.16 86.66 55.63 32.63-2.39 50.54-8.34 59.06-15.56 7.36 14.45-2.02 31.53-63.32 36"
|
||||
class="cls-1" style="opacity:.25" />
|
||||
<path d="M511.41 491c-1.16-2.37 5.21-.45 6.52 1.83" class="cls-9" />
|
||||
<path
|
||||
d="M517.93 492.82c2.79 4.87 5.26 9.75 7.65 14.67 2.38 4.91 4.69 9.84 6.92 14.78 4.47 9.89 8.77 19.82 13.04 29.75 8.52 19.87 16.95 39.74 25.54 59.48 4.31 9.87 8.68 19.69 13.26 29.37 2.29 4.84 4.64 9.64 7.07 14.36 2.44 4.7 4.98 9.36 7.72 13.67 1.37 2.14 2.82 4.22 4.27 5.87.7.81 1.49 1.55 1.86 1.76l.07.06h.02l.11.06.26.11.52.22c.69.31 1.41.58 2.07.92 5.4 2.6 10.29 5.91 14.71 9.98 2.22 2.02 4.25 4.33 6.09 6.87 1.84 2.53 3.43 5.46 4.4 8.81.99 3.32 1.23 7.19.28 10.85-.28.89-.52 1.81-.88 2.66-.4.82-.81 1.64-1.23 2.45-.45.78-.99 1.46-1.5 2.19-.5.75-1.08 1.35-1.66 1.96-4.7 4.89-10.2 7.65-15.57 9.81-5.42 2.1-10.89 3.64-16.36 4.82-10.95 2.39-21.9 3.54-32.85 4.34-11.39.77-23.13-.69-34.01-4.72-5.38-2.12-10.62-4.64-15.38-7.85-2.46-1.5-4.69-3.28-6.97-5-1.16-.84-2.17-1.84-3.26-2.75-1.05-.95-2.18-1.82-3.16-2.84-8.18-7.82-15.15-16.62-21.27-25.79-6.15-9.16-11.62-18.64-16.87-28.12l-7.75-14.22c-2.53-4.73-5.09-9.44-7.71-14.05-2.64-4.6-5.3-9.18-8.27-13.49-2.92-4.34-6.09-8.47-9.67-12.2l-.04-.04c-.93-.96-.9-2.5.07-3.42.85-.82 2.15-.89 3.08-.23 4.65 3.28 8.59 7.36 12.23 11.58 1.82 2.13 3.48 4.33 5.15 6.55.83 1.11 1.59 2.25 2.38 3.38.8 1.13 1.57 2.27 2.32 3.42.75 1.15 1.52 2.28 2.25 3.44l2.15 3.49c1.44 2.32 2.82 4.66 4.21 7l8.03 14.07c5.27 9.37 10.66 18.58 16.6 27.32 5.9 8.76 12.5 16.92 19.98 23.99.9.93 1.92 1.7 2.87 2.55.99.81 1.91 1.72 2.94 2.45 2.04 1.51 4.03 3.11 6.21 4.4 4.21 2.82 8.78 4.95 13.44 6.77 9.42 3.4 19.55 4.64 29.7 3.91 10.57-.83 21.15-2.03 31.29-4.31 5.07-1.13 10.01-2.57 14.65-4.39 4.6-1.82 8.9-4.26 11.66-7.23 1.39-1.47 2.38-3.01 2.73-4.6.4-1.58.34-3.28-.19-5.12-.52-1.83-1.5-3.76-2.83-5.58-1.33-1.82-2.86-3.61-4.64-5.22-3.51-3.26-7.66-6.07-11.98-8.15-.54-.28-1.09-.48-1.63-.73l-.95-.42c-.3-.14-.6-.29-.89-.44l-.44-.24-.35-.23c-1.91-1.26-3.02-2.48-4.1-3.69-2.11-2.41-3.72-4.8-5.27-7.2-3.05-4.8-5.67-9.65-8.2-14.53-2.51-4.88-4.9-9.78-7.23-14.7-4.64-9.85-9.04-19.75-13.37-29.68-8.65-19.85-24.55-59.57-24.55-59.57l-25.24-56.42 6.45-6.96Z"
|
||||
class="cls-9" />
|
||||
<g style="opacity:.4">
|
||||
<ellipse cx="304.82" cy="532.72" rx="66.87" ry="81.46" style="fill:#eeeff3"
|
||||
transform="rotate(-10.12 304.677 532.525)" />
|
||||
</g>
|
||||
<path
|
||||
d="M478.89 267.79s-66.49 20.77-66.64 21.09c-28.79 63.49 93.81 118.78 93.81 118.78s-63.19-90.07-27.18-139.87Z"
|
||||
class="cls-3" />
|
||||
<g class="cls-13">
|
||||
<path
|
||||
d="M415.22 287.79s.52-.21 1.42-.51c-3.71 39.9 46.24 74.77 76.22 91.96 8.48 16.38 16.17 27.34 16.17 27.34s-122.6-55.29-93.81-118.78Z"
|
||||
class="cls-1" />
|
||||
</g>
|
||||
<path
|
||||
d="m517.46 417.09-13-5.86c-.8-.36-19.88-9.02-41.42-23.53-12.7-8.55-23.58-17.36-32.34-26.18-11.12-11.19-18.87-22.46-23.03-33.51-5.26-13.94-4.92-27.65 1.02-40.75.71-1.57 1.96-2 3.07-2.37.51-.17 1.25-.42 2.19-.73 1.75-.57 4.3-1.39 7.6-2.44 5.54-1.76 13.25-4.2 22.91-7.24 16.45-5.17 33.1-10.37 33.27-10.43l11.23-3.51-6.9 9.54c-7.68 10.61-11.11 24.19-10.21 40.36.74 13.25 4.36 28.23 10.77 44.53 11 27.98 26.5 50.22 26.66 50.44l8.19 11.68Zm-102.29-125.1c-4.41 10.68-4.48 21.86-.18 33.25 8.62 22.85 33.21 43.01 52.32 55.9 10.43 7.03 20.42 12.72 27.84 16.68-5.65-9.44-13.41-23.67-19.82-39.98-6.71-17.08-10.51-32.88-11.29-46.96-.77-13.77 1.35-25.93 6.31-36.31-22.09 6.91-48.71 15.28-55.18 17.43Z"
|
||||
class="cls-9" />
|
||||
<path
|
||||
d="M169.61 365.65s66.34-21.26 66.64-21.09c60.08 35.37-8.4 151.13-8.4 151.13s-.12-110.02-58.23-130.04Z"
|
||||
class="cls-3" />
|
||||
<g class="cls-13">
|
||||
<path
|
||||
d="M233.19 345.39s-.54.13-1.45.4c25.99 30.5 5.19 87.76-9.45 119.07 2.48 18.28 2.5 31.66 2.5 31.66s68.48-115.75 8.4-151.13Z"
|
||||
class="cls-1" />
|
||||
</g>
|
||||
<path
|
||||
d="m223.95 509.97-.02-14.27c0-.27-.12-27.51-7.25-56.73-4.14-16.99-9.8-31.3-16.81-42.54-8.56-13.71-19.16-22.82-31.53-27.08l-11.13-3.83 11.21-3.59c.17-.05 16.78-5.38 33.21-10.61 9.65-3.07 17.36-5.52 22.91-7.26 3.3-1.04 5.86-1.84 7.62-2.37.94-.29 1.69-.51 2.21-.66 1.12-.33 2.39-.69 3.87.18 12.39 7.3 20.56 18.31 24.28 32.74 2.95 11.43 3.09 25.11.44 40.66-2.09 12.25-5.93 25.71-11.39 40.02-9.27 24.25-19.9 42.31-20.34 43.07l-7.26 12.28ZM180.5 366.28c10.02 5.64 18.75 14.37 26.05 26.07 7.46 11.97 13.44 27.08 17.77 44.91 4.14 17.04 5.98 33.13 6.79 44.11 3.8-7.51 8.69-17.91 13.18-29.66 8.22-21.54 16.74-52.17 10.64-75.82-3.04-11.79-9.52-20.89-19.27-27.09-6.53 1.97-33.12 10.43-55.16 17.48Z"
|
||||
class="cls-9" />
|
||||
<path
|
||||
d="M395.02 59.33s26.76-42.86 58.49-52.9 60.14 10.55 71.13 50.87c10.98 40.31 7.58 76.3 17.7 102.68 10.12 26.38 51.11 53.06 31.65 88.8-19.46 35.74-42.07 55.92-87.69 52.01-45.62-3.91-126.77-17.28-126.77-17.28l35.49-224.18Z"
|
||||
class="cls-7" />
|
||||
<path
|
||||
d="M498.05 299.26c-19.14-3.32-45.16.19-67.14-5.21-.64-12.75-2.5-23.36.18-34.97 16.05-69.61 73.52 22.89 109.73-18.21 17.11-19.41-43.12-150.1-46.9-195.72-1.88-22.64 6.32-25.4 15.05-22.45 6.71 9.29 12.32 21.32 16.34 35.59 11.63 41.36 10.92 77.5 21 104.75s54.75 59.48 27.68 85.73c-25.09 24.32-37.4 57.16-75.94 50.48Z"
|
||||
class="cls-11" />
|
||||
<path
|
||||
d="M454.82 28.32c-22.44 7.1-36.87 27.08-36.2 47.73a42.196 42.196 0 0 1-4.97-10.47c-7.67-24.25 7.66-50.74 34.24-59.15 26.59-8.41 54.36 4.43 62.04 28.68 1.2 3.78 1.83 7.61 1.96 11.42-11.33-17.27-34.62-25.32-57.06-18.22Z"
|
||||
class="cls-10" />
|
||||
<path
|
||||
d="M497.01 305.18c-3.56 0-7.24-.16-11.05-.49-45.24-3.88-126.26-17.19-127.07-17.32l-3.84-.63 36.22-228.8.42-.67c.28-.45 6.99-11.14 17.74-23.22 14.62-16.42 29.05-26.97 42.89-31.35 14.35-4.54 28.55-3.33 41.07 3.49 16.18 8.83 28.62 26.61 35.01 50.08 5.46 20.06 7.44 39.22 9.18 56.14 1.83 17.81 3.42 33.2 8.4 46.17 2.98 7.75 8.95 15.74 15.26 24.2 7.22 9.66 14.69 19.65 18.76 30.68 4.8 13 3.96 25.17-2.59 37.2-11.2 20.58-22.1 33.62-35.33 42.28-12.54 8.21-27.37 12.25-45.08 12.25ZM364 280.27c16.63 2.68 83.32 13.25 122.63 16.62 10.89.93 20.4.48 29.05-1.38 8.19-1.76 15.42-4.75 22.12-9.13 12.09-7.91 22.19-20.08 32.74-39.47 5.48-10.07 6.16-19.84 2.13-30.75-3.68-9.96-10.8-19.49-17.69-28.7-6.65-8.9-12.94-17.31-16.3-26.08-5.35-13.94-7.06-30.57-8.88-48.18-1.71-16.61-3.65-35.44-8.95-54.88-5.83-21.39-16.91-37.47-31.21-45.26-10.6-5.78-22.69-6.78-34.96-2.9-27.9 8.83-52.46 45.26-55.94 50.6l-34.75 219.52Z"
|
||||
class="cls-9" />
|
||||
<path
|
||||
d="M117.12 154.36s-46.54-19.67-78.28-9.63C7.11 154.77-4.29 187.96 9.92 227.25s37.7 66.77 44.59 94.17-11.28 72.8 25.2 90.85c36.48 18.04 66.58 21.54 101.64-7.9 35.06-29.44 93.75-87.06 93.75-87.06L117.12 154.36Z"
|
||||
class="cls-7" />
|
||||
<path
|
||||
d="M164.51 417.58c13.75-13.72 43.42-33.51 58.28-50.57-6.82-10.8-11.39-20.55-20.26-28.5-53.17-47.71-46.97 61.02-100.23 48.23-25.16-6.04-51.07-147.58-74.22-187.07-11.49-19.6-19.78-17.15-25.22-9.7-.14 11.46 2.18 24.53 7.11 38.51 14.28 40.53 35.65 69.68 43.08 97.76s-9.68 73.92 26.59 84.24c22.61 6.43 67.59 24.35 84.88 7.1Z"
|
||||
class="cls-11" />
|
||||
<path
|
||||
d="M50.37 163.4c22.44-7.1 45.73.94 57.06 18.22a42.04 42.04 0 0 0-1.96-11.42c-7.67-24.25-35.45-37.1-62.04-28.68-26.59 8.41-41.92 34.89-34.24 59.15 1.2 3.78 2.88 7.28 4.97 10.47-.67-20.65 13.75-40.63 36.2-47.73Z"
|
||||
class="cls-10" />
|
||||
<path
|
||||
d="M128.66 430.09c-15.03 0-30.8-4.47-50.68-14.3-12.28-6.07-19.97-15.54-23.52-28.94-3.01-11.36-2.65-23.83-2.3-35.88.31-10.55.59-20.52-1.43-28.57-3.39-13.48-10.95-26.97-19.69-42.6-8.3-14.84-17.72-31.65-24.78-51.2-8.27-22.87-8.33-44.57-.17-61.1 6.31-12.78 17.23-21.94 31.59-26.48 13.84-4.38 31.71-4.05 53.11.97 15.74 3.7 27.38 8.58 27.87 8.78l.73.31.55.57 160.7 165.74-2.77 2.72c-.59.58-59.2 58.07-93.98 87.27-17.45 14.65-34.68 22.07-52.68 22.67-.84.03-1.69.04-2.53.04ZM59.48 145.8c-6.77 0-13.42.76-19.45 2.67-12.27 3.88-21.58 11.66-26.93 22.49-7.21 14.6-7.03 34.13.51 54.98 6.85 18.95 16.1 35.46 24.25 50.04 8.64 15.44 16.81 30.03 20.45 44.51 2.29 9.11 1.99 19.6 1.67 30.71-.33 11.5-.68 23.39 2.04 33.65 2.98 11.24 9.15 18.85 19.43 23.93 19.79 9.79 35.04 13.93 49.49 13.45 8-.27 15.64-1.99 23.35-5.26 8.15-3.46 16.18-8.55 24.56-15.59 30.22-25.37 78.69-72.38 90.75-84.14L114.88 157.68c-4.63-1.85-30.85-11.88-55.41-11.88Z"
|
||||
class="cls-9" />
|
||||
<path
|
||||
d="M491.19 588.11c-159.82-46.08-241.51-209.96-241.51-209.98-152.04-83.46-144.45-179.68-83.33-243.45l205.24-64.94c63.52 19.38 101.89 88.17 52.99 232.85-41.18 146.84 82.52 225.46 82.52 225.46l-46.14 7.42 30.23 52.64Z"
|
||||
class="cls-7" />
|
||||
<path
|
||||
d="M213.78 119.08c-84.76 61.25-101.14 132.02 72.53 227.35 0 .02 44 156.39 172.96 193.69 5.86 3.37 26.35 43.29 26.35 43.29-157.58-45.83-234.06-208.69-234.06-208.7C58.1 268.52 108.92 173.45 213.78 119.09Z"
|
||||
class="cls-11" />
|
||||
<path
|
||||
d="m436.86 132.87 11.74 37.1 22.71-7.19 1.79 5.65c2.69 8.49 11.76 13.21 20.26 10.52l9.83-3.11c8.49-2.69 13.19-11.76 10.5-20.25l-15.05-47.56c-2.69-8.49-11.75-13.2-20.24-10.51l-9.83 3.11c-8.49 2.69-13.21 11.75-10.52 20.24l1.52 4.81-22.71 7.19Z"
|
||||
class="cls-8" />
|
||||
<g class="cls-21">
|
||||
<path
|
||||
d="m452.99 130.61 1.52 4.81-15.31 4.85-2.34-7.4 15.55-4.92c.12.89.3 1.78.58 2.66ZM508.63 165.33l-15.05-47.56c-2.69-8.49-11.75-13.2-20.24-10.51l-9.83 3.11a16.02 16.02 0 0 0-6.06 3.53c.8-6.01 4.96-11.32 11.12-13.27l9.83-3.11c8.49-2.69 17.55 2.02 20.24 10.51l15.05 47.56c1.95 6.16 0 12.62-4.46 16.73.3-2.28.14-4.66-.6-6.99Z"
|
||||
class="cls-3" />
|
||||
</g>
|
||||
<g class="cls-15">
|
||||
<path
|
||||
d="m447.22 129.59 2.59 8.2c2.98 9.42 13.04 14.64 22.46 11.66 3.12-.99 6.45.74 7.44 3.86 2.69 8.5 11.76 13.21 20.26 10.52l9.82-3.11c1.66-.53 3.17-1.3 4.51-2.26.95 7.58-3.58 14.99-11.12 17.38l-9.82 3.11c-8.5 2.69-17.57-2.02-20.26-10.52l-1.79-5.65-22.71 7.19-11.74-37.1 10.36-3.28Z"
|
||||
class="cls-9" />
|
||||
</g>
|
||||
<path
|
||||
d="m467.92 170.07-.15-.47-17.53 5.55a5.44 5.44 0 0 1-6.82-3.54l-11.74-37.1c-.91-2.86.68-5.91 3.54-6.82l17.54-5.55c-3.33-11.23 2.96-23.14 14.18-26.69l9.83-3.11c11.33-3.59 23.47 2.72 27.06 14.05l15.05 47.56c3.59 11.34-2.71 23.48-14.04 27.07l-9.83 3.11c-11.34 3.59-23.49-2.72-27.07-14.06Zm2.29-64.26c-5.63 1.78-8.76 7.8-6.98 13.43l1.52 4.81c.91 2.86-.68 5.91-3.54 6.82l-17.53 5.55 8.46 26.74 17.53-5.55c2.86-.9 5.91.68 6.82 3.54l1.79 5.65c1.78 5.63 7.81 8.76 13.44 6.98l9.83-3.11c5.62-1.78 8.75-7.81 6.96-13.44l-15.05-47.56c-1.78-5.62-7.8-8.75-13.42-6.97l-9.83 3.11Z"
|
||||
class="cls-9" />
|
||||
<path
|
||||
d="m129.88 256 315.53-99.84c2.14-.68 3.33-2.96 2.65-5.1s-2.96-3.33-5.1-2.65l-315.53 99.84a4.063 4.063 0 0 0-2.65 5.1 4.063 4.063 0 0 0 5.1 2.65Z"
|
||||
class="cls-9" />
|
||||
<path
|
||||
d="M419.91 180.48a5.816 5.816 0 0 0 3.79-7.29l-8.53-26.94a5.816 5.816 0 0 0-7.29-3.79 5.816 5.816 0 0 0-3.79 7.29l8.53 26.94a5.816 5.816 0 0 0 7.29 3.79ZM372.24 195.56a5.816 5.816 0 0 0 3.79-7.29l-8.53-26.94a5.816 5.816 0 0 0-7.29-3.79 5.816 5.816 0 0 0-3.79 7.29l8.53 26.94a5.816 5.816 0 0 0 7.29 3.79ZM324.56 210.65a5.816 5.816 0 0 0 3.79-7.29l-8.53-26.94a5.816 5.816 0 0 0-7.29-3.79 5.816 5.816 0 0 0-3.79 7.29l8.53 26.94a5.816 5.816 0 0 0 7.29 3.79ZM164.72 261.23a5.816 5.816 0 0 0 3.79-7.29L159.98 227a5.816 5.816 0 0 0-7.29-3.79 5.816 5.816 0 0 0-3.79 7.29l8.53 26.94a5.816 5.816 0 0 0 7.29 3.79ZM212.4 246.14a5.816 5.816 0 0 0 3.79-7.29l-8.53-26.94a5.816 5.816 0 0 0-7.29-3.79 5.816 5.816 0 0 0-3.79 7.29l8.53 26.94a5.816 5.816 0 0 0 7.29 3.79ZM260.07 231.06a5.816 5.816 0 0 0 3.79-7.29l-8.53-26.94a5.816 5.816 0 0 0-7.29-3.79 5.816 5.816 0 0 0-3.79 7.29l8.53 26.94a5.816 5.816 0 0 0 7.29 3.79Z"
|
||||
class="cls-9" />
|
||||
<path
|
||||
d="m125.35 236.76 11.74 37.1-22.71 7.19 1.79 5.65c2.69 8.49-2.03 17.57-10.52 20.26l-9.83 3.11c-8.49 2.69-17.56-2.03-20.24-10.52l-15.05-47.56c-2.69-8.49 2.02-17.55 10.51-20.24l9.83-3.11c8.49-2.69 17.57 2.01 20.25 10.5l1.52 4.81 22.71-7.19Z"
|
||||
class="cls-8" />
|
||||
<g class="cls-21">
|
||||
<path
|
||||
d="m110.86 244.2 1.52 4.81 15.31-4.85-2.34-7.4-15.55 4.92c.41.8.77 1.63 1.05 2.52ZM85.32 304.6l-15.05-47.56c-2.69-8.49 2.02-17.55 10.51-20.24l9.83-3.11c2.34-.74 4.71-.9 6.99-.6-4.11-4.46-10.57-6.41-16.73-4.46l-9.83 3.11c-8.49 2.69-13.2 11.75-10.51 20.24l15.05 47.56c1.95 6.16 7.26 10.32 13.27 11.12a16.096 16.096 0 0 1-3.53-6.06Z"
|
||||
class="cls-3" />
|
||||
</g>
|
||||
<g class="cls-15">
|
||||
<path
|
||||
d="m115 240.04 2.59 8.2c2.98 9.42-2.24 19.48-11.66 22.46a5.927 5.927 0 0 0-3.86 7.44c2.69 8.5-2.02 17.57-10.52 20.26l-9.82 3.11c-1.66.53-3.34.76-4.99.75 3.58 6.74 11.56 10.2 19.09 7.81l9.82-3.11c8.5-2.69 13.21-11.76 10.52-20.26l-1.79-5.65 22.71-7.19-11.74-37.1-10.36 3.28Z"
|
||||
class="cls-9" />
|
||||
</g>
|
||||
<path
|
||||
d="m107.29 312.14-9.83 3.11c-11.33 3.59-23.47-2.72-27.06-14.06l-15.05-47.56c-3.59-11.33 2.72-23.47 14.05-27.06l9.83-3.11c11.22-3.55 23.22 2.58 26.95 13.68l17.54-5.55c2.86-.9 5.91.68 6.82 3.54l11.74 37.1c.91 2.86-.68 5.91-3.54 6.82l-17.53 5.55.15.47c3.59 11.34-2.72 23.49-14.06 27.08Zm-34.61-75.21c-5.62 1.78-8.75 7.8-6.97 13.42l15.05 47.56c1.78 5.63 7.8 8.76 13.43 6.98l9.83-3.11c5.63-1.78 8.76-7.81 6.98-13.44l-1.79-5.65c-.91-2.86.68-5.91 3.54-6.82l17.53-5.55-8.46-26.74-17.53 5.55a5.44 5.44 0 0 1-6.82-3.54l-1.52-4.81c-1.78-5.62-7.81-8.75-13.43-6.96l-9.83 3.11ZM345.59 396.05c-19.9 10.03-31.58 28.01-28.61 42.47-1.24-1.38-2.3-2.9-3.15-4.58-7.59-15.07 4.41-36.44 26.81-47.73s46.71-8.22 54.31 6.86a20.81 20.81 0 0 1 1.81 5.25c-9.85-10.99-31.26-12.31-51.16-2.28Z"
|
||||
class="cls-9" />
|
||||
<path
|
||||
d="M361.94 425.47c-15.45 7.79-24.25 22.28-21.59 34.21-10.52-11.58-2.16-32.76 17.47-42.39 19.42-10.05 41.42-4.17 44.46 11.18-8-9.24-24.89-10.79-40.34-3ZM383.72 455.91c-11.87 5.98-18.66 17.04-16.66 26.12-8.03-8.82-1.53-24.93 13.54-32.33 14.91-7.7 31.73-3.34 34.03 8.36-6.1-7-19.04-8.13-30.9-2.15ZM172.17 213.6l-33.05-41.54c7.89-14.07 18.4-27.21 30.77-39.1l7.18-2.27 11.16-3.53 25.96-8.21 11.69-3.7 18.96-6 17.61-5.57 20.04-6.34 13.85-4.38 22.73-7.19 13.85-4.38 20.04-6.34 18.84-3.11c24.42 6 38.61 18.82 53.3 39.84l-3.35 22.87-33.9-42.61-3.22 54.35-33.41-41.99-3.17 53.56-30.95-38.9-2.94 49.63-33.41-41.99-3.17 53.56-34.39-43.23-3.26 55.14-28-35.2-2.66 44.9-33.9-42.61-3.22 54.35ZM138.7 172.85l-3.1 52.32-10.76-13.53c2.28-13.49 7.07-26.49 13.86-38.79Z"
|
||||
class="cls-9" />
|
||||
<path
|
||||
d="m499.4 594.55-9.29-2.68c-36.89-10.64-72.68-28.41-106.37-52.84-26.9-19.5-52.54-43.26-76.19-70.62-21.03-24.33-36.57-47.06-45.91-61.85-5.3-8.39-9.2-15.17-11.55-19.38-1.72-3.09-2.76-4.99-3.38-6.21-38.19-21.09-68.15-44.05-89.04-68.28-19.39-22.48-31.11-46.14-34.82-70.31-3.03-19.77-.7-39.69 6.94-59.21 7.03-17.96 18.38-35.19 33.73-51.2l.69-.72.95-.3 206.4-65.31 1.16.35c13.75 4.2 25.99 10.54 36.39 18.84 11.05 8.84 20.06 19.94 26.76 33 10.51 20.46 15.45 45.82 14.71 75.39-.8 31.96-8.3 69.15-22.27 110.52-9.18 32.79-10.67 64.76-4.43 95.05 5 24.26 14.95 47.52 29.57 69.15 13.06 19.31 27.5 33.72 37.32 42.41 10.67 9.44 18.34 14.35 18.41 14.4l8.68 5.53-50.7 8.16 32.23 56.12ZM253.58 377.17c2.98 5.79 23.18 43.8 60.42 86.75 23.23 26.78 48.37 50.02 74.72 69.07 29.96 21.66 61.58 37.94 94.14 48.49l-28.12-48.96 42.35-6.81a215.74 215.74 0 0 1-11.27-9.29c-10.16-8.97-25.12-23.85-38.67-43.82-15.25-22.49-25.65-46.73-30.89-72.02-6.55-31.61-5.02-64.92 4.54-99.03l.06-.2c13.74-40.66 21.11-77.1 21.9-108.31.71-28.24-3.95-52.34-13.85-71.62-6.2-12.07-14.51-22.32-24.69-30.46-9.33-7.46-20.3-13.21-32.63-17.11l-203.11 64.27c-14.29 15.06-24.85 31.18-31.4 47.92-7.13 18.22-9.32 36.78-6.5 55.17 3.48 22.69 14.59 45.03 33.01 66.38 20.48 23.74 50.08 46.33 87.97 67.13l1.99 1.09.02 1.37Z"
|
||||
class="cls-9" />
|
||||
<path
|
||||
d="M315.85 249.39c9.33 19.11 31.49 29.02 52.38 22.41 20.89-6.61 33.31-27.46 29.95-48.46l-82.33 26.05Z"
|
||||
class="cls-3" />
|
||||
<path
|
||||
d="M369.65 276.3a48.368 48.368 0 0 1-33.82-1.73c-10.58-4.59-19.18-12.8-24.22-23.11l-2.4-4.92 92.77-29.35.86 5.41c1.81 11.33-.5 22.99-6.52 32.83a48.367 48.367 0 0 1-26.67 20.87Zm-46.77-24.18c4.12 6.04 9.9 10.84 16.71 13.79 8.6 3.73 18.27 4.22 27.22 1.39s16.57-8.8 21.46-16.8a38.94 38.94 0 0 0 5.73-20.89l-71.12 22.5Z"
|
||||
class="cls-9" />
|
||||
<circle cx="359.31" cy="245.38" r="10.66" class="cls-9" />
|
||||
<path
|
||||
d="M213.64 282.92c9.33 19.11 31.49 29.02 52.38 22.41 20.89-6.61 33.31-27.46 29.95-48.46l-82.33 26.05Z"
|
||||
class="cls-3" />
|
||||
<path
|
||||
d="M267.44 309.83a48.368 48.368 0 0 1-33.82-1.73c-10.58-4.59-19.18-12.8-24.22-23.11l-2.4-4.92 92.77-29.35.86 5.41c1.81 11.33-.5 22.99-6.52 32.83a48.367 48.367 0 0 1-26.67 20.87Zm-46.77-24.18c4.12 6.04 9.9 10.84 16.71 13.79 8.6 3.73 18.27 4.22 27.22 1.39s16.57-8.8 21.46-16.8a38.94 38.94 0 0 0 5.73-20.89l-71.12 22.5Z"
|
||||
class="cls-9" />
|
||||
<circle cx="257.1" cy="278.91" r="10.66" class="cls-9" />
|
||||
<path
|
||||
d="M189.64 276.54c84.13-24.9 168.23-49.85 252.33-74.84 1.82-.54 2.28-.04 2.73 1.6 1.8 6.37 3.64 12.72 5.64 19.01.58 1.83.16 2.39-1.61 2.9-10.25 2.95-20.46 6.06-30.71 9.02-1.59.47-2 1.05-1.43 2.64.88 2.48 1.39 5.09 2.31 7.53.71 1.89.07 2.48-1.67 2.91-2.63.63-5.17 1.57-7.8 2.25-1.31.33-1.63.85-1.2 2.15.9 2.73 1.57 5.52 2.5 8.23.51 1.45.1 1.94-1.3 2.29-2.55.64-5.01 1.56-7.56 2.17-1.73.42-2.36 1.01-1.66 2.89.96 2.52 1.51 5.2 2.38 7.76.48 1.37.19 1.9-1.24 2.32a7385.42 7385.42 0 0 0-43.28 12.83c-1.29.39-1.82.21-2.17-1.14-.73-2.85-1.7-5.64-2.45-8.49-.35-1.34-.91-1.58-2.18-1.15-2.64.88-5.36 1.52-7.99 2.44-1.52.52-2.24.31-2.68-1.37-.86-3.23-1.95-6.39-2.95-9.57-3.35.99-6.72 1.94-10.04 3.01-1.08.35-1.56.18-1.87-.95-.92-3.38-1.93-6.73-2.9-10.09l.02.02s0-.01-.01-.02c-.14-.06-.32-.21-.42-.17-7.32 2.12-14.61 4.3-21.93 6.41-1.41.41-.71 1.31-.66 2.08.95 3.21 1.9 6.41 2.84 9.62-.03.96-.89.73-1.39.88-3.28 1.03-6.57 1.99-9.86 2.97h-.01c.91 3.22 1.75 6.45 2.75 9.63.45 1.41.34 2.12-1.3 2.5-2.78.67-5.49 1.66-8.26 2.38-1.35.34-1.57.93-1.15 2.2.89 2.72 1.58 5.51 2.49 8.23.46 1.34.28 1.92-1.19 2.35-14.44 4.23-28.87 8.5-43.27 12.84-1.54.46-1.93-.07-2.27-1.38-.73-2.77-1.68-5.49-2.39-8.26-.34-1.34-.92-1.57-2.17-1.16-2.5.82-5.07 1.4-7.54 2.31-1.8.65-2.67.44-3.11-1.6-.58-2.64-1.55-5.19-2.24-7.81-.31-1.21-.79-1.51-1.99-1.11-2.73.89-5.53 1.54-8.23 2.5-1.67.59-2.22.07-2.62-1.49-.68-2.7-1.61-5.34-2.32-8.03-.34-1.29-.84-1.65-2.16-1.21-2.72.91-5.52 1.58-8.23 2.52-1.44.49-1.89.1-2.29-1.29-1.85-6.51-3.75-13.01-5.77-19.47-.54-1.69-.24-2.28 1.49-2.79Z"
|
||||
class="cls-9" />
|
||||
<path
|
||||
d="m251.02 298.65-3.51-12.06.08.05c-4 1.21-8 2.41-12 3.62l.04-.08c1.41 3.19 2.12 6.61 3.1 9.94.4 1.35.87 1.77 2.31 1.3 3.31-1.06 6.67-1.92 10.02-2.86l-.05.09Z"
|
||||
style="fill:#fefffd" />
|
||||
<path
|
||||
d="M357.26 251.05c.38.7.84.95 1.7.67 3.44-1.12 6.91-2.15 10.37-3.21-.97-3.28-1.99-6.55-2.89-9.85-.32-1.18-.77-1.54-1.99-1.14-2.87.93-5.77 1.8-8.69 2.58-1.23.33-1.44.85-1.07 2.02.92 2.96 1.72 5.96 2.57 8.94M334.59 258.93c3.26-.97 6.51-2 9.79-2.88 1.33-.36 1.57-.89 1.15-2.17-1.05-3.24-1.98-6.52-2.95-9.78l-10.08 2.91c-.75.22-1.65.3-1.24 1.51 1.17 3.45 1.79 7.07 3.32 10.41"
|
||||
class="cls-4" />
|
||||
<path
|
||||
d="M372.91 260.57c-3.49.98-6.96 2.03-10.48 2.9-1.38.34-.82 1.25-.9 2.01.37.85.74 1.7.71 2.66-.16 1.38-.08 2.68 1.12 3.64 1.43 3.62 1.45 3.68 5.32 2.44 2.46-.79 6.11-.61 7.05-2.62.81-1.75-1-4.73-1.67-7.16-.36-1.3-.77-2.59-1.15-3.88"
|
||||
style="fill:#fbfbfb" />
|
||||
<path
|
||||
d="M247.5 286.59c3.43-.98 6.87-1.97 10.31-2.93.9-.25 1.35-.55 1-1.63-.97-3.03-1.88-6.07-2.71-9.14-.3-1.1-.81-1.1-1.71-.82-2.96.92-5.92 1.82-8.91 2.63-1.17.32-1.26.88-.94 1.9 1.05 3.33 2.03 6.69 3.04 10.04l-.08-.05Z"
|
||||
class="cls-3" />
|
||||
<path
|
||||
d="M235.59 290.25c-.46-3.65-1.97-7.01-2.85-10.55-.24-.96-.77-1-1.58-.75-2.97.91-5.94 1.82-8.93 2.64-1.09.3-1.4.74-1.04 1.85.92 2.88 1.8 5.78 2.57 8.7.34 1.29.95 1.36 2.06 1.01 3.26-1.04 6.54-1.99 9.82-2.98l-.04.08M251.07 298.56c.97 3.27 1.99 6.52 2.88 9.81.35 1.28.84 1.64 2.15 1.2 2.78-.93 5.6-1.73 8.43-2.51 1.09-.3 1.58-.64 1.15-1.93-.98-2.92-1.79-5.9-2.66-8.85-.2-.7-.3-1.4-1.37-1.03-3.51 1.21-7.2 1.85-10.61 3.39l.05-.09"
|
||||
class="cls-4" />
|
||||
<path
|
||||
d="M167.27 433.19c9.62-29.21 55.01-60.77 82.24-107.29 11.54-19.71 2.97-51.8-22.95-56.38-56.15-9.91-96.62 37.51-96.62 37.51s-37.46 35.45-25.85 86.54c0 0 7.93 30.62 36.95 50.52l23.64.81 2.6-11.71Z"
|
||||
class="cls-7" />
|
||||
<path
|
||||
d="M254.51 307.83c-3.13-13.15-12.37-24.66-27.22-27.28-57-10.05-98.1 38.09-98.1 38.09s-21.89 20.72-27.31 53.37c.84-39.23 28.05-64.98 28.05-64.98s40.47-47.42 96.63-37.51c18.87 3.33 28.53 21.22 27.95 38.31"
|
||||
class="cls-3" style="opacity:.4" />
|
||||
<path
|
||||
d="M164.98 432.44c1.35-6.88 4.47-13.2 8.05-18.95 3.61-5.76 7.73-11.08 12.05-16.12 8.69-10.05 17.73-19.53 26.34-29.27 8.63-9.73 16.9-19.67 24.26-30.18.93-1.31 1.84-2.63 2.72-3.97.89-1.33 1.78-2.66 2.62-4.02.86-1.35 1.72-2.7 2.52-4.07l1.23-2.05.31-.51.25-.46.49-.92c2.53-4.97 3.65-10.77 3.49-16.53-.17-5.76-1.68-11.5-4.38-16.45-2.69-4.97-6.7-9.02-11.51-11.52-2.41-1.26-5.01-2.12-7.74-2.6l-4.57-.66c-1.53-.18-3.07-.27-4.6-.41-6.14-.37-12.32-.08-18.42.85-12.21 1.84-24.01 6.43-34.88 12.65-5.41 3.16-10.64 6.7-15.56 10.63-2.46 1.96-4.86 4-7.16 6.13-1.15 1.07-2.29 2.15-3.38 3.25a74.216 74.216 0 0 0-3.09 3.27l-.21.23-.19.18c-.4.38-.99 1-1.48 1.53l-1.54 1.7a97.533 97.533 0 0 0-8.39 11.21 99.179 99.179 0 0 0-8.63 16.57c-2.31 5.77-4.09 11.75-5.18 17.83a83.369 83.369 0 0 0-1.18 18.46c.03 1.55.24 3.08.35 4.63.14 1.54.42 3.07.61 4.6.25 1.52.57 3 .85 4.5.04.18.08.41.1.46l.14.46c.1.34.21.69.33 1.06.22.71.48 1.44.74 2.16a93.879 93.879 0 0 0 8.13 16.8c3.27 5.33 7.02 10.36 11.27 14.92 4.25 4.56 7.25 8.48 12.31 12.1 0 0-1.68 8.9-3.84 7.41-11.42-7.86-21.15-17.32-28.38-29.1-3.66-5.86-6.72-12.06-9.18-18.6-.3-.82-.6-1.65-.88-2.5-.14-.42-.28-.85-.41-1.3l-.21-.72c-.1-.35-.13-.53-.17-.75-.35-1.73-.74-3.46-1.03-5.18-.24-1.72-.55-3.44-.73-5.17-.14-1.74-.39-3.46-.44-5.21-.39-6.96 0-13.97 1.16-20.85 1.17-6.87 3.11-13.59 5.7-20.03 2.6-6.43 5.81-12.59 9.55-18.39 1.87-2.91 3.87-5.72 6.01-8.45 1.06-1.37 2.18-2.7 3.32-4.02.58-.66 1.16-1.31 1.77-1.96.63-.67 1.17-1.25 1.96-2.01l-.4.42c1.29-1.47 2.41-2.63 3.65-3.88 1.21-1.22 2.45-2.4 3.7-3.57 2.51-2.32 5.1-4.53 7.76-6.66 5.31-4.26 10.97-8.1 16.87-11.55 11.84-6.8 24.89-11.92 38.63-14.01a92.636 92.636 0 0 1 20.78-.89c1.73.17 3.47.29 5.19.5l5.16.78c3.73.67 7.4 1.91 10.8 3.71 6.82 3.58 12.32 9.36 15.82 15.93 3.53 6.58 5.35 13.89 5.53 21.22.15 7.32-1.29 14.79-4.75 21.5l-.68 1.24-.34.62-.33.54-1.31 2.16c-.86 1.45-1.77 2.86-2.68 4.27-.9 1.42-1.83 2.81-2.78 4.2-.93 1.4-1.89 2.77-2.87 4.13-7.75 10.92-16.35 21.1-25.17 30.92-8.82 9.83-17.92 19.29-26.46 29-8.52 9.71-17.05 19.18-22.79 30.26l-.04.08a2.436 2.436 0 0 1-3.28 1.04 2.441 2.441 0 0 1-1.27-2.63"
|
||||
class="cls-9" />
|
||||
<g class="cls-20">
|
||||
<path
|
||||
d="M211.98 349.04c-8.63 8.62-21.18 10.05-28.04 3.19-6.86-6.86-5.43-19.41 3.2-28.03 8.62-8.62 21.18-10.05 28.03-3.2 6.86 6.86 5.43 19.41-3.2 28.04"
|
||||
class="cls-3" />
|
||||
</g>
|
||||
<g class="cls-20">
|
||||
<path
|
||||
d="M214.43 309.1c-3.66 3.66-9 4.27-11.91 1.36-2.91-2.91-2.31-8.25 1.36-11.91 3.66-3.66 9-4.27 11.91-1.36 2.91 2.91 2.31 8.25-1.36 11.91"
|
||||
class="cls-3" />
|
||||
</g>
|
||||
<g class="cls-20">
|
||||
<path
|
||||
d="M230.61 315.92c-3.74 3.75-9.19 4.37-12.17 1.39-2.98-2.98-2.36-8.43 1.39-12.17 3.74-3.74 9.19-4.37 12.17-1.39 2.98 2.98 2.36 8.43-1.39 12.17"
|
||||
class="cls-3" />
|
||||
</g>
|
||||
<g class="cls-20">
|
||||
<path
|
||||
d="M234.52 329.19c-3.03 3.03-7.45 3.54-9.86 1.12-2.41-2.41-1.91-6.83 1.12-9.86 3.03-3.03 7.45-3.54 9.86-1.12 2.41 2.41 1.91 6.83-1.12 9.86"
|
||||
class="cls-3" />
|
||||
</g>
|
||||
<path
|
||||
d="M232.2 483.14c-10.58-.05-29.68-6.12-56.76-18.06-19.9-8.77-37.07-17.65-37.24-17.74l3.84-7.41c.17.09 17.14 8.86 36.8 17.53 32.39 14.27 42.22 15.99 48.7 16.01l4.65 9.66Z"
|
||||
class="cls-9" />
|
||||
</svg>
|
||||
</div>
|
||||
<div class="right">
|
||||
<div class="content">
|
||||
<section class="general">
|
||||
<h2>If you are a member of the general public:</h2>
|
||||
|
||||
<p>The fact that you are seeing this page indicates that the website you just visited is either
|
||||
experiencing problems, or is undergoing routine maintenance.</p>
|
||||
|
||||
<p>
|
||||
If you would like to let the administrators of this website know that you've seen this page
|
||||
instead of the page you expected, you should send them e-mail.
|
||||
In general, mail sent to the name "webmaster" and directed to the website's domain should reach
|
||||
the appropriate person.
|
||||
</p>
|
||||
|
||||
<p>For example, try contacting <a
|
||||
href="mailto:webmaster@<?php echo $_SERVER['SERVER_NAME'] ?? 'example.com'; ?>">webmaster@<?php echo $_SERVER['SERVER_NAME'] ?? 'example.com'; ?></a>.
|
||||
</p>
|
||||
|
||||
<p>Learn more about FrankenPHP at the <a href="https://frankenphp.dev/">official website</a>.</p>
|
||||
</section>
|
||||
|
||||
<section class="administrator">
|
||||
<h2>If you are the website administrator:</h2>
|
||||
|
||||
<p>Your server is running and serving requests using FrankenPHP</p>
|
||||
|
||||
<p>To replace this page, deploy your application files to <code><?php echo getcwd(); ?></code>.</p>
|
||||
|
||||
<p>Configuration is handled in your <code>Caddyfile</code>.</p>
|
||||
|
||||
<div class="runtime-info">
|
||||
<strong>Served by PHP SAPI: </strong> <?php echo php_sapi_name(); ?><br />
|
||||
</div>
|
||||
|
||||
</section>
|
||||
</div>
|
||||
<footer class="footer">
|
||||
<p><a href="https://frankenphp.dev">FrankenPHP</a> is a free and open-source web server for PHP built on top
|
||||
of <a href="https://caddyserver.com">Caddy</a>.</p>
|
||||
<div class="logos">
|
||||
<a href="https://frankenphp.dev/"><img src="assets/frankenphp.svg" height="50" width="166" alt="Powered by FrankenPHP" /></a>
|
||||
<a href="https://caddyserver.com/"><img src="assets/caddy.png" height="50" width="166" alt="Powered by Caddy" /></a>
|
||||
<a href="https://frankenphp.dev/"><svg xmlns="http://www.w3.org/2000/svg" id="a"
|
||||
viewBox="0 0 699.37 92.29">
|
||||
<defs fill="#000000">
|
||||
<style>
|
||||
.b {
|
||||
fill: #390075;
|
||||
}
|
||||
|
||||
.c {
|
||||
fill: #b3d133;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<path class="c"
|
||||
d="M22.65,38.71h20.32c3.02,0,5.65,1.1,7.89,3.3,2.24,2.2,3.36,4.85,3.36,7.96s-1.12,5.67-3.36,7.96c-2.24,2.29-4.96,3.43-8.15,3.43H22.65v19.8c0,3.45-1.12,6.17-3.37,8.15-2.24,1.99-4.88,2.98-7.89,2.98s-5.78-.99-8.02-2.98c-2.24-1.98-3.37-4.7-3.37-8.15V20.2c0-3.45,.86-6.64,2.59-9.58,1.72-2.93,4.03-5.26,6.92-6.99,2.89-1.72,6.06-2.59,9.51-2.59h28.86c3.19,0,5.89,1.1,8.09,3.3,2.2,2.2,3.3,4.81,3.3,7.83s-1.14,5.8-3.43,8.09c-2.29,2.29-4.94,3.43-7.96,3.43H22.65v15.01Z"
|
||||
fill="#000000" />
|
||||
<path class="c"
|
||||
d="M118.29,54.76c3.88,2.42,6.66,5.18,8.35,8.28,1.68,3.11,2.52,6.77,2.52,11v6.6c0,3.11-1.08,5.76-3.24,7.96-2.16,2.2-4.75,3.3-7.77,3.3s-5.74-1.12-7.89-3.36c-2.16-2.24-3.24-4.87-3.24-7.89v-6.34l-22.13-26.92v33.26c0,3.11-1.08,5.76-3.24,7.96-2.16,2.2-4.79,3.3-7.89,3.3s-5.89-1.1-8.09-3.3c-2.2-2.2-3.3-4.85-3.3-7.96V12.44c0-3.19,1.1-5.89,3.3-8.09s4.9-3.3,8.09-3.3h25.24c5.09,0,9.62,1.86,13.59,5.57l11,10.61c4.05,4.06,6.08,8.72,6.08,13.98v5.05c0,8.54-3.8,14.71-11.39,18.51Zm-33.39-9.32h22.13V23.7h-22.13v21.74Z"
|
||||
fill="#000000" />
|
||||
<path class="c"
|
||||
d="M270.74,88.54c-2.16,2.24-4.83,3.36-8.02,3.36s-6-1.12-8.15-3.36c-2.16-2.24-3.24-4.96-3.24-8.15V23.57h-20.84v57.07c0,3.19-1.12,5.87-3.37,8.02-2.24,2.16-4.96,3.24-8.15,3.24s-5.76-1.1-7.96-3.3c-2.2-2.2-3.3-4.85-3.3-7.96V12.05c0-3.19,1.12-5.89,3.37-8.09,2.24-2.2,4.87-3.3,7.89-3.3,3.19,0,5.91,1.1,8.15,3.3,2.24,2.2,3.37,4.9,3.37,8.09v3.75c0,.43,.08,.65,.26,.65s.26-.08,.26-.26c1.55-5,4.12-8.8,7.7-11.39,3.58-2.59,7.87-3.88,12.88-3.88,6.47,0,11.82,1.92,16.05,5.76,4.23,3.84,6.34,8.99,6.34,15.47v58.24c0,3.19-1.08,5.91-3.24,8.15Z"
|
||||
fill="#000000" />
|
||||
<path class="c"
|
||||
d="M347.1,80.64c0,3.11-1.14,5.78-3.43,8.02-2.29,2.24-4.98,3.37-8.09,3.37s-5.8-1.12-8.09-3.37c-2.29-2.24-3.43-4.92-3.43-8.02v-24.72l-22.13-.26v24.98c0,3.19-1.1,5.89-3.3,8.09s-4.9,3.3-8.09,3.3-5.89-1.1-8.09-3.3-3.3-4.9-3.3-8.09V11.66c0-3.02,1.1-5.63,3.3-7.83,2.2-2.2,4.9-3.3,8.09-3.3s5.89,1.08,8.09,3.24c2.2,2.16,3.3,4.79,3.3,7.89V53.72l22.13-27.31V11.66c0-3.02,1.14-5.63,3.43-7.83,2.29-2.2,4.94-3.3,7.96-3.3s5.63,1.1,7.83,3.3c2.2,2.2,3.3,4.81,3.3,7.83v15.14c0,4.32-.84,8.05-2.52,11.19-1.68,3.15-4.51,5.98-8.48,8.48,7.68,3.62,11.52,9.79,11.52,18.51v15.66Z"
|
||||
fill="#000000" />
|
||||
<path class="c"
|
||||
d="M374.66,35.6h25.24c3.11,0,5.76,1.1,7.96,3.3,2.2,2.2,3.3,4.9,3.3,8.09,0,3.02-1.12,5.65-3.37,7.89-2.24,2.24-4.88,3.36-7.89,3.36h-25.24v10.87h27.44c3.11,0,5.76,1.1,7.96,3.3,2.2,2.2,3.3,4.9,3.3,8.09,0,3.02-1.1,5.61-3.3,7.77-2.2,2.16-4.85,3.32-7.96,3.49h-31.19c-3.37,0-6.49-.86-9.38-2.59-2.89-1.73-5.2-4.05-6.92-6.99-1.73-2.93-2.59-6.12-2.59-9.58v-6.99c0-5.26,.73-9.55,2.2-12.88,1.47-3.32,4.49-5.76,9.06-7.31-4.32-1.47-7.27-3.77-8.87-6.92-1.6-3.15-2.39-7.23-2.39-12.23v-6.08c0-3.45,.86-6.64,2.59-9.58,1.73-2.93,4.03-5.26,6.92-6.99,2.89-1.72,6.02-2.59,9.38-2.59h31.19c3.11,0,5.76,1.1,7.96,3.3s3.3,4.81,3.3,7.83-1.12,5.8-3.37,8.09c-2.24,2.29-4.88,3.43-7.89,3.43h-27.44v11.91Z"
|
||||
fill="#000000" />
|
||||
<path class="c"
|
||||
d="M480.4,88.54c-2.16,2.24-4.83,3.36-8.02,3.36s-6-1.12-8.15-3.36c-2.16-2.24-3.24-4.96-3.24-8.15V23.57h-20.84v57.07c0,3.19-1.12,5.87-3.37,8.02-2.24,2.16-4.96,3.24-8.15,3.24s-5.76-1.1-7.96-3.3c-2.2-2.2-3.3-4.85-3.3-7.96V12.05c0-3.19,1.12-5.89,3.37-8.09,2.24-2.2,4.87-3.3,7.89-3.3,3.19,0,5.91,1.1,8.15,3.3,2.24,2.2,3.37,4.9,3.37,8.09v3.75c0,.43,.08,.65,.26,.65s.26-.08,.26-.26c1.55-5,4.12-8.8,7.7-11.39,3.58-2.59,7.87-3.88,12.88-3.88,6.47,0,11.82,1.92,16.05,5.76,4.23,3.84,6.34,8.99,6.34,15.47v58.24c0,3.19-1.08,5.91-3.24,8.15Z"
|
||||
fill="#000000" />
|
||||
<path class="b"
|
||||
d="M511.07,80.25c0,3.19-1.06,5.91-3.17,8.15-2.12,2.24-4.72,3.37-7.83,3.37s-5.78-1.12-8.02-3.37c-2.24-2.24-3.37-4.96-3.37-8.15V20.07c0-3.45,.86-6.64,2.59-9.58,1.73-2.93,4.05-5.26,6.99-6.99,2.93-1.72,6.12-2.59,9.58-2.59h17.21c5.09,0,9.53,1.77,13.33,5.31l12.42,12.42c1.81,1.73,3.17,3.97,4.08,6.73,.91,2.76,1.36,5.74,1.36,8.93,0,3.71-.58,7.29-1.75,10.74-1.16,3.45-2.78,6.17-4.85,8.15l-11.26,10.74c-3.62,3.62-8.07,5.44-13.33,5.44h-13.98v10.87Zm21.74-56.69l-21.48-.26v23.42h21.48V23.57Z"
|
||||
fill="#000000" />
|
||||
<path class="b"
|
||||
d="M560.11,11.92c0-3.45,1.12-6.17,3.37-8.15,2.24-1.98,4.92-2.98,8.02-2.98s5.76,.97,7.96,2.91c2.2,1.94,3.3,4.64,3.3,8.09v28.47h21.35V11.92c0-3.45,1.14-6.17,3.43-8.15,2.29-1.98,4.98-2.98,8.09-2.98s5.76,.97,7.96,2.91,3.3,4.64,3.3,8.09V81.16c0,3.45-1.12,6.17-3.37,8.15-2.24,1.99-4.92,2.98-8.02,2.98s-5.78-.99-8.02-2.98c-2.24-1.98-3.37-4.7-3.37-8.15V43.5l-21.35,19.28v18.38c0,3.45-1.12,6.17-3.36,8.15-2.24,1.99-4.88,2.98-7.89,2.98s-5.78-.99-8.02-2.98c-2.24-1.98-3.37-4.7-3.37-8.15V11.92Z"
|
||||
fill="#000000" />
|
||||
<path class="b"
|
||||
d="M654.2,80.25c0,3.19-1.06,5.91-3.17,8.15-2.12,2.24-4.72,3.37-7.83,3.37s-5.78-1.12-8.02-3.37c-2.24-2.24-3.37-4.96-3.37-8.15V20.07c0-3.45,.86-6.64,2.59-9.58,1.73-2.93,4.05-5.26,6.99-6.99,2.93-1.72,6.12-2.59,9.58-2.59h17.21c5.09,0,9.53,1.77,13.33,5.31l12.42,12.42c1.81,1.73,3.17,3.97,4.08,6.73,.91,2.76,1.36,5.74,1.36,8.93,0,3.71-.58,7.29-1.75,10.74-1.16,3.45-2.78,6.17-4.85,8.15l-11.26,10.74c-3.62,3.62-8.07,5.44-13.33,5.44h-13.98v10.87Zm21.74-56.69l-21.48-.26v23.42h21.48V23.57Z"
|
||||
fill="#000000" />
|
||||
<g>
|
||||
<path class="c"
|
||||
d="M142.76,32.66v-3.51c0-1.32,1.04-2.4,2.32-2.4,1.29,0,2.33,1.07,2.33,2.39v3.51l7.92-.02v-3.51c0-1.32,1.04-2.4,2.32-2.4,1.29,0,2.33,1.07,2.33,2.39v3.51h6.64v-3.53c0-1.32,1.03-2.4,2.32-2.4s2.33,1.07,2.33,2.39v3.51h6.83v-3.53c0-1.32,1.03-2.4,2.32-2.4,1.29,0,2.33,1.07,2.33,2.39v3.51l7.69-.02v-3.51c0-1.32,1.03-2.4,2.32-2.4s2.33,1.07,2.33,2.39v3.51h6.89v-.85c-.17-3.02-.89-5.52-2.14-7.51-1.25-1.98-3.22-4.1-5.89-6.34l-16.95-13.85c-3.19-2.67-6.13-4.01-8.8-4.01s-5.61,1.34-9.06,4.01l-16.57,13.85c-2.68,2.33-4.66,4.49-5.95,6.47-1.29,1.99-2.07,4.44-2.33,7.38v.97l8.46-.02Z"
|
||||
fill="#000000" />
|
||||
<path class="c"
|
||||
d="M195.11,37.2v3.5c0,1.32-1.03,2.4-2.32,2.4s-2.33-1.07-2.33-2.39v-3.5l-7.69,.02v3.5c0,1.32-1.03,2.4-2.32,2.4s-2.33-1.07-2.33-2.39v-3.5h-6.83v3.51c0,1.32-1.04,2.4-2.32,2.4-1.29,0-2.33-1.07-2.33-2.39v-3.5h-6.64v3.51c0,1.32-1.03,2.4-2.32,2.4-1.29,0-2.33-1.07-2.33-2.39v-3.5l-7.92,.02v3.5c0,1.32-1.03,2.4-2.32,2.4-1.29,0-2.33-1.07-2.33-2.39v-3.5l-8.47,.02v43.43c0,3.11,1.12,5.74,3.37,7.89,2.24,2.16,4.92,3.24,8.02,3.24s5.76-1.08,7.96-3.24c2.2-2.16,3.3-4.79,3.3-7.89v-31.84l22.52,20.84v11c0,3.11,1.1,5.74,3.3,7.89,2.2,2.16,4.9,3.24,8.09,3.24s5.74-1.08,7.9-3.24,3.24-4.79,3.24-7.89V37.19h-6.88Z"
|
||||
fill="#000000" />
|
||||
</g>
|
||||
</svg></a>
|
||||
<a href="https://caddyserver.com/"><svg width="100%" height="100%" viewBox="0 0 379 114"
|
||||
version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xml:space="preserve" xmlns:serif="http://www.serif.com/"
|
||||
style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;">
|
||||
<g transform="matrix(1,0,0,1,-35.5985,-67.948)">
|
||||
<g transform="matrix(1.16548,0,0,1.10195,-124,-68.27)">
|
||||
<g id="Light-Logo" serif:id="Light Logo"
|
||||
transform="matrix(0.858013,0,0,0.907485,-3243.42,-1469.17)">
|
||||
<g id="Logo" transform="matrix(1,0,0,1,21.4759,36.7359)">
|
||||
<g id="Icon">
|
||||
<g>
|
||||
<g
|
||||
transform="matrix(-0.191794,-0.715786,0.715786,-0.191794,4329.14,4673.64)">
|
||||
<path
|
||||
d="M3901.56,610.734C3893.53,610.261 3886.06,608.1 3879.2,604.877C3872.24,601.608 3866.04,597.093 3860.8,591.633C3858.71,589.457 3856.76,587.149 3854.97,584.709C3853.2,582.281 3851.57,579.733 3850.13,577.066C3845.89,569.224 3843.21,560.381 3842.89,550.868C3842.57,543.321 3843.64,536.055 3845.94,529.307C3848.37,522.203 3852.08,515.696 3856.83,510.049L3855.79,509.095C3850.39,514.54 3846.02,520.981 3842.9,528.125C3839.84,535.125 3838.03,542.781 3837.68,550.868C3837.34,561.391 3839.51,571.425 3843.79,580.306C3845.27,583.38 3847.03,586.304 3849.01,589.049C3851.01,591.806 3853.24,594.39 3855.69,596.742C3861.75,602.568 3869,607.19 3877.03,610.1C3884.66,612.867 3892.96,614.059 3901.56,613.552L3901.56,610.734Z"
|
||||
style="fill:rgb(0,144,221);" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(-0.191794,-0.715786,0.715786,-0.191794,4329.14,4673.64)">
|
||||
<path
|
||||
d="M3875.69,496.573C3879.62,494.538 3883.8,492.897 3888.2,491.786C3892.49,490.704 3896.96,490.124 3901.56,490.032C3903.82,490.13 3906.03,490.332 3908.21,490.688C3917.13,492.147 3925.19,495.814 3932.31,500.683C3936.13,503.294 3939.59,506.335 3942.81,509.619C3947.09,513.98 3950.89,518.816 3953.85,524.232C3958.2,532.197 3960.96,541.186 3961.32,550.868C3961.61,558.748 3960.46,566.345 3957.88,573.322C3956.09,578.169 3953.7,582.753 3950.66,586.838C3947.22,591.461 3942.96,595.427 3938.27,598.769C3933.66,602.055 3928.53,604.619 3923.09,606.478C3922.37,606.721 3921.6,606.805 3920.93,607.167C3920.42,607.448 3920.14,607.854 3919.69,608.224L3920.37,610.389C3920.98,610.432 3921.47,610.573 3922.07,610.474C3922.86,610.344 3923.55,609.883 3924.28,609.566C3931.99,606.216 3938.82,601.355 3944.57,595.428C3947.02,592.903 3949.25,590.174 3951.31,587.319C3953.59,584.168 3955.66,580.853 3957.43,577.348C3961.47,569.34 3964.01,560.422 3964.36,550.868C3964.74,540.511 3962.66,530.628 3958.48,521.868C3955.57,515.775 3951.72,510.163 3946.95,505.478C3943.37,501.962 3939.26,498.99 3934.84,496.562C3926.88,492.192 3917.87,489.76 3908.37,489.229C3906.12,489.104 3903.86,489.054 3901.56,489.154C3896.87,489.06 3892.3,489.519 3887.89,490.397C3883.3,491.309 3878.89,492.683 3874.71,494.525L3875.69,496.573Z"
|
||||
style="fill:rgb(0,144,221);" />
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g
|
||||
transform="matrix(-3.37109,-0.514565,0.514565,-3.37109,4078.07,1806.88)">
|
||||
<path
|
||||
d="M22,12C22,10.903 21.097,10 20,10C19.421,10 18.897,10.251 18.53,10.649C18.202,11.006 18,11.481 18,12C18,13.097 18.903,14 20,14C21.097,14 22,13.097 22,12Z"
|
||||
style="fill:none;fill-rule:nonzero;stroke:rgb(0,144,221);stroke-width:1.05px;" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(-5.33921,-5.26159,-3.12106,-6.96393,4073.87,1861.55)">
|
||||
<path
|
||||
d="M10.315,5.333C10.315,5.333 9.748,5.921 9.03,6.673C7.768,7.995 6.054,9.805 6.054,9.805L6.237,9.86C6.237,9.86 8.045,8.077 9.36,6.771C10.107,6.028 10.689,5.444 10.689,5.444L10.315,5.333Z"
|
||||
style="fill:rgb(0,144,221);" />
|
||||
</g>
|
||||
</g>
|
||||
<g id="Padlock" transform="matrix(3.11426,0,0,3.11426,3938.31,1737.25)">
|
||||
<g>
|
||||
<path
|
||||
d="M9.876,21L18.162,21C18.625,21 19,20.625 19,20.162L19,11.838C19,11.375 18.625,11 18.162,11L5.838,11C5.375,11 5,11.375 5,11.838L5,16.758"
|
||||
style="fill:none;stroke:rgb(34,182,56);stroke-width:1.89px;stroke-linecap:butt;stroke-linejoin:miter;" />
|
||||
<path
|
||||
d="M8,11L8,7C8,4.806 9.806,3 12,3C14.194,3 16,4.806 16,7L16,11"
|
||||
style="fill:none;fill-rule:nonzero;stroke:rgb(34,182,56);stroke-width:1.89px;" />
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g
|
||||
transform="matrix(5.30977,0.697415,-0.697415,5.30977,3852.72,1727.97)">
|
||||
<path
|
||||
d="M22,12C22,11.659 21.913,11.337 21.76,11.055C21.421,10.429 20.756,10 20,10C18.903,10 18,10.903 18,12C18,13.097 18.903,14 20,14C21.097,14 22,13.097 22,12Z"
|
||||
style="fill:none;fill-rule:nonzero;stroke:rgb(0,144,221);stroke-width:0.98px;" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(4.93114,2.49604,1.11018,5.44847,3921.41,1726.72)">
|
||||
<path
|
||||
d="M8.902,6.77C8.902,6.77 7.235,8.253 6.027,9.366C5.343,9.996 4.819,10.502 4.819,10.502L5.52,11.164C5.52,11.164 6.021,10.637 6.646,9.951C7.749,8.739 9.219,7.068 9.219,7.068L8.902,6.77Z"
|
||||
style="fill:rgb(0,144,221);" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g id="Wordmark" transform="matrix(1.54159,0,0,2.8744,2710.6,709.804)">
|
||||
<g id="y" transform="matrix(0.50291,0,0,0.281607,905.533,304.987)">
|
||||
<path
|
||||
d="M192.152,286.875L202.629,268.64C187.804,270.106 183.397,265.779 180.143,263.391C176.888,261.004 174.362,257.99 172.563,254.347C170.765,250.705 169.866,246.691 169.866,242.305L169.866,208.107L183.21,208.107L183.21,242.213C183.21,245.188 183.896,247.822 185.268,250.116C186.64,252.41 188.465,254.197 190.743,255.475C193.022,256.754 195.501,257.393 198.182,257.393C200.894,257.393 203.393,256.75 205.68,255.463C207.966,254.177 209.799,252.391 211.178,250.105C212.558,247.818 213.248,245.188 213.248,242.213L213.248,208.107L226.545,208.107L226.545,242.305C226.545,246.707 225.378,258.46 218.079,268.64C215.735,271.909 207.835,286.875 207.835,286.875L192.152,286.875Z"
|
||||
style="fill:#2e2e2e;fill-rule:nonzero;" />
|
||||
</g>
|
||||
<g id="add" transform="matrix(0.525075,0,0,0.281607,801.871,304.987)">
|
||||
<g transform="matrix(116.242,0,0,116.242,161.846,267.39)">
|
||||
<path
|
||||
d="M0.276,0.012C0.227,0.012 0.186,0 0.15,-0.024C0.115,-0.048 0.088,-0.08 0.069,-0.12C0.05,-0.161 0.04,-0.205 0.04,-0.254C0.04,-0.305 0.051,-0.35 0.072,-0.39C0.094,-0.431 0.125,-0.463 0.165,-0.487C0.205,-0.51 0.254,-0.522 0.31,-0.522C0.366,-0.522 0.413,-0.51 0.452,-0.486C0.491,-0.463 0.521,-0.431 0.542,-0.39C0.562,-0.35 0.573,-0.305 0.573,-0.256L0.573,-0L0.458,-0L0.458,-0.095L0.456,-0.095C0.446,-0.076 0.433,-0.058 0.417,-0.042C0.401,-0.026 0.381,-0.013 0.358,-0.003C0.335,0.007 0.307,0.012 0.276,0.012ZM0.307,-0.086C0.337,-0.086 0.363,-0.093 0.386,-0.108C0.408,-0.123 0.426,-0.144 0.438,-0.17C0.45,-0.195 0.456,-0.224 0.456,-0.256C0.456,-0.288 0.45,-0.317 0.438,-0.342C0.426,-0.367 0.409,-0.387 0.387,-0.402C0.365,-0.417 0.338,-0.424 0.308,-0.424C0.276,-0.424 0.249,-0.417 0.226,-0.402C0.204,-0.387 0.186,-0.366 0.174,-0.341C0.162,-0.315 0.156,-0.287 0.156,-0.255C0.156,-0.224 0.162,-0.195 0.174,-0.169C0.186,-0.144 0.203,-0.123 0.226,-0.108C0.248,-0.093 0.275,-0.086 0.307,-0.086Z"
|
||||
style="fill:#2e2e2e;fill-rule:nonzero;" />
|
||||
</g>
|
||||
<g transform="matrix(116.242,0,0,116.242,226.592,267.39)">
|
||||
<path
|
||||
d="M0.306,0.012C0.265,0.012 0.229,0.006 0.196,-0.008C0.163,-0.021 0.135,-0.039 0.112,-0.064C0.089,-0.088 0.071,-0.117 0.059,-0.151C0.046,-0.185 0.04,-0.222 0.04,-0.263C0.04,-0.315 0.051,-0.36 0.072,-0.399C0.093,-0.437 0.122,-0.468 0.159,-0.489C0.196,-0.511 0.239,-0.522 0.287,-0.522C0.311,-0.522 0.333,-0.518 0.355,-0.511C0.377,-0.504 0.396,-0.493 0.413,-0.48C0.431,-0.466 0.445,-0.451 0.455,-0.433L0.456,-0.433L0.456,-0.73L0.571,-0.73L0.571,-0.261C0.571,-0.205 0.56,-0.156 0.537,-0.115C0.515,-0.074 0.484,-0.043 0.444,-0.021C0.405,0.001 0.358,0.012 0.306,0.012ZM0.306,-0.086C0.335,-0.086 0.361,-0.093 0.384,-0.107C0.406,-0.122 0.423,-0.141 0.436,-0.167C0.448,-0.192 0.455,-0.221 0.455,-0.255C0.455,-0.288 0.448,-0.317 0.436,-0.343C0.423,-0.368 0.406,-0.388 0.383,-0.402C0.361,-0.417 0.335,-0.424 0.305,-0.424C0.276,-0.424 0.251,-0.417 0.228,-0.402C0.206,-0.387 0.188,-0.368 0.175,-0.342C0.163,-0.317 0.156,-0.288 0.156,-0.255C0.156,-0.222 0.163,-0.193 0.175,-0.167C0.188,-0.142 0.206,-0.122 0.229,-0.108C0.251,-0.093 0.277,-0.086 0.306,-0.086Z"
|
||||
style="fill:#2e2e2e;fill-rule:nonzero;" />
|
||||
</g>
|
||||
<g transform="matrix(116.242,0,0,116.242,290.293,267.39)">
|
||||
<path
|
||||
d="M0.306,0.012C0.265,0.012 0.229,0.006 0.196,-0.008C0.163,-0.021 0.135,-0.039 0.112,-0.064C0.089,-0.088 0.071,-0.117 0.059,-0.151C0.046,-0.185 0.04,-0.222 0.04,-0.263C0.04,-0.315 0.051,-0.36 0.072,-0.399C0.093,-0.437 0.122,-0.468 0.159,-0.489C0.196,-0.511 0.239,-0.522 0.287,-0.522C0.311,-0.522 0.333,-0.518 0.355,-0.511C0.377,-0.504 0.396,-0.493 0.413,-0.48C0.431,-0.466 0.445,-0.451 0.455,-0.433L0.456,-0.433L0.456,-0.73L0.571,-0.73L0.571,-0.261C0.571,-0.205 0.56,-0.156 0.537,-0.115C0.515,-0.074 0.484,-0.043 0.444,-0.021C0.405,0.001 0.358,0.012 0.306,0.012ZM0.306,-0.086C0.335,-0.086 0.361,-0.093 0.384,-0.107C0.406,-0.122 0.423,-0.141 0.436,-0.167C0.448,-0.192 0.455,-0.221 0.455,-0.255C0.455,-0.288 0.448,-0.317 0.436,-0.343C0.423,-0.368 0.406,-0.388 0.383,-0.402C0.361,-0.417 0.335,-0.424 0.305,-0.424C0.276,-0.424 0.251,-0.417 0.228,-0.402C0.206,-0.387 0.188,-0.368 0.175,-0.342C0.163,-0.317 0.156,-0.288 0.156,-0.255C0.156,-0.222 0.163,-0.193 0.175,-0.167C0.188,-0.142 0.206,-0.122 0.229,-0.108C0.251,-0.093 0.277,-0.086 0.306,-0.086Z"
|
||||
style="fill:#2e2e2e;fill-rule:nonzero;" />
|
||||
</g>
|
||||
</g>
|
||||
<g id="c"
|
||||
transform="matrix(-0.0716462,0.31304,-0.583685,-0.0384251,1489.76,-444.051)">
|
||||
<path
|
||||
d="M2668.11,700.4C2666.79,703.699 2666.12,707.216 2666.12,710.766C2666.12,726.268 2678.71,738.854 2694.21,738.854C2709.71,738.854 2722.3,726.268 2722.3,710.766C2722.3,704.111 2719.93,697.672 2715.63,692.597L2707.63,699.378C2710.33,702.559 2711.57,706.602 2711.81,710.766C2712.2,717.38 2706.61,724.52 2697.27,726.637C2683.9,728.581 2676.61,720.482 2676.61,710.766C2676.61,708.541 2677.03,706.336 2677.85,704.269L2668.11,700.4Z"
|
||||
style="fill:#2e2e2e;" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g id="R" transform="matrix(0.497016,0,0,0.497016,2390.38,823.152)">
|
||||
<g transform="matrix(1,0,0,1,-0.10786,0.450801)">
|
||||
<g transform="matrix(12.1247,0,0,12.1247,3862.61,1929.9)">
|
||||
<path
|
||||
d="M0.073,-0L0.073,-0.7L0.383,-0.7C0.428,-0.7 0.469,-0.69 0.506,-0.67C0.543,-0.651 0.572,-0.623 0.594,-0.588C0.616,-0.553 0.627,-0.512 0.627,-0.465C0.627,-0.418 0.615,-0.377 0.592,-0.342C0.569,-0.306 0.539,-0.279 0.501,-0.259L0.57,-0.128C0.574,-0.12 0.579,-0.115 0.584,-0.111C0.59,-0.107 0.596,-0.106 0.605,-0.106L0.664,-0.106L0.664,-0L0.587,-0C0.56,-0 0.535,-0.007 0.514,-0.02C0.493,-0.034 0.476,-0.052 0.463,-0.075L0.381,-0.232C0.375,-0.231 0.368,-0.231 0.361,-0.231C0.354,-0.231 0.347,-0.231 0.34,-0.231L0.192,-0.231L0.192,-0L0.073,-0ZM0.192,-0.336L0.368,-0.336C0.394,-0.336 0.417,-0.341 0.438,-0.351C0.459,-0.361 0.476,-0.376 0.489,-0.396C0.501,-0.415 0.507,-0.438 0.507,-0.465C0.507,-0.492 0.501,-0.516 0.488,-0.535C0.475,-0.554 0.459,-0.569 0.438,-0.579C0.417,-0.59 0.394,-0.595 0.369,-0.595L0.192,-0.595L0.192,-0.336Z"
|
||||
style="fill:#2e2e2e;fill-rule:nonzero;" />
|
||||
</g>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,1,0.278569,0.101881)">
|
||||
<circle cx="3866.43" cy="1926.14" r="8.923"
|
||||
style="fill:none;stroke:#2e2e2e;stroke-width:2px;stroke-linecap:butt;stroke-linejoin:miter;" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
</section>
|
||||
</footer>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="footer">
|
||||
<p><a href="https://frankenphp.dev">FrankenPHP</a> is an open-source web server for PHP built on top of <a href="https://caddyserver.com">Caddy</a>.</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
</html>
|
||||
|
||||
@@ -13,8 +13,8 @@ import (
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/dunglas/frankenphp/internal/memory"
|
||||
"github.com/dunglas/frankenphp/internal/phpheaders"
|
||||
"frankenphp.dev/internal/memory"
|
||||
"frankenphp.dev/internal/phpheaders"
|
||||
)
|
||||
|
||||
// represents the main PHP thread
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/dunglas/frankenphp/internal/phpheaders"
|
||||
"frankenphp.dev/internal/phpheaders"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/dunglas/frankenphp/internal/fastabs"
|
||||
"frankenphp.dev/internal/fastabs"
|
||||
)
|
||||
|
||||
// RequestOption instances allow to configure a FrankenPHP Request.
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/dunglas/frankenphp/internal/cpu"
|
||||
"frankenphp.dev/internal/cpu"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
11
testdata/only-headers.php
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__.'/_executor.php';
|
||||
|
||||
return function () {
|
||||
header('Content-Type: application/json');
|
||||
header('HTTP/1.1 204 No Content', true, 204);
|
||||
|
||||
echo '{"status": "test"}';
|
||||
flush();
|
||||
};
|
||||
@@ -8,8 +8,8 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/dunglas/frankenphp/internal/fastabs"
|
||||
"github.com/dunglas/frankenphp/internal/watcher"
|
||||
"frankenphp.dev/internal/fastabs"
|
||||
"frankenphp.dev/internal/watcher"
|
||||
)
|
||||
|
||||
// represents a worker script and can have many threads assigned to it
|
||||
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/dunglas/frankenphp"
|
||||
"frankenphp.dev"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"go.uber.org/zap/exp/zapslog"
|
||||
"go.uber.org/zap/zapcore"
|
||||
|
||||