Skip to content

Commit

Permalink
Merge pull request #97 from ozh/timeouts
Browse files Browse the repository at this point in the history
Transfer & connect timeouts, in seconds & milliseconds
  • Loading branch information
rmccue committed Jan 24, 2014
2 parents 541e6d0 + b025d3c commit 628533e
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 5 deletions.
17 changes: 17 additions & 0 deletions examples/timeout.php
@@ -0,0 +1,17 @@
<?php

// First, include Requests
include('../library/Requests.php');

// Next, make sure Requests can load internal classes
Requests::register_autoloader();

// Define a timeout of 2.5 seconds
$options = array(
'timeout' => 2.5,
);

// Now let's make a request to a page that will delay its response by 3 seconds
$request = Requests::get('http://httpbin.org/delay/3', array(), $options);

// An exception will be thrown, stating a timeout of the request !
5 changes: 4 additions & 1 deletion library/Requests.php
Expand Up @@ -253,7 +253,9 @@ public static function patch($url, $headers, $data = array(), $options = array()
* options:
*
* - `timeout`: How long should we wait for a response?
* (integer, seconds, default: 10)
* (float, seconds with a millisecond precision, default: 10, example: 0.01)
* - `connect_timeout`: How long should we wait while trying to connect?
* (float, seconds with a millisecond precision, default: 10, example: 0.01)
* - `useragent`: Useragent to send to the server
* (string, default: php-requests/$version)
* - `follow_redirects`: Should we follow 3xx redirects?
Expand Down Expand Up @@ -443,6 +445,7 @@ public static function request_multiple($requests, $options = array()) {
protected static function get_default_options($multirequest = false) {
$defaults = array(
'timeout' => 10,
'connect_timeout' => 10,
'useragent' => 'php-requests/' . self::VERSION,
'redirected' => 0,
'redirects' => 10,
Expand Down
12 changes: 10 additions & 2 deletions library/Requests/Transport/cURL.php
Expand Up @@ -249,9 +249,17 @@ protected function setup_handle($url, $headers, $data, $options) {
break;
}

if( is_int($options['timeout']) or version_compare($this->version, '7.16.2', '<') ) {
curl_setopt($this->fp, CURLOPT_TIMEOUT, ceil($options['timeout']));
} else {
curl_setopt($this->fp, CURLOPT_TIMEOUT_MS, round($options['timeout'] * 1000) );
}
if( is_int($options['connect_timeout']) or version_compare($this->version, '7.16.2', '<') ) {
curl_setopt($this->fp, CURLOPT_CONNECTTIMEOUT, ceil($options['connect_timeout']));
} else {
curl_setopt($this->fp, CURLOPT_CONNECTTIMEOUT_MS, round($options['connect_timeout'] * 1000));
}
curl_setopt($this->fp, CURLOPT_URL, $url);
curl_setopt($this->fp, CURLOPT_TIMEOUT, $options['timeout']);
curl_setopt($this->fp, CURLOPT_CONNECTTIMEOUT, $options['timeout']);
curl_setopt($this->fp, CURLOPT_REFERER, $url);
curl_setopt($this->fp, CURLOPT_USERAGENT, $options['useragent']);
curl_setopt($this->fp, CURLOPT_HTTPHEADER, $headers);
Expand Down
14 changes: 12 additions & 2 deletions library/Requests/Transport/fsockopen.php
Expand Up @@ -13,6 +13,13 @@
* @subpackage Transport
*/
class Requests_Transport_fsockopen implements Requests_Transport {
/**
* Second to microsecond conversion
*
* @var integer
*/
const SECOND_IN_MICROSECONDS = 1000000;

/**
* Raw HTTP data
*
Expand Down Expand Up @@ -99,7 +106,7 @@ public function request($url, $headers = array(), $data = array(), $options = ar

$options['hooks']->dispatch('fsockopen.remote_socket', array(&$remote_socket));

$fp = stream_socket_client($remote_socket, $errno, $errstr, $options['timeout'], STREAM_CLIENT_CONNECT, $context);
$fp = stream_socket_client($remote_socket, $errno, $errstr, ceil($options['connect_timeout']), STREAM_CLIENT_CONNECT, $context);

restore_error_handler();

Expand Down Expand Up @@ -198,7 +205,10 @@ public function request($url, $headers = array(), $data = array(), $options = ar
$options['hooks']->dispatch('fsockopen.after_request', array(&$fake_headers));
return '';
}
stream_set_timeout($fp, $options['timeout']);

$timeout_sec = (int) floor($options['timeout']);
$timeout_msec = $timeout_sec == $options['timeout'] ? 0 : self::SECOND_IN_MICROSECONDS * $options['timeout'] % self::SECOND_IN_MICROSECONDS;
stream_set_timeout($fp, $timeout_sec, $timeout_msec);

$this->info = stream_get_meta_data($fp);

Expand Down
8 changes: 8 additions & 0 deletions tests/Requests.php
Expand Up @@ -137,4 +137,12 @@ public function test30xWithoutLocation() {
$this->assertEquals(302, $response->status_code);
$this->assertEquals(0, $response->redirects);
}

/**
* @expectedException Requests_Exception
*/
public function testTimeoutException() {
$options = array('timeout' => 0.5);
$response = Requests::get('http://httpbin.org/delay/3', array(), $options);
}
}

0 comments on commit 628533e

Please sign in to comment.