diff --git a/httprl.module b/httprl.module
index 665f736..fb63f6f 100644
--- a/httprl.module
+++ b/httprl.module
@@ -6,22 +6,64 @@
  */
 
 /**
+ * Error code indicating that the request made by httprl_request() exceeded
+ * the maximum allowed redirects without reaching the final target.
+ */
+define('HTTPRL_REQUEST_ALLOWED_REDIRECTS_EXHAUSTED', -2);
+
+/**
+ * Error code indicating that the request made by httprl_request() exceeded
+ * the maximum allowed redirects without reaching the final target.
+ */
+define('HTTPRL_REQUEST_FWRITE_FAIL', -3);
+
+/**
  * Error code indicating that all requests made by httprl_send_request()
  * exceeded the specified timeout.
  */
-define('HTTP_FUNCTION_TIMEOUT', -3);
+define('HTTPRL_FUNCTION_TIMEOUT', -4);
 
 /**
  * Error code indicating that this request made by stream_select() couldn't
  * open a read and/or write steam after a minimum of ~2.5 seconds.
  */
-define('HTTP_STREAM_SELECT_TIMEOUT', -4);
+define('HTTPRL_STREAM_SELECT_TIMEOUT', -5);
+
+/**
+ * parse_url() was unable to parse the given url.
+ */
+define('HTTPRL_URL_PARSE_ERROR', -1001);
+
+/**
+ * Given URL is missing a schema (http, https, feed).
+ */
+define('HTTPRL_URL_MISSING_SCHEMA', -1002);
+
+/**
+ * Invalid schema. Only http, feed, and https allowed currently.
+ */
+define('HTTPRL_URL_INVALID_SCHEMA', -1003);
+
+/**
+ * An error occurred before the system connect() call. This is most likely due
+ * to a problem initializing the stream.
+ */
+define('HTTPRL_ERROR_INITIALIZING_STREAM', -1004);
+
+/**
+ * Error code indicating that the request exceeded the specified timeout.
+ *
+ * @see http://msdn.microsoft.com/en-us/library/aa924071.aspx
+ */
+define('HTTPRL_REQUEST_TIMEOUT', -10060);
 
 /**
  * Error code indicating that the endpoint server has refused or dropped the
  * connection.
+ *
+ * @see http://msdn.microsoft.com/en-us/library/aa924071.aspx
  */
