feat(web): implement PHP session support for --web mode#455
Conversation
--web mode
8c4ef8f to
22c7437
Compare
22c7437 to
de6f286
Compare
de6f286 to
ac4de27
Compare
ac4de27 to
f8d5c2e
Compare
37bc436 to
e8af9e9
Compare
Full PHP session support for elephc's --web mode: the session_*() API, the $_SESSION superglobal, PHP_SESSION_* / SID constants, file-based storage with flock concurrency safety, and cookie/cache-limiter handling — plus complete parity for custom save handlers and session runtime configuration. Core & parity: - All session_*() functions; $_SESSION; predefined PHP_SESSION_* constants; serialize handlers (php / php_serialize / php_binary), strict mode, lazy_write, probabilistic auto-GC, sid_length/bits, cache_limiter headers, session_abort/reset/gc/encode/decode/commit/register_shutdown. - Custom save handlers via the object form (SessionHandlerInterface, SessionHandler, SessionIdInterface, SessionUpdateTimestampHandlerInterface) and the legacy 6-callable form (function-name, closure, and instance array callables). Runtime configuration (ini): - ini_get()/ini_set()/ini_get_all() scoped to the session.* directive surface (PHP ini_get string convention; unknown directives return false). - session.auto_start seeded per worker from ELEPHC_SESSION_AUTO_START; when on, the request bootstrap auto-starts the session. - session.referer_check: a cookie-supplied id whose request Referer lacks the configured substring is invalidated (session-fixation defense). Warning channel: - E_* error-level constants; error_log() and trigger_error() write to the worker stderr via fwrite(STDERR); session misuse emits the real PHP warning/notice text. Streaming upload progress: - session.upload_progress is tracked in real time as the multipart request body is drained (frame-by-frame) and written into the session file under short flock(LOCK_EX) read-modify-write cycles, so a concurrent poll request reads progress via the flock'd file; cleanup on/off; php + php_serialize handlers. URL rewriting (trans_sid): - When session.use_trans_sid=1, use_only_cookies=0, and no session cookie was sent, the buffered HTML response is rewritten (before gzip) to propagate the session id: NAME=ID appended to same-origin href/src attributes and a hidden input injected into <form> tags; same-origin Location headers rewritten too. Enabling compiler fixes: - EIR: dispatch boxed-Mixed instance array callables [$obj, 'method']; call_user_func/_array accept a Mixed/Union callback dispatched by runtime tag. - EIR static-property store ownership: acquire a borrowed value so it survives the borrow, and release the previous occupant of a boxed Mixed/nullable slot on overwrite instead of leaking it. - Gate superglobal type seeding on --web (fixes a pre-existing CLI SIGSEGV). Tests: full web-session e2e suite plus unit coverage for the callable dispatch, upload-progress serializer/RMW, trans_sid rewriter, and error constants. Docs (docs/php/sessions.md, spec, ROADMAP) and three runnable examples (examples/web-session, web-session-upload streaming progress, and web-session-trans-sid cookieless URL rewriting) included.
e8af9e9 to
f785dcb
Compare
|
@nahime0 Here's the support for session, it only works on |
|
Hi @Guikingone. Great, thanks! |
|
Hi @Guikingone I'm taking time for this cause the time needed for Non-Codegen tests exploded. I'm trying to understand if the prelude can be somehow skimmed down, or maybe injected only if the code calls any sessions function. I'll keep you posted. |
|
Hi @Guikingone, I’ve completed the session implementation audit and the follow-up work on this PR. The main fixes include:
I also clarified that The session prelude was then optimized substantially:
On the local Web integration tests have also been moved out of the Non-Codegen jobs and split into two balanced shards per supported target. Validation is now green across macOS AArch64, Linux AArch64, and Linux x86_64. GitHub reports 112 passing checks, no conflicts, A possible further optimization—sharing the remaining runtime callable selector itself—is tracked separately in #552 and is not a From my side, this is ready to merge. Thanks again for the substantial session implementation! |
Overview
Full PHP session support for elephc's
--webmode: thesession_*()API,$_SESSION, session constants, file persistence, custom handlers, runtimeconfiguration, upload progress, and
trans_sidrewriting.The implementation is version-aware across every maintained PHP minor. Use
--php-version=8.2|8.3|8.4|8.5(default:8.5) to select version-dependentsession behavior. The audit references the official
php-srcbranchesPHP-8.2,PHP-8.3,PHP-8.4, andPHP-8.5and theirext/sessionPHPTsuites.
The branch is squashed to one commit and rebased onto current
main.Session surface
$_SESSION,SID,PHP_SESSION_NONE,PHP_SESSION_ACTIVE, andPHP_SESSION_DISABLED.ext/session.SessionHandlerInterface,SessionIdInterface,SessionUpdateTimestampHandlerInterface, andSessionHandler.files, object, and legacy callable save handlers.php,php_binary, andphp_serializewire formats, including binarystrings and embedded NUL bytes.
read_and_close, GET/POST SID transport, referer checks, regeneration,shutdown write-close, upload progress, and trans-SID rewriting.
Maintained PHP version compatibility
session.cookie_httponly=0, empty SameSite, andsession.use_strict_mode=0.session_set_save_handler()deprecation;gc_probability/gc_divisorwarnings and rejection;session_create_id()prefixValueError.session.cookie_partitioned,partitionedcookie parameters, andSecure enforcement;
session_start()option keys;read_and_closevalidation;|session-key warning for thephpserializer.session_create_id()now distinguishes invalid characters, embedded NULs,and the versioned prefix-length boundary.
session_set_cookie_params()handles case-insensitive keys, numeric/unknownkey warnings, the at-least-one-valid-key rule, cookie-disable state, and the
PHP 8.5-only
partitionedkey.Runtime and lifecycle
[depth;[mode;]]pathgrammar,flock, safe openflags, complete I/O loops, recursive GC, and correct lock/unlink ordering.
abort/reset/destroy/regenerate follow PHP ordering and persistence semantics.
updateTimestamp()for capableuser handlers.
retaining request-scoped owners so bridge calls cannot invalidate borrowed
payloads.
between requests.
Runtime configuration and diagnostics
ini_get,ini_set, andini_get_allcover the session directive surface;session.cookie_partitionedappears only in the PHP 8.5 profile.auto-start/upload-progress settings.
trigger_erroranderror_logroute PHP-style notices, warnings, anddeprecations to worker stderr; file append logging is supported.
session.auto_startand upload-progress deployment settings can be seededthrough their
ELEPHC_SESSION_*environment variables.Upload progress and trans-SID
locked read-modify-write cycles, so another worker can poll it concurrently.
php,php_binary, andphp_serializepaths are covered.Locationheadersbefore compression while leaving external, unsafe, already-tagged, non-HTML,
and non-UTF-8 content untouched.
Tests and validation
The branch now contains 41 end-to-end HTTP session scenarios plus bridge,
codegen, ownership, callable, optimizer, and constant regressions.
Post-rebase local validation:
cargo buildcargo test -p elephc-web session— 50 passedcargo test --test web_session_tests— 37 passed in the grouped run;the subsequently added PHP 8.5 invalid-key case and updated version matrix
were rerun focused
and with per-test timeouts — 4 profiles passed in 72.6 seconds total
--php-version— 3 passedregeneration, abort, and ownership regressions — passed
cargo fmt --all -- --checkgit diff --checkCI owns the complete supported-target matrix: macOS AArch64, Linux AArch64,
and Linux x86_64.
Documentation and examples
docs/php/sessions.mddocs/specs/session-support.mddocs/compiling/cli-reference.mddocs/beyond-php/web.mdexamples/web-sessionexamples/web-session-uploadexamples/web-session-trans-sidScope notes
--web-only because they require an HTTP request lifecycle.files; other backends use PHP save handlers.php.iniand dynamically loaded PHP session modules are outside thestandalone compiler/runtime model.
SIDremains the predefined empty string; automatic trans-SID rewriting ownstransparent propagation in compiled web responses.