Repository navigation
feat: upgrade to Mercure 1.0 - #2611
Conversation
6cacc6a to
2aacd4c
Compare
alexandre-daubois
left a comment
There was a problem hiding this comment.
I know it's a draft so feel free close anything that was already planned to be fixed 🙂
7fb6208 to
6c8e74e
Compare
alexandre-daubois
left a comment
There was a problem hiding this comment.
Congrats on the 1.0 release! 🎉
|
There's a small issue here @dunglas - rebuilds from source currently already lead to Mercure 1.0. I just updated my dev environment to 8.6-rc2 and was met with some fields not being recognised anymore until I change the compatibility level to 8. |
|
Which ones? |
|
Jwt subscriber and publisher token iirc. I can check again tomorrow. Startup errored out saying they live under jwt now and in order to keep working as they used to, compatibility level has to be set to 8. |
|
Yes, it's intended. |
|
Yes, that's not the issue - the issue is that duo to Go automatically updating, building FrankenPHP right now already pulls in Mercure v1.0.0, without a new release. So right now php 8.2-8.5 have frankenphp-1.12.7 with Mercure 0.24.0, php 8.6 (rc released yesterday) has frankenphp-1.12.7 with Mercure 1.0.0. |
Publish-side validation is part of the protocol now: report what Update.Validate() rejects (reserved topics and event types, forbidden event IDs, invalid UTF-8 data) as a ValueError carrying the reason, and the dispatch failures as a RuntimeException. The subscribe query parameter becomes "match", so hot reloading advertises its topic with it. The publisher_jwt and subscriber_jwt directives now require the compatibility mode, which drops the audience, expiration and issuer checks: bind the keys to a trusted issuer instead.
The publisher_jwt and subscriber_jwt directives only work in the compatibility mode of the hub, which FrankenPHP is built without. Octane writes every entry of the mercure array as a Caddyfile line, so the issuer block is passed as a multi-line value.
Like the official Mercure binaries and images, ship the deprecated_topic and deprecated_claim build tags so protocol_version_compatibility 8 can accept 0.x tokens and topic selectors during a migration. The hub stays in modern mode unless the directive is set. Static builds go through static-php-cli, which sets the tags itself and needs a matching change.
MERCURE_TRUSTED_ISSUERS is a list separated by commas or whitespace, each identifier bound to the same publisher and subscriber keys.
The caddy module only takes what Mercure 1.0.0 requires: a broader bump outruns the versions Caddy 2.11.4 compiles against (automemlimit, cel-go).
The hub validates the update in Publish(), so the extra Validate() call is dropped and its error is classified with errors.Is against the exported sentinels, then raised through zend_argument_value_error() with the position of the argument at fault. Non-string topics are rejected in C with the standard TypeError wording instead of a Go type name. Tests cover the missing hub, a failing transport, the invalid id and the non-string topic cases.
symfony/mercure 0.8 requires the sub and client_id claims of RFC 9068 and the Hub must be told the protocol version to write the 1.0 cookie.
The protocol requires the hub to assign an ID to every update, so an empty one is a transport bug rather than a case to handle.
golang.org/x/net v0.59.0 deprecates http2.Transport in favor of http.Transport with Protocols, which staticcheck now flags.
The security release scopes pooled transports by hub name and allows a single unnamed hub per configuration, so the second test hub gets a name.
automemlimit and cel-go stay at the versions Caddy 2.11.4 compiles against.
a5569e6 to
0eee4db
Compare
…e solo HTTPS Aggiunta una sezione dedicata in Fase 4 con causa esatta (php/frankenphp#2611), cosa e' cambiato in config/mercure.php e nei tre Caddyfile, il secondo bug trovato dal vivo (hardening "un hub senza nome" di Mercure 1.0.2) e la conseguente semplificazione a solo HTTPS. Aggiornate anche le righe HTTPS e Realtime della tabella di contesto, che descrivevano ancora il vecchio motivo (QZ Tray) per tenere HTTP in parallelo - QZ Tray e' stato rimosso in Fase 4, quel motivo non c'e' piu'. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Upgrades
github.com/dunglas/mercureandgithub.com/dunglas/mercure/caddyfromv0.24.2tov1.0.2, and adapts the integration to the protocol changes of draft-dunglas-mercure-08.mercure_publish()The hub validates updates before dispatching them, so the function now distinguishes the caller's mistakes from a failed publication:
ValueErrorcarrying the reason for a topic addressing the reserved/.well-known/mercurenamespace or equal to*, an$idstarting with#or equal toearliest, a$typeequal tomercure, control characters, invalid UTF-8$data, or no topic at all;RuntimeExceptionwith the message of the hub when the dispatch fails.The negative values of
$retryare also rejected, as the protocol only allows digits in that field.An enum in
frankenphp.hreplaces the status codesgo_mercure_publish()returned as bare integers. On the way, an array of topics that cannot be converted no longer reportsNo Mercure hub configured.Hot reloading
The subscribe query parameter of the protocol is
match, so$_SERVER['FRANKENPHP_HOT_RELOAD']advertises/.well-known/mercure?match=<topic>. Thetopicparameter it replaces is only honored by a hub built with thedeprecated_topictag, which FrankenPHP doesn't set.Hub configuration
Setting
publisher_jwtorsubscriber_jwtwithoutprotocol_version_compatibilityis a configuration error now, because that mode also drops the requiredexp, the audience check, theat+jwtcheck and the issuer check. The keys are bound to a trusted issuer instead:php-server --mercureand the sampleCaddyfilefollow.MERCURE_TRUSTED_ISSUERSaccepts several identifiers separated by commas or whitespace, all bound to the same keys.FrankenPHP is built with the
deprecated_topicanddeprecated_claimtags of the hub, like the official Mercure binaries, soprotocol_version_compatibility 8accepts the 0.x tokens andtopic=selectors during a migration. Static builds get the tags through static-php-cli: crazywhalecc/static-php-cli#1240.Docs
docs/mercure.mdand the Laravel Octane section ofdocs/laravel.mddescribe the 1.0 configuration. Octane writes each entry of itsmercurearray as aCaddyfileline, so theissuerblock is passed as a multi-line value (verified withcaddy adaptand a live hub). The Symfony example targets symfony/mercure 0.8, which shipsProtocolVersion::V1.The translations of
docs/mercure.mdanddocs/laravel.mdstill describe the 0.x configuration.The other Go dependencies are updated on the way.