Skip to content

fix!: only reset request state between worker requests - #2790

Open
dunglas wants to merge 2 commits into
mainfrom
fix/worker-reset-request-state-only
Open

dunglas wants to merge 2 commits into
mainfrom
fix/worker-reset-request-state-only

Conversation

@dunglas

@dunglas dunglas commented Oct 30, 2026

Copy link
Copy Markdown
Member

After a discussion with @TimWolla about a proposal to introduce "logical" HTTP requests hook in php-src, I think introducing reset of states not built from an incoming request in worker mode was a mistake.

Worker mode shares state between the requests a thread handles, like a long-running CLI script. FrankenPHP should only resets the state tied to the HTTP request being handled: superglobals (except $_ENV), the request body, response headers and output, and the session. That's all.

Recent releases also reset state unrelated to the request as "security" issues. This was design mistake of mine.

This PR removes those resets:

  • strtok() and http_get_last_response_headers() (added in 1.13.4)
  • error_get_last(), libxml_get_errors() and libxml_get_last_error() (added in 1.13.2)

I'll also retract the related security advisories and update the related release note. This a breaking change, but introducing these changes were also breaking changes, and bad design.
Better fix it now as this has been released recently.

Resetting them made some engine and extension state behave differently from userland state, which persists anyway. Applications that need a clean state can call error_clear_last(), libxml_clear_errors() and http_clear_last_response_headers().

The URL rewriter (output_add_rewrite_var(), session.use_trans_sid) is still reset, because it rewrites the response output.

The worker mode and security docs now state this rule and list the state that persists.

Worker mode shares state across requests like a long-running CLI script.
Resetting strtok() and http_get_last_response_headers() made state
unrelated to the HTTP request behave differently from userland state.
The URL rewriter is still reset because it belongs to the response output.
error_get_last() and libxml_get_errors() report engine and extension state
unrelated to the HTTP request. Like other shared state in worker mode, the
application clears it when needed.

@henderkes henderkes left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huh, I didn't even notice this was added.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants