- Patch #156582 by c960657, pwolanin, townxelliot, Damien Tournoud, kbahey, mikeytown2, drico, jpmckinney: drupal_http_request() should support timeout setting.

merge-requests/26/head
Dries Buytaert 2010-08-17 16:03:30 +00:00
parent 077617424c
commit 30ecab3775
1 changed files with 28 additions and 13 deletions

View File

@ -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