PHP Script not timing out while using curl_exec( )

3 days ago 1
ARTICLE AD BOX

I have a php shell script that runs at scheduled intervals via launchd. The script has a 2 minute php timeout, but I understand that time spend in curl_exec( ) doesn't count towards that. But I also have a 10 second curl_exec( ) timeout set, but that is also not applied during certain situations.

The situation is that sometimes this server gets knocked offline via ddos, and has to reset it's own TCP stack. While that is happening, when this script runs, it will usually hang on the curl_exec( ) function for as long as 6 minutes or so before finally failing.

Others have suggested, and I agree thats whats most likely going on is that internal parts of curl are hanging while trying to make the HTTP request, and these hangups are either not counting towards the timeout, or its just a bug of sorts where the whole function kind of freezes while trying to make these http requests.

Here is my code:

set_time_limit(120); $ch = curl_init($url); curl_setopt($ch,CURLOPT_USERAGENT,"Mozilla/5.0 etc"); curl_setopt($ch,CURLOPT_RETURNTRANSFER,true); curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,10); curl_setopt($ch,CURLOPT_TIMEOUT,10); curl_setopt($ch,CURLOPT_INTERFACE,OPERATING_IP); $return = curl_exec($ch);

From what I understand here, the CURLOPT_CONNECTTIMEOUT timeout is included within the CURLOPT_TIMEOUT timeout, so calling it is kind of redundant. But neither one is actually working as during TCP resets on the server, this curl call regularly takes 5 minutes or more to complete.

Is there some other way I can make this call fail QUICKLY. Its only loading a very small static file, 10 seconds is MORE than enough time to load it.

The only way I can think of, is putting the curl_exec() wrapper function in it's own separate script, and have my script call it with a command line argument that would feed it the actual URL. And then use a CLI timeout call to force it to fail after 10 seconds. But thats a mess of a solution, there has to be SOMETHING more elegant than that?

UPDATE: I don't want to add this as the official "answer" because it is still a bandaid fix. But as I mentioned in one of my comments, I converted my curl request over to an external curl command and ran that with the timeout command to force it to fail after 10 seconds.

$clicurl = "curl -A 'Mozilla/5.0 (etc)' -m 10 --interface ".OPERATING_IP." $url"; $check_result = exec("/usr/local/bin/timeout 10s $clicurl");

The -m 10 is a 10 second timeout within curl, but the timeout command within the exec( ) call forces a 10 second timeout that DOES seem to work when my tcp stack is being reset and things can't resolve. Note that the only problem I ran in to is that when this script is run by launchd, it requires the full path to timeout, unlike when I ran it manually in the terminal. That made debugging fun . . . So this is my bandaid fix. If anyone knows a way I can keep it in php and make it work, that would still be preferred.

Read Entire Article