Index: includes/common.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/common.inc,v
retrieving revision 1.935
diff -u -p -r1.935 common.inc
--- includes/common.inc	15 Jul 2009 17:40:17 -0000	1.935
+++ includes/common.inc	18 Jul 2009 23:57:38 -0000
@@ -483,11 +483,27 @@ function drupal_http_request($url, array
     'timeout' => 30,
   );
 
+  $proxy_server = variable_get('proxy_server', '');
+  if ((strlen($proxy_server) > 0) && (FALSE == _matches_proxy_exceptions($uri['host']))) {
+      $use_proxy = TRUE;
+      $proxy_port = variable_get('proxy_port', 8080);
+      $proxy_username = variable_get('proxy_username', '');
+      $proxy_password = variable_get('proxy_password', '');
+  }
+  else {
+    $use_proxy = FALSE;
+  }
+
   switch ($uri['scheme']) {
     case 'http':
       $port = isset($uri['port']) ? $uri['port'] : 80;
       $host = $uri['host'] . ($port != 80 ? ':' . $port : '');
-      $fp = @fsockopen($uri['host'], $port, $errno, $errstr, $options['timeout']);
+      if ($use_proxy) {
+        $fp = @fsockopen($proxy_server, $proxy_port, $errno, $errstr, $options['timeout']);
+      }
+      else {
+        $fp = @fsockopen($uri['host'], $port, $errno, $errstr, $options['timeout']);
+      }
       break;
     case 'https':
       // Note: Only works when PHP is compiled with OpenSSL support.
@@ -517,9 +533,15 @@ function drupal_http_request($url, array
   }
 
   // Construct the path to act on.
-  $path = isset($uri['path']) ? $uri['path'] : '/';
-  if (isset($uri['query'])) {
-    $path .= '?' . $uri['query'];
+  // if ((variable_get('proxy_server', '') != '') && (FALSE == $proxy_not_required)) {
+  if ($use_proxy) {
+    $path = $url;
+  }
+  else {
+    $path = isset($uri['path']) ? $uri['path'] : '/';
+    if (isset($uri['query'])) {
+      $path .= '?' . $uri['query'];
+    }
   }
 
   // Merge the default headers.
@@ -546,6 +568,11 @@ function drupal_http_request($url, array
     $options['headers']['Authorization'] = 'Basic ' . base64_encode($uri['user'] . (!empty($uri['pass']) ? ":" . $uri['pass'] : ''));
   }
 
+  if ($use_proxy && !empty($proxy_username)) {
+    $auth_string = base64_encode($proxy_username . ($proxy_password != '' ? ':'. $proxy_password : ''));
+    $defaults['Proxy-Authorization'] = 'Proxy-Authorization: Basic '. $auth_string ."\r\n";
+  }
+  
   // If the database prefix is being used by SimpleTest to run the tests in a copied
   // database then set the user-agent header to the database prefix so that any
   // calls to other Drupal pages will run the SimpleTest prefixed database. The
@@ -680,6 +707,34 @@ function drupal_http_request($url, array
 
   return $result;
 }
+
+/**
+ * Checks host against proxy exceptions
+ *
+ * @param $host
+ *   A string containing the host part of the requested URI.
+ * @return
+ *   - TRUE if one of the proxy exceptions equals or is part of $host.
+ *   - FALSE if none of the proxy exceptions equals or is part of $host.
+ */
+function _matches_proxy_exceptions($host) {
+  $rv = FALSE;
+                                                                                                    
+  $proxy_exceptions = variable_get('proxy_exceptions', '');
+  if (FALSE == empty($proxy_exceptions)) {
+    $patterns = explode(",", $proxy_exceptions);
+    foreach ($patterns as $pattern) {
+      $pattern = trim($pattern, " ");
+
+      if (strstr($host, $pattern)) {
+        $rv = TRUE;
+        break;
+      }
+    }
+  }
+  return $rv;
+}
+
 /**
  * @} End of "HTTP handling".
  */
Index: modules/system/system.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.admin.inc,v
retrieving revision 1.161
diff -u -p -r1.161 system.admin.inc
--- modules/system/system.admin.inc	16 Jul 2009 10:44:20 -0000	1.161
+++ modules/system/system.admin.inc	18 Jul 2009 23:58:05 -0000
@@ -1377,6 +1377,75 @@ function system_clear_cache_submit($form
 }
 
 /**
+ * Form builder; Configure the site proxy settings.
+ *
+ * @ingroup forms
+ * @see system_settings_form()
+ */
+function system_proxy_settings() {
+
+  $form['forward_proxy'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Forward Proxy Settings'),
+    '#description' => t('The proxy server used when Drupal needs to connect to other sites on the Internet.'),
+  );
+
+  $form['forward_proxy']['proxy_server'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Proxy host name'),
+    '#default_value' => '',
+    '#description' => t('The host name of the proxy server, eg. localhost. If this is empty Drupal will connect directly to the internet.'),
+  );
+
+  $form['forward_proxy']['proxy_port'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Proxy port number'),
+    '#default_value' => 8080,
+    '#description' => t('The port number of the proxy server, eg. 8080'),
+  );
+
+  $form['forward_proxy']['proxy_username'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Proxy username'),
+    '#default_value' => '',
+    '#description' => t('The username used to authenticate with the proxy server.'),
+  );
+
+  $form['forward_proxy']['proxy_password'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Proxy password'),
+    '#default_value' => '',
+    '#description' => t('The password used to connect to the proxy server. This is kept as plain text.'),
+  );
+
+  $form['forward_proxy']['proxy_exceptions'] = array(
+    '#type' => 'textfield',
+    '#title' => t('No proxy for'),
+    '#default_value' => 'localhost',
+    '#description' => t('Example: .example.com,localhost,192.168.1.2'),
+  );
+
+  $form['#validate'][] = 'system_proxy_settings_validate';
+
+  return system_settings_form($form);
+}
+
+/**
+ * Validate the submitted proxy form.
+ */
+function system_proxy_settings_validate($form, &$form_state) {
+  // Validate the proxy settings
+  $form_state['values']['proxy_server'] = trim($form_state['values']['proxy_server']);
+  if (strlen($form_state['values']['proxy_server']) > 0) {
+    $proxy_port = $form_state['values']['proxy_port'];
+    // TCP allows the port to be between 0 and 65535 inclusive
+    if (!is_numeric($proxy_port) || ($proxy_port < 0) || ($proxy_port > 65535)) {
+      form_set_error('proxy_port', t('The proxy port is invalid. It must be a number between 0 and 65535.'));
+    }
+  }
+}
+
+/**
  * Form builder; Configure the site file handling.
  *
  * @ingroup forms
Index: modules/system/system.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.module,v
retrieving revision 1.724
diff -u -p -r1.724 system.module
--- modules/system/system.module	18 Jul 2009 02:36:01 -0000	1.724
+++ modules/system/system.module	18 Jul 2009 23:58:29 -0000
@@ -710,6 +710,14 @@ function system_menu() {
     'page arguments' => array('system_performance_settings'),
     'access arguments' => array('administer site configuration'),
   );
+  $items['admin/settings/proxy'] = array(
+    'title' => 'Proxy Server',
+    'description' => 'Configure settings when the site is behind a proxy server.',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('system_proxy_settings'),
+    'access arguments' => array('administer site configuration'),
+    'file' => 'system.admin.inc',
+  );
   $items['admin/settings/file-system'] = array(
     'title' => 'File system',
     'description' => 'Tell Drupal where to store uploaded files and how they are accessed.',
