fread timeout with 'mod_fcgid: read timeout from pipe'
Asked Answered
B

1

5

I have an issue with a URL my application is trying to access timing out. I am trying to catch this timeout and to solve this problem am using this code:

    $timeout = 120;

    if(false == $handle = @fsockopen($host, $port, $errno, $errstr, $timeout))
    {
        throw new Exception("Could not connect to url: ".$errstr);
    }

    $getRequest = "GET {$url} HTTP/1.0\r\n";
    $getRequest .= "Host: {$urlParts['host']}\r\n";
    $getRequest .= "Connection: close\r\n\r\n";

    fwrite($handle, $getRequest);

    $maxExecutionTime = ini_get('max_execution_time');
    set_time_limit($timeout+10);
    stream_set_timeout($handle, $timeout);

    $head = fread($handle, 1024); // Read the first 1024 bytes

    if($maxExecutionTime == 0) {
        $maxExecutionTime = 30;
    }
    set_time_limit($maxExecutionTime);

    $stream_metadata = stream_get_meta_data($handle);

    if($stream_metadata['timed_out'] === true) {
        throw new Exception("Connection timed out");
    }

My URL I am using for the timeout is behind a firewall, so I can not share it, but it is designed to sleep() for 5 minutes. When I try to run this code, execution stops at $head = fread($handle, 1024); and after 90 seconds I get a 500 error from the server "Premature end of script". When I investigate at the debug level in the apache logs I see:

[Fri Aug 26 11:10:45 2011] [warn] [client 192.168.10.202] mod_fcgid: read timeout from pipe
[Fri Aug 26 11:10:45 2011] [error] [client 192.168.10.202] Premature end of script headers: validateUrl.php

with 'validateUrl.php' being the url I am accessing this script through. I'm not sure increasing FcgidIOTimeout to a higher value is safe, as it would apply to all of my pages. Any ideas/ comments?

System details: PHP Version 5.2.13 running on Windows NT EPG-WEB 5.2 build 3790 Apache: Apache/2.2.19 (Win32) mod_fcgid/2.3.6

Bobodioulasso answered 26/8, 2011 at 2:32 Comment(2)
Try using lib curl, it does http and timeout handling for youBuber
I need pretty strict control over the data flowing back and forth to the server, so I'd like to stick with sockets if I can.Bobodioulasso
B
15

Try some of those directives in your httpd.conf:

<IfModule fcgid_module>

    FcgidIOTimeout 1200
    FcgidConnectTimeout 1200
    FcgidBusyScanInterval 1200
    FcgidBusyTimeout 1200
    FcgidErrorScanInterval 1200
    FcgidIdleScanInterval 1200
    FcgidIdleTimeout 1200

    FcgidProcessLifeTime 3600
    FcgidZombieScanInterval 1200

</IfModule>

source: http://httpd.apache.org/mod_fcgid/mod/mod_fcgid.html

Boyfriend answered 14/3, 2012 at 9:58 Comment(1)
It's handy to set up FcgidIOTimeout and FcgidBusyTimeout to exceed the max_execution_time in PHP. However, you'll probably want to leave the *Interval times as default, or as a multiple of the corresponding value, or the timeout for the corresponding value may be almost double of what you set it (i.e. actual Busy timeout may be BusyTimeout + BusyScanInterval).Hootenanny

© 2022 - 2024 — McMap. All rights reserved.