diff --git includes/common.inc includes/common.inc
index 14e716b..4b3c56f 100644
--- includes/common.inc
+++ 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
@@ -793,21 +795,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'];
@@ -815,12 +823,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' => $transport . $uri['host'] . ':' . $port));
 
     // 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
@@ -842,11 +858,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
@@ -877,8 +888,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
