feat(web): implement PHP session support for --web mode#455
Draft
Guikingone wants to merge 1 commit into
Draft
Conversation
--web mode
bf526ec to
8c4ef8f
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.
8c4ef8f to
22c7437
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
Full PHP session support for elephc's
--webmode: thesession_*()API, the$_SESSIONsuperglobal,PHP_SESSION_*/SIDconstants, file-based storage withflockconcurrency safety, and cookie / cache-limiter handling — plus complete parity for custom save handlers, session runtime configuration, a warning channel, real-time upload progress, andtrans_sidURL rewriting.Sessions are
--web-only: the bridge (crates/elephc-web) provides C-ABI session primitives and the web prelude (src/web_prelude.rs) defines the PHP-visible functions on top of them. Per-worker state lives in Rust process statics (no PHP globals to leak) and is reset each request.What's included
Core & parity
session_*()functions;$_SESSION; predefinedPHP_SESSION_*constants; file-based storage matchingsession.save_handler = filesinsys_get_temp_dir()by default.php/php_serialize/php_binary), strict mode,lazy_write, probabilistic auto-GC (gc_probability/gc_divisor/gc_maxlifetime),sid_length/sid_bits_per_character, completecache_limiterheaders.session_abort/session_reset/session_gc/session_encode/session_decode/session_commit/session_register_shutdown, withsession_write_close()auto-called at handler end via afinallyblock.Custom save handlers
SessionHandlerInterface,SessionHandler,SessionIdInterface,SessionUpdateTimestampHandlerInterface.[$obj, 'method']. Static array callables['Class', 'method']use the object form.Runtime configuration (
ini)ini_get()/ini_set()/ini_get_all()scoped to thesession.*directive surface (PHPini_getstring convention — integers as decimals, booleans as'1'/''; unknown directives returnfalse).session.auto_startseeded per worker fromELEPHC_SESSION_AUTO_START(thephp.ini-PERDIRanalog in a compiled binary); when on, the request bootstrap auto-starts the session.session.referer_check: a cookie-supplied id whose requestRefererlacks the configured substring is invalidated, starting a fresh session (session-fixation defense).Warning channel
E_*error-level constants (global, like PHP).error_log()andtrigger_error()write to the worker's stderr viafwrite(STDERR, …)(error_logtype 3 appends to a file); session misuse emits the real PHP warning/notice text (e.g.session_start()while active →E_NOTICE; mutating id/name/save_path/cookie-params while active →E_WARNING). "Headers already sent" cannot occur because output is buffered.Streaming upload progress
session.upload_progressis tracked in real time as the multipart request body is drained frame-by-frame (the body is still buffered in full for the handler), then written into the session file under shortflock(LOCK_EX)read-modify-write cycles — the lock is never held across the upload, so a concurrent poll request reads progress via theflock'd file as the cross-worker channel.php+php_serialize);cleanupon/off. Config is read at drain time (before the handler), so it is process-level viaELEPHC_SESSION_UPLOAD_PROGRESS_{ENABLED,CLEANUP}, mirroringsession.auto_start.URL rewriting (
trans_sid)session.use_trans_sid=1,session.use_only_cookies=0, and the client sent no session cookie, the buffered HTML response is rewritten (before gzip) to propagate the session id:NAME=IDappended to same-originhref/srcattributes (a/area/framepersession.trans_sid_tags) and a hidden<input>injected into<form>tags; same-originLocationheaders are rewritten too. Off-host,mailto:/javascript:, fragment-only, and already-tagged URLs are left untouched; non-text/htmland non-UTF-8 bodies pass through byte-identical. Default config (use_only_cookies=1) never rewrites: zero overhead.Enabling compiler fixes
Mixedinstance array callables[$obj, 'method'];call_user_func/call_user_func_arrayaccept aMixed/Unioncallback dispatched by runtime tag.Mixed/nullable-object slot on overwrite instead of leaking one object per reassignment.--web, fixing a pre-existing CLISIGSEGVwhen a non-web program reads$_SERVER/$_SESSIONbefore assignment.Testing
web_sessionend-to-end suite (27/0): object and 6-callable save-handler round-trips,session_abort/resetsemantics,ini_get/ini_set,referer_check,error_log/trigger_error(incl. stderr capture), streaming upload-progress round-trip, andtrans_sidrewrite / no-rewrite.Mixedcallable dispatch, upload-progress serializer (cross-checked againstphp -r) and raw-splice read-modify-write,trans_sidrewriter, and theE_*constants.git diff --checkclean, module preambles + function docblocks present, assembly-comment alignment preserved.Scope & notes
--webonly — sessions require the HTTP request lifecycle; theini, warning, andtrans_sidsurfaces are--web-scoped alongside them.SIDstays empty: automatic URL rewriting supersedes manually appendingSID, matchinguse_trans_sid=1usage.upload_progress/trans_sidconfig is honored, with the drain-timeupload_progresstoggles configurable via theELEPHC_SESSION_*env vars (thephp.inianalog).Docs
docs/php/sessions.md,docs/specs/session-support.md,ROADMAP.md(Phase 5 / 5.1 / 5.2), and anexamples/web-sessiondemo (session counter +ini_set/ini_get).