FrankenPHP 1.13.0 se publicó el 4 de octubre a las 14:01. El servidor Caddy incluido se actualiza de la versión 2.11.4, usada en FrankenPHP 1.12.7, a la 2.11.7. Mercure 1.0 queda integrado. La versión también añade compatibilidad con PHP 8.6 y actualiza la toolchain de Go a Go 1.27.

Se corrigen cinco problemas de seguridad. La resolución de SCRIPT_FILENAME en Windows ya no puede salir de la raíz de documentos, según GHSA-868c-7h7m-mmj9. Caddy 2.11.7 descarta por defecto los encabezados con puntos. Esto corrige una suplantación relacionada con el mapeo de PHP de Foo.Bar a HTTP_FOO_BAR, identificada como GHSA-qcrp-8483-f2f2. La división de rutas CGI exige ahora un límite entre segmentos. /uploads/a.php.txt/b.php ya no puede ejecutar uploads/a.php, según GHSA-xxjp-cjxr-2x6m. putenv() ha dejado de escribir en el entorno del sistema operativo asociado al proceso. Los valores ya no se comparten entre peticiones y threads, como cubre GHSA-996f-w38m-f574. Un array creado especialmente para frankenphp_log() ya no provoca el cierre de todo el servidor, según GHSA-4prg-hv4r-g6mv. Dos de las cinco vulnerabilidades tienen una calificación alta.

Caddy 2.11.7 incorpora protección contra Slowloris. Los tiempos de espera de lectura y escritura se reinician tras cada operación correcta. Las conexiones bloqueadas se terminan. La directiva timeouts permite ajustar estos valores por ruta. El matcher url_pattern sigue el estándar web URLPattern y admite grupos con nombre, comodines y expresiones regulares. Los grupos capturados se convierten en placeholders.

El encabezado de respuesta Incremental: ?1 sigue la RFC 10036 y ofrece una alternativa estandarizada a X-Accel-Buffering de NGINX. reverse_proxy y encode envían estas respuestas sin demora. Los eventos enviados por el servidor detrás de encode también se transmiten sin buffering, lo que beneficia a Mercure. El apagado ordenado espera a los servidores de configuraciones anteriores para que las respuestas de larga duración sobrevivan a una recarga. La opción global tls_automate_names gestiona certificados para nombres que no aparecen en bloques de sitio.

La búsqueda de certificados TLS es aproximadamente dos veces más rápida y usa 10 asignaciones en lugar de 15. El proxy inverso vacía correctamente las respuestas parciales, propaga el TCP half-close en streams actualizados y separa las comprobaciones de salud activas según su configuración. Las opciones expected_underscore_headers y expected_dot_headers permiten conservar encabezados que Caddy descarta por defecto.

Mercure 1.0 modifica mercure_publish(). La función lanza ValueError cuando la actualización usa un topic del espacio reservado /.well-known/mercure, un ID que empieza por #, caracteres de control, UTF-8 no válido, un valor retry negativo o ningún topic. Un fallo en el envío produce RuntimeException con el mensaje del hub. El nuevo bloque issuer vincula las claves de publicadores y suscriptores a un emisor de confianza. El Caddyfile de ejemplo y php-server --mercure usan esta configuración.

La configuración se valida antes de sustituir la que está activa. La falta de un archivo de worker, un nombre de worker duplicado o un presupuesto de threads incoherente mantienen en servicio la configuración actual. Los usuarios de la biblioteca pueden usar frankenphp.Validate().

Cambia el cálculo de threads. num_threads cuenta ahora los threads disponibles para peticiones que ningún worker atiende. Los threads de los workers se suman aparte. Una configuración con num_threads y workers inicia por ello más threads. El arranque falla si max_threads es menor que num_threads más los threads de workers. El error muestra las tres cifras. Los valores predeterminados no cambian.

En Mercure, usar publisher_jwt o subscriber_jwt sin protocol_version_compatibility convierte la configuración en inválida. El bloque issuer debe encargarse de vincular las claves a un emisor de confianza. Durante una recarga en caliente, $_SERVER['FRANKENPHP_HOT_RELOAD'] expone ahora /.well-known/mercure?match=<topic>. Las URL fijadas con ?topic= deben actualizarse.

Caddy limita por defecto los encabezados de petición a 16 KiB. max_header_size permite aumentar el límite. Las lecturas y escrituras bloqueadas se cancelan después de un minuto. Los encabezados con puntos se filtran igual que los que contienen guiones bajos. El client_auth de un sitio wildcard ya no se aplica a sitios más específicos. También se rechazan otras configuraciones inválidas. Las compilaciones de PHP sin --disable-zend-signals, es decir, las compilaciones ZTS, se niegan a iniciar y muestran un error explícito. Así se evita un bloqueo con crecimiento de memoria.

Las extensiones PHP basadas en Go reciben Thread(index), PHPThread.Pin(), PHPThread.IsRequestDone() y la función C frankenphp_thread_index(). Los bloques php_server se reflejan en el lado de FrankenPHP para mantener las peticiones y los workers dentro de su bloque. phpinfo() incluye una sección de FrankenPHP con la versión de Caddy. El código Go puede añadir filas mediante frankenphp.AddPHPInfoEntry(). Desde PHP 8.5, php-cli utiliza la SAPI CLI integrada de PHP. Los reinicios de la memoria compartida de Opcache se registran y se cuentan desde PHP 8.4 con la métrica experimental frankenphp_opcache_restarts{reason}. Estos reinicios son inseguros bajo ZTS, donde el contador debería permanecer en cero. Los registros de arranque muestran ahora total_threads y worker_threads.

Las peticiones que llegan antes de que estén listos los threads normales ya no se quedan colgadas. Desaparecen las respuestas 499 y 504 aleatorias tras iniciar un contenedor. Los fallos de workers se registran con nivel warning y su estado de salida. Shutdown() ya no espera indefinidamente a un worker que abandonó el arranque después de max_consecutive_failures. Las compilaciones estáticas impiden que la extensión parallel incluida convierta errores de Go recuperables en cierres del proceso. El array de extensiones retenido por register_extensions queda protegido frente a un posible use-after-free. extgen ya admite parámetros agrupados y nullable, callables, retornos mixed, wrappers de métodos, constantes y literales enteros en las extensiones generadas.

La documentación registra los ajustes del motor que persisten entre peticiones en modo worker, incluidos ini_set(), stream_context_set_default(), date_default_timezone_set() y chdir(). También describe las diferencias del filtrado de peticiones HTTP y amplía la documentación de métricas. Se añadió una página sobre Yii 3. El fragmento de hot reload usa la URL CDN corregida de Idiomorph. Las traducciones al turco quedaron completadas.