From: boen dot robot at gmail dot com
Operating system: Windows 2008 R2
PHP version: 5.6.4
Package: OpenSSL related
Bug Type: Bug
Bug description:stream_select on a TLS stream does not report last chunk as readable
Description:
------------
If one end (say, client) sends more than one chunk of data (8192 bytes)
at once, the last chunk (8192 or fewer remaining bytes) is not detected
as readable by the other end (say, server) with stream_select() on the
connection.
Issue occurs on both ends if they do reading, so whether it's server
receiving client data or client receiving server data - the same thing
happens.
This issue does not occur on a plain (non-encrypted) TCP stream. Only on
encrypted streams.
This is sort of related to #65137 in that it is apparently caused by
stream_select() reporting the underlying TCP stream, rather than the TLS
stream. By the time one calls stream_select() on the last chunk, the
last chunk has already been read from the TCP layer, and is ready to be
read, but there's no way to find that out from PHP userland. Not even
stream_get_meta_data() helps - it reports 0 unread bytes after the last
successful fread().
Test script:
---------------
Here's an echo client/server duo demonstrating the issue.
https://gist.github.com/boenrobot/f636eba79043f7303fb4
The server can be ran with the port as an argument, and an optional
second argument with the protocol (tcp or tls; defaults to tcp). The
client can be ran with the ip as a first argument, port as second, and
optional port as third (again tcp or tls; defaults to tcp).
From the client, you write the number of bytes to be sent to the server,
with PHP_EOL appended after those, after which reading is done until
PHP_EOL is found.
(I also have an equivalent Java version, which I used to confirm that
issue occurs on both client and server; You'll notice MakeKeys.php which
generates a self signed certificate and exports it in .p12 format too -
that was for the sake of Java)
Expected result:
----------------
Same as with non-encrypted sockets - you write number of bytes, you send
that many (plus EOL), and get that same many back (plus EOL), after
which you can ask for more.
Actual result:
--------------
Trying to send f.e. 8191 on Windows (so 8193 bytes with the EOL in
there) makes the server receive only 8192 bytes, and hanging on that
last one. Same with any data larger than that, except that every next
8192 bytes are received, before the last chunk.
--
Edit bug report at https://bugs.php.net/bug.php?id=68853&edit=1
--
Try a snapshot (PHP 5.4): https://bugs.php.net/fix.php?id=68853&r=trysnapshot54
Try a snapshot (PHP 5.5): https://bugs.php.net/fix.php?id=68853&r=trysnapshot55
Try a snapshot (trunk): https://bugs.php.net/fix.php?id=68853&r=trysnapshottrunk
Fixed in SVN: https://bugs.php.net/fix.php?id=68853&r=fixed
Fixed in release: https://bugs.php.net/fix.php?id=68853&r=alreadyfixed
Need backtrace: https://bugs.php.net/fix.php?id=68853&r=needtrace
Need Reproduce Script: https://bugs.php.net/fix.php?id=68853&r=needscript
Try newer version: https://bugs.php.net/fix.php?id=68853&r=oldversion
Not developer issue: https://bugs.php.net/fix.php?id=68853&r=support
Expected behavior: https://bugs.php.net/fix.php?id=68853&r=notwrong
Not enough info: https://bugs.php.net/fix.php?id=68853&r=notenoughinfo
Submitted twice: https://bugs.php.net/fix.php?id=68853&r=submittedtwice
register_globals: https://bugs.php.net/fix.php?id=68853&r=globals
PHP 4 support discontinued: https://bugs.php.net/fix.php?id=68853&r=php4
Daylight Savings: https://bugs.php.net/fix.php?id=68853&r=dst
IIS Stability: https://bugs.php.net/fix.php?id=68853&r=isapi
Install GNU Sed: https://bugs.php.net/fix.php?id=68853&r=gnused
Floating point limitations: https://bugs.php.net/fix.php?id=68853&r=float
No Zend Extensions: https://bugs.php.net/fix.php?id=68853&r=nozend
MySQL Configuration Error: https://bugs.php.net/fix.php?id=68853&r=mysqlcfg