Fixed issues
Bugs from previous versions and the version in which they were fixed. If you are on an affected version, upgrade or use the workaround. Open issues are on the Open issues page.
rpc.post_response was not fired for all executed requests
Verified against the code of tags 9.2.1, 10.2.3, 10.4.1 and 10.4.2.
Symptom.
- Before 10.4.2: for each HTTP request or console command, the event was fired once — for the last
rpc.pre_response. In a process batch, only one request received it, not each executed one. - 10.2.x — 10.4.1: on
kernel.terminate, the event was fired only when the carrier was theRpcFromHttpof that HTTP request. For calls via adapters (REST, etc.) it was not fired, so#[RPC\CacheRelation]invalidation and execution of notifications / callback did not work. For console commands the event was fired.
Fix. Requests are collected in PostResponseQueue, and the event is fired once for each successfully executed request — for any carrier (IRpcHttpCarrier or execution via RpcExecutor) and for each batch item.
Adapter routes overwrote each other across API groups
Affected versions: 10.2.1 — 10.4.0. Based on the 10.4.1 release notes; not verified against the code.
Symptom. Two imports of the same adapter router.yaml (for example, /mcp and /mcp/internal) produced identical route names, and the second import overwrote the first.
Fix. The adapter registers its router.yaml via IApiRouteImport; each import gets route names prefixed with the group.
#[Autowire] in RPC method arguments did not work
Affected versions: 10.0.1 — 10.3.0. Verified against the code of tags 10.0.6, 10.2.3 and 10.3.1.
Symptom. A service marked with #[Autowire] in an RPC method argument was not injected.
Cause. RpcServiceMapPass::processParams() skipped every typed parameter, so such arguments were not registered in the method's locator.
Workaround for older versions. Constructor injection.
#[RPC\Info(concat: …)] was ignored
Affected versions: 10.0.0 — 10.3.0. Verified against the code of tags 9.2.1, 10.0.6, 10.2.3 and 10.3.1.
Symptom. Methods always had the . separator regardless of concat.
Important when upgrading. After the fix, concat is applied again: if it is set and clients call methods using ., method names will change. Update the clients or remove concat.
Deprecated methods were not marked in OpenRPC
Affected versions: 9.2.1 — 10.3.0. Verified against the code of tags 9.1.5, 9.2.1, 10.2.3 and 10.3.1.
Symptom. Methods with @deprecated or #[\Deprecated] did not get "deprecated": true in the documentation, even though the flag was collected in Service::isDeprecated().
Cause. OpenRpcAdapter did not pass the flag to OpenRpcSpecBuilder::buildMethod().
XHR requests received an empty response
Affected versions: 8.0.0 — 10.3.0. Verified against the code of tags 8.0.5, 9.2.1, 10.2.3 and 10.3.1.
Symptom. A POST with the X-Requested-With: XMLHttpRequest header (for example, jQuery $.ajax) received an empty 200 response, and the method was not called.
Fix. Only a CORS preflight OPTIONS now gets an empty response.
The response cache was shared between different implementations and versions with the same name
Affected versions: 10.0.0 — 10.2.3. Verified against the code of tags 10.0.6, 10.2.3 and 10.3.1.
Symptom. Methods with the same name in different API versions or different groups, implemented by different classes, could receive each other's cached result.
Fix. The response cache key includes the implementation (Class::method) and the API version. After upgrading, the existing cache will miss once and be repopulated.
Notifications were not executed without PHP-FPM
Affected versions: 10.1.0 — 10.2.3. Verified against the code of tags 10.1.0, 10.2.3 and 10.3.1.
Symptom.
- 10.1.x: outside PHP-FPM (Apache mod_php, the PHP built-in server), the
fastcgi_finish_request()call failed with an error that the bundle silently caught, sorpc.post_responsewas not fired and the notification was not executed at all. - 10.2.x: the call was guarded by a
function_exists()check, but withoutignore_user_abort()PHP aborted execution if the client had already closed the connection, and the notification was silently lost.
In addition, execution printed the request and response to stdout via echo.
Fix. A notification is executed under any SAPI, even if the client has closed the connection; execution is logged via LoggerInterface::info().
Process batch hogged a CPU core and passed the token on the command line
Affected versions: up to and including 10.2.3. Passing the token as an argument was verified against the code of tags 10.2.3 and 10.3.1; the CPU load — based on the 10.3 release notes.
Symptom. During a process batch, the wait loop used 100% of a core; the token and the request body were passed to child processes as command-line arguments and were visible in the process list.
Fix. No busy wait loop; the token is passed via the UFO_RPC_TOKEN variable, the request via stdin.
@FROM turned an integer into a float
Affected versions: up to and including 10.2.3 (batch process mode). Based on the 10.3 release notes; not verified against the code.
Symptom. An integer result of a batch item, when substituted into another item via @FROM:<id>(<field>), became a float, and a method with an int parameter got a type error.
The application's terminate listeners did not run after RPC requests
Affected versions: up to and including 10.2.3. Verified against the code of tags 9.2.1 — 10.2.3 (propagation is stopped) and 10.3.1 (it is not).
Symptom. The application's kernel.terminate / console.terminate listeners (sending mail, flushing logs, Sentry, etc.) did not fire after RPC requests.
Cause. The bundle stopped propagation of these events.
Important when upgrading. Check the listeners that were previously silently skipped — they now run.
Batch and documentation protection on versioned addresses
Affected versions: 10.0.0 — 10.0.6, 10.1.0. Based on the 10.2 release notes; not verified against the code.
Symptom. A batch request to a versioned address (/rpc/v2) executed the items in the default version; versioned documentation addresses (/rpc/v2, /rpc/v2/postman) were not covered by protected_doc.
All client headers, including the token, were forwarded to the callback
Affected versions: 9.2.0 — 10.0.5. Verified against the code of tags 9.2.1 (all headers) and 10.0.6 (filter); intermediate 10.0.x patch versions were not checked individually.
Symptom. For a single HTTP request with $rpc.callback, the server copied all headers of the incoming request, including the RPC token (Ufo-RPC-Token) and other credentials, into the POST request to the callback URL. For callbacks from process batch items, headers were not forwarded (the child process has no HTTP request).
Cause. RpcCallbackProcessor::process() took $httpRequest->headers->all() without a filter.
Fix. Only tracing headers are forwarded: X-Request-Id, X-Correlation-Id, traceparent, tracestate, baggage. The 9.2 release notes still describe the old behavior.
What to do if you were on an affected version. If clients passed $rpc.callback pointing to hosts you do not trust, rotate the tokens that may have ended up there.
Regressions in versions 8.1.1–8.1.5
Affected versions: 8.1.1 — 8.1.5. Based on the 8.1 release notes; not verified against the code.
Symptom. Release 8.1.1 rolled back some of the changes from 8.0.4–8.1.0: enum schemas in the documentation and special $rpc parameters in RequestCarrier.
Fix. Special parameters — in 8.1.5, enum schemas — in 8.1.6. Do not stay on 8.1.1–8.1.5; use 8.1.14.