diff --git a/httprl.install b/httprl.install
index 01f029b..b5dcf76 100644
--- a/httprl.install
+++ b/httprl.install
@@ -6,32 +6,32 @@
  */
 
 /**
- * Implementation of hook_enable().
+ * Implements hook_enable().
  */
 function httprl_enable() {
 }
 
 /**
- * Implementation of hook_disable().
+ * Implements hook_disable().
  */
 function httprl_disable() {
 }
 
 /**
- * Implementation of hook_install().
+ * Implements hook_install().
  */
 function httprl_install() {
 }
 
 /**
- * Implementation of hook_uninstall().
+ * Implements hook_uninstall().
  */
 function httprl_uninstall() {
   variable_del('httprl_server_addr');
 }
 
 /**
- * Implementation of hook_requirements().
+ * Implements hook_requirements().
  */
 function httprl_requirements($phase) {
   $requirements = array();
diff --git a/httprl.module b/httprl.module
index 6b7fd2d..2c1363c 100644
--- a/httprl.module
+++ b/httprl.module
@@ -127,7 +127,7 @@ function httprl_build_url_self($path = '', $detect_schema = FALSE) {
   // Server auth.
   $auth = '';
   if (isset($_SERVER['AUTH_TYPE']) && $_SERVER['AUTH_TYPE'] == 'Basic') {
-    $auth = $_SERVER['PHP_AUTH_USER'] . ':' . $_SERVER['PHP_AUTH_PW'] .'@';
+    $auth = $_SERVER['PHP_AUTH_USER'] . ':' . $_SERVER['PHP_AUTH_PW'] . '@';
   }
 
   // Pull in the httprl_server_addr variable from the DB.
@@ -292,11 +292,58 @@ function httprl_request($url, $options = array()) {
     '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();
+  }
 
   // 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']);
+    }
+    elseif ($proxy_user_agent) {
+      $options['headers']['User-Agent'] = $proxy_user_agent;
+    }
+  }
+
   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;
+
     case 'http':
     case 'feed':
       $port = isset($uri['port']) ? $uri['port'] : 80;
@@ -311,6 +358,7 @@ function httprl_request($url, $options = array()) {
         $options['headers']['Host'] .= ':' . $port;
       }
       break;
+
     case 'https':
       // Note: Only works when PHP is compiled with OpenSSL support.
       $port = isset($uri['port']) ? $uri['port'] : 443;
@@ -322,6 +370,7 @@ function httprl_request($url, $options = array()) {
         $options['headers']['Host'] .= ':' . $port;
       }
       break;
+
     default:
       $result->error = 'Invalid schema ' . $uri['scheme'] . '.';
       $result->code = HTTPRL_URL_INVALID_SCHEMA;
@@ -421,18 +470,6 @@ function httprl_request($url, $options = array()) {
     $path .= '?' . $uri['query'];
   }
 
-  // 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();
-  }
-
   // Encode data if not already done.
   if (!is_null($options['data']) && !is_string($options['data'])) {
     $options['data'] = http_build_query($options['data'], '', '&');
@@ -1499,3 +1536,14 @@ function httprl_pr($data) {
   $output = str_replace('    ', '&nbsp;&nbsp;&nbsp;&nbsp;', nl2br(implode("\n", $output))) . '<br />';
   return $output;
 }
+
+/**
+ * Helper function for determining hosts excluded from needing a proxy.
+ *
+ * @return
+ *   TRUE if a proxy should be used for this host.
+ */
+function _httprl_use_proxy($host) {
+  $proxy_exceptions = variable_get('proxy_exceptions', array('localhost', '127.0.0.1'));
+  return !in_array(strtolower($host), $proxy_exceptions, TRUE);
+}
