Topic: CGI error on Admin page
When I installed PunBB, I had a problem that appears to be fairly common. Everything seemed to work properly, but the Administration page returned this error message:
The specified CGI application misbehaved by not returning a complete set of HTTP headers.
I spent a long time searching for the cause of this. It's an error message that can arise with many problems including IIS and PHP problems. This one is caused by the fact that Windows does not support the "uptime" function, which is used when the admin script calculates the server load averages.
The error arises in this part of the code in admin_index.php:
// Get the server load averages (if possible)
if (@file_exists('/proc/loadavg') && is_readable('/proc/loadavg'))
{
// We use @ just in case
$fh = @fopen('/proc/loadavg', 'r');
$load_averages = @fread($fh, 64);
@fclose($fh);
$load_averages = @explode(' ', $load_averages);
$server_load = isset($load_averages[2]) ? $load_averages[0].' '.$load_averages[1].' '.$load_averages[2] : 'Not available';
}
else if (preg_match('/averages?: ([0-9\.]+),[\s]+([0-9\.]+),[\s]+([0-9\.]+)/i', @exec('uptime'), $load_averages))
$server_load = $load_averages[1].' '.$load_averages[2].' '.$load_averages[3];
else
$server_load = 'Not available';
The problem appears to be in the "else if" block. If you're feeling daring, comment that out and you're golden.
In the alternative, you can get Windows to calculate the uptime with a call to php_w32api.dll in your php extensions. This doesn't seem to be well supported, so it may change. For now, it appears to work (I'm using php 4.3.10, so that's already old).
In the following block of code, I've expanded the "else if" block so it calculates the uptime using php_w32api.dll, creating an object called $ticks. The only thing I'm not sure about in this code is where I look at $ticks[0] -- I meant to call a string from the $ticks object, but I may be doing that wrong. Anyhow, here's the code:
// Get the server load averages (if possible)
if (@file_exists('/proc/loadavg') && is_readable('/proc/loadavg'))
{
// We use @ just in case
$fh = @fopen('/proc/loadavg', 'r');
$load_averages = @fread($fh, 64);
@fclose($fh);
$load_averages = @explode(' ', $load_averages);
$server_load = isset($load_averages[2]) ? $load_averages[0].' '.$load_averages[1].' '.$load_averages[2] : 'Not available';
}
else {
dl("php_w32api.dll");
$ticks = new win32;
$ticks->registerfunction("long GetTickCount () From Kernel32.dll");
if (preg_match("/averages?: ([0-9\.]+),[\s]+([0-9\.]+),[\s]+([0-9\.]+)/", $ticks[0], $load_averages))
$server_load = $load_averages[1].' '.$load_averages[2].' '.$load_averages[3];
}
else
$server_load = 'Not available';
Good luck to all you other Windows/PHP/PunBB coders!
Cheers,
Andy