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

2 (edited by Smartys 2005-08-02 23:43)

Re: CGI error on Admin page

You have 2 else's in a row

And when I changed it slightly I got this:

Warning: dl(): Not supported in multithreaded Web servers - use extension statements in your php.ini in c:\apache\htdocs\upload\admin_index.php on line 91

Fatal error: Cannot instantiate non-existent class: win32 in c:\apache\htdocs\upload\admin_index.php on line 92


And enabling that dll file killed Apache when I tried to load the admin index page smile

Re: CGI error on Admin page

Here's an idea -- just like the first IF statement checks to see if /proc/loadavg exists, the ELSE IF should check to see if "uptime" exists:

This works on my system:

// 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 (@file_exists('uptime') && is_readable('uptime')) {
    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';

Cheers,
Andy

Re: CGI error on Admin page

I'll have a look at it.

"Programming is like sex: one mistake and you have to support it for the rest of your life."