Package home | Report new bug | New search | Development Roadmap Status: Open | Feedback | All | Closed Since Version 2.6.0

Request #5735 No "true" timeout exists
Submitted: 2005-10-20 19:46 UTC
From: sprice Assigned: avb
Status: Closed Package: HTTP_Request2
PHP Version: 4.4.0 OS: Mac
Roadmaps: 0.2.0    
Subscription  


 [2005-10-20 19:46 UTC] seth at pricepages dot org
Description: ------------ I'm not sure if this is a bug or a feature request, but although there exists two timeout options in HTTP_Request, it can be delayed indefinitely. This is done by sending a little data at a time. The documentation says: "timeout - Connection timeout in seconds" "readTimeout - Timeout for reading / writing data over the socket" It seems to imply that there is a true way to limit the connection time, but there is not. (Leading to some of my pages taking a 22 seconds to render.) I think that the way to be the most BC would be to make a third timeout option that limits the total time taken (including connection time and redirects). This option could be checked after each socket read. If requested, I could implement this. Test script: --------------- test.php: <?php require_once('PEAR.php'); require_once('HTTP/Request.php'); $url = 'http://pricepages.org/pear/slow_page.php'; $req = new HTTP_Request($url, array( 'timeout' => 2, 'readTimeout' => array(2,0))); $req->sendRequest(); ?> slow_page.php: <?php sleep(1); ob_end_flush(); for($i = 0; $i < 100; $i++){ echo "a big block of text, just rendered "; flush(); usleep(100000); } ?> Expected result: ---------------- $ time php -f test.php real 0m2.000s user 0m0.085s sys 0m0.059s Actual result: -------------- $ time php -f test.php real 0m12.258s user 0m0.085s sys 0m0.059s

Comments

 [2005-11-06 18:38 UTC] avb
I have a feeling that such feature may easily be implemented by attaching a Listener to the HTTP_Request instance, with no need to patch the class itself, except probably a means to make the Response class stop receiving data. Can you try doing this?
 [2005-11-08 05:17 UTC] seth at pricepages dot org
Would the best way to do this be to readAll() from the socket in non-blocking mode and then after each read, check the utime? (That is the best I can think of.) There would also need to be another option passed into the constructor for the true timeout time. (Instead of the other fake times :)
 [2005-11-08 09:50 UTC] avb
I'd not use the word "fake" there. "Timeout" usually means that you didn't receive any data for N seconds, not that you *were* receiving data for N seconds already. As for my suggestion: HTTP_Response sends a tick / gzTick event to its Listeners after receiving each portion of data. Consult the download-progress.php example where this is used for drawing a progress-bar. One can add a check of elapsed time in a Listener.
 [2005-11-08 17:31 UTC] seth at pricepages dot org
Please excuse any of my ignorance, I haven't worked at the socket level before. (Well, only once, and that was for a Comp. Sci. class.) I think the problem that I am having with the listener is that I don't see how the listener can respond to an expired timeout. It can check the elapsed time, but it can't do anything about it without changing the interface between the Response and the Listener classes. Also, no ticks are called during the reading of the header (from what I can tell from the code). I suppose I could add a "shouldEndRequest()" method to the Listener class that returns a boolean, but you run into problems with multiple listeners, or calling Request::getResponseBody after a listener ends the request. It just seems like it opens up a big can of unpredictable behavior. Also, how would the Listener deal with setting the socket's timeout so the various Socket::readLine calls would return at an appropriate time? Instead of shouldEndRequest, we could use timeRemaining, and for each readLine call, set the socket timeout to be the time returned from timeRemaining. The best way that I see it working is if the code is located in the request and response classes. However, if you prefer shouldEndRequest or timeRemaining, I'd be willing to work on it.
 [2006-10-11 11:01 UTC] lobbin at gmail dot com (Robin Ericsson)
This is related to a problem with readTimeout I'm having. As far as I've debugged this. HTTP_Request sets this on Net_Socket which uses stream_set_timeout , but something probably in Net_Socket or PHP makes the timeout not work, however, it works with the really small example available on stream_set_timeout manual page.
 [2008-10-17 21:12 UTC] avb (Alexey Borzov)
Moving feature requests to HTTP_Request2.
 [2009-01-04 11:24 UTC] avb (Alexey Borzov)
Impemented in CVS. The request will now throw an exception if it takes more seconds than given 'timeout' parameter.