--- includes/_common.inc.original 2008-08-18 18:05:59.000000000 +0200 +++ includes/common.inc 2008-08-19 14:16:22.000000000 +0200 @@ -416,6 +416,9 @@ function drupal_access_denied() { function drupal_http_request($url, $headers = array(), $method = 'GET', $data = NULL, $retry = 3) { static $self_test = FALSE; $result = new stdClass(); + + $proxy_not_required = TRUE; + // Try to clear the drupal_http_request_fails variable if it's set. We // can't tie this call to any error because there is no surefire way to // tell whether a request has failed, so we add the check to places where @@ -449,7 +452,15 @@ function drupal_http_request($url, $head case 'http': $port = isset($uri['port']) ? $uri['port'] : 80; $host = $uri['host'] . ($port != 80 ? ':'. $port : ''); - $fp = @fsockopen($uri['host'], $port, $errno, $errstr, 15); + $proxy_not_required = is_in_no_proxy_list($uri['host']); + if ((variable_get('proxy_server', '') != '') && (FALSE == $proxy_not_required)) { + $proxy_server = variable_get('proxy_server', ''); + $proxy_port = variable_get('proxy_port', 8080); + $fp = @fsockopen($proxy_server, $proxy_port, $errno, $errstr, 15); + } + else { + $fp = @fsockopen($uri['host'], $port, $errno, $errstr, 15); + } break; case 'https': // Note: Only works for PHP 4.3 compiled with OpenSSL. @@ -472,9 +483,14 @@ function drupal_http_request($url, $head } // 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)) { + $path = $url; + } + else { + $path = isset($uri['path']) ? $uri['path'] : '/'; + if (isset($uri['query'])) { + $path .= '?'. $uri['query']; + } } // Create HTTP request. @@ -492,6 +508,13 @@ function drupal_http_request($url, $head $defaults['Authorization'] = 'Authorization: Basic '. base64_encode($uri['user'] . (!empty($uri['pass']) ? ":". $uri['pass'] : '')); } + if ((variable_get('proxy_username', '') != '') && (FALSE == $proxy_not_required)) { + $username = variable_get('proxy_username', ''); + $password = variable_get('proxy_password', ''); + $auth_string = base64_encode($username . ($password != '' ? ':'. $password : '')); + $defaults['Proxy-Authorization'] = 'Proxy-Authorization: Basic '. $auth_string ."\r\n"; + } + foreach ($headers as $header => $value) { $defaults[$header] = $header .': '. $value; } @@ -569,6 +592,23 @@ function drupal_http_request($url, $head $result->code = $code; return $result; } + +function is_in_no_proxy_list($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". */ --- modules/system/_system.admin.inc.original 2008-08-18 18:06:15.000000000 +0200 +++ modules/system/system.admin.inc 2008-08-19 14:12:28.000000000 +0200 @@ -1363,6 +1363,77 @@ function system_clear_cache_submit(&$for } /** + * 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' => variable_get('proxy_server', ''), + '#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' => variable_get('proxy_port', 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' => variable_get('proxy_username', ''), + '#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' => variable_get('proxy_password', ''), + '#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' => variable_get('proxy_exceptions', 'localhost'), + '#description' => t('Example: .example.com,localhost,192.168.1.2', '') + ); + $form['forward_proxy']['proxy_skip_selftest'] = array( + '#type' => 'checkbox', + '#title' => t('Skip HTTP self test'), + '#description' => t('Skip HTTP request self test.'), + '#default_value' => variable_get('proxy_skip_selftest', '0'), + ); + $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 ($form_state['values']['proxy_server'] != '') { + // TCP allows the port to be between 0 and 65536 inclusive + if (!is_numeric($form_state['values']['proxy_port'])) { + form_set_error('proxy_port', t('The proxy port is invalid. It must be a number between 0 and 65535.')); + } + elseif ($form_state['values']['proxy_port'] < 0 || $form_state['values']['proxy_port'] >= 65536) { + form_set_error('proxy_port', t('The proxy port is invalid. It must be between 0 and 65535.')); + } + } +} + +/** * Form builder; Configure the site file handling. * * @ingroup forms --- modules/system/_system.module.original 2008-08-18 18:06:20.000000000 +0200 +++ modules/system/system.module 2008-08-19 14:13:52.000000000 +0200 @@ -55,7 +55,7 @@ function system_help($path, $arg) { $output .= '
  • '. t('support for enabling and disabling themes, which determine the design and presentation of your site. Drupal comes packaged with several core themes and additional contributed themes are available at the Drupal.org theme page.', array('@themes' => url('admin/build/themes'), '@drupal-themes' => 'http://drupal.org/project/themes')) .'
  • '; $output .= '
  • '. t('a robust caching system that allows the efficient re-use of previously-constructed web pages and web page components. Drupal stores the pages requested by anonymous users in a compressed format; depending on your site configuration and the amount of your web traffic tied to anonymous visitors, Drupal\'s caching system may significantly increase the speed of your site.', array('@cache-settings' => url('admin/settings/performance'))) .'
  • '; $output .= '
  • '. t('a set of routine administrative operations that rely on a correctly-configured cron maintenance task to run automatically. A number of other modules, including the feed aggregator, ping module and search also rely on cron maintenance tasks. For more information, see the online handbook entry for configuring cron jobs.', array('@cron' => url('admin/reports/status'), '@handbook' => 'http://drupal.org/cron')) .'
  • '; - $output .= '
  • '. t('basic configuration options for your site, including date and time settings, file system settings, clean URL support, site name and other information, and a site maintenance function for taking your site temporarily off-line.', array('@date-settings' => url('admin/settings/date-time'), '@file-system' => url('admin/settings/file-system'), '@clean-url' => url('admin/settings/clean-urls'), '@site-info' => url('admin/settings/site-information'), '@site-maintenance' => url('admin/settings/site-maintenance'))) .'
  • '; + $output .= '
  • '. t('basic configuration options for your site, including date and time settings, file system settings, clean URL support, proxy server settings, site name and other information, and a site maintenance function for taking your site temporarily off-line.', array('@date-settings' => url('admin/settings/date-time'), '@file-system' => url('admin/settings/file-system'), '@clean-url' => url('admin/settings/clean-urls'), '@proxy-server' => url('admin/settings/proxy'), '@site-info' => url('admin/settings/site-information'), '@site-maintenance' => url('admin/settings/site-maintenance'))) .'
  • '; $output .= '

    '. t('For more information, see the online handbook entry for System module.', array('@system' => 'http://drupal.org/handbook/modules/system/')) .'

    '; return $output; case 'admin': @@ -406,6 +406,14 @@ function system_menu() { 'access arguments' => array('administer site configuration'), 'file' => 'system.admin.inc', ); + $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.', @@ -1877,13 +1885,19 @@ function system_check_http_request() { // Check whether we can do any request at all. First get the results for // a very simple page which has access TRUE set via the menu system. Then, // try to drupal_http_request() the same page and compare. - ob_start(); - $path = 'admin/reports/request-test'; - menu_execute_active_handler($path); - $nothing = ob_get_contents(); - ob_end_clean(); - $result = drupal_http_request(url($path, array('absolute' => TRUE))); - $works = isset($result->data) && $result->data == $nothing; + $skip_selftest = variable_get('proxy_skip_selftest', '0'); + if (0 == $skip_selftest) { + ob_start(); + $path = 'admin/reports/request-test'; + menu_execute_active_handler($path); + $nothing = ob_get_contents(); + ob_end_clean(); + $result = drupal_http_request(url($path, array('absolute' => TRUE))); + $works = isset($result->data) && $result->data == $nothing; + } + else { + $works = TRUE; + } variable_set('drupal_http_request_fails', !$works); return $works; }