diff --git a/httprl.module b/httprl.module
index 2c1363c..b36bec6 100644
--- a/httprl.module
+++ b/httprl.module
@@ -192,8 +192,8 @@ function httprl_build_url_self($path = '', $detect_schema = FALSE) {
  * This is a flexible and powerful HTTP client implementation. Correctly
  * handles GET, POST, PUT or any other HTTP requests.
  *
- * @param $url
- *   A string containing a fully qualified URI.
+ * @param $urls
+ *   A string or an array containing a fully qualified URI(s).
  * @param array $options
  *   (optional) An array that can have one or more of the following elements:
  *   - headers: An array containing request headers to send as name/value pairs.
@@ -249,261 +249,279 @@ function httprl_build_url_self($path = '', $detect_schema = FALSE) {
  * @return bool
  *   return value from httprl_send_request().
  */
-function httprl_request($url, $options = array()) {
+function httprl_request($urls, $options = array()) {
   global $base_root;
-  $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 = HTTPRL_URL_PARSE_ERROR;
-
-    // Add in failed request to the output.
-    // Exit if the URL passed in is bad.
-    return httprl_send_request(FALSE, $url, $result, $options);
+  // Transform string to an array.
+  if (!is_array($urls)) {
+    $temp = $urls;
+    unset($urls);
+    $urls = array($temp);
+    unset($temp);
   }
 
-  if (!isset($uri['scheme'])) {
-    $result->error = 'Missing schema.';
-    $result->code = HTTPRL_URL_MISSING_SCHEMA;
+  $return = array();
+  foreach ($urls as $url) {
+    $result = new stdClass();
 
-    // Add in failed request to the output.
-    // Exit if no scheme was passed in.
-    return httprl_send_request(FALSE, $url, $result, $options);
-  }
+    // Parse the URL and make sure we can handle the schema.
+    $uri = @parse_url($url);
 
-  // Merge the default options.
-  $options += array(
-    'headers' => array(),
-    'method' => 'GET',
-    'data' => NULL,
-    'max_redirects' => 3,
-    'timeout' => 30.0,
-    'context' => NULL,
-    'blocking' => TRUE,
-    'version' => '1.0',
-    'referrer' => FALSE,
-    'domain_connections' => 8,
-    'global_connections' => 128,
-    'global_timeout' => 120.0,
-    'chunk_size_read' => 32768,
-    'chunk_size_write' => 1024,
-    'async_connect' => TRUE,
-  );
-  // Merge the default headers.
-  // Set user agent to drupal.
-  // Set connection to closed to prevent keep-alive from causing a timeout.
-  $options['headers'] += array(
-    'User-Agent' => 'Drupal (+http://drupal.org/)',
-    'Connection' => 'close',
-  );
-  // Set referrer to current page.
-  if (!isset($options['headers']['Referer']) && !empty($options['referrer'])) {
-    $options['headers']['Referer'] = $base_root . request_uri();
-  }
+    if (empty($uri)) {
+      $result->error = 'Unable to parse URL.';
+      $result->code = HTTPRL_URL_PARSE_ERROR;
 
-  // stream_socket_client() requires timeout to be a float.
-  $options['timeout'] = (float) $options['timeout'];
-
-  // Proxy setup
-  $proxy_server = variable_get('proxy_server', '');
-  // Use a proxy if one is defined and the host is not on the excluded list.
-  if ($proxy_server && _httprl_use_proxy($uri['host'])) {
-    // Set the scheme so we open a socket to the proxy server.
-    $uri['scheme'] = 'proxy';
-    // Set the path to be the full URL.
-    $uri['path'] = $url;
-    // Since the full URL is passed as the path, we won't use the parsed query.
-    unset($uri['query']);
-
-    // Add in username and password to Proxy-Authorization header if needed.
-    if ($proxy_username = variable_get('proxy_username', '')) {
-      $proxy_password = variable_get('proxy_password', '');
-      $options['headers']['Proxy-Authorization'] = 'Basic ' . base64_encode($proxy_username . (!empty($proxy_password) ? ":" . $proxy_password : ''));
-    }
-    // Some proxies reject requests with any User-Agent headers, while others
-    // require a specific one.
-    $proxy_user_agent = variable_get('proxy_user_agent', '');
-    // The default value matches neither condition.
-    if (is_null($proxy_user_agent)) {
-      unset($options['headers']['User-Agent']);
+      // Add in failed request to the output.
+      // Continue if the URL passed in is bad.
+      $return[$url] = httprl_send_request(FALSE, $url, $result, $options);
+      continue;
     }
-    elseif ($proxy_user_agent) {
-      $options['headers']['User-Agent'] = $proxy_user_agent;
+
+    if (!isset($uri['scheme'])) {
+      $result->error = 'Missing schema.';
+      $result->code = HTTPRL_URL_MISSING_SCHEMA;
+
+      // Add in failed request to the output.
+      // Continue if no scheme was passed in.
+      $return[$url] = httprl_send_request(FALSE, $url, $result, $options);
+      continue;
     }
-  }
 
-  switch ($uri['scheme']) {
-    case 'proxy':
-      // 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.
-      $options['headers']['Host'] = $uri['host'];
-      $options['headers']['Host'] .= isset($uri['port']) && $uri['port'] != 80 ? ':' . $uri['port'] : '';
-      break;
+    // Merge the default options.
+    $options += array(
+      'headers' => array(),
+      'method' => 'GET',
+      'data' => NULL,
+      'max_redirects' => 3,
+      'timeout' => 30.0,
+      'context' => NULL,
+      'blocking' => TRUE,
+      'version' => '1.0',
+      'referrer' => FALSE,
+      'domain_connections' => 8,
+      'global_connections' => 128,
+      'global_timeout' => 120.0,
+      'chunk_size_read' => 32768,
+      'chunk_size_write' => 1024,
+      'async_connect' => TRUE,
+    );
+    // Merge the default headers.
+    // Set user agent to drupal.
+    // Set connection to closed to prevent keep-alive from causing a timeout.
+    $options['headers'] += array(
+      'User-Agent' => 'Drupal (+http://drupal.org/)',
+      'Connection' => 'close',
+    );
+    // Set referrer to current page.
+    if (!isset($options['headers']['Referer']) && !empty($options['referrer'])) {
+      $options['headers']['Referer'] = $base_root . request_uri();
+    }
 
-    case 'http':
-    case 'feed':
-      $port = isset($uri['port']) ? $uri['port'] : 80;
-      $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.
-      if (empty($options['headers']['Host'])) {
-        $options['headers']['Host'] = $uri['host'];
+    // stream_socket_client() requires timeout to be a float.
+    $options['timeout'] = (float) $options['timeout'];
+
+    // Proxy setup
+    $proxy_server = variable_get('proxy_server', '');
+    // Use a proxy if one is defined and the host is not on the excluded list.
+    if ($proxy_server && _httprl_use_proxy($uri['host'])) {
+      // Set the scheme so we open a socket to the proxy server.
+      $uri['scheme'] = 'proxy';
+      // Set the path to be the full URL.
+      $uri['path'] = $url;
+      // Since the full URL is passed as the path, we won't use the parsed query.
+      unset($uri['query']);
+
+      // Add in username and password to Proxy-Authorization header if needed.
+      if ($proxy_username = variable_get('proxy_username', '')) {
+        $proxy_password = variable_get('proxy_password', '');
+        $options['headers']['Proxy-Authorization'] = 'Basic ' . base64_encode($proxy_username . (!empty($proxy_password) ? ":" . $proxy_password : ''));
       }
-      if ($port != 80) {
-        $options['headers']['Host'] .= ':' . $port;
+      // Some proxies reject requests with any User-Agent headers, while others
+      // require a specific one.
+      $proxy_user_agent = variable_get('proxy_user_agent', '');
+      // The default value matches neither condition.
+      if (is_null($proxy_user_agent)) {
+        unset($options['headers']['User-Agent']);
       }
-      break;
+      elseif ($proxy_user_agent) {
+        $options['headers']['User-Agent'] = $proxy_user_agent;
+      }
+    }
 
-    case 'https':
-      // Note: Only works when PHP is compiled with OpenSSL support.
-      $port = isset($uri['port']) ? $uri['port'] : 443;
-      $socket = 'ssl://' . $uri['host'] . ':' . $port;
-      if (empty($options['headers']['Host'])) {
+    switch ($uri['scheme']) {
+      case 'proxy':
+        // 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.
         $options['headers']['Host'] = $uri['host'];
-      }
-      if ($port != 443) {
-        $options['headers']['Host'] .= ':' . $port;
-      }
-      break;
+        $options['headers']['Host'] .= isset($uri['port']) && $uri['port'] != 80 ? ':' . $uri['port'] : '';
+        break;
 
-    default:
-      $result->error = 'Invalid schema ' . $uri['scheme'] . '.';
-      $result->code = HTTPRL_URL_INVALID_SCHEMA;
+      case 'http':
+      case 'feed':
+        $port = isset($uri['port']) ? $uri['port'] : 80;
+        $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.
+        if (empty($options['headers']['Host'])) {
+          $options['headers']['Host'] = $uri['host'];
+        }
+        if ($port != 80) {
+          $options['headers']['Host'] .= ':' . $port;
+        }
+        break;
 
-      // Add in failed request to the output.
-      // Exit if an invalid scheme was passed in.
-      return httprl_send_request(FALSE, $url, $result, $options);
-  }
+      case 'https':
+        // Note: Only works when PHP is compiled with OpenSSL support.
+        $port = isset($uri['port']) ? $uri['port'] : 443;
+        $socket = 'ssl://' . $uri['host'] . ':' . $port;
+        if (empty($options['headers']['Host'])) {
+          $options['headers']['Host'] = $uri['host'];
+        }
+        if ($port != 443) {
+          $options['headers']['Host'] .= ':' . $port;
+        }
+        break;
 
-  // 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' && (version_compare(PHP_VERSION, '5.2.11', '<') || version_compare(PHP_VERSION, '5.3.0', '='))) {
-      $flags = STREAM_CLIENT_CONNECT;
-      $options['async_connect'] = FALSE;
-    }
-    else {
-      $flags = STREAM_CLIENT_ASYNC_CONNECT|STREAM_CLIENT_CONNECT;
+      default:
+        $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[$url] = httprl_send_request(FALSE, $url, $result, $options);
+        continue;
     }
-  }
-  else {
-    $flags = STREAM_CLIENT_CONNECT;
-  }
 
-  // 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') {
+    // 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' && (version_compare(PHP_VERSION, '5.2.11', '<') || version_compare(PHP_VERSION, '5.3.0', '='))) {
         $flags = STREAM_CLIENT_CONNECT;
         $options['async_connect'] = FALSE;
       }
       else {
-        break;
+        $flags = STREAM_CLIENT_ASYNC_CONNECT|STREAM_CLIENT_CONNECT;
       }
     }
-
-    // Open the connection.
-    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;
     }
-    $count++;
-  }
 
-  // Stop the timer.
-  $options['timeout'] = $options['timeout'] - timer_read($timer_name) / 1000;
-  timer_stop($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;
+        }
+      }
 
-  // Make sure the socket opened properly.
-  if (!$fp) {
-    // Make sure drupal_convert_to_utf8() is available.
-    if (defined('VERSION') && substr(VERSION, 0, 1) >= 7) {
-      require_once DRUPAL_ROOT . '/includes/unicode.inc';
-    }
-    else {
-      require_once './includes/unicode.inc';
-    }
-    // Convert error message to utf-8. Using ISO-8859-1 (Latin-1) as source
-    // encoding could be wrong; it is a simple workaround :)
-    $errstr = trim(drupal_convert_to_utf8($errstr, 'ISO-8859-1'));
-    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 stream.
-      $result->code = HTTPRL_ERROR_INITIALIZING_STREAM;
-      $result->error = !empty($errstr) ? $errstr : t('Error initializing socket @socket.', array('@socket' => $socket));
+      // Open the connection.
+      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']);
+      }
+      $count++;
     }
-    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));
+
+    // 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.
+      if (defined('VERSION') && substr(VERSION, 0, 1) >= 7) {
+        require_once DRUPAL_ROOT . '/includes/unicode.inc';
+      }
+      else {
+        require_once './includes/unicode.inc';
+      }
+      // Convert error message to utf-8. Using ISO-8859-1 (Latin-1) as source
+      // encoding could be wrong; it is a simple workaround :)
+      $errstr = trim(drupal_convert_to_utf8($errstr, 'ISO-8859-1'));
+      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 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));
+      }
+
+      // Add in failed request to the output.
+      // Exit if a stream was not created.
+      $return[$url] = httprl_send_request(FALSE, $url, $result, $options);
+      continue;
     }
 
