diff --git a/httprl.module b/httprl.module index 1eb42c9..06756e5 100644 --- a/httprl.module +++ b/httprl.module @@ -135,6 +135,7 @@ function httprl_build_url_self($path = '', $detect_schema = FALSE) { * Some of the more useful headers: * - For POST: 'Content-Type' => 'application/x-www-form-urlencoded', * - Limit number of bytes server sends back: 'Range' => 'bytes=0-1024', + * - Compression: 'Accept-Encoding' => 'gzip, deflate', * - Let server know where request came from: 'Referer' => 'example.com', * - Content-Types that are acceptable: 'Accept' => 'text/plain', * - Send Cookies: 'Cookie' => 'key1=value1; key2=value2;', @@ -266,6 +267,10 @@ function httprl_request($url, $options = array()) { } // Try one last time without using STREAM_CLIENT_ASYNC_CONNECT. if (!$fp && $flags === STREAM_CLIENT_ASYNC_CONNECT|STREAM_CLIENT_CONNECT) { + // Start the timer. + $timer_name = mt_rand(); + timer_start($timer_name); + if (empty($options['context'])) { $fp = @stream_socket_client($socket, $errno, $errstr, $options['timeout'], STREAM_CLIENT_CONNECT); } @@ -273,6 +278,10 @@ function httprl_request($url, $options = array()) { // Create a stream with context. Allows verification of a SSL certificate. $fp = @stream_socket_client($socket, $errno, $errstr, $options['timeout'], STREAM_CLIENT_CONNECT, $options['context']); } + + $options['timeout'] = $options['timeout'] - timer_read($timer_name) / 1000; + // Stop the timer. + timer_stop($timer_name); } // Make sure the socket opened properly. @@ -421,26 +430,39 @@ function httprl_send_request($fp = NULL, $url = '', $request = '', $options = '' $timer_name = mt_rand(); timer_start($timer_name); + if (defined('HTTP_REQUEST_TIMEOUT')) { + $http_request_timeout = HTTP_REQUEST_TIMEOUT; + } + else { + $http_request_timeout = -1; + } + if (defined('HTTP_REQUEST_FWRITE_FAIL')) { + $http_request_fwrite_fail = HTTP_REQUEST_FWRITE_FAIL; + } + else { + $http_request_fwrite_fail = -2; + } + // HTTP_REQUEST_ALLOWED_REDIRECTS_EXHAUSTED is defined in + // http://drupal.org/node/1096890 + if (defined('HTTP_REQUEST_ALLOWED_REDIRECTS_EXHAUSTED')) { + $http_request_allowed_redirects_exhausted = HTTP_REQUEST_ALLOWED_REDIRECTS_EXHAUSTED; + } + else { + $http_request_allowed_redirects_exhausted = 2; + } + // Run the loop as long as we have a stream to read/write to. while (!empty($streams)) { // Check for timeouts. $current_time = timer_read($timer_name) / 1000; - $max_time_left = 0; foreach ($streams as $id => $fp) { // Calculate how much time is left of the original timeout value. $timeout = $responses[$id]->options['timeout'] - $current_time; - $max_time_left = max($max_time_left, $timeout); if ($timeout <= 0) { - if (defined('HTTP_REQUEST_TIMEOUT')) { - $http_request_timeout = HTTP_REQUEST_TIMEOUT; - } - else { - $http_request_timeout = -1; - } // Stream timed out & the request is not done. $responses[$id]->error = 'request timed out'; - $responses[$id]->code = HTTP_REQUEST_TIMEOUT; + $responses[$id]->code = $http_request_timeout; $responses[$id]->status = 'Done.'; $responses[$id]->options['timeout'] = $timeout; fclose($fp); @@ -461,7 +483,7 @@ function httprl_send_request($fp = NULL, $url = '', $request = '', $options = '' $responses[$id]->error = 'function timed out'; $responses[$id]->code = HTTP_FUNCTION_TIMEOUT; $responses[$id]->status = 'Done.'; - $responses[$id]->options['timeout'] = $timeout; + $responses[$id]->options['timeout'] = $global_time; fclose($fp); unset($streams[$id]); // If stream is not done writing, then remove one from the write count. @@ -506,7 +528,7 @@ function httprl_send_request($fp = NULL, $url = '', $request = '', $options = '' $except = array(); // Do some voodoo and open all streams at once. - $n = stream_select($read, $write, $except, max($max_time_left, 1)); + $n = stream_select($read, $write, $except, 1); // We have some streams to read/write to. if (!empty($n)) { @@ -514,8 +536,13 @@ function httprl_send_request($fp = NULL, $url = '', $request = '', $options = '' // Readable sockets either have data for us, or are failed connection attempts. foreach ($read as $r) { $id = array_search($r, $streams); + // Make sure ID is in the streams. + if ($id === FALSE) { + continue; + } // Do not read from the non blocking sockets. if (empty($responses[$id]->options['blocking'])) { + fclose($r); continue; } @@ -558,6 +585,7 @@ function httprl_send_request($fp = NULL, $url = '', $request = '', $options = '' else { $responses[$id]->status = 'Done.'; } + $responses[$id]->options['timeout'] = $responses[$id]->options['timeout'] - $current_time; fclose($r); unset($streams[$id]); } @@ -570,9 +598,10 @@ function httprl_send_request($fp = NULL, $url = '', $request = '', $options = '' if ($stream_write_count > 0) { foreach ($write as $w) { $id = array_search($w, $streams); - if ($id === FALSE || !isset($streams[$id]) || empty($responses[$id]->status) || $responses[$id]->status != 'in progress') { + if ($id === FALSE || empty($responses[$id]->status) || $responses[$id]->status != 'in progress') { continue; } + // Calculate the number of bytes we need to write to the stream. $len = strlen($responses[$id]->request); if ($len > 0) { @@ -586,16 +615,11 @@ function httprl_send_request($fp = NULL, $url = '', $request = '', $options = '' // See if we are done with writing. if ($bytes === FALSE) { - if (defined('HTTP_REQUEST_FWRITE_FAIL')) { - $http_request_fwrite_fail = HTTP_REQUEST_FWRITE_FAIL; - } - else { - $http_request_fwrite_fail = -2; - } // fwrite failed. $responses[$id]->error = 'fwrite failed'; $responses[$id]->code = $http_request_fwrite_fail; $responses[$id]->status = 'Done.'; + $responses[$id]->options['timeout'] = $responses[$id]->options['timeout'] - $current_time; $stream_write_count--; @fclose($w); unset($streams[$id]); @@ -604,6 +628,7 @@ function httprl_send_request($fp = NULL, $url = '', $request = '', $options = '' $stream_write_count--; // If this is a non blocking request then close the connection and destroy the stream. if (empty($responses[$id]->options['blocking'])) { + $responses[$id]->options['timeout'] = $responses[$id]->options['timeout'] - $current_time; fclose($w); unset($streams[$id]); $responses[$id]->status = 'Non-Blocking request sent out. Not waiting for the response.'; @@ -632,15 +657,6 @@ function httprl_send_request($fp = NULL, $url = '', $request = '', $options = '' // Stop the timer. timer_stop($timer_name); - // HTTP_REQUEST_ALLOWED_REDIRECTS_EXHAUSTED is defined in - // http://drupal.org/node/1096890 - if (defined('HTTP_REQUEST_ALLOWED_REDIRECTS_EXHAUSTED')) { - $http_request_allowed_redirects_exhausted = HTTP_REQUEST_ALLOWED_REDIRECTS_EXHAUSTED; - } - else { - $http_request_allowed_redirects_exhausted = 2; - } - // Check to see if any of the requests where a redirect. $redirects = array(); foreach ($responses as $id => $result) { @@ -751,6 +767,14 @@ function httprl_parse_data(&$result) { unset($protocol_code_array); $result->headers = array(); + // HTTP_REQUEST_ALLOWED_REDIRECTS_EXHAUSTED is defined in + // http://drupal.org/node/1096890 + if (defined('HTTP_REQUEST_ALLOWED_REDIRECTS_EXHAUSTED')) { + $http_request_allowed_redirects_exhausted = HTTP_REQUEST_ALLOWED_REDIRECTS_EXHAUSTED; + } + else { + $http_request_allowed_redirects_exhausted = 2; + } // Parse the response headers. $cookie_primary_counter = 0; @@ -869,14 +893,6 @@ function httprl_parse_data(&$result) { // Error out if we hit the max redirect. if ($result->options['max_redirects'] <= 0) { - // HTTP_REQUEST_ALLOWED_REDIRECTS_EXHAUSTED is defined in - // http://drupal.org/node/1096890 - if (defined('HTTP_REQUEST_ALLOWED_REDIRECTS_EXHAUSTED')) { - $http_request_allowed_redirects_exhausted = HTTP_REQUEST_ALLOWED_REDIRECTS_EXHAUSTED; - } - else { - $http_request_allowed_redirects_exhausted = 2; - } $result->code = $http_request_allowed_redirects_exhausted; $result->error = 'maximum allowed redirects exhausted'; }