From d4893a555e5243c3ca0bfd0cb029a7f35e358c1a Mon Sep 17 00:00:00 2001
From: robocoder <anthon.pang@gmail.com>
Date: Mon, 14 Dec 2009 22:24:19 +0000
Subject: [PATCH] fixes #869 - Installation - detect presence of a reverse
 proxy and warn if mismatch with $_SERVER['HTTPS']; add 'reverse_proxy' config
 setting

git-svn-id: http://dev.piwik.org/svn/trunk@1705 59fd770c-687e-43c8-a1e3-f5a4ff64c105
---
 config/global.ini.php                         |  3 ++
 core/Visualization/Chart.php                  |  7 ++--
 lang/en.php                                   |  2 +
 plugins/Installation/Controller.php           | 39 +++++++++++++++++++
 .../Installation/templates/systemCheck.tpl    |  6 +++
 plugins/Installation/templates/welcome.tpl    | 11 ++++++
 6 files changed, 65 insertions(+), 3 deletions(-)

diff --git a/config/global.ini.php b/config/global.ini.php
index 01be3fb701..edb43629da 100644
--- a/config/global.ini.php
+++ b/config/global.ini.php
@@ -154,6 +154,9 @@ swfobject_version = 2.2
 ; If set to 1, Piwik uses a single HTTP request per Flash widget to serve both the widget and data
 serve_widget_and_data = 1
 
+; If set to 1, Piwik adds a response header to workaround the IE+Flash+HTTPS bug.
+reverse_proxy = 0
+
 [Tracker]
 ; set to 0 if you want to stop tracking the visitors. Useful if you need to stop all the connections on the DB.
 record_statistics			= 1
diff --git a/core/Visualization/Chart.php b/core/Visualization/Chart.php
index c5026f1b0c..35624b89fc 100644
--- a/core/Visualization/Chart.php
+++ b/core/Visualization/Chart.php
@@ -128,10 +128,11 @@ abstract class Piwik_Visualization_Chart implements Piwik_iView
 	
 	public function render()
 	{
-		if(Piwik_Url::getCurrentScheme() == 'https')
+		if(Piwik_Url::getCurrentScheme() == 'https' ||
+			Zend_Registry::get('config')->General->reverse_proxy)
 		{
-    		@header("Pragma: ");
-    		@header("Cache-Control: must-revalidate");
+			@header("Pragma: ");
+			@header("Cache-Control: must-revalidate");
 		}
 		return $this->chart->toPrettyString();
 	}
diff --git a/lang/en.php b/lang/en.php
index 50b4d0fa88..8281401456 100644
--- a/lang/en.php
+++ b/lang/en.php
@@ -781,6 +781,8 @@ Note that it is not necessary to specify the URLs with and without \'www\' as Pi
 	'Installation_SystemCheckMailHelp' => 'Feedback and Lost Password messages will not be sent without mail().',
 	'Installation_SystemCheckError' => 'An error occured - must be fixed before you proceed',
 	'Installation_SystemCheckWarning' => 'Piwik will work normally but some features may be missing',
+	'Installation_SystemCheckProtocol' => 'Protocol',
+	'Installation_SystemCheckProtocolHelp' => 'If you are behind a reverse proxy, add these lines to config/config.ini.php:',
 	'Installation_Tables' => 'Creating the tables',
 	'Installation_TablesWithSameNamesFound' => 'Some %s tables in your database %s have the same names as the tables Piwik is trying to create',
 	'Installation_TablesFound' => 'The following tables have been found in the database',
diff --git a/plugins/Installation/Controller.php b/plugins/Installation/Controller.php
index facabedbf5..e72671da86 100644
--- a/plugins/Installation/Controller.php
+++ b/plugins/Installation/Controller.php
@@ -319,6 +319,7 @@ class Piwik_Installation_Controller extends Piwik_Controller
 				'login' 		=> $form->getSubmitValue('login'),
 				'password' 		=> md5( $form->getSubmitValue('password') ),
 				'email' 		=> $form->getSubmitValue('email'),
+				'salt'			=> Piwik_Common::generateUniqId(),
 			);
 
 			$this->session->superuser_infos = $superUserInfos;
@@ -637,9 +638,47 @@ class Piwik_Installation_Controller extends Piwik_Controller
 
 		$infos['isWindows'] = substr(PHP_OS, 0, 3) == 'WIN';
 
+		$infos['protocol_ok'] = true;
+		$infos['protocol'] = self::getProtocolInformation();
+		if(Piwik_Url::getCurrentScheme() == 'http' &&
+			$infos['protocol'] !== null)
+		{
+			$infos['protocol_ok'] = false;
+		}
+
 		return $infos;
 	}
 
+	public static function getProtocolInformation()
+	{
+		if(Piwik_Common::getRequestVar('clientProtocol', 'http', 'string') == 'https')
+		{
+			return 'https';
+		}
+
+		if(isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == 443)
+		{
+			return 'SERVER_PORT=443';
+		}
+
+		if(isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) == 'https')
+		{
+			return 'X-Forwarded-Proto';
+		}
+
+		if(isset($_SERVER['HTTP_X_FORWARDED_SCHEME']) && strtolower($_SERVER['HTTP_X_FORWARDED_SCHEME']) == 'https')
+		{
+			return 'X-Forwarded-Scheme';
+		}
+
+		if(isset($_SERVER['HTTP_X_URL_SCHEME']) && strtolower($_SERVER['HTTPS']) == 'HTTP_X_URL_SCHEME')
+		{
+			return 'X-Url-Scheme';
+		}
+
+		return null;
+	}
+
 	protected function skipThisStep( $step )
 	{
 		if(isset($this->session->skipThisStep[$step])
diff --git a/plugins/Installation/templates/systemCheck.tpl b/plugins/Installation/templates/systemCheck.tpl
index 75b3c6843b..0de5f0c938 100644
--- a/plugins/Installation/templates/systemCheck.tpl
+++ b/plugins/Installation/templates/systemCheck.tpl
@@ -165,6 +165,12 @@
 			{/foreach}
 		</td>
 	</tr>
+	<tr>
+		<td class="label">{'Installation_SystemCheckProtocol'|translate}</td>
+		<td>
+			{if $infos.protocol_ok}{$ok}{else}{$warning} {$infos.protocol}<br /><i>{'Installation_SystemCheckProtocolHelp'|translate}</i><br /><br /><code>[General]</code><br /><code>reverse_proxy = 1</code><br />{/if}
+		</td>
+	</tr>
 </table>
 
 <p>
diff --git a/plugins/Installation/templates/welcome.tpl b/plugins/Installation/templates/welcome.tpl
index c2985c3c36..40b958a78e 100644
--- a/plugins/Installation/templates/welcome.tpl
+++ b/plugins/Installation/templates/welcome.tpl
@@ -2,3 +2,14 @@
 
 {'Installation_WelcomeHelp'|translate:$totalNumberOfSteps}
 
+{literal}
+<script type="text/javascript">
+<!--
+$(function() {
+if (document.location.protocol === 'https:') {
+	$('p.nextStep a').attr('href', $('p.nextStep a').attr('href') + '&clientProtocol=https');
+}
+});
+//-->
+</script>
+{/literal}
-- 
GitLab