ID: 39809
Updated by: [EMAIL PROTECTED]
Reported By: e at osterman dot com
-Status: Open
+Status: Assigned
Bug Type: CGI related
Operating System: FC6
PHP Version: 5.2.0
-Assigned To:
+Assigned To: dmitry
Previous Comments:
------------------------------------------------------------------------
[2006-12-13 06:55:06] e at osterman dot com
Reproduce Code:
<?
// test-fcgi.php - a sample FCGI client
define('FCGI_VERSION_1', 1);
define('FCGI_BEGIN_REQUEST', 1);
define('FCGI_ABORT_REQUEST', 2);
define('FCGI_END_REQUEST', 3);
define('FCGI_PARAMS', 4);
define('FCGI_STDIN', 5);
define('FCGI_STDOUT', 6);
define('FCGI_STDERR', 7);
define('FCGI_DATA', 8);
define('FCGI_GET_VALUES', 9);
define('FCGI_GET_VALUES_RESULT', 10);
define('FCGI_RESPONDER', 1);
define('FCGI_KEEP_CONN', 1);
function FCGI_Packet($type, $content)
{
$len=strlen($content);
$packet=chr(FCGI_VERSION_1).chr($type).chr(0).chr(1).chr((int)($len/256)).chr($len%256).chr(0).chr(0).$content;
return($packet);
}
function FCGI_NVPair($name, $value)
{
$nlen = strlen($name);
$vlen = strlen($value);
if ($nlen < 128)
$nvpair = chr($nlen);
else
$nvpair = chr(($nlen >> 24) | 0x80) . chr(($nlen >> 16) & 0xFF) .
chr(($nlen >> 8) & 0xFF) . chr($nlen & 0xFF);
if ($vlen < 128)
$nvpair .= chr($vlen);
else
$nvpair .= chr(($vlen >> 24) | 0x80) . chr(($vlen >> 16) & 0xFF) .
chr(($vlen >> 8) & 0xFF) . chr($vlen & 0xFF);
return $nvpair . $name . $value;
}
function FCGI_Decode($data)
{
if( strlen($data) < 8 )
die("Packet too small " . strlen($data) . "\n");
$length = (ord($data{4}) << 8)+ord($data{5});
$packet = Array( 'version' => ord($data{0}),
'type' => ord($data{1}),
'length' => $length,
'content' => substr($data, 8, $length) );
return $packet;
}
function FCGI_Connect($host, $port) {
// Connect to FastCGI server
$socket = fsockopen($host, $port, $errno, $errstr, 5);
if( !$socket )
die("Failed to connect to $host:$port\n");
return $socket;
}
function FCGI_Test($socket)
{
// Begin session
$packet = '';
$packet .= FCGI_Packet(FCGI_BEGIN_REQUEST,
chr(0).chr(FCGI_RESPONDER).chr(FCGI_KEEP_CONN).chr(0).chr(0).chr(0).chr(0).chr(0)
);
// Build params
$params = '';
$params .= FCGI_NVPair('GATEWAY_INTERFACE', 'FastCGI/1.0');
$params .= FCGI_NVPair('REQUEST_METHOD', 'GET');
$params .= FCGI_NVPair('SCRIPT_FILENAME', '/tmp/test.php');
$packet .= FCGI_Packet(FCGI_PARAMS, $params);
$packet .= FCGI_Packet(FCGI_PARAMS, null);
$packet .= FCGI_Packet(FCGI_STDIN, null);
fwrite($socket, $packet);
}
function FCGI_Response($socket)
{
// Read answers from fastcgi server
while(true)
{
if(feof($socket))
die("Socket closed\n");
$packet = fread($socket, 8);
if( $packet === false )
die("Read failed\n");
$header = FCGI_Decode($packet);
//print_r($header);
$len=$header['length']%8;
$padlen=($len?(8-$len):0);
$packet .= fread($socket, $header['length']+$padlen);
$response = FCGI_Decode($packet);
if( $response['type'] == FCGI_END_REQUEST )
break;
else
print "[{$response['type']}] [{$response['content']}]\n";
}
}
$socket1 = FCGI_Connect('localhost', 1234);
FCGI_Test($socket1);
FCGI_Response($socket1);
$socket2 = FCGI_Connect('localhost', 1234);
FCGI_Test($socket2);
FCGI_Response($socket2);
?>
<?
// /tmp/test.php - a sample cgi
echo "Hello World\n";
?>
Then start php-cgi in single process mode.
php-cgi -b 1234
Run test-fcgi.php. The second request will never return. If you only
open up 1 socket, and run multiple requests it works fine.
------------------------------------------------------------------------
[2006-12-13 03:27:22] e at osterman dot com
Description:
------------
Dimitry states in bug #37422:
> The "indle timeout" error is not a bug. It may occur
> on high load, then requests concurrency is larger
> then number of running PHP processes.
This is the incorrect behavior and makes it impossible to detect when
php-cgi is taking forever or simply ignoring you.
According to the FastCGI specification, when the server is overloaded
(e.g. connections exceed PHP_FCGI_CHILDREN), it should respond with
FCGI_END_REQUEST packet with the protocolStatus flag of
FCGI_OVERLOADED. The current behavior is php-cgi accepts the request,
but never responds -- simply discarding it. It would be much better if
PHP responded with FCGI_OVERLOADED, or simply rejected connections when
it is too busy.
http://www.fastcgi.com/devkit/doc/fcgi-spec.html#S5.5
Reproduce code:
---------------
To reproduce, open up more than PHP_FCGI_CHILDREN connections to the
php-cgi server. All connections will be accepted and all will accept
packets, but only PHP_FCGI_CHILDREN of the connections will ever return
a response. The rest of the connections will simply accept the request
and do nothing.
Expected result:
----------------
Server should respond with FCGI_END_REQUEST packet with the
protocolStatus flag of FCGI_OVERLOADED or simply reject connections
when connections exceed PHP_FCGI_CHILDREN.
Actual result:
--------------
php-cgi never responds; request is lost.
------------------------------------------------------------------------
--
Edit this bug report at http://bugs.php.net/?id=39809&edit=1