-    // Add in failed request to the output.
-    // Exit if a stream was not created.
-    return httprl_send_request(FALSE, $url, $result, $options);
-  }
+    // Set the stream to be non blocking.
+    stream_set_blocking($fp, 0);
 
-  // Set the stream to be non blocking.
-  stream_set_blocking($fp, 0);
+    // Construct the path to act on.
+    $path = isset($uri['path']) ? $uri['path'] : '/';
+    if (isset($uri['query'])) {
+      $path .= '?' . $uri['query'];
+    }
 
-  // Construct the path to act on.
-  $path = isset($uri['path']) ? $uri['path'] : '/';
-  if (isset($uri['query'])) {
-    $path .= '?' . $uri['query'];
-  }
+    // Encode data if not already done.
+    if (!is_null($options['data']) && !is_string($options['data'])) {
+      $options['data'] = http_build_query($options['data'], '', '&');
+    }
 
-  // Encode data if not already done.
-  if (!is_null($options['data']) && !is_string($options['data'])) {
-    $options['data'] = http_build_query($options['data'], '', '&');
-  }
+    // 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
+    // POST/PUT requests.
+    $content_length = httprl_strlen($options['data']);
+    if ($content_length > 0 || $options['method'] == 'POST' || $options['method'] == 'PUT') {
+      $options['headers']['Content-Length'] = $content_length;
+    }
 
