summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwebchick <webchick@24967.no-reply.drupal.org>2012-09-01 22:25:49 -0700
committerwebchick <webchick@24967.no-reply.drupal.org>2012-09-01 22:25:49 -0700
commit76acfb9b16f808f9fadf4e12359e225637cbaa77 (patch)
tree46b9c675643753ba3b762caf19721364ef89ea00
parent3b64ddd9630648eb267d63536feff41cad92e5e4 (diff)
downloadbrdo-76acfb9b16f808f9fadf4e12359e225637cbaa77.tar.gz
brdo-76acfb9b16f808f9fadf4e12359e225637cbaa77.tar.bz2
Issue #7881 by mikeytown2, effulgentsia, gwynnebaer, Patrizio, sylus, pwolanin, David_Rothstein: Add support to drupal_http_request() for proxy servers.
-rw-r--r--CHANGELOG.txt1
-rw-r--r--includes/common.inc60
-rw-r--r--sites/default/default.settings.php18
3 files changed, 74 insertions, 5 deletions
diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index 90c116dfa..afdd67e05 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -13,6 +13,7 @@ Drupal 7.16, xxxx-xx-xx (development version)
- Fixed a regression which caused a "call to undefined function
drupal_find_base_themes()" fatal error under rare circumstances.
- Added "lang" attributes to language links, to better support screen readers.
+- Added proxy server support to drupal_http_request().
Drupal 7.15, 2012-08-01
-----------------------
diff --git a/includes/common.inc b/includes/common.inc
index efb7926a3..ef2cffbb4 100644
--- a/includes/common.inc
+++ b/includes/common.inc
@@ -798,10 +798,51 @@ function drupal_http_request($url, array $options = array()) {
'timeout' => 30.0,
'context' => NULL,
);
+
+ // Merge the default headers.
+ $options['headers'] += array(
+ 'User-Agent' => 'Drupal (+http://drupal.org/)',
+ );
+
// stream_socket_client() requires timeout to be a float.
$options['timeout'] = (float) $options['timeout'];
+ // Use a proxy if one is defined and the host is not on the excluded list.
+ $proxy_server = variable_get('proxy_server', '');
+ if ($proxy_server && _drupal_http_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 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 ($proxy_user_agent === NULL) {
+ 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;
@@ -811,12 +852,14 @@ function drupal_http_request($url, array $options = array()) {
// checking the host that do not take into account the port number.
$options['headers']['Host'] = $uri['host'] . ($port != 80 ? ':' . $port : '');
break;
+
case 'https':
// Note: Only works when PHP is compiled with OpenSSL support.
$port = isset($uri['port']) ? $uri['port'] : 443;
$socket = 'ssl://' . $uri['host'] . ':' . $port;
$options['headers']['Host'] = $uri['host'] . ($port != 443 ? ':' . $port : '');
break;
+
default:
$result->error = 'invalid schema ' . $uri['scheme'];
$result->code = -1003;
@@ -853,11 +896,6 @@ function drupal_http_request($url, array $options = array()) {
$path .= '?' . $uri['query'];
}
- // Merge the default headers.
- $options['headers'] += array(
- 'User-Agent' => 'Drupal (+http://drupal.org/)',
- );
-
// 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
@@ -1028,6 +1066,18 @@ function drupal_http_request($url, array $options = array()) {
return $result;
}
+
+/**
+ * Helper function for determining hosts excluded from needing a proxy.
+ *
+ * @return
+ * TRUE if a proxy should be used for this host.
+ */
+function _drupal_http_use_proxy($host) {
+ $proxy_exceptions = variable_get('proxy_exceptions', array('localhost', '127.0.0.1'));
+ return !in_array(strtolower($host), $proxy_exceptions, TRUE);
+}
+
/**
* @} End of "HTTP handling".
*/
diff --git a/sites/default/default.settings.php b/sites/default/default.settings.php
index 0ae34a2bb..2e5654b2e 100644
--- a/sites/default/default.settings.php
+++ b/sites/default/default.settings.php
@@ -506,6 +506,24 @@ $conf['404_fast_html'] = '<html xmlns="http://www.w3.org/1999/xhtml"><head><titl
# drupal_fast_404();
/**
+ * External access proxy settings:
+ *
+ * If your site must access the Internet via a web proxy then you can enter
+ * the proxy settings here. Currently only basic authentication is supported
+ * by using the username and password variables. The proxy_user_agent variable
+ * can be set to NULL for proxies that require no User-Agent header or to a
+ * non-empty string for proxies that limit requests to a specific agent. The
+ * proxy_exceptions variable is an array of host names to be accessed directly,
+ * not via proxy.
+ */
+# $conf['proxy_server'] = '';
+# $conf['proxy_port'] = 8080;
+# $conf['proxy_username'] = '';
+# $conf['proxy_password'] = '';
+# $conf['proxy_user_agent'] = '';
+# $conf['proxy_exceptions'] = array('127.0.0.1', 'localhost');
+
+/**
* Authorized file system operations:
*
* The Update manager module included with Drupal provides a mechanism for