WritableResourceStream::handleWrite() enters infinite loop on broken TLS socket (EPIPE without PHP warning)
Personne n'a encore pris cette issue.
Évaluation
- Difficulté
- 2/5
- Temps estimé
- 1-3 heures
- Accessibilité débutants
- 76/100
- Type d'issue
- Bug
- Clarté
- Clairement spécifiée
- Activité
- Calme
- Stack technique
- php
- Domaine
- backend, networking
Piste de recherche
Commencez dans src/WritableResourceStream.php, au niveau du guard de handleWrite() vers la ligne 151, puis suivez l’impact des résultats de fwrite() et des avertissements capturés sur le tampon d’écriture et le listener. Reproduisez le problème avec un ReactPHP SecureServer et un client TLS arrêté brutalement alors que des écritures sont en file d’attente. Le travail est terminé lorsqu’une écriture false silencieuse ferme le flux, tandis qu’une écriture à zéro conserve le comportement existant dépendant des avertissements et ne provoque plus de boucle CPU.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Description
On PHP 8.x with react/socket's SecureServer (TLS), when a remote client disconnects abruptly, epoll reports EPOLLOUT|EPOLLHUP on the dead socket FD. WritableResourceStream::handleWrite() calls fwrite(), which returns false because the kernel write() returns -1 EPIPE. However, PHP's OpenSSL stream wrapper does not call php_error_docref() for SSL_ERROR_SYSCALL+EPIPE errors in all code paths. The set_error_handler capture therefore gets nothing ($error === null).
The guard evaluates to false, so close() is never called. WritableResourceStream then silently passes false to substr() (implicit cast to 0 in non-strict mode), leaving the write buffer unchanged and the write listener active. epoll keeps returning EPOLLOUT|EPOLLHUP, fwrite() keeps returning false silently - 100% CPU lockup.
Reproduction: use react/socket SecureServer with TLS, kill a client with kill -9 while the server has queued writes to that client.
Fix: separate the $sent === false case (hard error - always close) from $sent === 0 (may be transient EAGAIN/WANT_WRITE - only close when PHP warning is present):
// Before
if (($sent === 0 || $sent === false) && $error !== null) {
// After
if ($sent === false || ($sent === 0 && $error !== null)) {
This issue was investigated with the help of AI, but the 100% CPU usage issue is real and after applying the above fix on production, it seems to have disappeared.
- Langage dominant
- PHP
- Étoiles
- 692
- Forks
- 63
- Métriques de merge des PR
- Aucune PR mergée en 30 j
Guide de contribution
Aucun guide de contribution indexé pour ce dépôt
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Autres issues de reactphp/stream
-
Roadmap to reactphp/stream v3 Ouvertemaintenance
Difficulté 5/5 Plus d'une semaine Accessibilité débutants 20/100
Toutes les issues de reactphp/stream
Issues similaires
-
Solved site promotion gate fails on runner PHP patch drift (expects 8.2.33, runner installs 8.2.34) Ouverte
Difficulté 2/5 1-3 heures Accessibilité débutants 75/100
Automattic/blocks-engine#2161 ·
-
Difficulté 2/5 1-3 heures Accessibilité débutants 70/100
Automattic/static-site-importer#1824 ·
-
[Chore] Keep one viget-block-generator skill and replicate it, instead of four tracked copies Ouverte
Difficulté 2/5 1-3 heures Accessibilité débutants 70/100
-
Cannot reset column width Ouverte0. Needs triage bug
Difficulté 2/5 1-3 heures Accessibilité débutants 75/100
-
0. Needs triage 35-feedback bug
Difficulté 2/5 1-3 heures Accessibilité débutants 75/100