FrankenPHP 1.13.0 a été publiée le 4 octobre à 14:01. Le serveur Caddy intégré passe de la version 2.11.4, utilisée par FrankenPHP 1.12.7, à la version 2.11.7. Mercure 1.0 est désormais embarqué. La version prend aussi en charge PHP 8.6 et met à jour la toolchain Go vers Go 1.27.

Cinq problèmes de sécurité sont corrigés. La résolution de SCRIPT_FILENAME sous Windows ne permet plus de sortir de la racine documentaire, avec le correctif GHSA-868c-7h7m-mmj9. Caddy 2.11.7 rejette par défaut les en-têtes contenant un point. Cela corrige une usurpation liée à la conversion PHP de Foo.Bar en HTTP_FOO_BAR, référencée par GHSA-qcrp-8483-f2f2. Le découpage du chemin CGI exige désormais une limite entre segments. /uploads/a.php.txt/b.php ne peut donc plus exécuter uploads/a.php, selon GHSA-xxjp-cjxr-2x6m. putenv() n’écrit plus dans l’environnement système du processus. Les valeurs ne passent plus d’une requête ou d’un thread à l’autre, conformément à GHSA-996f-w38m-f574. Un tableau spécialement construit transmis à frankenphp_log() ne fait plus tomber tout le serveur, selon GHSA-4prg-hv4r-g6mv. Deux des cinq problèmes ont un niveau élevé.

Caddy 2.11.7 ajoute une protection contre Slowloris. Les délais d’inactivité des lectures et des écritures sont réinitialisés après une opération réussie. Les connexions bloquées sont interrompues. La directive timeouts permet d’ajuster ces valeurs par route. Le matcher url_pattern suit le standard web URLPattern et prend en charge les groupes nommés, les jokers et les expressions régulières. Les groupes capturés deviennent des placeholders.

L’en-tête de réponse Incremental: ?1 suit la RFC 10036 et fournit une solution standard au mécanisme X-Accel-Buffering de NGINX. reverse_proxy et encode transmettent immédiatement ces réponses. Les événements envoyés par le serveur derrière encode ne sont plus mis en tampon, ce qui améliore le fonctionnement de Mercure. Lors d’un arrêt gracieux, les serveurs issus des configurations précédentes sont attendus afin de préserver les réponses longues pendant un rechargement. L’option globale tls_automate_names gère les certificats de noms absents des blocs de site.

La recherche des certificats TLS est environ deux fois plus rapide et passe à 10 allocations au lieu de 15. Le reverse proxy vide correctement les réponses partielles, transmet le TCP half-close sur les flux mis à niveau et isole les contrôles de santé actifs selon leur configuration. Les options expected_underscore_headers et expected_dot_headers permettent de conserver certains en-têtes normalement supprimés par Caddy.

Mercure 1.0 modifie mercure_publish(). Un ValueError est levé pour un topic situé dans l’espace réservé /.well-known/mercure, un identifiant commençant par #, des caractères de contrôle, un UTF-8 invalide, une valeur retry négative ou l’absence de topic. Un échec de distribution produit une RuntimeException contenant le message du hub. Le nouveau bloc issuer lie les clés des éditeurs et des abonnés à un émetteur de confiance. Le Caddyfile d’exemple et php-server --mercure utilisent ce mécanisme.

La configuration est validée avant de remplacer celle qui sert les requêtes. Un fichier worker absent, un nom de worker dupliqué ou un budget de threads incohérent laisse la configuration active en place. Les utilisateurs de la bibliothèque disposent de frankenphp.Validate().

Le calcul des threads évolue. num_threads compte désormais les threads réservés aux requêtes qu’aucun worker ne sert. Les threads des workers s’ajoutent à ce nombre. Une configuration qui combine num_threads et des workers lance donc davantage de threads. Le démarrage échoue si max_threads est inférieur à num_threads plus les threads des workers. Le message affiche les trois valeurs. Les valeurs par défaut ne changent pas.

Dans Mercure, publisher_jwt ou subscriber_jwt sans protocol_version_compatibility rendent désormais la configuration invalide. Le bloc issuer doit servir à lier les clés à un émetteur de confiance. Lors d’un hot reload, $_SERVER['FRANKENPHP_HOT_RELOAD'] expose maintenant /.well-known/mercure?match=<topic>. Les URL codées en dur avec ?topic= doivent être modifiées.

Caddy limite par défaut les en-têtes de requête à 16 KiB. max_header_size permet d’augmenter cette limite. Les lectures et écritures bloquées sont interrompues après une minute. Les en-têtes contenant un point sont filtrés comme ceux contenant un underscore. Le client_auth d’un site wildcard ne s’applique plus aux sites plus spécifiques. D’autres configurations invalides sont également refusées. Un build PHP sans --disable-zend-signals, c’est-à-dire un build ZTS, refuse désormais de démarrer avec une erreur explicite. Cette règle évite un blocage accompagné d’une consommation mémoire croissante.

Les extensions PHP écrites en Go obtiennent Thread(index), PHPThread.Pin(), PHPThread.IsRequestDone() et la fonction C frankenphp_thread_index(). Les blocs php_server sont reproduits côté FrankenPHP afin de maintenir les requêtes et les workers dans leur bloc. phpinfo() affiche une section FrankenPHP avec la version de Caddy. Le code Go peut ajouter des lignes avec frankenphp.AddPHPInfoEntry(). À partir de PHP 8.5, php-cli utilise la SAPI CLI intégrée à PHP. Les redémarrages de la mémoire partagée d’Opcache sont journalisés et comptés à partir de PHP 8.4 par la métrique expérimentale frankenphp_opcache_restarts{reason}. Ces redémarrages sont dangereux sous ZTS, où le compteur doit rester à zéro. Les journaux de démarrage indiquent maintenant total_threads et worker_threads.

Les requêtes arrivant avant la préparation des threads ordinaires ne restent plus bloquées. Les réponses 499 et 504 aléatoires après le lancement d’un conteneur disparaissent. Les crashs de workers sont journalisés au niveau warning avec leur code de sortie. Shutdown() ne reste plus bloqué sur un worker ayant abandonné son démarrage après max_consecutive_failures. Les builds statiques empêchent l’extension parallel intégrée de transformer des erreurs Go récupérables en crashs du processus. Le tableau d’extensions conservé par register_extensions est protégé contre un possible use-after-free. extgen gère désormais les paramètres groupés et nullable, les callables, les retours mixed, les wrappers de méthodes, les constantes et les littéraux entiers dans les extensions générées.

La documentation recense les réglages du moteur qui persistent entre les requêtes en mode worker, notamment ini_set(), stream_context_set_default(), date_default_timezone_set() et chdir(). Elle décrit aussi les différences de filtrage des requêtes HTTP et développe la documentation des métriques. Une page consacrée à Yii 3 a été ajoutée. L’extrait de hot reload utilise désormais l’URL CDN Idiomorph corrigée. Les traductions turques ont été complétées.