--- drupal-7.17.orig/includes/common.inc	2012-12-10 17:52:21.000000000 +0100
+++ drupal-7.17/includes/common.inc	2012-12-13 15:04:36.000000000 +0100
@@ -746,6 +746,235 @@
 }
 
 /**
+ * This callback function is used to store the headers data provided by Curl
+ * @see drupal_curl_request()
+ */
+function _drupal_curl_request_header_callback($curl_handle, $data) {
+  $curl_storage = &drupal_static('drupal_curl_request', array('headers' => ''));
+  $curl_storage['headers'] .= $data;
+  return strlen($data);
+}
+
+/**
+ * This function attemps at mimicking drupal_http_request() but does so by
+ * relying on Curl.
+ * @see drupal_http_request()
+ */
+function drupal_curl_request($url, array $options = array()) {
+  $curl_storage = &drupal_static(__FUNCTION__, array('headers' => ''));
+  $result = new stdClass();
+  $result->error = NULL;
+  $result->redirect_code = NULL;
+  $result->redirect_url = NULL;
+
+  // Parse the URL and make sure we can handle the schema.
+  $uri = @parse_url($url);
+
+  if ($uri == FALSE) {
+    $result->error = 'unable to parse URL';
+    $result->code = -1001;
+    return $result;
+  }
+
+  if (!isset($uri['scheme'])) {
+    $result->error = 'missing schema';
+    $result->code = -1002;
+    return $result;
+  }
+  if ($uri['scheme'] == 'feed') {
+    $uri['scheme'] = 'http';
+    $url = str_replace('feed://', 'http://', $url);
+  }
+
+  // Merge the default options.
+  $options += array(
+    'headers' => array(),
+    'method' => 'GET',
+    'data' => NULL,
+    'max_redirects' => 3,
+    'timeout' => 30.0,
+    'context' => NULL,
+  );
+
+  // Merge the default headers.
+  $options['headers'] += array(
+    'User-Agent' => 'Drupal (+http://drupal.org/)',
+  );
+
+  // Note: the code below make many assumptions (ranging from proxy type to TLS
+  // security); this function provides ways to change the Curl handle right
+  // before curl_exec is called so most assumptions should remain harmless.
+  $curl_handle = curl_init();
+  curl_setopt($curl_handle, CURLOPT_URL, $url);
+  curl_setopt($curl_handle, CURLOPT_USERAGENT, $options['headers']['User-Agent']);
+
+  if ($options['max_redirects'] > 0) {
+    curl_setopt($curl_handle, CURLOPT_FOLLOWLOCATION, TRUE);
+    curl_setopt($curl_handle, CURLOPT_MAXREDIRS, $options['max_redirects']);
+  }
+  else {
+    curl_setopt($curl_handle, CURLOPT_FOLLOWLOCATION, FALSE);
+  }
+  
+  // Attempt to make the connection short and non-persistent (still, Curl will
+  // respect keep-alive required by remote servers until it times out).
+  $options['headers']['Connection'] = 'close';
+  curl_setopt($curl_handle, CURLOPT_FORBID_REUSE, TRUE);
+
+  // No TLS checks at all by default
+  curl_setopt($curl_handle, CURLOPT_SSL_VERIFYHOST, FALSE);
+  curl_setopt($curl_handle, CURLOPT_SSL_VERIFYPEER, FALSE);
+
+  // store outgoing HTTP headers so the ycan be retrieved later using curl_getinfo
+  curl_setopt($curl_handle, CURLINFO_HEADER_OUT, TRUE);
+  // Make curl_exec return response data without any response header
+  curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, TRUE);
+  curl_setopt($curl_handle, CURLOPT_HEADER, FALSE);
+  // Make curl_exec provide us with the response headers through a callback function
+  curl_setopt($curl_handle, CURLOPT_HEADERFUNCTION, '_drupal_curl_request_header_callback');
+
+  // set HTTP method
+  curl_setopt($curl_handle, CURLOPT_CUSTOMREQUEST, $options['method']);
+
+  // Set timeout
+  curl_setopt($curl_handle, CURLOPT_TIMEOUT, (int) $options['timeout']);
+
+  // Use a proxy if one is defined and the host is not on the excluded list.
+  $proxy_server = variable_get('proxy_server', '');
+  if ($proxy_server && _drupal_http_use_proxy($uri['host'])) {
+    // We assume a HTTP proxy -- we provide several ways to change this near
+    // the end of this function.
+    curl_setopt($curl_handle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
+    curl_setopt($curl_handle, CURLOPT_PROXY, $proxy_server);
+    curl_setopt($curl_handle, CURLOPT_PROXYPORT, variable_get('proxy_port', 8080));
+
+    // Add in username and password to Proxy-Authorization header if needed.
+    if ($proxy_username = variable_get('proxy_username', '')) {
+      curl_setopt($curl_handle, CURLOPT_PROXYAUTH, CURLAUTH_BASIC);
+      $proxy_user_pass = $proxy_username . ':' . variable_get('proxy_password', '');
+      curl_setopt($curl_handle, CURLOPT_PROXYUSERPWD, $proxy_user_pass);
+    }
+
+    if ($proxy_user_agent = variable_get('proxy_user_agent', '')) {
+      if ($proxy_user_agent !== NULL) {
+        curl_setopt($curl_handle, CURLOPT_USERAGENT, $proxy_user_agent);
+      }
+    }
+  }
+
+  $content_length = strlen($options['data']);
+  if ($content_length > 0 || $options['method'] == 'POST' || $options['method'] == 'PUT') {
+    $options['headers']['Content-Length'] = $content_length;
+    curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $options['data']); 
+  }
+
+  // If the server URL has a user then attempt to use basic authentication.
+  if (isset($uri['user'])) {
+    curl_setopt($curl_handle, CURLOPT_USERPWD, $uri['user'] . ':' . $uri['pass']);
+  }
+
+  // If the database prefix is being used by SimpleTest to run the tests in a copied
+  // database then set the user-agent header to the database prefix so that any
+  // calls to other Drupal pages will run the SimpleTest prefixed database. The
+  // user-agent is used to ensure that multiple testing sessions running at the
+  // same time won't interfere with each other as they would if the database
+  // prefix were stored statically in a file or database variable.
+  $test_info = &$GLOBALS['drupal_test_info'];
+  if (!empty($test_info['test_run_id'])) {
+    curl_setopt($curl_handle, CURLOPT_USERAGENT, drupal_generate_test_ua($test_info['test_run_id']));
+  }
+
+  $headers_array = array();
+  foreach ($options['headers'] as $name => $value) {
+    $headers_array[] = $name . ': ' . trim($value);
+  }
+  curl_setopt($curl_handle, CURLOPT_HTTPHEADER, $headers_array);
+
+
+  // provide various ways to customize the behavior of Curl:
+  // 1 - "System-wide" (well, Drupal instance-wide actually) options
+  $system_wide_options = variable_get('curl_options', array());
+  if (is_array($system_wide_options) && count($system_wide_options)) {
+    curl_setopt_array($curl_handle, $system_wide_options);
+  }
+  // 2 - Request-specific options
+  if (isset($options['curl_options']) && is_array($options['curl_options'])) {
+    curl_setopt_array($curl_handle, $options['curl_options']);
+  }
+  // 3 - Ability to alter the handle right before curl_exec is called.
+  if (function_exists('drupal_alter')) {
+    drupal_alter('curl_handle', $curl_handle);
+  }
+
+
+  $curl_result = curl_exec($curl_handle);
+
+  // Organize all data fetched by Curl so they can be returned to the caller.
+  $result->curlinfo = curl_getinfo($curl_handle);
+  if ($result->curlinfo['header_size'] > 0) {
+    // Due to proxying and/or redirects, we may have more than one HTTP response
+    // in the headers provided by Curl.
+    $all_headers = preg_split("/\r\n|\n|\r/", $curl_storage['headers']);
+
+    $result->curl_all_reponses = array();
+    while (count($all_headers)) {
+      $response = new StdClass();
+      // we first expect the usual version-code-status reponse line
+      list($protocol, $code, $status_message) = explode(' ', trim(array_shift($all_headers)), 3);
+      $response->protocol = $protocol;
+      $response->code = $code;
+      $response->status_message = $status_message;
+
+      // Parse the response headers.
+      $response->headers = array();
+      while ($line = trim(array_shift($all_headers))) {
+        list($name, $value) = explode(':', $line, 2);
+        $name = strtolower($name);
+        if (isset($response->headers[$name]) && $name == 'set-cookie') {
+          // RFC 2109: the Set-Cookie response header comprises the token Set-
+          // Cookie:, followed by a comma-separated list of one or more cookies.
+          $response->headers[$name] .= ',' . trim($value);
+        }
+        else {
+          $response->headers[$name] = trim($value);
+        }
+      }
+
+      // Fill result attributes related to redirections
+      if ($options['max_redirects'] > 0) {
+        if ($response->code == 301 || $response->code == 302 || $response->code == 307) {
+          $result->redirect_code = $response->code;
+          $result->redirect_url = $response->headers['location'];
+        }
+      }
+      $result->curl_all_reponses[] = $response;
+
+      // Consume trailing blank lines.
+      while (count($all_headers) && !trim($all_headers[0])) {
+        array_shift($all_headers);
+      }
+    }
+
+    $result->request = $result->curlinfo['request_header'];
+    // consider the last response as the most adequate one
+    if (isset($response)) {
+      $result->protocol = $response->protocol;
+      $result->code = $result->curlinfo['http_code'];
+      $result->status_message = $response->status_message;
+      $result->headers = $response->headers;
+    }
+    $result->data = $curl_result;
+  }
+  else {
+    $result->code = -curl_errno($curl_handle);
+    $result->error = curl_error($curl_handle);
+  }
+  
+  @curl_close($curl_handle);
+  return $result;
+}
+
+/**
  * Performs an HTTP request.
  *
  * This is a flexible and powerful HTTP client implementation. Correctly
@@ -785,6 +1014,7 @@
  *   - data: A string containing the response body that was received.
  */
 function drupal_http_request($url, array $options = array()) {
+  return drupal_curl_request($url, $options);
   $result = new stdClass();
 
   // Parse the URL and make sure we can handle the schema.