-define('HTTP_CONNECTION_REFUSED', -5);
+define('HTTPRL_CONNECTION_REFUSED', -10061);
 
 /**
  * Implement hook_menu().
@@ -161,7 +203,7 @@ function httprl_build_url_self($path = '', $detect_schema = FALSE) {
  *     may be followed. Defaults to 3.
  *   - timeout: A float representing the maximum number of seconds a connection
  *     may take. The default is 30 seconds. If a timeout occurs, the error code
- *     is set to the HTTP_REQUEST_TIMEOUT constant.
+ *     is set to the HTTPRL_REQUEST_TIMEOUT constant.
  *   - context: A context resource created with stream_context_create().
  *   - blocking: set to FALSE to make this not care about the returned data.
  *   - version: HTTP Version 1.0 or 1.1. Default is 1.0 for a good reason.
@@ -173,24 +215,25 @@ function httprl_build_url_self($path = '', $detect_schema = FALSE) {
  *     be open on the server. Default is 128.
  *   - global_timeout: 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_FUNCTION_TIMEOUT constant. Default is
+ *     the error code is set to the HTTPRL_FUNCTION_TIMEOUT constant. Default is
  *     120 seconds.
  *   - chunk_size_write: max size of what will be written in fwrite().
  *   - chunk_size_read: max size of what will be read from fread().
+ *   - async_connect: default it TRUE. FALSE may give more info on errors but is
+ *     generally slower.
  * @return bool
  *   return value from httprl_send_request().
  */
 function httprl_request($url, $options = array()) {
   global $base_root;
-  static $https_flags;
   $result = new stdClass();
 
   // Parse the URL and make sure we can handle the schema.
   $uri = @parse_url($url);
 
   if (empty($uri)) {
-    $result->error = 'unable to parse URL';
-    $result->code = -1001;
+    $result->error = 'Unable to parse URL.';
+    $result->code = HTTPRL_URL_PARSE_ERROR;
 
     // Add in failed request to the output.
     // Exit if the URL passed in is bad.
@@ -198,8 +241,8 @@ function httprl_request($url, $options = array()) {
   }
 
   if (!isset($uri['scheme'])) {
-    $result->error = 'missing schema';
-    $result->code = -1002;
+    $result->error = 'Missing schema.';
+    $result->code = HTTPRL_URL_MISSING_SCHEMA;
 
     // Add in failed request to the output.
     // Exit if no scheme was passed in.
@@ -222,6 +265,7 @@ function httprl_request($url, $options = array()) {
     'global_timeout' => 120.0,
     'chunk_size_read' => 32768,
     'chunk_size_write' => 1024,
+    'async_connect' => TRUE,
   );
 
   // stream_socket_client() requires timeout to be a float.
@@ -254,52 +298,64 @@ function httprl_request($url, $options = array()) {
       }
       break;
     default:
-      $result->error = 'invalid schema ' . $uri['scheme'];
-      $result->code = -1003;
+      $result->error = 'Invalid schema ' . $uri['scheme'] . '.';
+      $result->code = HTTPRL_URL_INVALID_SCHEMA;
 
       // Add in failed request to the output.
       // Exit if an invalid scheme was passed in.
       return httprl_send_request(FALSE, $url, $result, $options);
   }
 
-  $flags = STREAM_CLIENT_ASYNC_CONNECT|STREAM_CLIENT_CONNECT;
-  // Workaround for PHP bug with STREAM_CLIENT_ASYNC_CONNECT and SSL
-  // https://bugs.php.net/bug.php?id=48182 - Fixed in PHP 5.2.11 and 5.3.1
-  if ($uri['scheme'] == 'https') {
-    if (!isset($https_flags) && (version_compare(PHP_VERSION, '5.2.11', '<') || version_compare(PHP_VERSION, '5.3.0', '='))) {
-      $https_flags = STREAM_CLIENT_CONNECT;
+  // Set connection flag.
+  if ($options['async_connect']) {
+    // Workaround for PHP bug with STREAM_CLIENT_ASYNC_CONNECT and SSL
+    // https://bugs.php.net/bug.php?id=48182 - Fixed in PHP 5.2.11 and 5.3.1
+    if (($uri['scheme'] == 'https' && $options['async_connect']) && (version_compare(PHP_VERSION, '5.2.11', '<') || version_compare(PHP_VERSION, '5.3.0', '='))) {
+      $flags = STREAM_CLIENT_ASYNC_CONNECT|STREAM_CLIENT_CONNECT;
     }
     else {
-      $https_flags = STREAM_CLIENT_ASYNC_CONNECT|STREAM_CLIENT_CONNECT;
+      $flags = STREAM_CLIENT_CONNECT;
+      $options['async_connect'] = FALSE;
     }
-    $flags = $https_flags;
-  }
-  if (empty($options['context'])) {
-    $fp = @stream_socket_client($socket, $errno, $errstr, $options['timeout'], $flags);
   }
   else {
-    // Create a stream with context. Allows verification of a SSL certificate.
-    $fp = @stream_socket_client($socket, $errno, $errstr, $options['timeout'], $flags, $options['context']);
+    $flags = STREAM_CLIENT_CONNECT;
   }
-  // Try one last time without using STREAM_CLIENT_ASYNC_CONNECT.
-  if (!$fp && $flags === STREAM_CLIENT_ASYNC_CONNECT|STREAM_CLIENT_CONNECT) {
-    // Start the timer.
-    $timer_name = mt_rand();
-    timer_start($timer_name);
 
+  // Start the timer.
+  $timer_name = mt_rand();
+  timer_start($timer_name);
+  $fp = FALSE;
+
+  // Connection loop.
+  $count = 0;
+  while (!$fp) {
+    // Try the connection again not using async if in https mode.
+    if ($count > 0) {
+      if ($flags === STREAM_CLIENT_ASYNC_CONNECT|STREAM_CLIENT_CONNECT && $uri['scheme'] == 'https') {
+        $flags = STREAM_CLIENT_CONNECT;
+        $options['async_connect'] = FALSE;
+      }
+      else {
+        break;
+      }
+    }
+
+    // Open the connection.
     if (empty($options['context'])) {
-      $fp = @stream_socket_client($socket, $errno, $errstr, $options['timeout'], STREAM_CLIENT_CONNECT);
+      $fp = @stream_socket_client($socket, $errno, $errstr, $options['timeout'], $flags);
     }
     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']);
+      $fp = @stream_socket_client($socket, $errno, $errstr, $options['timeout'], $flags, $options['context']);
     }
-
-    $options['timeout'] = $options['timeout'] - timer_read($timer_name) / 1000;
-    // Stop the timer.
-    timer_stop($timer_name);
+    $count++;
   }
 
+  // Stop the timer.
+  $options['timeout'] = $options['timeout'] - timer_read($timer_name) / 1000;
+  timer_stop($timer_name);
+
   // Make sure the socket opened properly.
   if (!$fp) {
     // Make sure drupal_convert_to_utf8() is available.
@@ -315,15 +371,15 @@ function httprl_request($url, $options = array()) {
     if (!$errno) {
       // If $errno is 0, it is an indication that the error occurred
       // before the connect() call. This is most likely due to a problem
-      // initializing the socket.
-      $result->code = -1004;
-      $result->error = !empty($errstr) ? $errstr : t('Error initializing socket @socket', array('@socket' => $socket));
+      // initializing the stream.
+      $result->code = HTTPRL_ERROR_INITIALIZING_STREAM;
+      $result->error = !empty($errstr) ? $errstr : t('Error initializing socket @socket.', array('@socket' => $socket));
     }
     else {
       // When a network error occurs, we use a negative number so it does not
       // clash with the HTTP status codes.
       $result->code = (int) -$errno;
-      $result->error = !empty($errstr) ? $errstr : t('Error opening socket @socket', array('@socket' => $socket));
+      $result->error = !empty($errstr) ? $errstr : t('Error opening socket @socket.', array('@socket' => $socket));
     }
 
     // Add in failed request to the output.
@@ -445,27 +501,6 @@ function httprl_send_request($fp = NULL, $url = '', $request = '', $options = ''
   $timer_name = mt_rand();
   timer_start($timer_name);
 
-  if (defined('HTTP_REQUEST_TIMEOUT')) {
-    $http_request_timeout = HTTP_REQUEST_TIMEOUT;
-  }
-  else {
-    $http_request_timeout = -1;
-  }
-  if (defined('HTTP_REQUEST_FWRITE_FAIL')) {
-    $http_request_fwrite_fail = HTTP_REQUEST_FWRITE_FAIL;
-  }
-  else {
-    $http_request_fwrite_fail = -2;
-  }
-  // HTTP_REQUEST_ALLOWED_REDIRECTS_EXHAUSTED is defined in
-  // http://drupal.org/node/1096890
-  if (defined('HTTP_REQUEST_ALLOWED_REDIRECTS_EXHAUSTED')) {
-    $http_request_allowed_redirects_exhausted = HTTP_REQUEST_ALLOWED_REDIRECTS_EXHAUSTED;
-  }
-  else {
-    $http_request_allowed_redirects_exhausted = 2;
-  }
-
   // Run the loop as long as we have a stream to read/write to.
   $empty_runs = 0;
   $stream_select_timeout = 1;
@@ -474,42 +509,51 @@ function httprl_send_request($fp = NULL, $url = '', $request = '', $options = ''
     // Check for timeouts.
     $current_time = timer_read($timer_name) / 1000;
     $global_time = $global_timeout - timer_read($timer_name) / 1000;
+
+    // Set connection limits.
+    $this_run = array();
+    $global_connection_count = 0;
+    $domain_connection_count = array();
+
+    // Inspect each stream, checking for timeouts and connection limits.
     foreach ($streams as $id => $fp) {
       // Calculate how much time is left of the original timeout value.
       $timeout = $responses[$id]->options['timeout'] - $current_time;
       if ($timeout <= 0) {
         // Stream timed out & the request is not done.
         if ($responses[$id]->status == 'in progress') {
-          $responses[$id]->error = 'request timed out, write';
+          $responses[$id]->error = 'Request timed out. Write.';
           // If stream is not done writing, then remove one from the write count.
           $stream_write_count--;
         }
         else {
-          $responses[$id]->error = 'request timed out';
+          $responses[$id]->error = 'Request timed out.';
         }
-        $responses[$id]->code = $http_request_timeout;
+        $responses[$id]->code = HTTPRL_REQUEST_TIMEOUT;
         $responses[$id]->status = 'Done.';
         $responses[$id]->options['timeout'] = $timeout;
         fclose($fp);
         unset($streams[$id]);
+        continue;
       }
 
       // See if function timed out.
       if ($global_time <= 0) {
         // Function timed out & the request is not done.
         if ($responses[$id]->status == 'in progress') {
-          $responses[$id]->error = 'function timed out, write';
+          $responses[$id]->error = 'Function timed out. Write.';
           // If stream is not done writing, then remove one from the write count.
           $stream_write_count--;
         }
         else {
-          $responses[$id]->error = 'function timed out';
+          $responses[$id]->error = 'Function timed out.';
         }
-        $responses[$id]->code = HTTP_FUNCTION_TIMEOUT;
+        $responses[$id]->code = HTTPRL_FUNCTION_TIMEOUT;
         $responses[$id]->status = 'Done.';
         $responses[$id]->options['timeout'] = $global_time;
         fclose($fp);
         unset($streams[$id]);
+        continue;
       }
 
       // See if end server has dropped the connection.
@@ -519,31 +563,23 @@ function httprl_send_request($fp = NULL, $url = '', $request = '', $options = ''
           // Connection was dropped.
           if ($responses[$id]->status == 'in progress') {
             // If stream is not done writing, then remove one from the write count.
+            $responses[$id]->error = 'Connection refused by destination. Write.';
             $stream_write_count--;
           }
-          $responses[$id]->error = 'connection refused/dropped';
-          $responses[$id]->code = HTTP_CONNECTION_REFUSED;
+          else {
+            $responses[$id]->error = 'Connection refused by destination.';
+          }
+          $responses[$id]->code = HTTPRL_CONNECTION_REFUSED;
           $responses[$id]->status = 'Done.';
           $responses[$id]->options['timeout'] = $timeout;
           fclose($fp);
           unset($streams[$id]);
+          continue;
         }
       }
-    }
-
-    // All streams removed; exit loop.
-    if (empty($streams)) {
-      break;
-    }
 
-    // Set connection limits.
-    $this_run = array();
-    $global_connection_count = 0;
-    $domain_connection_count = array();
-    foreach ($streams as $id => $fp) {
       // Get the host name.
       $host = $responses[$id]->options['headers']['Host'];
-
       // Count up the number of connections.
       $global_connection_count++;
       if (empty($domain_connection_count[$host])) {
@@ -552,23 +588,26 @@ function httprl_send_request($fp = NULL, $url = '', $request = '', $options = ''
       else {
         $domain_connection_count[$host]++;
       }
-
       // If the conditions are correct, let the stream be ran in this loop.
       if ($global_connection_limit >= $global_connection_count && $domain_connection_limit[$host] >= $domain_connection_count[$host]) {
         $this_run[$id] = $fp;
       }
     }
 
-    $rw_done = FALSE;
+    // All streams removed; exit loop.
+    if (empty($this_run) || empty($streams)) {
+      break;
+    }
+
     // Set the read and write vars to the streams var.
     $read = $write = $this_run;
     $except = array();
-
     // Do some voodoo and open all streams at once. Wait 25ms for streams to respond.
     $n = stream_select($read, $write, $except, $stream_select_timeout, 25000);
     $stream_select_timeout = 0;
 
     // We have some streams to read/write to.
+    $rw_done = FALSE;
     if (!empty($n)) {
       $empty_runs = 0;
 
@@ -619,11 +658,10 @@ function httprl_send_request($fp = NULL, $url = '', $request = '', $options = ''
         $alive = !$info['eof'] && !feof($r) && !$info['timed_out'] && httprl_strlen($chunk);
         if (!$alive) {
           if ($responses[$id]->status == 'in progress') {
-            $responses[$id]->status = 'Failed to connect.';
-          }
-          else {
-            $responses[$id]->status = 'Done.';
+            $responses[$id]->error = 'Connection refused by destination. Write.';
+            $responses[$id]->code = HTTPRL_CONNECTION_REFUSED;
           }
+          $responses[$id]->status = 'Done.';
           $responses[$id]->options['timeout'] = $responses[$id]->options['timeout'] - $current_time;
           fclose($r);
           unset($streams[$id]);
@@ -661,8 +699,8 @@ function httprl_send_request($fp = NULL, $url = '', $request = '', $options = ''
           // See if we are done with writing.
           if ($bytes === FALSE) {
             // fwrite failed.
-            $responses[$id]->error = 'fwrite failed';
-            $responses[$id]->code = $http_request_fwrite_fail;
+            $responses[$id]->error = 'fwrite() failed.';
+            $responses[$id]->code = HTTPRL_REQUEST_FWRITE_FAIL;
             $responses[$id]->status = 'Done.';
             $responses[$id]->options['timeout'] = $responses[$id]->options['timeout'] - $current_time;
             $stream_write_count--;
@@ -704,8 +742,8 @@ function httprl_send_request($fp = NULL, $url = '', $request = '', $options = ''
       // 2.5+ seconds, error out.
       foreach ($streams as $id => $fp) {
         // stream_select timed out & the request is not done.
-        $responses[$id]->error = 'stream_select timed out';
-        $responses[$id]->code = HTTP_STREAM_SELECT_TIMEOUT;
+        $responses[$id]->error = 'stream_select() timed out.';
+        $responses[$id]->code = HTTPRL_STREAM_SELECT_TIMEOUT;
         $responses[$id]->status = 'Done.';
         $responses[$id]->options['timeout'] = $responses[$id]->options['timeout'] - $current_time;
         fclose($fp);
@@ -731,7 +769,7 @@ function httprl_send_request($fp = NULL, $url = '', $request = '', $options = ''
       'url' => $result->url,
     );
     // Make sure the redirect was requested before killing this request.
-    if ($result->code != $http_request_allowed_redirects_exhausted) {
+    if ($result->code != HTTPRL_REQUEST_ALLOWED_REDIRECTS_EXHAUSTED) {
       unset($responses[$id]);
     }
   }
@@ -777,7 +815,7 @@ function httprl_send_request($fp = NULL, $url = '', $request = '', $options = ''
   foreach ($responses as $id => &$result) {
     httprl_decode_data($result);
 
-    // Assign redirect arrays to values for core compatiblity.
+    // Assign redirect arrays to values for core compatibility.
     if (isset($result->redirect_url)) {
       $result->redirect_url_array = $result->redirect_url;
       $last = array_pop($result->redirect_url);
@@ -844,14 +882,6 @@ function httprl_parse_data(&$result) {
   unset($protocol_code_array);
 
   $result->headers = array();
-  // HTTP_REQUEST_ALLOWED_REDIRECTS_EXHAUSTED is defined in
-  // http://drupal.org/node/1096890
-  if (defined('HTTP_REQUEST_ALLOWED_REDIRECTS_EXHAUSTED')) {
-    $http_request_allowed_redirects_exhausted = HTTP_REQUEST_ALLOWED_REDIRECTS_EXHAUSTED;
-  }
-  else {
-    $http_request_allowed_redirects_exhausted = 2;
-  }
 
   // Parse the response headers.
   $cookie_primary_counter = 0;
@@ -970,8 +1000,8 @@ function httprl_parse_data(&$result) {
 
       // Error out if we hit the max redirect.
       if ($result->options['max_redirects'] <= 0) {
-        $result->code = $http_request_allowed_redirects_exhausted;
-        $result->error = 'maximum allowed redirects exhausted';
+        $result->code = HTTPRL_REQUEST_ALLOWED_REDIRECTS_EXHAUSTED;
+        $result->error = 'Maximum allowed redirects exhausted.';
       }
       else {
         // Redirect to the new location.
