Edit report at http://bugs.php.net/bug.php?id=54062&edit=1
ID: 54062
Comment by: ceo at l-i-e dot com
Reported by: james dot mk dot green at gmail dot com
Summary: PHP does not notice user abort
Status: Open
Type: Bug
Package: Network related
Operating System: Linux/Windows
PHP Version: Irrelevant
Block user comment: N
Private report: N
New Comment:
"I have never known this to be the case."
...
$usleep = 2000000;
...
usleep($usleep);
...
if (connection_aborted()) {
// This almost never happens!
syslog(LOG_DEBUG, 'The connection has aborted');
} else {
"almost never" or "never"?
Not really the same...
Not sure PHP even processes and abort in the middle of usleep.
2 seconds is a long time in a normal request.
Try shorter usleep.
And when you *do* get an abort, call exit to really really really END
the script, bypassing any other shutdown functions.
Previous Comments:
------------------------------------------------------------------------
[2011-02-21 15:44:03] james dot mk dot green at gmail dot com
Description:
------------
Referencing http://php.net/manual/en/features.connection-handling.php
I understand that providing PHP is writing to or reading from the web
server connection, a registered shutdown function should be called
should the client abort.
I have never known this to be the case.
I attach a simple script. It attempts to sleep then write back to the
client. It has a registered shutdown function that checks
connection_status() and connection_aborted(). According to my syslog
however, the full script executes followed by the shutdown function
which says the user is still connected, despite my pressing the browser
stop button immediately after placing the request.
I have tested this on Windows using Lighttpd with PHP 5.2, and on Ubuntu
with Apache preforking PHP 5.3. Both exhibit the same behaviour.
These tests were conducted with ignore_user_abort(true) and (false) - no
difference observed so I removed it.
Test script:
---------------
<?php
syslog(LOG_DEBUG, 'Connection opened');
register_shutdown_function('shutdown');
$usleep = 2000000;
for ($i=0; $i < 100; $i++) {
$str[$i] = '';
for ($x=0; $x < 1000; $x++) {
$str[$i] .= 'flubber';
}
}
if (isset($_REQUEST['usleep'])) {
$usleep = (int) $_REQUEST['usleep'];
}
usleep($usleep);
syslog(LOG_DEBUG, 'Completed usleep()');
echo "Thanks for waiting\n";
print_r($str);
ob_end_flush();
syslog(LOG_DEBUG, 'ob_end_flush() called');
flush();
syslog(LOG_DEBUG, 'Have flushed()');
// We get to this part regardless of having already pressed STOP
function shutdown()
{
echo "Thanks for waiting\n";
flush();
syslog(LOG_DEBUG, 'Echo completed');
// sleep(1);
syslog(LOG_DEBUG, 'Have slept');
syslog(LOG_DEBUG, 'Shutdown detected.');
syslog(LOG_DEBUG, "The result of connection_status() is: " .
connection_status());
// The above is almost always 0
if (connection_aborted()) {
// This almost never happens!
syslog(LOG_DEBUG, 'The connection has aborted');
} else {
// This almost always happens!
syslog(LOG_DEBUG, 'The connection remains');
}
}
Expected result:
----------------
syslog entries should stop when PHP writes to the client socket and
notes that the client has sent an abort signal. Then, the shutdown
function should show that the connection_status() is no longer 0, and
that the connection_aborted() method returns true.
Actual result:
--------------
syslog entries continue to Have flushed(), then show that "The result of
connection_status() is: 0." and "The connection remains."
This should not be the case. Perhaps Apache is not sending the
appropriate signal, yet neither is Lighttpd..?
------------------------------------------------------------------------
--
Edit this bug report at http://bugs.php.net/bug.php?id=54062&edit=1