From: boen dot robot at gmail dot com Operating system: Windows Server 2008 R2 PHP version: 5.5.0 Package: Streams related Bug Type: Bug Bug description:stream_select misleads when TLS socket is used
Description: ------------ When stream_select() is called on a socket stream created by stream_socket_client() which uses TLS (with ADH), it seems to report too early. That is, it would report that that the stream can be read, but then when you try to read it, it would block, and potentially fail. The exact same code, if called without encryption, would always work just fine. Also, if right before receiving, the script is made to sleep for a while (in my case, about 100 miliseconds did the trick), the script is also fine. Sample code is hard to give, as this occurs only when the server sends large enough data at once over the encrypted connection, and I seem to be unable to mock a TLS+ADH server with PHP (which is a separate issue that, at this point, could be just me being stupid). I *think* the issue might be that stream_select() reports on the underlying socket (i.e. the data being received before decryption), rather than the *readable data* from the socket, while fread() blocks until there's at least 1 byte of readable data to be read. But this shouldn't be so IMHO. Note that this occurs not just with PHP 5.5.0, but also the latest releases of 5.4.16 and 5.3.26, and at least as early as 5.3.8. Test script: --------------- NOTE: This script is an "approximation" so to speak, in that it demonstrates the exact settings for the client where this occurs, but due to the lack of a mock server, it's not confirmed to always fail. <?php $socket = stream_socket_client( 'tls://example.com:8729', $errno, $errstr, 2, STREAM_CLIENT_CONNECT, stream_context_create( array('ssl' => array('ciphers' => 'ADH')) ) ); fwrite($socket, chr(6) . '/login' . chr(0)); $r = array($socket); $w = $e = null; if (1 === stream_select($r, $w, $e, null)) { echo fread($socket, 1); } else { echo 'stream_select() returned with errors'; } Expected result: ---------------- stream_select() should only report the encrypted socket as readable if there's at least 1 byte of readable data in the buffer that can be read by fread(). Actual result: -------------- stream_select() reports the encrypted socket as readable, but fread() blocks, and may even time out. -- Edit bug report at https://bugs.php.net/bug.php?id=65137&edit=1 -- Try a snapshot (PHP 5.4): https://bugs.php.net/fix.php?id=65137&r=trysnapshot54 Try a snapshot (PHP 5.3): https://bugs.php.net/fix.php?id=65137&r=trysnapshot53 Try a snapshot (trunk): https://bugs.php.net/fix.php?id=65137&r=trysnapshottrunk Fixed in SVN: https://bugs.php.net/fix.php?id=65137&r=fixed Fixed in release: https://bugs.php.net/fix.php?id=65137&r=alreadyfixed Need backtrace: https://bugs.php.net/fix.php?id=65137&r=needtrace Need Reproduce Script: https://bugs.php.net/fix.php?id=65137&r=needscript Try newer version: https://bugs.php.net/fix.php?id=65137&r=oldversion Not developer issue: https://bugs.php.net/fix.php?id=65137&r=support Expected behavior: https://bugs.php.net/fix.php?id=65137&r=notwrong Not enough info: https://bugs.php.net/fix.php?id=65137&r=notenoughinfo Submitted twice: https://bugs.php.net/fix.php?id=65137&r=submittedtwice register_globals: https://bugs.php.net/fix.php?id=65137&r=globals PHP 4 support discontinued: https://bugs.php.net/fix.php?id=65137&r=php4 Daylight Savings: https://bugs.php.net/fix.php?id=65137&r=dst IIS Stability: https://bugs.php.net/fix.php?id=65137&r=isapi Install GNU Sed: https://bugs.php.net/fix.php?id=65137&r=gnused Floating point limitations: https://bugs.php.net/fix.php?id=65137&r=float No Zend Extensions: https://bugs.php.net/fix.php?id=65137&r=nozend MySQL Configuration Error: https://bugs.php.net/fix.php?id=65137&r=mysqlcfg