summaryrefslogtreecommitdiff
path: root/includes/common.inc
diff options
context:
space:
mode:
authorDries Buytaert <dries@buytaert.net>2010-08-17 16:03:30 +0000
committerDries Buytaert <dries@buytaert.net>2010-08-17 16:03:30 +0000
commit30ecab3775b7f0fc13fd19d6d245a0f774168d9c (patch)
treec1f154909bfe7a38cf139de42fbc3f5face01fdf /includes/common.inc
parent077617424ce4917fa6bdbb01873c0c2207342a03 (diff)
downloadbrdo-30ecab3775b7f0fc13fd19d6d245a0f774168d9c.tar.gz
brdo-30ecab3775b7f0fc13fd19d6d245a0f774168d9c.tar.bz2
- Patch #156582 by c960657, pwolanin, townxelliot, Damien Tournoud, kbahey, mikeytown2, drico, jpmckinney: drupal_http_request() should support timeout setting.
Diffstat (limited to 'includes/common.inc')
-rw-r--r--includes/common.inc41
1 files changed, 28 insertions, 13 deletions
diff --git a/includes/common.inc b/includes/common.inc
index 412c8df04..fc5971dc0 100644
--- a/includes/common.inc
+++ b/includes/common.inc
@@ -741,6 +741,8 @@ function drupal_access_denied() {
* A float representing the maximum number of seconds the function call
* may take. The default is 30 seconds. If a timeout occurs, the error
* code is set to the HTTP_REQUEST_TIMEOUT constant.
+ * - context
+ * A context resource created with stream_context_create().
* @return
* An object which can have one or more of the following parameters:
* - request
@@ -791,21 +793,27 @@ function drupal_http_request($url, array $options = array()) {
'method' => 'GET',
'data' => NULL,
'max_redirects' => 3,
- 'timeout' => 30,
+ 'timeout' => 30.0,
+ 'context' => NULL,
);
+ // stream_socket_client() requires timeout to be a float.
+ $options['timeout'] = (float) $options['timeout'];
switch ($uri['scheme']) {
case 'http':
case 'feed':
$port = isset($uri['port']) ? $uri['port'] : 80;
- $host = $uri['host'] . ($port != 80 ? ':' . $port : '');
- $fp = @fsockopen($uri['host'], $port, $errno, $errstr, $options['timeout']);
+ $socket = 'tcp://' . $uri['host'] . ':' . $port;
+ // RFC 2616: "non-standard ports MUST, default ports MAY be included".
+ // We don't add the standard port to prevent from breaking rewrite rules
+ // checking the host that do not take into account the port number.
+ $options['headers']['Host'] = $uri['host'] . ($port != 80 ? ':' . $port : '');
break;
case 'https':
// Note: Only works when PHP is compiled with OpenSSL support.
$port = isset($uri['port']) ? $uri['port'] : 443;
- $host = $uri['host'] . ($port != 443 ? ':' . $port : '');
- $fp = @fsockopen('ssl://' . $uri['host'], $port, $errno, $errstr, $options['timeout']);
+ $socket = 'ssl://' . $uri['host'] . ':' . $port;
+ $options['headers']['Host'] = $uri['host'] . ($port != 443 ? ':' . $port : '');
break;
default:
$result->error = 'invalid schema ' . $uri['scheme'];
@@ -813,12 +821,20 @@ function drupal_http_request($url, array $options = array()) {
return $result;
}
+ if (empty($options['context'])) {
+ $fp = @stream_socket_client($socket, $errno, $errstr, $options['timeout']);
+ }
+ else {
+ // 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']);
+ }
+
// Make sure the socket opened properly.
if (!$fp) {
// When a network error occurs, we use a negative number so it does not
// clash with the HTTP status codes.
$result->code = -$errno;
- $result->error = trim($errstr);
+ $result->error = trim($errstr) ? trim($errstr) : t('Error opening socket @socket', array('@socket' => $socket));
// Mark that this request failed. This will trigger a check of the web
// server's ability to make outgoing HTTP requests the next time that
@@ -840,11 +856,6 @@ function drupal_http_request($url, array $options = array()) {
'User-Agent' => 'Drupal (+http://drupal.org/)',
);
- // RFC 2616: "non-standard ports MUST, default ports MAY be included".
- // We don't add the standard port to prevent from breaking rewrite rules
- // checking the host that do not take into account the port number.
- $options['headers']['Host'] = $host;
-
// Only add Content-Length if we actually have any content or if it is a POST
// or PUT request. Some non-standard servers get confused by Content-Length in
// at least HEAD/GET requests, and Squid always requires Content-Length in
@@ -876,8 +887,12 @@ function drupal_http_request($url, array $options = array()) {
}
$request .= "\r\n" . $options['data'];
$result->request = $request;
-
- fwrite($fp, $request);
+ // Calculate how much time is left of the original timeout value.
+ $timeout = $options['timeout'] - timer_read(__FUNCTION__) / 1000;
+ if ($timeout > 0) {
+ stream_set_timeout($fp, floor($timeout), floor(1000000 * fmod($timeout, 1)));
+ fwrite($fp, $request);
+ }
// Fetch response. Due to PHP bugs like http://bugs.php.net/bug.php?id=43782
// and http://bugs.php.net/bug.php?id=46049 we can't rely on feof(), but