diff --git a/includes/common.inc b/includes/common.inc
index d521268..511e66b 100644
--- a/includes/common.inc
+++ b/includes/common.inc
@@ -765,6 +765,8 @@ function drupal_access_denied() {
  *     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().
+ * @param $fp_in
+ *   An optional file pointer, if the socket is provided externally
  *
  * @return object
  *   An object that can have one or more of the following components:
@@ -784,7 +786,7 @@ function drupal_access_denied() {
  *     easy access the array keys are returned in lower case.
  *   - data: A string containing the response body that was received.
  */
-function drupal_http_request($url, array $options = array()) {
+function drupal_http_request($url, array $options = array(), $fp_in = NULL) {
   $result = new stdClass();
 
   // Parse the URL and make sure we can handle the schema.
@@ -826,7 +828,7 @@ function drupal_http_request($url, array $options = array()) {
   $proxy_server = variable_get('proxy_server', '');
   if ($proxy_server && _drupal_http_use_proxy($uri['host'])) {
     // Set the scheme so we open a socket to the proxy server.
-    $uri['scheme'] = 'proxy';
+    $uri['scheme'] = $uri['scheme'] == 'https' ? 'proxy_https' : 'proxy_http';
     // Set the path to be the full URL.
     $uri['path'] = $url;
     // Since the URL is passed as the path, we won't use the parsed query.
@@ -850,7 +852,8 @@ function drupal_http_request($url, array $options = array()) {
   }
 
   switch ($uri['scheme']) {
-    case 'proxy':
+    case 'proxy_http':
+    case 'proxy_https':
       // Make the socket connection to a proxy server.
       $socket = 'tcp://' . $proxy_server . ':' . variable_get('proxy_port', 8080);
       // The Host header still needs to match the real request.
@@ -881,7 +884,10 @@ function drupal_http_request($url, array $options = array()) {
       return $result;
   }
 
-  if (empty($options['context'])) {
+  if (!empty($fp_in)) {
+    $fp = $fp_in;
+  }
+  elseif (empty($options['context'])) {
     $fp = @stream_socket_client($socket, $errno, $errstr, $options['timeout']);
   }
   else {
@@ -905,6 +911,24 @@ function drupal_http_request($url, array $options = array()) {
     return $result;
   }
 
+  if ($uri['scheme'] == 'proxy_https') {
+    $options_connect = array(
+      'headers' => array(),
+      'method' => 'CONNECT',
+      'protocol' => 'HTTP/1.0'
+    );
+    $options_connect['headers']['Host'] = $options['headers']['Host'];
+    $options_connect['headers']['User-Agent'] = $options['headers']['User-Agent'];
+    $options_connect['headers']['Proxy-Authorization']  = $options['headers']['Proxy-Authorization'];
+    if (!($result_connect = drupal_http_request($url, $options_connect, $fp))) {
+      if (!$fp_in) {
+        fclose($fp);
+      }
+      return $result_connect;
+    }
+    stream_socket_enable_crypto($fp, TRUE, STREAM_CRYPTO_METHOD_SSLv23_CLIENT);
+  }
+
   // Construct the path to act on.
   $path = isset($uri['path']) ? $uri['path'] : '/';
   if (isset($uri['query'])) {
@@ -936,7 +960,16 @@ function drupal_http_request($url, array $options = array()) {
     $options['headers']['User-Agent'] = drupal_generate_test_ua($test_info['test_run_id']);
   }
 
-  $request = $options['method'] . ' ' . $path . " HTTP/1.0\r\n";
+  // Build request
+  switch ($options['method']) {
+    case 'CONNECT':
+      $request = $options['method'] . ' ' . $uri['host'] . ':' . $uri['port'];
+      break;
+    default:
+      $request = $options['method'] . ' ' . $path;
+  }
+  $request .= ' ' . $options['protocol'] . "\r\n";
+
   foreach ($options['headers'] as $name => $value) {
     $request .= $name . ': ' . trim($value) . "\r\n";
   }
