diff --git a/httprl.module b/httprl.module index d55b543..56aad92 100644 --- a/httprl.module +++ b/httprl.module @@ -18,6 +18,12 @@ define('HTTP_FUNCTION_TIMEOUT', -3); define('HTTP_STREAM_SELECT_TIMEOUT', -4); /** + * Error code indicating that the endpoint server has refused or dropped the + * connection. + */ +define('HTTP_CONNECTION_REFUSED', -5); + +/** * Implement hook_menu(). */ function httprl_menu() { @@ -462,49 +468,70 @@ function httprl_send_request($fp = NULL, $url = '', $request = '', $options = '' // Run the loop as long as we have a stream to read/write to. $empty_runs = 0; + $stream_select_timeout = 1; while (!empty($streams)) { // Check for timeouts. $current_time = timer_read($timer_name) / 1000; + $global_time = $global_timeout - timer_read($timer_name) / 1000; foreach ($streams as $id => $fp) { // Calculate how much time is left of the original timeout value. $timeout = $responses[$id]->options['timeout'] - $current_time; if ($timeout <= 0) { // Stream timed out & the request is not done. - $responses[$id]->error = 'request timed out'; + if ($responses[$id]->status == 'in progress') { + $responses[$id]->error = 'request timed out, write'; + // If stream is not done writing, then remove one from the write count. + $stream_write_count--; + } + else { + $responses[$id]->error = 'request timed out'; + } $responses[$id]->code = $http_request_timeout; $responses[$id]->status = 'Done.'; $responses[$id]->options['timeout'] = $timeout; fclose($fp); unset($streams[$id]); - // If stream is not done writing, then remove one from the write count. - if ($responses[$id]->status == 'in progress') { - $responses[$id]->error = 'request timed out, write'; - $stream_write_count--; - } } - } - // See if function timed out. - $global_time = $global_timeout - timer_read($timer_name) / 1000; - if ($global_time <= 0) { - foreach ($streams as $id => $fp) { + // See if function timed out. + if ($global_time <= 0) { // Function timed out & the request is not done. - $responses[$id]->error = 'function timed out'; + if ($responses[$id]->status == 'in progress') { + $responses[$id]->error = 'function timed out, write'; + // If stream is not done writing, then remove one from the write count. + $stream_write_count--; + } + else { + $responses[$id]->error = 'function timed out'; + } $responses[$id]->code = HTTP_FUNCTION_TIMEOUT; $responses[$id]->status = 'Done.'; $responses[$id]->options['timeout'] = $global_time; fclose($fp); unset($streams[$id]); - // If stream is not done writing, then remove one from the write count. - if ($responses[$id]->status == 'in progress') { - $responses[$id]->error = 'request timed out, write'; - $stream_write_count--; + } + + // See if end server has dropped the connection. + if ($empty_runs > 10) { + $socket_name = stream_socket_get_name($fp, TRUE); + if (empty($socket_name)) { + // Connection was dropped. + if ($responses[$id]->status == 'in progress') { + // If stream is not done writing, then remove one from the write count. + $stream_write_count--; + } + $responses[$id]->error = 'connection refused/dropped'; + $responses[$id]->code = HTTP_CONNECTION_REFUSED; + $responses[$id]->status = 'Done.'; + $responses[$id]->options['timeout'] = $timeout; + fclose($fp); + unset($streams[$id]); } } } - // All streams timed out. + // All streams removed; exit loop. if (empty($streams)) { break; } @@ -537,8 +564,9 @@ function httprl_send_request($fp = NULL, $url = '', $request = '', $options = '' $read = $write = $this_run; $except = array(); - // Do some voodoo and open all streams at once. - $n = stream_select($read, $write, $except, 1); + // Do some voodoo and open all streams at once. Wait 25ms for streams to respond. + $n = stream_select($read, $write, $except, $stream_select_timeout, 25000); + $stream_select_timeout = 0; // We have some streams to read/write to. if (!empty($n)) { @@ -679,17 +707,12 @@ function httprl_send_request($fp = NULL, $url = '', $request = '', $options = '' $responses[$id]->error = 'stream_select timed out'; $responses[$id]->code = HTTP_STREAM_SELECT_TIMEOUT; $responses[$id]->status = 'Done.'; - $responses[$id]->options['timeout'] = $global_time; + $responses[$id]->options['timeout'] = $responses[$id]->options['timeout'] - $current_time; fclose($fp); unset($streams[$id]); } break; } - - // Sleep for 25ms if there are open streams and no data was transfered. - if (!empty($streams) && !$rw_done) { - usleep(25000); - } } // Stop the timer.