Alexander Stecher
356d2e1745
refactor: cleaner cgi string handling
...
Introduces C-side interned string registry (frankenphp_strings) and a frankenphp_server_vars struct to bulk-register known $_SERVER variables with pre-sized hashtable capacity.
2026-03-04 17:20:24 +01:00
Kévin Dunglas
25ed020036
feat: Windows support ( #2119 )
...
Closes #83 #880 #1286 .
Working patch for Windows support.
Supports linking to the [official PHP release (TS
version)](https://www.php.net/downloads.php ).
Includes some work from #1286 (thanks @TenHian!!)
This patch allows using Visual Studio to compile the cgo code. To do so,
it must be compiled with Go 1.26 (RC) with the following setup:
```powershell
winget install -e --id Microsoft.VisualStudio.2022.Community --override "--passive --wait --add Microsoft.VisualStudio.Workload.NativeDesktop --add Microsoft.VisualStudio.Component.VC.Llvm.Clang --includeRecommended"
winget install -e --id GoLang.Go
$env:PATH += ';C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\Llvm\bin'
cd c:\
gh repo clone microsoft/vcpkg
.\vcpkg\bootstrap-vcpkg.bat
.\vcpkg\vcpkg install pthreads brotli
# build watcher
Invoke-WebRequest -Uri "https://github.com/e-dant/watcher/releases/download/0.14.3/x86_64-pc-windows-msvc.tar " -OutFile "$env:TEMP\watcher.tar"
tar -xf "$env:TEMP\watcher.tar" -C C:\
Rename-Item -Path "C:\x86_64-pc-windows-msvc" -NewName "watcher-x86_64-pc-windows-msvc"
Remove-Item "$env:TEMP\watcher.tar"
# download php
Invoke-WebRequest -Uri "https://downloads.php.net/~windows/releases/archives/php-8.5.1-Win32-vs17-x64.zip " -OutFile "$env:TEMP\php.zip"
Expand-Archive -Path "$env:TEMP\php.zip" -DestinationPath "C:\"
Remove-Item "$env:TEMP\php.zip"
# download php development package
Invoke-WebRequest -Uri "https://downloads.php.net/~windows/releases/archives/php-devel-pack-8.5.1-Win32-vs17-x64.zip " -OutFile "$env:TEMP\php-devel.zip"
Expand-Archive -Path "$env:TEMP\php-devel.zip" -DestinationPath "C:\"
Remove-Item "$env:TEMP\php-devel.zip"
$env:GOTOOLCHAIN = 'go1.26rc1'
$env:CC = 'clang'
$env:CXX = 'clang++'
$env:CGO_CFLAGS = "-I$env:C:\vcpkg\installed\x64-windows\include -IC:\watcher-x86_64-pc-windows-msvc -IC:\php-8.5.1-devel-vs17-x64\include -IC:\php-8.5.1-devel-vs17-x64\include\main -IC:\php-8.5.1-devel-vs17-x64\include\TSRM -IC:\php-8.5.1-devel-vs17-x64\include\Zend -IC:\php-8.5.1-devel-vs17-x64\include\ext"
$env:CGO_LDFLAGS = '-LC:\vcpkg\installed\x64-windows\lib -lbrotlienc -LC:\watcher-x86_64-pc-windows-msvc -llibwatcher-c -LC:\php-8.5.1-Win32-vs17-x64 -LC:\php-8.5.1-devel-vs17-x64\lib -lphp8ts -lphp8embed'
# clone frankenphp and build
git clone -b windows https://github.com/php/frankenphp.git
cd frankenphp\caddy\frankenphp
go build -ldflags '-extldflags="-fuse-ld=lld"' -tags nowatcher,nobadger,nomysql,nopgx
# Tests
$env:PATH += ";$env:VCPKG_ROOT\installed\x64-windows\bin;C:\watcher-x86_64-pc-windows-msvc";C:\php-8.5.1-Win32-vs17-x64"
"opcache.enable=0`r`nopcache.enable_cli=0" | Out-File -Encoding ascii php.ini
$env:PHPRC = Get-Location
go test -ldflags '-extldflags="-fuse-ld=lld"' -tags nowatcher,nobadger,nomysql,nopgx .
```
TODO:
- [x] Fix remaining skipped tests (scaling and watcher)
- [x] Test if the watcher mode works as expected
- [x] Automate the build with GitHub Actions
---------
Signed-off-by: Marc <m@pyc.ac >
Co-authored-by: Kévin Dunglas <kevin@dunglas.dev >
Co-authored-by: DubbleClick <m@pyc.ac >
2026-02-26 12:38:14 +01:00
Kévin Dunglas
040ce55e17
perf: various optimizations ( #2175 )
2026-02-11 15:21:55 +01:00
Kévin Dunglas
04fdc0c1e8
fix: path confusion via unicode casing in CGI path splitting
2026-02-11 11:59:16 +01:00
Kévin Dunglas
c30fef09d3
fix: ensure $SERVER["PHP_SELF"] always starts with a slash ( #2172 )
...
Closes #2166 .
2026-02-09 13:51:55 +01:00
Alexander Stecher
0c2a0105b5
fix: let PHP handle basic auth. ( #2142 )
...
I noticed that PHP likes to handle and free basic auth parameters
internally (see
[here](9f774e3a85/main/main.c (L2739) )
and
[here](9f774e3a85/main/SAPI.c (L514-L525) )).
This PR changes it so the basic auth header is forwarded to PHP instead
of resolving it in go.
I suspect that this might fix some crashes in shutdown functions (like
#2121 and #1841 ) since it allows us freeing the `request_info` after
shutdown is finished. I haven't been able to reproduce these crashes yet
though.
2026-01-26 10:42:32 +01:00
Alexander Stecher
98573ed7c0
refactor: extract the state module and make the backoff error instead of panic
...
This PR:
- moves state.go to its own module
- moves the phpheaders test the phpheaders module
- simplifies backoff.go
- makes the backoff error instead of panic (so it can be tested)
- removes some unused C structs
2025-12-02 23:10:12 +01:00
Max
c9ad9fc55a
headerKeyCache: use otter v2 ( #2040 )
...
Benchmarks show that version 1, while extremely fast with hot keys,
becomes several times slower than no‑cache under frequent misses.
Version 2 delivers consistently better performance across all scenarios,
with no allocations and stable latency.
```
BenchmarkGetUnCommonHeaderNoCacheSequential-12 7545640 169.4 ns/op 72 B/op 4 allocs/op
BenchmarkGetUnCommonHeaderV2Sequential-12 14471982 85.98 ns/op 0 B/op 0 allocs/op
BenchmarkGetUnCommonHeaderV1Sequential-12 19748048 59.63 ns/op 0 B/op 0 allocs/op
BenchmarkGetUnCommonHeaderNoCacheParallelOneKey-12 24352088 44.47 ns/op 72 B/op 4 allocs/op
BenchmarkGetUnCommonHeaderV2ParallelOneKey-12 91024160 11.76 ns/op 0 B/op 0 allocs/op
BenchmarkGetUnCommonHeaderV1ParallelOneKey-12 192048842 6.186 ns/op 0 B/op 0 allocs/op
BenchmarkGetUnCommonHeaderNoCacheParallelRandomMaximumSize-12 26261611 43.07 ns/op 62 B/op 3 allocs/op
BenchmarkGetUnCommonHeaderV2ParallelRandomMaximumSize-12 100000000 14.43 ns/op 0 B/op 0 allocs/op
BenchmarkGetUnCommonHeaderV1ParallelRandomMaximumSize-12 137813384 8.965 ns/op 0 B/op 0 allocs/op
BenchmarkGetUnCommonHeaderNoCacheParallelRandomLenKeys-12 24224664 46.57 ns/op 71 B/op 3 allocs/op
BenchmarkGetUnCommonHeaderV2ParallelRandomLenKeys-12 69002575 17.42 ns/op 0 B/op 0 allocs/op
BenchmarkGetUnCommonHeaderV1ParallelRandomLenKeys-12 8498404 253.1 ns/op 42 B/op 1 allocs/op
```
---------
Co-authored-by: Kévin Dunglas <kevin@dunglas.fr >
2025-12-01 11:37:40 +01:00
Kévin Dunglas
8341cc98c6
refactor: rely on context.Context for log/slog and others ( #1969 )
...
* refactor: rely on context.Context for log/slog and others
* optimize
* refactor
* Apply suggestion from @Copilot
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com >
* fix watcher-skip
* better globals handling
* fix
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com >
2025-11-17 16:32:23 +01:00
Kévin Dunglas
c42d287138
refactor: extension worker ( #1910 )
...
* refactor: extension worker
* feat: optional HTTP request
* allow passing unsafe.Pointer to the extension callback
* lint
* simplify
2025-10-09 14:10:09 +02:00
Alexander Stecher
c10e85b905
refactor: cleanup context ( #1816 )
...
* Removes NewRequestWithContext.
* Moves cgi logic to cgi.go
* Calls 'update_request_info' from the C side.
* Calls 'update_request_info' from the C side.
* clang-format
* Removes unnecessary export.
* Adds TODO.
* Adds TODO.
* Removes 'is_worker_thread'
* Shortens return statement.
* Removes the context refactor.
* adjusts comment.
* Skips parsing cgi path variables on explicitly assigned worker.
* suggesions by @dunglas.
* Re-introduces 'is_worker_thread'.
* More formatting.
2025-08-25 16:18:20 +02:00
Alexandre Daubois
d2a1b619a5
feat: expose SSL_CIPHER env var ( #1693 )
2025-06-27 14:27:20 +02:00
Kévin Dunglas
8092f4a35c
chore!: update to golangci-lint-action 7 ( #1508 )
2025-04-17 20:33:22 +02:00
Alexander Stecher
f50248a7d2
refactor: removes context on the C side ( #1404 )
2025-03-10 08:44:03 +01:00
Alexander Stecher
619c903386
perf: nocallback and noescape cgo flags ( #1406 )
2025-02-28 12:08:08 +01:00
Alexander Stecher
dd250e3bda
perf: optimized request headers ( #1335 )
...
* Optimizes header registration.
* Adds malformed cookie tests.
* Sets key to NULL (releasing them is unnecessary)
* Adjusts test.
* Sanitizes null bytes anyways.
* Sorts headers.
* trigger
* clang-format
* More clang-format.
* Updates headers and tests.
* Adds header test.
* Adds more headers.
* Updates headers again.
* ?Removes comments.
* ?Reformats headers
* ?Reformats headers
* renames header files.
* ?Renames test.
* ?Fixes assertion.
* test
* test
* test
* Moves headers test to main package.
* Properly capitalizes headers.
* Allows and tests multiple cookie headers.
* Fixes comment.
* Adds otter back in.
* Verifies correct capitalization.
* Resets package version.
* Removes debug log.
* Makes persistent strings also interned and saves them once on the main thread.
---------
Co-authored-by: Alliballibaba <alliballibaba@gmail.com >
2025-01-27 21:48:20 +01:00
Alexander Stecher
2b7b3d1e4b
perf: put all $_SERVER vars into one function call. ( #1303 )
...
* Puts everything into one function call.
* Clang-format off.
* Cleans up.
* Changes function name.
* Removes unnecessary check.
* Passes hash table directly.
* Also tests that the original request path is passed.
* Puts vars into a struct.
* clang-format
---------
Co-authored-by: Alliballibaba <alliballibaba@gmail.com >
2025-01-08 08:23:23 +01:00
Alexander Stecher
045ce00c15
perf: remove some useless string pinning ( #1295 )
...
* Removes pinning.
* trigger build
* Cleans up function params.
---------
Co-authored-by: Alliballibaba <alliballibaba@gmail.com >
2025-01-05 10:07:45 +01:00
Alliballibaba2
f592e0f47b
refactor: decouple worker threads from non-worker threads ( #1137 )
...
* Decouple workers.
* Moves code to separate file.
* Cleans up the exponential backoff.
* Initial working implementation.
* Refactors php threads to take callbacks.
* Cleanup.
* Cleanup.
* Cleanup.
* Cleanup.
* Adjusts watcher logic.
* Adjusts the watcher logic.
* Fix opcache_reset race condition.
* Fixing merge conflicts and formatting.
* Prevents overlapping of TSRM reservation and script execution.
* Adjustments as suggested by @dunglas.
* Adds error assertions.
* Adds comments.
* Removes logs and explicitly compares to C.false.
* Resets check.
* Adds cast for safety.
* Fixes waitgroup overflow.
* Resolves waitgroup race condition on startup.
* Moves worker request logic to worker.go.
* Removes defer.
* Removes call from go to c.
* Fixes merge conflict.
* Adds fibers test back in.
* Refactors new thread loop approach.
* Removes redundant check.
* Adds compareAndSwap.
* Refactor: removes global waitgroups and uses a 'thread state' abstraction instead.
* Removes unnecessary method.
* Updates comment.
* Removes unnecessary booleans.
* test
* First state machine steps.
* Splits threads.
* Minimal working implementation with broken tests.
* Fixes tests.
* Refactoring.
* Fixes merge conflicts.
* Formatting
* C formatting.
* More cleanup.
* Allows for clean state transitions.
* Adds state tests.
* Adds support for thread transitioning.
* Fixes the testdata path.
* Formatting.
* Allows transitioning back to inactive state.
* Fixes go linting.
* Formatting.
* Removes duplication.
* Applies suggestions by @dunglas
* Removes redundant check.
* Locks the handler on restart.
* Removes unnecessary log.
* Changes Unpin() logic as suggested by @withinboredom
* Adds suggestions by @dunglas and resolves TODO.
* Makes restarts fully safe.
* Will make the initial startup fail even if the watcher is enabled (as is currently the case)
* Also adds compareAndSwap to the test.
* Adds comment.
* Prevents panic on initial watcher startup.
2024-12-17 11:28:51 +01:00
Kévin Dunglas
75dab8f33d
chore: bump deps and misc improvements ( #1135 )
2024-11-04 16:42:15 +01:00
Alexander Stecher
e5ca97308e
perf: optimize $_SERVER import ( #1106 )
...
Co-authored-by: Kévin Dunglas <kevin@dunglas.fr >
Co-authored-by: a.stecher <a.stecher@sportradar.com >
Co-authored-by: Alliballibaba <alliballibaba@gmail.com >
2024-11-04 15:34:00 +01:00
Kévin Dunglas
07a74e5c5a
perf: reduce allocs when creating $_SERVER ( #540 )
...
* perf: reduce allocs when creating $_SERVER
* improve
* refactor: prevent C allocs when populating $_SERVER
* cs
* remove append()
* simplify
* wip
* cleanup
* add cache
* cleanup otter init
* some fixes
* cleanup
* test with a leak
* remove const?
* add const
* wip
* wip
* allocate dynamic variables in Go memory
* cleanup
* typo
* bump otter
* chore: bump deps
2024-03-12 18:31:30 +01:00
Kévin Dunglas
aa1d968dcf
refactor: faster $_SERVER variables creation
2023-11-16 14:40:52 +01:00
Kennedy Tedesco
e7bd54cc00
Chore: remove duplicated code in populateEnv()
2023-11-01 15:51:00 +01:00
Kévin Dunglas
48908f599d
fix: ensure that SERVER_PORT is always defined
2023-09-17 13:20:16 +02:00
Kévin Dunglas
91f6620151
fix: ensure SERVER_PORT is always set
2023-07-18 14:58:22 +02:00
Dylan Blokhuis
18940108d1
feat: add support for $_SERVER['PHP_SELF'] ( #71 )
...
* PHP_SELF
* remove accidental formatting
* test: add test for PHP_SELF
Co-authored-by: Kévin Dunglas <kevin@dunglas.fr >
2022-10-28 17:25:02 +02:00
Kévin Dunglas
7d81fa51fe
feat: add a woker mode ( #1 )
...
* refactor: better memory management
* wip
* tmp
* introduce a go-like api
* upgraded to PHP 8.2
* Fix thread safety issues
* fix tests
* wip
* refactor worker
* worker prototype
* fix populate env
* session
* improve tests
* fix Caddy tests
* refactor
2022-05-18 11:52:24 +02:00