mirror of
https://github.com/php/frankenphp.git
synced 2026-03-24 00:52:11 +01:00
ci: add Super-Linter (#323)
This commit is contained in:
1
.github/FUNDING.yml
vendored
1
.github/FUNDING.yml
vendored
@@ -1 +0,0 @@
|
||||
github: dunglas
|
||||
@@ -1,3 +1,4 @@
|
||||
---
|
||||
name: Build Docker images
|
||||
on:
|
||||
pull_request:
|
||||
@@ -31,10 +32,12 @@ jobs:
|
||||
name: Create variants matrix
|
||||
id: matrix
|
||||
run: |
|
||||
METADATA=$(docker buildx bake --print | jq -c)
|
||||
echo "metadata=$METADATA" >> "$GITHUB_OUTPUT"
|
||||
echo "variants=$(jq -c '.group.default.targets|map(sub("runner-|builder-"; ""))|unique' <<< $METADATA)" >> "$GITHUB_OUTPUT"
|
||||
echo "platforms=$(jq -c 'first(.target[]) | .platforms' <<< $METADATA)" >> "$GITHUB_OUTPUT"
|
||||
METADATA="$(docker buildx bake --print | jq -c)"
|
||||
{
|
||||
echo metadata="$METADATA"
|
||||
echo variants="$(jq -c '.group.default.targets|map(sub("runner-|builder-"; ""))|unique' <<< "$METADATA")"
|
||||
echo platforms="$(jq -c 'first(.target[]) | .platforms' <<< "$METADATA")"
|
||||
} >> "$GITHUB_OUTPUT"
|
||||
env:
|
||||
LATEST: '1' # TODO: unset this variable when releasing the first stable version
|
||||
SHA: ${{github.sha}}
|
||||
@@ -107,10 +110,10 @@ jobs:
|
||||
run: |
|
||||
mkdir -p /tmp/metadata/builder /tmp/metadata/runner
|
||||
|
||||
builderDigest=$(jq -r '."builder-${{matrix.variant}}"."containerimage.digest"' <<< $METADATA)
|
||||
builderDigest="$(jq -r '."builder-${{matrix.variant}}"."containerimage.digest"' <<< "$METADATA")"
|
||||
touch "/tmp/metadata/builder/${builderDigest#sha256:}"
|
||||
|
||||
runnerDigest=$(jq -r '."runner-${{matrix.variant}}"."containerimage.digest"' <<< $METADATA)
|
||||
runnerDigest="$(jq -r '."runner-${{matrix.variant}}"."containerimage.digest"' <<< "$METADATA")"
|
||||
touch "/tmp/metadata/runner/${runnerDigest#sha256:}"
|
||||
env:
|
||||
METADATA: ${{steps.build.outputs.metadata}}
|
||||
@@ -138,7 +141,7 @@ jobs:
|
||||
continue-on-error: ${{fromJson(needs.prepare.outputs.push)}}
|
||||
run: |
|
||||
docker run --platform=${{matrix.platform}} --rm \
|
||||
$(jq -r '."builder-${{matrix.variant}}"."containerimage.config.digest"' <<< $METADATA) \
|
||||
"$(jq -r '."builder-${{matrix.variant}}"."containerimage.config.digest"' <<< "$METADATA")" \
|
||||
sh -c 'go test ${{matrix.race}} -v ./... && cd caddy && go test ${{matrix.race}} -v ./...'
|
||||
env:
|
||||
METADATA: ${{steps.build.outputs.metadata}}
|
||||
@@ -176,13 +179,12 @@ jobs:
|
||||
name: Create manifest list and push
|
||||
working-directory: /tmp/metadata
|
||||
run: |
|
||||
docker buildx imagetools create $(jq -cr '.target."${{matrix.target}}-${{matrix.variant}}".tags | map("-t " + .) | join(" ")' <<< $METADATA) \
|
||||
$(printf 'dunglas/frankenphp@sha256:%s ' *)
|
||||
docker buildx imagetools create "$(jq -cr '.target."${{matrix.target}}-${{matrix.variant}}".tags | map("-t " + .) | join(" ")' <<< "$METADATA")" \
|
||||
"$(printf 'dunglas/frankenphp@sha256:%s ' *)"
|
||||
env:
|
||||
METADATA: ${{needs.prepare.outputs.metadata}}
|
||||
-
|
||||
name: Inspect image
|
||||
run: |
|
||||
docker buildx imagetools inspect $(jq -cr '.target."${{matrix.target}}-${{matrix.variant}}".tags | first' <<< $METADATA)
|
||||
run: docker buildx imagetools inspect "$(jq -cr '.target."${{matrix.target}}-${{matrix.variant}}".tags | first' <<< "$METADATA")"
|
||||
env:
|
||||
METADATA: ${{needs.prepare.outputs.metadata}}
|
||||
43
.github/workflows/lint.yaml
vendored
Normal file
43
.github/workflows/lint.yaml
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
---
|
||||
name: Lint Code Base
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Lint Code Base
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
packages: read
|
||||
statuses: write
|
||||
|
||||
steps:
|
||||
-
|
||||
name: Checkout Code
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
-
|
||||
name: Lint Code Base
|
||||
uses: super-linter/super-linter@v5
|
||||
env:
|
||||
VALIDATE_ALL_CODEBASE: true
|
||||
DEFAULT_BRANCH: main
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
LINTER_RULES_PATH: /
|
||||
FILTER_REGEX_EXCLUDE: '.*C-Thread-Pool/.*'
|
||||
MARKDOWN_CONFIG_FILE: .markdown-lint.yaml
|
||||
VALIDATE_CPP: false
|
||||
VALIDATE_JSCPD: false
|
||||
VALIDATE_GO: false
|
||||
VALIDATE_PHP_PHPCS: false
|
||||
VALIDATE_PHP_PHPSTAN: false
|
||||
VALIDATE_PHP_PSALM: false
|
||||
VALIDATE_TERRAGRUNT: false
|
||||
@@ -1,3 +1,4 @@
|
||||
---
|
||||
name: Build binary releases
|
||||
on:
|
||||
pull_request:
|
||||
@@ -52,7 +53,7 @@ jobs:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
-
|
||||
name: Copy binary
|
||||
run: docker cp $(docker create --name static-builder dunglas/frankenphp:static-builder):/go/src/app/dist/frankenphp-linux-x86_64 frankenphp-linux-x86_64 ; docker rm static-builder
|
||||
run: docker cp "$(docker create --name static-builder dunglas/frankenphp:static-builder):/go/src/app/dist/frankenphp-linux-x86_64" frankenphp-linux-x86_64 ; docker rm static-builder
|
||||
-
|
||||
name: Upload asset
|
||||
if: github.ref_type == 'tag'
|
||||
@@ -1,3 +1,4 @@
|
||||
---
|
||||
name: Tests
|
||||
on:
|
||||
pull_request:
|
||||
@@ -52,3 +53,8 @@ jobs:
|
||||
name: Run Caddy module tests
|
||||
working-directory: caddy/
|
||||
run: go test -race -v ./...
|
||||
-
|
||||
name: Lint Go code
|
||||
uses: golangci/golangci-lint-action@v3
|
||||
with:
|
||||
version: latest
|
||||
6
.hadolint.yaml
Normal file
6
.hadolint.yaml
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
ignored:
|
||||
- DL3006
|
||||
- DL3008
|
||||
- DL3018
|
||||
- DL3022
|
||||
4
.markdown-lint.yaml
Normal file
4
.markdown-lint.yaml
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
no-hard-tabs: false
|
||||
MD013: false
|
||||
MD033: false
|
||||
@@ -1,15 +1,20 @@
|
||||
# Contributing
|
||||
|
||||
## Compiling PHP
|
||||
|
||||
### With Docker (Linux)
|
||||
|
||||
Build the dev Docker image:
|
||||
|
||||
docker build -t frankenphp-dev -f dev.Dockerfile .
|
||||
docker run --cap-add=SYS_PTRACE --security-opt seccomp=unconfined -p 8080:8080 -p 443:443 -v $PWD:/go/src/app -it frankenphp-dev
|
||||
```console
|
||||
docker build -t frankenphp-dev -f dev.Dockerfile .
|
||||
docker run --cap-add=SYS_PTRACE --security-opt seccomp=unconfined -p 8080:8080 -p 443:443 -v $PWD:/go/src/app -it frankenphp-dev
|
||||
```
|
||||
|
||||
The image contains the usual development tools (Go, GDB, Valgrind, Neovim...).
|
||||
|
||||
If docker version is lower than 23.0, build is failed by dockerignore [pattern issue](https://github.com/moby/moby/pull/42676). Add directories to `.dockerignore`.
|
||||
|
||||
```patch
|
||||
!testdata/*.php
|
||||
!testdata/*.txt
|
||||
@@ -24,65 +29,79 @@ If docker version is lower than 23.0, build is failed by dockerignore [pattern i
|
||||
|
||||
## Running the test suite
|
||||
|
||||
go test -race -v ./...
|
||||
```console
|
||||
go test -race -v ./...
|
||||
```
|
||||
|
||||
## Caddy module
|
||||
|
||||
Build Caddy with the FrankenPHP Caddy module:
|
||||
|
||||
cd caddy/frankenphp/
|
||||
go build
|
||||
cd ../../
|
||||
```console
|
||||
cd caddy/frankenphp/
|
||||
go build
|
||||
cd ../../
|
||||
```
|
||||
|
||||
Run the Caddy with the FrankenPHP Caddy module:
|
||||
|
||||
cd testdata/
|
||||
../caddy/frankenphp/frankenphp run
|
||||
```console
|
||||
cd testdata/
|
||||
../caddy/frankenphp/frankenphp run
|
||||
```
|
||||
|
||||
The server is listening on `127.0.0.1:8080`:
|
||||
|
||||
curl -vk https://localhost/phpinfo.php
|
||||
```console
|
||||
curl -vk https://localhost/phpinfo.php
|
||||
```
|
||||
|
||||
## Minimal test server
|
||||
|
||||
Build the minimal test server:
|
||||
|
||||
cd internal/testserver/
|
||||
go build
|
||||
cd ../../
|
||||
```console
|
||||
cd internal/testserver/
|
||||
go build
|
||||
cd ../../
|
||||
```
|
||||
|
||||
Run the test server:
|
||||
|
||||
cd testdata/
|
||||
../internal/testserver/testserver
|
||||
```console
|
||||
cd testdata/
|
||||
../internal/testserver/testserver
|
||||
```
|
||||
|
||||
The server is listening on `127.0.0.1:8080`:
|
||||
|
||||
curl -v http://127.0.0.1:8080/phpinfo.php
|
||||
```console
|
||||
curl -v http://127.0.0.1:8080/phpinfo.php
|
||||
```
|
||||
|
||||
# Building Docker Images Locally
|
||||
## Building Docker Images Locally
|
||||
|
||||
Print bake plan:
|
||||
|
||||
```
|
||||
```console
|
||||
docker buildx bake -f docker-bake.hcl --print
|
||||
```
|
||||
|
||||
Build FrankenPHP images for amd64 locally:
|
||||
|
||||
```
|
||||
```console
|
||||
docker buildx bake -f docker-bake.hcl --pull --load --set "*.platform=linux/amd64"
|
||||
```
|
||||
|
||||
Build FrankenPHP images for arm64 locally:
|
||||
|
||||
```
|
||||
```console
|
||||
docker buildx bake -f docker-bake.hcl --pull --load --set "*.platform=linux/arm64"
|
||||
```
|
||||
|
||||
Build FrankenPHP images from scratch for arm64 & amd64 and push to Docker Hub:
|
||||
|
||||
```
|
||||
```console
|
||||
docker buildx bake -f docker-bake.hcl --pull --no-cache --push
|
||||
```
|
||||
|
||||
@@ -90,6 +109,7 @@ docker buildx bake -f docker-bake.hcl --pull --no-cache --push
|
||||
|
||||
1. Open `.github/workflows/tests.yml`
|
||||
2. Enable PHP debug symbols
|
||||
|
||||
```patch
|
||||
- uses: shivammathur/setup-php@v2
|
||||
# ...
|
||||
@@ -97,7 +117,9 @@ docker buildx bake -f docker-bake.hcl --pull --no-cache --push
|
||||
phpts: ts
|
||||
+ debug: true
|
||||
```
|
||||
|
||||
3. Enable `tmate` to connect to the container
|
||||
|
||||
```patch
|
||||
-
|
||||
name: Set CGO flags
|
||||
@@ -110,19 +132,24 @@ docker buildx bake -f docker-bake.hcl --pull --no-cache --push
|
||||
+ -
|
||||
+ uses: mxschmitt/action-tmate@v3
|
||||
```
|
||||
|
||||
4. Connect to the container
|
||||
5. Open `frankenphp.go`
|
||||
6. Enable `cgosymbolizer`
|
||||
|
||||
```patch
|
||||
- //_ "github.com/ianlancetaylor/cgosymbolizer"
|
||||
+ _ "github.com/ianlancetaylor/cgosymbolizer"
|
||||
```
|
||||
|
||||
7. Download the module: `go get`
|
||||
8. In the container, you can use GDB and the like:
|
||||
```sh
|
||||
|
||||
```console
|
||||
go test -c -ldflags=-w
|
||||
gdb --args ./frankenphp.test -test.run ^MyTest$
|
||||
```
|
||||
|
||||
9. When the bug is fixed, revert all these changes
|
||||
|
||||
## Misc Dev Resources
|
||||
@@ -142,10 +169,9 @@ docker buildx bake -f docker-bake.hcl --pull --no-cache --push
|
||||
* [Bake file definition](https://docs.docker.com/build/customize/bake/file-definition/)
|
||||
* [docker buildx build](https://docs.docker.com/engine/reference/commandline/buildx_build/)
|
||||
|
||||
|
||||
## Useful Command
|
||||
|
||||
```
|
||||
```console
|
||||
apk add strace util-linux gdb
|
||||
strace -e 'trace=!futex,epoll_ctl,epoll_pwait,tgkill,rt_sigreturn' -p 1
|
||||
```
|
||||
|
||||
16
Dockerfile
16
Dockerfile
@@ -46,6 +46,7 @@ LABEL org.opencontainers.image.vendor="Kévin Dunglas"
|
||||
FROM common AS builder
|
||||
|
||||
ARG FRANKENPHP_VERSION='dev'
|
||||
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
||||
|
||||
COPY --from=golang-base /usr/local/go /usr/local/go
|
||||
|
||||
@@ -71,12 +72,11 @@ WORKDIR /go/src/app
|
||||
COPY --link go.mod go.sum ./
|
||||
RUN go mod graph | awk '{if ($1 !~ "@") print $2}' | xargs go get
|
||||
|
||||
RUN mkdir caddy && cd caddy
|
||||
COPY --link caddy/go.mod caddy/go.sum ./caddy/
|
||||
|
||||
RUN cd caddy && \
|
||||
go mod graph | awk '{if ($1 !~ "@") print $2}' | xargs go get
|
||||
WORKDIR /go/src/app/caddy
|
||||
COPY --link caddy/go.mod caddy/go.sum ./
|
||||
RUN go mod graph | awk '{if ($1 !~ "@") print $2}' | xargs go get
|
||||
|
||||
WORKDIR /go/src/app
|
||||
COPY --link *.* ./
|
||||
COPY --link caddy caddy
|
||||
COPY --link C-Thread-Pool C-Thread-Pool
|
||||
@@ -87,12 +87,14 @@ COPY --link testdata testdata
|
||||
# see https://github.com/docker-library/php/blob/master/8.2/bookworm/zts/Dockerfile#L57-L59 for PHP values
|
||||
ENV CGO_LDFLAGS="-lssl -lcrypto -lreadline -largon2 -lcurl -lonig -lz $PHP_LDFLAGS" CGO_CFLAGS="-DFRANKENPHP_VERSION=$FRANKENPHP_VERSION $PHP_CFLAGS" CGO_CPPFLAGS=$PHP_CPPFLAGS
|
||||
|
||||
RUN cd caddy/frankenphp && \
|
||||
GOBIN=/usr/local/bin go install -ldflags "-X 'github.com/caddyserver/caddy/v2.CustomVersion=FrankenPHP $FRANKENPHP_VERSION PHP $PHP_VERSION Caddy'" && \
|
||||
WORKDIR /go/src/app/caddy/frankenphp
|
||||
RUN GOBIN=/usr/local/bin go install -ldflags "-X 'github.com/caddyserver/caddy/v2.CustomVersion=FrankenPHP $FRANKENPHP_VERSION PHP $PHP_VERSION Caddy'" && \
|
||||
setcap cap_net_bind_service=+ep /usr/local/bin/frankenphp && \
|
||||
cp Caddyfile /etc/caddy/Caddyfile && \
|
||||
frankenphp version
|
||||
|
||||
WORKDIR /go/src/app
|
||||
|
||||
|
||||
FROM common AS runner
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ FrankenPHP is a modern application server for PHP built on top of the [Caddy](ht
|
||||
|
||||
FrankenPHP gives superpowers to your PHP apps thanks to its stunning features: [*Early Hints*](docs/early-hints.md), [worker mode](docs/worker.md), [real-time capabilities](docs/mercure.md), automatic HTTPS, HTTP/2, and HTTP/3 support...
|
||||
|
||||
FrankenPHP works with any PHP app and makes your Symfony projects faster than ever thanks to provided integration with the worker mode (Laravel Octane support coming).
|
||||
FrankenPHP works with any PHP app and makes your Symfony projects faster than ever thanks to the provided integration with the worker mode (Laravel Octane support coming).
|
||||
|
||||
FrankenPHP can also be used as a standalone Go library to embed PHP in any app using `net/http`.
|
||||
|
||||
|
||||
@@ -43,11 +43,13 @@ LABEL org.opencontainers.image.vendor="Kévin Dunglas"
|
||||
FROM common AS builder
|
||||
|
||||
ARG FRANKENPHP_VERSION='dev'
|
||||
SHELL ["/bin/ash", "-eo", "pipefail", "-c"]
|
||||
|
||||
COPY --link --from=golang-base /usr/local/go /usr/local/go
|
||||
|
||||
ENV PATH /usr/local/go/bin:$PATH
|
||||
|
||||
# hadolint ignore=SC2086
|
||||
RUN apk add --no-cache --virtual .build-deps \
|
||||
$PHPIZE_DEPS \
|
||||
argon2-dev \
|
||||
@@ -67,11 +69,11 @@ WORKDIR /go/src/app
|
||||
COPY --link go.mod go.sum ./
|
||||
RUN go mod graph | awk '{if ($1 !~ "@") print $2}' | xargs go get
|
||||
|
||||
RUN mkdir caddy && cd caddy
|
||||
COPY caddy/go.mod caddy/go.sum ./caddy/
|
||||
|
||||
RUN cd caddy && go mod graph | awk '{if ($1 !~ "@") print $2}' | xargs go get
|
||||
WORKDIR /go/src/app/caddy
|
||||
COPY caddy/go.mod caddy/go.sum ./
|
||||
RUN go mod graph | awk '{if ($1 !~ "@") print $2}' | xargs go get
|
||||
|
||||
WORKDIR /go/src/app
|
||||
COPY --link *.* ./
|
||||
COPY --link caddy caddy
|
||||
COPY --link C-Thread-Pool C-Thread-Pool
|
||||
@@ -82,11 +84,13 @@ COPY --link testdata testdata
|
||||
# see https://github.com/docker-library/php/blob/master/8.2/bookworm/zts/Dockerfile#L57-L59 for php values
|
||||
ENV CGO_LDFLAGS="-lssl -lcrypto -lreadline -largon2 -lcurl -lonig -lz $PHP_LDFLAGS" CGO_CFLAGS="-DFRANKENPHP_VERSION=$FRANKENPHP_VERSION $PHP_CFLAGS" CGO_CPPFLAGS=$PHP_CPPFLAGS
|
||||
|
||||
RUN cd caddy/frankenphp && \
|
||||
GOBIN=/usr/local/bin go install -ldflags "-extldflags '-Wl,-z,stack-size=0x80000' -X 'github.com/caddyserver/caddy/v2.CustomVersion=FrankenPHP $FRANKENPHP_VERSION PHP $PHP_VERSION Caddy'" && \
|
||||
WORKDIR /go/src/app/caddy/frankenphp
|
||||
RUN GOBIN=/usr/local/bin go install -ldflags "-extldflags '-Wl,-z,stack-size=0x80000' -X 'github.com/caddyserver/caddy/v2.CustomVersion=FrankenPHP $FRANKENPHP_VERSION PHP $PHP_VERSION Caddy'" && \
|
||||
setcap cap_net_bind_service=+ep /usr/local/bin/frankenphp && \
|
||||
frankenphp version
|
||||
|
||||
WORKDIR /go/src/app
|
||||
|
||||
|
||||
FROM common AS runner
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -o errexit
|
||||
trap 'echo "Aborting due to errexit on line $LINENO. Exit code: $?" >&2' ERR
|
||||
set -o xtrace
|
||||
|
||||
if ! type "git" > /dev/null; then
|
||||
@@ -38,7 +37,13 @@ if [ -z "$FRANKENPHP_VERSION" ]; then
|
||||
elif [ -d ".git/" ]; then
|
||||
CURRENT_REF="$(git rev-parse --abbrev-ref HEAD)"
|
||||
export CURRENT_REF
|
||||
|
||||
if echo "$FRANKENPHP_VERSION" | grep -F -q "."; then
|
||||
# Tag
|
||||
git checkout "v$FRANKENPHP_VERSION"
|
||||
else
|
||||
git checkout "$FRANKENPHP_VERSION"
|
||||
fi
|
||||
fi
|
||||
|
||||
bin="frankenphp-$os-$arch"
|
||||
@@ -72,6 +77,7 @@ fi
|
||||
|
||||
./bin/spc doctor
|
||||
./bin/spc fetch --with-php="$PHP_VERSION" --for-extensions="$PHP_EXTENSIONS"
|
||||
# shellcheck disable=SC2086
|
||||
./bin/spc build --enable-zts --build-embed $extraOpts "$PHP_EXTENSIONS" --with-libs="$PHP_EXTENSION_LIBS"
|
||||
CGO_CFLAGS="-DFRANKENPHP_VERSION=$FRANKENPHP_VERSION $(./buildroot/bin/php-config --includes | sed s#-I/#-I"$PWD"/buildroot/#g)"
|
||||
export CGO_CFLAGS
|
||||
|
||||
@@ -37,8 +37,8 @@ RUN apk add --no-cache \
|
||||
libtool && \
|
||||
echo 'set auto-load safe-path /' > /root/.gdbinit
|
||||
|
||||
RUN git clone --branch=PHP-8.3 https://github.com/php/php-src.git && \
|
||||
cd php-src && \
|
||||
WORKDIR /usr/local/src/php
|
||||
RUN git clone --branch=PHP-8.3 https://github.com/php/php-src.git . && \
|
||||
# --enable-embed is only necessary to generate libphp.so, we don't use this SAPI directly
|
||||
./buildconf --force && \
|
||||
./configure \
|
||||
@@ -47,18 +47,19 @@ RUN git clone --branch=PHP-8.3 https://github.com/php/php-src.git && \
|
||||
--disable-zend-signals \
|
||||
--enable-zend-max-execution-timers \
|
||||
--enable-debug && \
|
||||
make -j$(nproc) && \
|
||||
make -j"$(nproc)" && \
|
||||
make install && \
|
||||
ldconfig /etc/ld.so.conf.d && \
|
||||
cp php.ini-development /usr/local/lib/php.ini && \
|
||||
echo -e "zend_extension=opcache.so\nopcache.enable=1" >> /usr/local/lib/php.ini &&\
|
||||
echo "zend_extension=opcache.so" >> /usr/local/lib/php.ini && \
|
||||
echo "opcache.enable=1" >> /usr/local/lib/php.ini && \
|
||||
php --version
|
||||
|
||||
WORKDIR /go/src/app
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN cd caddy/frankenphp && \
|
||||
go build
|
||||
WORKDIR /go/src/app/caddy/frankenphp
|
||||
RUN go build
|
||||
|
||||
WORKDIR /go/src/app
|
||||
CMD [ "zsh" ]
|
||||
|
||||
@@ -13,6 +13,7 @@ ENV PHPIZE_DEPS \
|
||||
pkg-config \
|
||||
re2c
|
||||
|
||||
# hadolint ignore=DL3009
|
||||
RUN apt-get update && \
|
||||
apt-get -y --no-install-recommends install \
|
||||
$PHPIZE_DEPS \
|
||||
@@ -41,8 +42,8 @@ RUN apt-get update && \
|
||||
&& \
|
||||
apt-get clean
|
||||
|
||||
RUN git clone --branch=PHP-8.3 https://github.com/php/php-src.git && \
|
||||
cd php-src && \
|
||||
WORKDIR /usr/local/src/php
|
||||
RUN git clone --branch=PHP-8.3 https://github.com/php/php-src.git . && \
|
||||
# --enable-embed is only necessary to generate libphp.so, we don't use this SAPI directly
|
||||
./buildconf --force && \
|
||||
./configure \
|
||||
@@ -51,18 +52,19 @@ RUN git clone --branch=PHP-8.3 https://github.com/php/php-src.git && \
|
||||
--disable-zend-signals \
|
||||
--enable-zend-max-execution-timers \
|
||||
--enable-debug && \
|
||||
make -j$(nproc) && \
|
||||
make -j"$(nproc)" && \
|
||||
make install && \
|
||||
ldconfig && \
|
||||
cp php.ini-development /usr/local/lib/php.ini && \
|
||||
echo "zend_extension=opcache.so\nopcache.enable=1" >> /usr/local/lib/php.ini &&\
|
||||
echo "zend_extension=opcache.so" >> /usr/local/lib/php.ini && \
|
||||
echo "opcache.enable=1" >> /usr/local/lib/php.ini && \
|
||||
php --version
|
||||
|
||||
WORKDIR /go/src/app
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN cd caddy/frankenphp && \
|
||||
go build
|
||||
WORKDIR /go/src/app/caddy/frankenphp
|
||||
RUN go build
|
||||
|
||||
WORKDIR /go/src/app
|
||||
CMD [ "zsh" ]
|
||||
|
||||
@@ -15,8 +15,8 @@ COPY . /app/public
|
||||
Then, run the commands to build and run the Docker image:
|
||||
|
||||
```console
|
||||
$ docker build -t my-php-app .
|
||||
$ docker run -it --rm --name my-running-app my-php-app
|
||||
docker build -t my-php-app .
|
||||
docker run -it --rm --name my-running-app my-php-app
|
||||
```
|
||||
|
||||
## How to Install More PHP Extensions
|
||||
@@ -70,7 +70,7 @@ COPY --from=builder /usr/local/bin/frankenphp /usr/local/bin/frankenphp
|
||||
The `builder` image provided by FrankenPHP contains a compiled version of libphp.
|
||||
[Builders images](https://hub.docker.com/r/dunglas/frankenphp/tags?name=builder) are provided for all versions of FrankenPHP and PHP, both for Alpine and Debian.
|
||||
|
||||
# Enabling the Worker Mode by Default
|
||||
## Enabling the Worker Mode by Default
|
||||
|
||||
Set the `FRANKENPHP_CONFIG` environment variable to start FrankenPHP with a worker script:
|
||||
|
||||
@@ -82,7 +82,7 @@ FROM dunglas/frankenphp
|
||||
ENV FRANKENPHP_CONFIG="worker ./public/index.php"
|
||||
```
|
||||
|
||||
# Using a Volume in Development
|
||||
## Using a Volume in Development
|
||||
|
||||
To develop easily with FrankenPHP, mount the directory from your host containing the source code of the app as a volume in the Docker container:
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ Calling PHP functions and language constructs that themselves call [cgo](https:/
|
||||
|
||||
This issue [is being worked on by the Go project](https://github.com/golang/go/issues/62130).
|
||||
|
||||
|
||||
In the meantime, one solution is not to use constructs (like `echo`) and functions (like `header()`) that delegate to Go from inside Fibers.
|
||||
|
||||
This code will likely crash because it uses `echo` in the Fiber:
|
||||
|
||||
@@ -18,20 +18,22 @@ Alternatively, you can run your Laravel projects with FrankenPHP from your local
|
||||
|
||||
1. [Download the binary corresponding to your system](https://github.com/dunglas/frankenphp/releases)
|
||||
2. Add the following configuration to a file named `Caddyfile` in the root directory of your Laravel project:
|
||||
```caddyfile
|
||||
{
|
||||
|
||||
```caddyfile
|
||||
{
|
||||
frankenphp
|
||||
order php_server before file_server
|
||||
}
|
||||
}
|
||||
|
||||
# The domain name of your server
|
||||
localhost {
|
||||
# The domain name of your server
|
||||
localhost {
|
||||
# Enable compression (optional)
|
||||
encode zstd gzip
|
||||
# Execute PHP files in the current directory and serve assets
|
||||
php_server
|
||||
}
|
||||
```
|
||||
}
|
||||
```
|
||||
|
||||
3. Start FrankenPHP from the root directory of your Laravel project: `./frankenphp run`
|
||||
|
||||
## Laravel Octane
|
||||
|
||||
@@ -7,6 +7,6 @@ No JS library or SDK required!
|
||||
|
||||

|
||||
|
||||
To enable the Mercure hub, update the `Caddyfile` as described [on Mercure's website](https://mercure.rocks/docs/hub/config).
|
||||
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).
|
||||
|
||||
418
frankenphp.c
418
frankenphp.c
@@ -1,52 +1,44 @@
|
||||
#include <SAPI.h>
|
||||
#include <Zend/zend_alloc.h>
|
||||
#include <Zend/zend_exceptions.h>
|
||||
#include <Zend/zend_interfaces.h>
|
||||
#include <Zend/zend_types.h>
|
||||
#include <errno.h>
|
||||
#include <ext/spl/spl_exceptions.h>
|
||||
#include <ext/standard/head.h>
|
||||
#include <php.h>
|
||||
#include <php_config.h>
|
||||
#include <php_main.h>
|
||||
#include <php_output.h>
|
||||
#include <php_variables.h>
|
||||
#include <sapi/embed/php_embed.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <php_config.h>
|
||||
#include <php.h>
|
||||
#include <php_main.h>
|
||||
#include <php_variables.h>
|
||||
#include <php_output.h>
|
||||
#include <SAPI.h>
|
||||
#include <Zend/zend_alloc.h>
|
||||
#include <Zend/zend_types.h>
|
||||
#include <Zend/zend_exceptions.h>
|
||||
#include <Zend/zend_interfaces.h>
|
||||
#include <sapi/embed/php_embed.h>
|
||||
#include <ext/standard/head.h>
|
||||
#include <ext/spl/spl_exceptions.h>
|
||||
|
||||
#include "C-Thread-Pool/thpool.h"
|
||||
#include "C-Thread-Pool/thpool.c"
|
||||
#include "C-Thread-Pool/thpool.h"
|
||||
|
||||
#include "frankenphp_arginfo.h"
|
||||
#include "_cgo_export.h"
|
||||
#include "frankenphp_arginfo.h"
|
||||
|
||||
#if defined(PHP_WIN32) && defined(ZTS)
|
||||
ZEND_TSRMLS_CACHE_DEFINE()
|
||||
#endif
|
||||
|
||||
/* Timeouts are currently fundamentally broken with ZTS except on Linux: https://bugs.php.net/bug.php?id=79464 */
|
||||
/* Timeouts are currently fundamentally broken with ZTS except on Linux:
|
||||
* https://bugs.php.net/bug.php?id=79464 */
|
||||
#ifndef ZEND_MAX_EXECUTION_TIMERS
|
||||
static const char HARDCODED_INI[] =
|
||||
"max_execution_time=0\n"
|
||||
static const char HARDCODED_INI[] = "max_execution_time=0\n"
|
||||
"max_input_time=-1\n\0";
|
||||
#endif
|
||||
|
||||
static const char *MODULES_TO_RELOAD[] = {
|
||||
"filter",
|
||||
"session",
|
||||
NULL
|
||||
};
|
||||
static const char *MODULES_TO_RELOAD[] = {"filter", "session", NULL};
|
||||
|
||||
frankenphp_version frankenphp_get_version() {
|
||||
return (frankenphp_version){
|
||||
PHP_MAJOR_VERSION,
|
||||
PHP_MINOR_VERSION,
|
||||
PHP_RELEASE_VERSION,
|
||||
PHP_EXTRA_VERSION,
|
||||
PHP_VERSION,
|
||||
PHP_VERSION_ID,
|
||||
PHP_MAJOR_VERSION, PHP_MINOR_VERSION, PHP_RELEASE_VERSION,
|
||||
PHP_EXTRA_VERSION, PHP_VERSION, PHP_VERSION_ID,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -91,13 +83,13 @@ static uintptr_t frankenphp_clean_server_context() {
|
||||
free(SG(request_info).auth_user);
|
||||
SG(request_info).auth_user = NULL;
|
||||
|
||||
free((char *) SG(request_info).request_method);
|
||||
free((char *)SG(request_info).request_method);
|
||||
SG(request_info).request_method = NULL;
|
||||
|
||||
free(SG(request_info).query_string);
|
||||
SG(request_info).query_string = NULL;
|
||||
|
||||
free((char *) SG(request_info).content_type);
|
||||
free((char *)SG(request_info).content_type);
|
||||
SG(request_info).content_type = NULL;
|
||||
|
||||
free(SG(request_info).path_translated);
|
||||
@@ -113,43 +105,43 @@ static void frankenphp_request_reset() {
|
||||
zend_try {
|
||||
int i;
|
||||
|
||||
for (i=0; i<NUM_TRACK_VARS; i++) {
|
||||
for (i = 0; i < NUM_TRACK_VARS; i++) {
|
||||
zval_ptr_dtor(&PG(http_globals)[i]);
|
||||
}
|
||||
|
||||
memset(&PG(http_globals), 0, sizeof(zval) * NUM_TRACK_VARS);
|
||||
} zend_end_try();
|
||||
}
|
||||
zend_end_try();
|
||||
}
|
||||
|
||||
/* Adapted from php_request_shutdown */
|
||||
static void frankenphp_worker_request_shutdown() {
|
||||
/* Flush all output buffers */
|
||||
zend_try {
|
||||
php_output_end_all();
|
||||
} zend_end_try();
|
||||
zend_try { php_output_end_all(); }
|
||||
zend_end_try();
|
||||
|
||||
// TODO: store the list of modules to reload in a global module variable
|
||||
const char **module_name;
|
||||
zend_module_entry *module;
|
||||
for (module_name = MODULES_TO_RELOAD; *module_name; module_name++) {
|
||||
if ((module = zend_hash_str_find_ptr(&module_registry, *module_name, strlen(*module_name)))) {
|
||||
if ((module = zend_hash_str_find_ptr(&module_registry, *module_name,
|
||||
strlen(*module_name)))) {
|
||||
module->request_shutdown_func(module->type, module->module_number);
|
||||
}
|
||||
}
|
||||
|
||||
/* Shutdown output layer (send the set HTTP headers, cleanup output handlers, etc.) */
|
||||
zend_try {
|
||||
php_output_deactivate();
|
||||
} zend_end_try();
|
||||
/* Shutdown output layer (send the set HTTP headers, cleanup output handlers,
|
||||
* etc.) */
|
||||
zend_try { php_output_deactivate(); }
|
||||
zend_end_try();
|
||||
|
||||
/* Clean super globals */
|
||||
frankenphp_request_reset();
|
||||
|
||||
/* SAPI related shutdown (free stuff) */
|
||||
frankenphp_clean_server_context();
|
||||
zend_try {
|
||||
sapi_deactivate();
|
||||
} zend_end_try();
|
||||
zend_try { sapi_deactivate(); }
|
||||
zend_end_try();
|
||||
|
||||
zend_set_memory_limit(PG(memory_limit));
|
||||
}
|
||||
@@ -169,7 +161,8 @@ static int frankenphp_worker_request_startup() {
|
||||
sapi_activate();
|
||||
|
||||
/*
|
||||
* Timeouts are currently fundamentally broken with ZTS: https://bugs.php.net/bug.php?id=79464
|
||||
* Timeouts are currently fundamentally broken with ZTS:
|
||||
*https://bugs.php.net/bug.php?id=79464
|
||||
*
|
||||
*if (PG(max_input_time) == -1) {
|
||||
* zend_set_timeout(EG(timeout_seconds), 1);
|
||||
@@ -179,7 +172,8 @@ static int frankenphp_worker_request_startup() {
|
||||
*/
|
||||
|
||||
if (PG(expose_php)) {
|
||||
sapi_add_header(SAPI_PHP_VERSION_HEADER, sizeof(SAPI_PHP_VERSION_HEADER)-1, 1);
|
||||
sapi_add_header(SAPI_PHP_VERSION_HEADER,
|
||||
sizeof(SAPI_PHP_VERSION_HEADER) - 1, 1);
|
||||
}
|
||||
|
||||
if (PG(output_handler) && PG(output_handler)[0]) {
|
||||
@@ -189,7 +183,9 @@ static int frankenphp_worker_request_startup() {
|
||||
php_output_start_user(&oh, 0, PHP_OUTPUT_HANDLER_STDFLAGS);
|
||||
zval_ptr_dtor(&oh);
|
||||
} else if (PG(output_buffering)) {
|
||||
php_output_start_user(NULL, PG(output_buffering) > 1 ? PG(output_buffering) : 0, PHP_OUTPUT_HANDLER_STDFLAGS);
|
||||
php_output_start_user(NULL,
|
||||
PG(output_buffering) > 1 ? PG(output_buffering) : 0,
|
||||
PHP_OUTPUT_HANDLER_STDFLAGS);
|
||||
} else if (PG(implicit_flush)) {
|
||||
php_output_set_implicit_flush(1);
|
||||
}
|
||||
@@ -206,16 +202,15 @@ static int frankenphp_worker_request_startup() {
|
||||
const char **module_name;
|
||||
zend_module_entry *module;
|
||||
for (module_name = MODULES_TO_RELOAD; *module_name; module_name++) {
|
||||
if (
|
||||
(module = zend_hash_str_find_ptr(&module_registry, *module_name, sizeof(*module_name)-1))
|
||||
&& module->request_startup_func
|
||||
) {
|
||||
if ((module = zend_hash_str_find_ptr(&module_registry, *module_name,
|
||||
sizeof(*module_name) - 1)) &&
|
||||
module->request_startup_func) {
|
||||
module->request_startup_func(module->type, module->module_number);
|
||||
}
|
||||
}
|
||||
} zend_catch {
|
||||
retval = FAILURE;
|
||||
} zend_end_try();
|
||||
}
|
||||
zend_catch { retval = FAILURE; }
|
||||
zend_end_try();
|
||||
|
||||
SG(sapi_started) = 1;
|
||||
|
||||
@@ -237,7 +232,8 @@ PHP_FUNCTION(frankenphp_finish_request) { /* {{{ */
|
||||
php_header();
|
||||
|
||||
if (ctx->current_request != 0) {
|
||||
go_frankenphp_finish_request(ctx->main_request, ctx->current_request, false);
|
||||
go_frankenphp_finish_request(ctx->main_request, ctx->current_request,
|
||||
false);
|
||||
}
|
||||
|
||||
ctx->finished = true;
|
||||
@@ -257,7 +253,9 @@ PHP_FUNCTION(frankenphp_handle_request) {
|
||||
|
||||
if (ctx->main_request == 0) {
|
||||
// not a worker, throw an error
|
||||
zend_throw_exception(spl_ce_RuntimeException, "frankenphp_handle_request() called while not in worker mode", 0);
|
||||
zend_throw_exception(
|
||||
spl_ce_RuntimeException,
|
||||
"frankenphp_handle_request() called while not in worker mode", 0);
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
@@ -276,12 +274,11 @@ PHP_FUNCTION(frankenphp_handle_request) {
|
||||
zend_unset_timeout();
|
||||
#endif
|
||||
|
||||
uintptr_t request = go_frankenphp_worker_handle_request_start(ctx->main_request);
|
||||
if (
|
||||
frankenphp_worker_request_startup() == FAILURE
|
||||
uintptr_t request =
|
||||
go_frankenphp_worker_handle_request_start(ctx->main_request);
|
||||
if (frankenphp_worker_request_startup() == FAILURE
|
||||
/* Shutting down */
|
||||
|| !request
|
||||
) {
|
||||
|| !request) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
@@ -299,7 +296,8 @@ PHP_FUNCTION(frankenphp_handle_request) {
|
||||
zval_ptr_dtor(&retval);
|
||||
}
|
||||
|
||||
/* If an exception occured, print the message to the client before closing the connection */
|
||||
/* If an exception occured, print the message to the client before closing the
|
||||
* connection */
|
||||
if (EG(exception)) {
|
||||
zend_exception_error(EG(exception), E_ERROR);
|
||||
}
|
||||
@@ -342,21 +340,19 @@ static zend_module_entry frankenphp_module = {
|
||||
NULL, /* request shutdown */
|
||||
NULL, /* information */
|
||||
TOSTRING(FRANKENPHP_VERSION),
|
||||
STANDARD_MODULE_PROPERTIES
|
||||
};
|
||||
STANDARD_MODULE_PROPERTIES};
|
||||
|
||||
static uintptr_t frankenphp_request_shutdown()
|
||||
{
|
||||
static uintptr_t frankenphp_request_shutdown() {
|
||||
frankenphp_server_context *ctx = SG(server_context);
|
||||
|
||||
if (ctx->main_request && ctx->current_request) {
|
||||
frankenphp_request_reset();
|
||||
}
|
||||
|
||||
php_request_shutdown((void *) 0);
|
||||
php_request_shutdown((void *)0);
|
||||
|
||||
free(ctx->cookie_data);
|
||||
((frankenphp_server_context*) SG(server_context))->cookie_data = NULL;
|
||||
((frankenphp_server_context *)SG(server_context))->cookie_data = NULL;
|
||||
uintptr_t rh = frankenphp_clean_server_context();
|
||||
|
||||
free(ctx);
|
||||
@@ -370,33 +366,25 @@ static uintptr_t frankenphp_request_shutdown()
|
||||
}
|
||||
|
||||
int frankenphp_update_server_context(
|
||||
bool create,
|
||||
uintptr_t current_request,
|
||||
uintptr_t main_request,
|
||||
bool create, uintptr_t current_request, uintptr_t main_request,
|
||||
|
||||
const char *request_method,
|
||||
char *query_string,
|
||||
zend_long content_length,
|
||||
char *path_translated,
|
||||
char *request_uri,
|
||||
const char *content_type,
|
||||
char *auth_user,
|
||||
char *auth_password,
|
||||
int proto_num
|
||||
) {
|
||||
const char *request_method, char *query_string, zend_long content_length,
|
||||
char *path_translated, char *request_uri, const char *content_type,
|
||||
char *auth_user, char *auth_password, int proto_num) {
|
||||
frankenphp_server_context *ctx;
|
||||
|
||||
if (create) {
|
||||
#ifdef ZTS
|
||||
/* initial resource fetch */
|
||||
(void)ts_resource(0);
|
||||
# ifdef PHP_WIN32
|
||||
#ifdef PHP_WIN32
|
||||
ZEND_TSRMLS_CACHE_UPDATE();
|
||||
# endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* todo: use a pool */
|
||||
ctx = (frankenphp_server_context *) calloc(1, sizeof(frankenphp_server_context));
|
||||
ctx = (frankenphp_server_context *)calloc(
|
||||
1, sizeof(frankenphp_server_context));
|
||||
if (ctx == NULL) {
|
||||
return FAILURE;
|
||||
}
|
||||
@@ -406,7 +394,7 @@ int frankenphp_update_server_context(
|
||||
|
||||
SG(server_context) = ctx;
|
||||
} else {
|
||||
ctx = (frankenphp_server_context *) SG(server_context);
|
||||
ctx = (frankenphp_server_context *)SG(server_context);
|
||||
}
|
||||
|
||||
ctx->main_request = main_request;
|
||||
@@ -425,27 +413,26 @@ int frankenphp_update_server_context(
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
static int frankenphp_startup(sapi_module_struct *sapi_module)
|
||||
{
|
||||
static int frankenphp_startup(sapi_module_struct *sapi_module) {
|
||||
return php_module_startup(sapi_module, &frankenphp_module);
|
||||
}
|
||||
|
||||
static int frankenphp_deactivate(void)
|
||||
{
|
||||
static int frankenphp_deactivate(void) {
|
||||
/* TODO: flush everything */
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
static size_t frankenphp_ub_write(const char *str, size_t str_length)
|
||||
{
|
||||
frankenphp_server_context* ctx = SG(server_context);
|
||||
static size_t frankenphp_ub_write(const char *str, size_t str_length) {
|
||||
frankenphp_server_context *ctx = SG(server_context);
|
||||
|
||||
if(ctx->finished) {
|
||||
if (ctx->finished) {
|
||||
// TODO: maybe log a warning that we tried to write to a finished request?
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct go_ub_write_return result = go_ub_write(ctx->current_request ? ctx->current_request : ctx->main_request, (char *) str, str_length);
|
||||
struct go_ub_write_return result = go_ub_write(
|
||||
ctx->current_request ? ctx->current_request : ctx->main_request,
|
||||
(char *)str, str_length);
|
||||
|
||||
if (result.r1) {
|
||||
php_handle_aborted_connection();
|
||||
@@ -454,14 +441,13 @@ static size_t frankenphp_ub_write(const char *str, size_t str_length)
|
||||
return result.r0;
|
||||
}
|
||||
|
||||
static int frankenphp_send_headers(sapi_headers_struct *sapi_headers)
|
||||
{
|
||||
static int frankenphp_send_headers(sapi_headers_struct *sapi_headers) {
|
||||
if (SG(request_info).no_headers == 1) {
|
||||
return SAPI_HEADER_SENT_SUCCESSFULLY;
|
||||
}
|
||||
|
||||
int status;
|
||||
frankenphp_server_context* ctx = SG(server_context);
|
||||
frankenphp_server_context *ctx = SG(server_context);
|
||||
|
||||
if (ctx->current_request == 0) {
|
||||
return SAPI_HEADER_SEND_FAILED;
|
||||
@@ -482,25 +468,24 @@ static int frankenphp_send_headers(sapi_headers_struct *sapi_headers)
|
||||
return SAPI_HEADER_SENT_SUCCESSFULLY;
|
||||
}
|
||||
|
||||
static void frankenphp_sapi_flush(void *server_context)
|
||||
{
|
||||
frankenphp_server_context *ctx = (frankenphp_server_context *) server_context;
|
||||
static void frankenphp_sapi_flush(void *server_context) {
|
||||
frankenphp_server_context *ctx = (frankenphp_server_context *)server_context;
|
||||
|
||||
if (ctx && ctx->current_request != 0 && go_sapi_flush(ctx->current_request)) {
|
||||
php_handle_aborted_connection();
|
||||
}
|
||||
}
|
||||
|
||||
static size_t frankenphp_read_post(char *buffer, size_t count_bytes)
|
||||
{
|
||||
frankenphp_server_context* ctx = SG(server_context);
|
||||
static size_t frankenphp_read_post(char *buffer, size_t count_bytes) {
|
||||
frankenphp_server_context *ctx = SG(server_context);
|
||||
|
||||
return ctx->current_request ? go_read_post(ctx->current_request, buffer, count_bytes) : 0;
|
||||
return ctx->current_request
|
||||
? go_read_post(ctx->current_request, buffer, count_bytes)
|
||||
: 0;
|
||||
}
|
||||
|
||||
static char* frankenphp_read_cookies(void)
|
||||
{
|
||||
frankenphp_server_context* ctx = SG(server_context);
|
||||
static char *frankenphp_read_cookies(void) {
|
||||
frankenphp_server_context *ctx = SG(server_context);
|
||||
|
||||
if (ctx->current_request == 0) {
|
||||
return "";
|
||||
@@ -511,14 +496,15 @@ static char* frankenphp_read_cookies(void)
|
||||
return ctx->cookie_data;
|
||||
}
|
||||
|
||||
static void frankenphp_register_known_variable(const char *key, char *value, zval *track_vars_array, bool f)
|
||||
{
|
||||
static void frankenphp_register_known_variable(const char *key, char *value,
|
||||
zval *track_vars_array, bool f) {
|
||||
if (value == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
size_t new_val_len;
|
||||
if (sapi_module.input_filter(PARSE_SERVER, key, &value, strlen(value), &new_val_len)) {
|
||||
if (sapi_module.input_filter(PARSE_SERVER, key, &value, strlen(value),
|
||||
&new_val_len)) {
|
||||
php_register_variable_safe(key, value, new_val_len, track_vars_array);
|
||||
}
|
||||
|
||||
@@ -528,66 +514,100 @@ static void frankenphp_register_known_variable(const char *key, char *value, zva
|
||||
}
|
||||
}
|
||||
|
||||
void frankenphp_register_bulk_variables(char *known_variables[27], char **dynamic_variables, size_t size, zval *track_vars_array)
|
||||
{
|
||||
void frankenphp_register_bulk_variables(char *known_variables[27],
|
||||
char **dynamic_variables, size_t size,
|
||||
zval *track_vars_array) {
|
||||
/* Not used, but must be present */
|
||||
frankenphp_register_known_variable("AUTH_TYPE", "", track_vars_array, false);
|
||||
frankenphp_register_known_variable("REMOTE_IDENT", "", track_vars_array, false);
|
||||
frankenphp_register_known_variable("REMOTE_IDENT", "", track_vars_array,
|
||||
false);
|
||||
|
||||
/* Allocated in frankenphp_update_server_context() */
|
||||
frankenphp_register_known_variable("CONTENT_TYPE", (char *) SG(request_info).content_type, track_vars_array, false);
|
||||
frankenphp_register_known_variable("PATH_TRANSLATED", (char *) SG(request_info).path_translated, track_vars_array, false);
|
||||
frankenphp_register_known_variable("QUERY_STRING", SG(request_info).query_string, track_vars_array, false);
|
||||
frankenphp_register_known_variable("REMOTE_USER", (char *) SG(request_info).auth_user, track_vars_array, false);
|
||||
frankenphp_register_known_variable("REQUEST_METHOD", (char *) SG(request_info).request_method, track_vars_array, false);
|
||||
frankenphp_register_known_variable("REQUEST_URI", SG(request_info).request_uri, track_vars_array,false);
|
||||
frankenphp_register_known_variable("CONTENT_TYPE",
|
||||
(char *)SG(request_info).content_type,
|
||||
track_vars_array, false);
|
||||
frankenphp_register_known_variable("PATH_TRANSLATED",
|
||||
(char *)SG(request_info).path_translated,
|
||||
track_vars_array, false);
|
||||
frankenphp_register_known_variable(
|
||||
"QUERY_STRING", SG(request_info).query_string, track_vars_array, false);
|
||||
frankenphp_register_known_variable("REMOTE_USER",
|
||||
(char *)SG(request_info).auth_user,
|
||||
track_vars_array, false);
|
||||
frankenphp_register_known_variable("REQUEST_METHOD",
|
||||
(char *)SG(request_info).request_method,
|
||||
track_vars_array, false);
|
||||
frankenphp_register_known_variable(
|
||||
"REQUEST_URI", SG(request_info).request_uri, track_vars_array, false);
|
||||
|
||||
/* Known variables */
|
||||
frankenphp_register_known_variable("CONTENT_LENGTH", known_variables[0], track_vars_array, true);
|
||||
frankenphp_register_known_variable("DOCUMENT_ROOT", known_variables[1], track_vars_array, true);
|
||||
frankenphp_register_known_variable("DOCUMENT_URI", known_variables[2], track_vars_array, true);
|
||||
frankenphp_register_known_variable("GATEWAY_INTERFACE", known_variables[3], track_vars_array, true);
|
||||
frankenphp_register_known_variable("HTTP_HOST", known_variables[4], track_vars_array, true);
|
||||
frankenphp_register_known_variable("HTTPS", known_variables[5], track_vars_array, true);
|
||||
frankenphp_register_known_variable("PATH_INFO", known_variables[6], track_vars_array, true);
|
||||
frankenphp_register_known_variable("PHP_SELF", known_variables[7], track_vars_array, true);
|
||||
frankenphp_register_known_variable("REMOTE_ADDR", known_variables[8], track_vars_array, known_variables[8] != known_variables[9]);
|
||||
frankenphp_register_known_variable("REMOTE_HOST", known_variables[9], track_vars_array, true);
|
||||
frankenphp_register_known_variable("REMOTE_PORT", known_variables[10], track_vars_array, true);
|
||||
frankenphp_register_known_variable("REQUEST_SCHEME", known_variables[11], track_vars_array, true);
|
||||
frankenphp_register_known_variable("SCRIPT_FILENAME", known_variables[12], track_vars_array, true);
|
||||
frankenphp_register_known_variable("SCRIPT_NAME", known_variables[13], track_vars_array, true);
|
||||
frankenphp_register_known_variable("SERVER_NAME", known_variables[14], track_vars_array, true);
|
||||
frankenphp_register_known_variable("SERVER_PORT", known_variables[15], track_vars_array, true);
|
||||
frankenphp_register_known_variable("SERVER_PROTOCOL", known_variables[16], track_vars_array, true);
|
||||
frankenphp_register_known_variable("SERVER_SOFTWARE", known_variables[17], track_vars_array, true);
|
||||
frankenphp_register_known_variable("SSL_PROTOCOL", known_variables[18], track_vars_array, true);
|
||||
frankenphp_register_known_variable("CONTENT_LENGTH", known_variables[0],
|
||||
track_vars_array, true);
|
||||
frankenphp_register_known_variable("DOCUMENT_ROOT", known_variables[1],
|
||||
track_vars_array, true);
|
||||
frankenphp_register_known_variable("DOCUMENT_URI", known_variables[2],
|
||||
track_vars_array, true);
|
||||
frankenphp_register_known_variable("GATEWAY_INTERFACE", known_variables[3],
|
||||
track_vars_array, true);
|
||||
frankenphp_register_known_variable("HTTP_HOST", known_variables[4],
|
||||
track_vars_array, true);
|
||||
frankenphp_register_known_variable("HTTPS", known_variables[5],
|
||||
track_vars_array, true);
|
||||
frankenphp_register_known_variable("PATH_INFO", known_variables[6],
|
||||
track_vars_array, true);
|
||||
frankenphp_register_known_variable("PHP_SELF", known_variables[7],
|
||||
track_vars_array, true);
|
||||
frankenphp_register_known_variable("REMOTE_ADDR", known_variables[8],
|
||||
track_vars_array,
|
||||
known_variables[8] != known_variables[9]);
|
||||
frankenphp_register_known_variable("REMOTE_HOST", known_variables[9],
|
||||
track_vars_array, true);
|
||||
frankenphp_register_known_variable("REMOTE_PORT", known_variables[10],
|
||||
track_vars_array, true);
|
||||
frankenphp_register_known_variable("REQUEST_SCHEME", known_variables[11],
|
||||
track_vars_array, true);
|
||||
frankenphp_register_known_variable("SCRIPT_FILENAME", known_variables[12],
|
||||
track_vars_array, true);
|
||||
frankenphp_register_known_variable("SCRIPT_NAME", known_variables[13],
|
||||
track_vars_array, true);
|
||||
frankenphp_register_known_variable("SERVER_NAME", known_variables[14],
|
||||
track_vars_array, true);
|
||||
frankenphp_register_known_variable("SERVER_PORT", known_variables[15],
|
||||
track_vars_array, true);
|
||||
frankenphp_register_known_variable("SERVER_PROTOCOL", known_variables[16],
|
||||
track_vars_array, true);
|
||||
frankenphp_register_known_variable("SERVER_SOFTWARE", known_variables[17],
|
||||
track_vars_array, true);
|
||||
frankenphp_register_known_variable("SSL_PROTOCOL", known_variables[18],
|
||||
track_vars_array, true);
|
||||
|
||||
size_t new_val_len;
|
||||
for (size_t i = 0; i < size; i = i+2)
|
||||
{
|
||||
if (sapi_module.input_filter(PARSE_SERVER, dynamic_variables[i], &dynamic_variables[i+1], strlen(dynamic_variables[i+1]), &new_val_len)) {
|
||||
php_register_variable_safe(dynamic_variables[i], dynamic_variables[i+1], new_val_len, track_vars_array);
|
||||
for (size_t i = 0; i < size; i = i + 2) {
|
||||
if (sapi_module.input_filter(
|
||||
PARSE_SERVER, dynamic_variables[i], &dynamic_variables[i + 1],
|
||||
strlen(dynamic_variables[i + 1]), &new_val_len)) {
|
||||
php_register_variable_safe(dynamic_variables[i], dynamic_variables[i + 1],
|
||||
new_val_len, track_vars_array);
|
||||
}
|
||||
|
||||
free(dynamic_variables[i]);
|
||||
free(dynamic_variables[i+1]);
|
||||
free(dynamic_variables[i + 1]);
|
||||
}
|
||||
|
||||
free(dynamic_variables);
|
||||
}
|
||||
|
||||
static void frankenphp_register_variables(zval *track_vars_array)
|
||||
{
|
||||
static void frankenphp_register_variables(zval *track_vars_array) {
|
||||
/* https://www.php.net/manual/en/reserved.variables.server.php */
|
||||
frankenphp_server_context* ctx = SG(server_context);
|
||||
frankenphp_server_context *ctx = SG(server_context);
|
||||
|
||||
go_register_variables(ctx->current_request ? ctx->current_request : ctx->main_request, track_vars_array);
|
||||
go_register_variables(ctx->current_request ? ctx->current_request
|
||||
: ctx->main_request,
|
||||
track_vars_array);
|
||||
}
|
||||
|
||||
static void frankenphp_log_message(const char *message, int syslog_type_int)
|
||||
{
|
||||
go_log((char *) message, syslog_type_int);
|
||||
static void frankenphp_log_message(const char *message, int syslog_type_int) {
|
||||
go_log((char *)message, syslog_type_int);
|
||||
}
|
||||
|
||||
sapi_module_struct frankenphp_sapi_module = {
|
||||
@@ -619,38 +639,38 @@ sapi_module_struct frankenphp_sapi_module = {
|
||||
NULL, /* Get request time */
|
||||
NULL, /* Child terminate */
|
||||
|
||||
STANDARD_SAPI_MODULE_PROPERTIES
|
||||
};
|
||||
STANDARD_SAPI_MODULE_PROPERTIES};
|
||||
|
||||
static void *manager_thread(void *arg) {
|
||||
#ifdef ZTS
|
||||
// TODO: use tsrm_startup() directly as we know the number of expected threads
|
||||
php_tsrm_startup();
|
||||
/*tsrm_error_set(TSRM_ERROR_LEVEL_INFO, NULL);*/
|
||||
# ifdef PHP_WIN32
|
||||
#ifdef PHP_WIN32
|
||||
ZEND_TSRMLS_CACHE_UPDATE();
|
||||
# endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
sapi_startup(&frankenphp_sapi_module);
|
||||
|
||||
#ifndef ZEND_MAX_EXECUTION_TIMERS
|
||||
# if (PHP_VERSION_ID >= 80300)
|
||||
#if (PHP_VERSION_ID >= 80300)
|
||||
frankenphp_sapi_module.ini_entries = HARDCODED_INI;
|
||||
# else
|
||||
#else
|
||||
frankenphp_sapi_module.ini_entries = malloc(sizeof(HARDCODED_INI));
|
||||
memcpy(frankenphp_sapi_module.ini_entries, HARDCODED_INI, sizeof(HARDCODED_INI));
|
||||
# endif
|
||||
memcpy(frankenphp_sapi_module.ini_entries, HARDCODED_INI,
|
||||
sizeof(HARDCODED_INI));
|
||||
#endif
|
||||
#endif
|
||||
|
||||
frankenphp_sapi_module.startup(&frankenphp_sapi_module);
|
||||
|
||||
threadpool thpool = thpool_init(*((int *) arg));
|
||||
threadpool thpool = thpool_init(*((int *)arg));
|
||||
free(arg);
|
||||
|
||||
uintptr_t rh;
|
||||
while ((rh = go_fetch_request())) {
|
||||
thpool_add_work(thpool, go_execute_script, (void *) rh);
|
||||
thpool_add_work(thpool, go_execute_script, (void *)rh);
|
||||
}
|
||||
|
||||
/* channel closed, shutdown gracefully */
|
||||
@@ -682,7 +702,8 @@ int frankenphp_init(int num_threads) {
|
||||
int *num_threads_ptr = calloc(1, sizeof(int));
|
||||
*num_threads_ptr = num_threads;
|
||||
|
||||
if (pthread_create(&thread, NULL, *manager_thread, (void *) num_threads_ptr) != 0) {
|
||||
if (pthread_create(&thread, NULL, *manager_thread, (void *)num_threads_ptr) !=
|
||||
0) {
|
||||
go_shutdown();
|
||||
|
||||
return -1;
|
||||
@@ -691,8 +712,7 @@ int frankenphp_init(int num_threads) {
|
||||
return pthread_detach(thread);
|
||||
}
|
||||
|
||||
int frankenphp_request_startup()
|
||||
{
|
||||
int frankenphp_request_startup() {
|
||||
if (php_request_startup() == SUCCESS) {
|
||||
return SUCCESS;
|
||||
}
|
||||
@@ -701,13 +721,12 @@ int frankenphp_request_startup()
|
||||
SG(server_context) = NULL;
|
||||
free(ctx);
|
||||
|
||||
php_request_shutdown((void *) 0);
|
||||
php_request_shutdown((void *)0);
|
||||
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
int frankenphp_execute_script(char* file_name)
|
||||
{
|
||||
int frankenphp_execute_script(char *file_name) {
|
||||
if (frankenphp_request_startup() == FAILURE) {
|
||||
free(file_name);
|
||||
|
||||
@@ -726,9 +745,9 @@ int frankenphp_execute_script(char* file_name)
|
||||
EG(exit_status) = 0;
|
||||
php_execute_script(&file_handle);
|
||||
status = EG(exit_status);
|
||||
} zend_catch {
|
||||
status = EG(exit_status);
|
||||
} zend_end_try();
|
||||
}
|
||||
zend_catch { status = EG(exit_status); }
|
||||
zend_end_try();
|
||||
|
||||
zend_destroy_file_handle(&file_handle);
|
||||
|
||||
@@ -743,21 +762,25 @@ static char *cli_script;
|
||||
static int cli_argc;
|
||||
static char **cli_argv;
|
||||
|
||||
// Adapted from https://github.com/php/php-src/sapi/cli/php_cli.c (The PHP Group, The PHP License)
|
||||
// Adapted from https://github.com/php/php-src/sapi/cli/php_cli.c (The PHP
|
||||
// Group, The PHP License)
|
||||
static void cli_register_file_handles(bool no_close) /* {{{ */
|
||||
{
|
||||
php_stream *s_in, *s_out, *s_err;
|
||||
php_stream_context *sc_in=NULL, *sc_out=NULL, *sc_err=NULL;
|
||||
php_stream_context *sc_in = NULL, *sc_out = NULL, *sc_err = NULL;
|
||||
zend_constant ic, oc, ec;
|
||||
|
||||
s_in = php_stream_open_wrapper_ex("php://stdin", "rb", 0, NULL, sc_in);
|
||||
s_out = php_stream_open_wrapper_ex("php://stdout", "wb", 0, NULL, sc_out);
|
||||
s_err = php_stream_open_wrapper_ex("php://stderr", "wb", 0, NULL, sc_err);
|
||||
|
||||
if (s_in==NULL || s_out==NULL || s_err==NULL) {
|
||||
if (s_in) php_stream_close(s_in);
|
||||
if (s_out) php_stream_close(s_out);
|
||||
if (s_err) php_stream_close(s_err);
|
||||
if (s_in == NULL || s_out == NULL || s_err == NULL) {
|
||||
if (s_in)
|
||||
php_stream_close(s_in);
|
||||
if (s_out)
|
||||
php_stream_close(s_out);
|
||||
if (s_err)
|
||||
php_stream_close(s_err);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -767,22 +790,22 @@ static void cli_register_file_handles(bool no_close) /* {{{ */
|
||||
s_err->flags |= PHP_STREAM_FLAG_NO_CLOSE;
|
||||
}
|
||||
|
||||
//s_in_process = s_in;
|
||||
// s_in_process = s_in;
|
||||
|
||||
php_stream_to_zval(s_in, &ic.value);
|
||||
php_stream_to_zval(s_out, &oc.value);
|
||||
php_stream_to_zval(s_err, &ec.value);
|
||||
|
||||
ZEND_CONSTANT_SET_FLAGS(&ic, CONST_CS, 0);
|
||||
ic.name = zend_string_init_interned("STDIN", sizeof("STDIN")-1, 0);
|
||||
ic.name = zend_string_init_interned("STDIN", sizeof("STDIN") - 1, 0);
|
||||
zend_register_constant(&ic);
|
||||
|
||||
ZEND_CONSTANT_SET_FLAGS(&oc, CONST_CS, 0);
|
||||
oc.name = zend_string_init_interned("STDOUT", sizeof("STDOUT")-1, 0);
|
||||
oc.name = zend_string_init_interned("STDOUT", sizeof("STDOUT") - 1, 0);
|
||||
zend_register_constant(&oc);
|
||||
|
||||
ZEND_CONSTANT_SET_FLAGS(&ec, CONST_CS, 0);
|
||||
ec.name = zend_string_init_interned("STDERR", sizeof("STDERR")-1, 0);
|
||||
ec.name = zend_string_init_interned("STDERR", sizeof("STDERR") - 1, 0);
|
||||
zend_register_constant(&ec);
|
||||
}
|
||||
/* }}} */
|
||||
@@ -799,28 +822,36 @@ static void sapi_cli_register_variables(zval *track_vars_array) /* {{{ */
|
||||
|
||||
/* Build the special-case PHP_SELF variable for the CLI version */
|
||||
len = strlen(cli_script);
|
||||
if (sapi_module.input_filter(PARSE_SERVER, "PHP_SELF", &cli_script, len, &len)) {
|
||||
if (sapi_module.input_filter(PARSE_SERVER, "PHP_SELF", &cli_script, len,
|
||||
&len)) {
|
||||
php_register_variable_safe("PHP_SELF", cli_script, len, track_vars_array);
|
||||
}
|
||||
if (sapi_module.input_filter(PARSE_SERVER, "SCRIPT_NAME", &cli_script, len, &len)) {
|
||||
php_register_variable_safe("SCRIPT_NAME", cli_script, len, track_vars_array);
|
||||
if (sapi_module.input_filter(PARSE_SERVER, "SCRIPT_NAME", &cli_script, len,
|
||||
&len)) {
|
||||
php_register_variable_safe("SCRIPT_NAME", cli_script, len,
|
||||
track_vars_array);
|
||||
}
|
||||
/* filenames are empty for stdin */
|
||||
if (sapi_module.input_filter(PARSE_SERVER, "SCRIPT_FILENAME", &cli_script, len, &len)) {
|
||||
php_register_variable_safe("SCRIPT_FILENAME", cli_script, len, track_vars_array);
|
||||
if (sapi_module.input_filter(PARSE_SERVER, "SCRIPT_FILENAME", &cli_script,
|
||||
len, &len)) {
|
||||
php_register_variable_safe("SCRIPT_FILENAME", cli_script, len,
|
||||
track_vars_array);
|
||||
}
|
||||
if (sapi_module.input_filter(PARSE_SERVER, "PATH_TRANSLATED", &cli_script, len, &len)) {
|
||||
php_register_variable_safe("PATH_TRANSLATED", cli_script, len, track_vars_array);
|
||||
if (sapi_module.input_filter(PARSE_SERVER, "PATH_TRANSLATED", &cli_script,
|
||||
len, &len)) {
|
||||
php_register_variable_safe("PATH_TRANSLATED", cli_script, len,
|
||||
track_vars_array);
|
||||
}
|
||||
/* just make it available */
|
||||
len = 0U;
|
||||
if (sapi_module.input_filter(PARSE_SERVER, "DOCUMENT_ROOT", &docroot, len, &len)) {
|
||||
if (sapi_module.input_filter(PARSE_SERVER, "DOCUMENT_ROOT", &docroot, len,
|
||||
&len)) {
|
||||
php_register_variable_safe("DOCUMENT_ROOT", docroot, len, track_vars_array);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static void * execute_script_cli(void *arg) {
|
||||
static void *execute_script_cli(void *arg) {
|
||||
void *exit_status;
|
||||
|
||||
// The SAPI name "cli" is hardcoded into too many programs... let's usurp it.
|
||||
@@ -836,9 +867,10 @@ static void * execute_script_cli(void *arg) {
|
||||
zend_stream_init_filename(&file_handle, cli_script);
|
||||
|
||||
php_execute_script(&file_handle);
|
||||
} zend_end_try();
|
||||
}
|
||||
zend_end_try();
|
||||
|
||||
exit_status = (void *) (intptr_t) EG(exit_status);
|
||||
exit_status = (void *)(intptr_t)EG(exit_status);
|
||||
|
||||
php_embed_shutdown();
|
||||
|
||||
@@ -854,7 +886,8 @@ int frankenphp_execute_script_cli(char *script, int argc, char **argv) {
|
||||
cli_argc = argc;
|
||||
cli_argv = argv;
|
||||
|
||||
// Start the script in a dedicated thread to prevent conflicts between Go and PHP signal handlers
|
||||
// Start the script in a dedicated thread to prevent conflicts between Go and
|
||||
// PHP signal handlers
|
||||
err = pthread_create(&thread, NULL, execute_script_cli, NULL);
|
||||
if (err != 0) {
|
||||
return err;
|
||||
@@ -865,6 +898,5 @@ int frankenphp_execute_script_cli(char *script, int argc, char **argv) {
|
||||
return err;
|
||||
}
|
||||
|
||||
return (intptr_t) exit_status;
|
||||
return (intptr_t)exit_status;
|
||||
}
|
||||
|
||||
|
||||
25
frankenphp.h
25
frankenphp.h
@@ -1,9 +1,9 @@
|
||||
#ifndef _FRANKENPPHP_H
|
||||
#define _FRANKENPPHP_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <Zend/zend_types.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef FRANKENPHP_VERSION
|
||||
#define FRANKENPHP_VERSION dev
|
||||
@@ -32,23 +32,16 @@ frankenphp_config frankenphp_get_config();
|
||||
int frankenphp_init(int num_threads);
|
||||
|
||||
int frankenphp_update_server_context(
|
||||
bool create,
|
||||
uintptr_t current_request,
|
||||
uintptr_t main_request,
|
||||
bool create, uintptr_t current_request, uintptr_t main_request,
|
||||
|
||||
const char *request_method,
|
||||
char *query_string,
|
||||
zend_long content_length,
|
||||
char *path_translated,
|
||||
char *request_uri,
|
||||
const char *content_type,
|
||||
char *auth_user,
|
||||
char *auth_password,
|
||||
int proto_num
|
||||
);
|
||||
const char *request_method, char *query_string, zend_long content_length,
|
||||
char *path_translated, char *request_uri, const char *content_type,
|
||||
char *auth_user, char *auth_password, int proto_num);
|
||||
int frankenphp_request_startup();
|
||||
int frankenphp_execute_script(char *file_name);
|
||||
void frankenphp_register_bulk_variables(char *known_variables[27], char **dynamic_variables, size_t size, zval *track_vars_array);
|
||||
void frankenphp_register_bulk_variables(char *known_variables[27],
|
||||
char **dynamic_variables, size_t size,
|
||||
zval *track_vars_array);
|
||||
|
||||
int frankenphp_execute_script_cli(char *script, int argc, char **argv);
|
||||
|
||||
|
||||
@@ -1,29 +1,28 @@
|
||||
/* This is a generated file, edit the .stub.php file instead.
|
||||
* Stub hash: de4dc4063fafd8c933e3068c8349889a7ece5f03 */
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_frankenphp_handle_request, 0, 1, _IS_BOOL, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, callback, IS_CALLABLE, 0)
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_frankenphp_handle_request, 0, 1,
|
||||
_IS_BOOL, 0)
|
||||
ZEND_ARG_TYPE_INFO(0, callback, IS_CALLABLE, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_headers_send, 0, 0, IS_LONG, 0)
|
||||
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, status, IS_LONG, 0, "200")
|
||||
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, status, IS_LONG, 0, "200")
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_frankenphp_finish_request, 0, 0, _IS_BOOL, 0)
|
||||
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_frankenphp_finish_request, 0, 0,
|
||||
_IS_BOOL, 0)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
#define arginfo_fastcgi_finish_request arginfo_frankenphp_finish_request
|
||||
|
||||
|
||||
ZEND_FUNCTION(frankenphp_handle_request);
|
||||
ZEND_FUNCTION(headers_send);
|
||||
ZEND_FUNCTION(frankenphp_finish_request);
|
||||
|
||||
|
||||
static const zend_function_entry ext_functions[] = {
|
||||
ZEND_FE(frankenphp_handle_request, arginfo_frankenphp_handle_request)
|
||||
ZEND_FE(headers_send, arginfo_headers_send)
|
||||
ZEND_FE(frankenphp_finish_request, arginfo_frankenphp_finish_request)
|
||||
ZEND_FALIAS(fastcgi_finish_request, frankenphp_finish_request, arginfo_fastcgi_finish_request)
|
||||
ZEND_FE_END
|
||||
};
|
||||
ZEND_FE(headers_send, arginfo_headers_send) ZEND_FE(
|
||||
frankenphp_finish_request, arginfo_frankenphp_finish_request)
|
||||
ZEND_FALIAS(fastcgi_finish_request, frankenphp_finish_request,
|
||||
arginfo_fastcgi_finish_request) ZEND_FE_END};
|
||||
|
||||
@@ -5,6 +5,7 @@ ARG FRANKENPHP_VERSION=''
|
||||
ARG PHP_VERSION=''
|
||||
ARG PHP_EXTENSIONS=''
|
||||
ARG PHP_EXTENSION_LIBS=''
|
||||
SHELL ["/bin/ash", "-eo", "pipefail", "-c"]
|
||||
|
||||
RUN apk update; \
|
||||
apk add --no-cache \
|
||||
@@ -56,15 +57,14 @@ ENV PATH="${PATH}:/root/.composer/vendor/bin"
|
||||
COPY --from=composer/composer:2-bin --link /composer /usr/bin/composer
|
||||
|
||||
WORKDIR /go/src/app
|
||||
|
||||
COPY go.mod go.sum ./
|
||||
RUN go mod graph | awk '{if ($1 !~ "@") print $2}' | xargs go get
|
||||
|
||||
RUN mkdir caddy && cd caddy
|
||||
COPY caddy/go.mod caddy/go.sum ./caddy/
|
||||
|
||||
RUN cd caddy && go mod graph | awk '{if ($1 !~ "@") print $2}' | xargs go get
|
||||
WORKDIR /go/src/app/caddy
|
||||
COPY caddy/go.mod caddy/go.sum ./
|
||||
RUN go mod graph | awk '{if ($1 !~ "@") print $2}' | xargs go get
|
||||
|
||||
WORKDIR /go/src/app
|
||||
COPY *.* ./
|
||||
COPY caddy caddy
|
||||
COPY C-Thread-Pool C-Thread-Pool
|
||||
|
||||
Reference in New Issue
Block a user