-  // 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
-  // POST/PUT requests.
-  $content_length = httprl_strlen($options['data']);
-  if ($content_length > 0 || $options['method'] == 'POST' || $options['method'] == 'PUT') {
-    $options['headers']['Content-Length'] = $content_length;
-  }
+    // Set the Content-Type to application/x-www-form-urlencoded if the data is
+    // not empty, the Content-Type is not set, and the method is POST.
+    if ($content_length > 0 && !isset($options['headers']['Content-Type']) && $options['method'] == 'POST') {
+      $options['headers']['Content-Type'] = 'application/x-www-form-urlencoded';
+    }
 
-  // Set the Content-Type to application/x-www-form-urlencoded if the data is
-  // not empty, the Content-Type is not set, and the method is POST.
-  if ($content_length > 0 && !isset($options['headers']['Content-Type']) && $options['method'] == 'POST') {
-    $options['headers']['Content-Type'] = 'application/x-www-form-urlencoded';
-  }
+    // If the server URL has a user then attempt to use basic authentication.
+    if (isset($uri['user'])) {
+      $options['headers']['Authorization'] = 'Basic ' . base64_encode($uri['user'] . (!empty($uri['pass']) ? ":" . $uri['pass'] : ''));
+    }
 
-  // If the server URL has a user then attempt to use basic authentication.
-  if (isset($uri['user'])) {
-    $options['headers']['Authorization'] = 'Basic ' . base64_encode($uri['user'] . (!empty($uri['pass']) ? ":" . $uri['pass'] : ''));
-  }
+    // Assemble the request together. HTTP version requires to be a float.
+    $request = $options['method'] . ' ' . $path . ' HTTP/' . sprintf("%.1F", $options['version']) . "\r\n";
+    foreach ($options['headers'] as $name => $value) {
+      $request .= $name . ': ' . trim($value) . "\r\n";
+    }
+    $request .= "\r\n" . $options['data'];
 
-  // Assemble the request together. HTTP version requires to be a float.
-  $request = $options['method'] . ' ' . $path . ' HTTP/' . sprintf("%.1F", $options['version']) . "\r\n";
-  foreach ($options['headers'] as $name => $value) {
-    $request .= $name . ': ' . trim($value) . "\r\n";
+    // Put this request into the queue to be processed.
+    $return[$url] = httprl_send_request($fp, $url, $request, $options);
+    continue;
   }
-  $request .= "\r\n" . $options['data'];
-
-  // Put this request into the queue to be processed.
-  return httprl_send_request($fp, $url, $request, $options);
+  return $return;
 }
 
 /**
