Merge branch 'support/2.7' into develop

This commit is contained in:
odain
2021-03-09 15:40:30 +01:00
7 changed files with 371 additions and 62 deletions

View File

@@ -722,7 +722,7 @@ class LoginWebPage extends NiceWebPage
public static function HTTPReload()
{
$sOriginURL = $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
$sOriginURL = utils::GetCurrentAbsoluteUrl();
if (!utils::StartsWith($sOriginURL, utils::GetAbsoluteUrlAppRoot()))
{
// If the found URL does not start with the configured AppRoot URL

View File

@@ -860,16 +860,34 @@ class utils
// }
}
/**
* @return bool The boolean value of the conf. "trust_proxies" (except if there is no REMOTE_ADDR int his case, it return false)
*
* @since 2.7.4
*/
public static function IsProxyTrusted()
{
if (empty($_SERVER['REMOTE_ADDR'])) {
return false;
}
$bTrustProxies = (bool) self::GetConfig()->Get('trust_proxies');
return $bTrustProxies;
}
/**
* Returns the absolute URL to the application root path
*
* @param bool $bTrustProxy
* @param bool $bForceTrustProxy
*
* @return string The absolute URL to the application root, without the first slash
*
* @throws \Exception
*
* @since 2.7.4 $bForceTrustProxy param added
*/
public static function GetAbsoluteUrlAppRoot($bTrustProxy=false)
public static function GetAbsoluteUrlAppRoot($bForceTrustProxy = false)
{
static $sUrl = null;
if ($sUrl === null)
@@ -877,7 +895,7 @@ class utils
$sUrl = self::GetConfig()->Get('app_root_url');
if ($sUrl == '')
{
$sUrl = self::GetDefaultUrlAppRoot($bTrustProxy);
$sUrl = self::GetDefaultUrlAppRoot($bForceTrustProxy);
}
elseif (strpos($sUrl, SERVER_NAME_PLACEHOLDER) > -1)
{
@@ -901,33 +919,116 @@ class utils
* For most usages, when an root url is needed, use utils::GetAbsoluteUrlAppRoot() instead as uses this only as a fallback when the
* app_root_url conf parameter is not defined.
*
* @param bool $bTrustProxy
*
* @param bool $bForceTrustProxy
*
* @return string
*
* @throws \Exception
*/
public static function GetDefaultUrlAppRoot($bTrustProxy=false)
*
* @since 2.7.4 $bForceTrustProxy param added
*/
public static function GetDefaultUrlAppRoot($bForceTrustProxy = false)
{
$sAbsoluteUrl = self::GetCurrentAbsoluteUrl($bForceTrustProxy, true);
$sCurrentScript = realpath($_SERVER['SCRIPT_FILENAME']);
$sAppRoot = realpath(APPROOT);
return self::GetAppRootUrl($sCurrentScript, $sAppRoot, $sAbsoluteUrl);
}
/**
* Build the current absolute URL from the server's variables.
*
* For almost every usage, you should use the more secure utils::GetAbsoluteUrlAppRoot() : instead of reading the current uri, it provide you the configured application's root URL (this is done during the setup and chn be changed in the configuration file)
*
* @see utils::GetAbsoluteUrlAppRoot
*
* @param bool $bForceTrustProxy
* @param bool $bTrimQueryString
*
* @return string
*
* @since 2.7.4
*/
public static function GetCurrentAbsoluteUrl($bForceTrustProxy = false, $bTrimQueryString = false)
{
// Build an absolute URL to this page on this server/port
$sServerName = isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : '';
$sProtocol = self::IsConnectionSecure($bTrustProxy) ? 'https' : 'http';
$iPort = isset($_SERVER['SERVER_PORT']) ? $_SERVER['SERVER_PORT'] : 80;
if ($sProtocol == 'http')
{
$sServerName = self::GetServerName($bForceTrustProxy);
$bIsSecure = self::IsConnectionSecure($bForceTrustProxy);
$sProtocol = $bIsSecure ? 'https' : 'http';
$iPort = self::GetServerPort($bForceTrustProxy);
if ($bIsSecure) {
$sPort = ($iPort == 443) ? '' : ':'.$iPort;
} else {
$sPort = ($iPort == 80) ? '' : ':'.$iPort;
}
else
{
$sPort = ($iPort == 443) ? '' : ':'.$iPort;
$sPath = self::GetRequestUri($bForceTrustProxy);
if ($bTrimQueryString) {
// remove all the parameters from the query string
$iQuestionMarkPos = strpos($sPath, '?');
if ($iQuestionMarkPos !== false) {
$sPath = substr($sPath, 0, $iQuestionMarkPos);
}
}
$sAbsoluteUrl = "$sProtocol://{$sServerName}{$sPort}{$sPath}";
return $sAbsoluteUrl;
}
/**
* @param bool $bForceTrustProxy
*
* @return string
*
* @since 2.7.4
*/
public static function GetServerName($bForceTrustProxy = false)
{
$bTrustProxy = $bForceTrustProxy || self::IsProxyTrusted();
$sServerName = isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : '';
if ($bTrustProxy) {
$sServerName = isset($_SERVER['HTTP_X_FORWARDED_HOST']) ? $_SERVER['HTTP_X_FORWARDED_HOST'] : $sServerName;
}
return $sServerName;
}
/**
* @param bool $bForceTrustProxy
*
* @return int|mixed
* @since 2.7.4
*/
public static function GetServerPort($bForceTrustProxy = false)
{
$bTrustProxy = $bForceTrustProxy || self::IsProxyTrusted();
$sServerPort = isset($_SERVER['SERVER_PORT']) ? $_SERVER['SERVER_PORT'] : 80;
if ($bTrustProxy) {
$sServerPort = isset($_SERVER['HTTP_X_FORWARDED_PORT']) ? $_SERVER['HTTP_X_FORWARDED_PORT'] : $sServerPort;
}
return $sServerPort;
}
/**
* @return string
*
* @since 2.7.4
*/
public static function GetRequestUri()
{
// $_SERVER['REQUEST_URI'] is empty when running on IIS
// Let's use Ivan Tcholakov's fix (found on www.dokeos.com)
if (!empty($_SERVER['REQUEST_URI']))
{
$sPath = $_SERVER['REQUEST_URI'];
}
else
if (empty($_SERVER['REQUEST_URI']))
{
$sPath = $_SERVER['SCRIPT_NAME'];
if (!empty($_SERVER['QUERY_STRING']))
@@ -938,18 +1039,7 @@ class utils
}
$sPath = $_SERVER['REQUEST_URI'];
// remove all the parameters from the query string
$iQuestionMarkPos = strpos($sPath, '?');
if ($iQuestionMarkPos !== false)
{
$sPath = substr($sPath, 0, $iQuestionMarkPos);
}
$sAbsoluteUrl = "$sProtocol://{$sServerName}{$sPort}{$sPath}";
$sCurrentScript = realpath($_SERVER['SCRIPT_FILENAME']);
$sAppRoot = realpath(APPROOT);
return self::GetAppRootUrl($sCurrentScript, $sAppRoot, $sAbsoluteUrl);
return $sPath;
}
/**
@@ -1015,28 +1105,32 @@ class utils
/**
* Helper to handle the variety of HTTP servers
* See N°286 (fixed in [896]), and N°634 (this fix)
*
*
* Though the official specs says 'a non empty string', some servers like IIS do set it to 'off' !
* nginx set it to an empty string
* Others might leave it unset (no array entry)
* Others might leave it unset (no array entry)
*
* @param bool $bTrustProxy
* @param bool $bForceTrustProxy
*
* @return bool
*/
public static function IsConnectionSecure($bTrustProxy=false)
*
* @since 2.7.4 reverse proxies handling
*/
public static function IsConnectionSecure($bForceTrustProxy = false)
{
$bSecured = false;
if (!empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && $bTrustProxy)
$bTrustProxy = $bForceTrustProxy || self::IsProxyTrusted();
if ($bTrustProxy && !empty($_SERVER['HTTP_X_FORWARDED_PROTO']))
{
$bSecured = ($_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https');
}
elseif (!empty($_SERVER['HTTP_X_FORWARDED_PROTOCOL']) && $bTrustProxy)
elseif ($bTrustProxy && !empty($_SERVER['HTTP_X_FORWARDED_PROTOCOL']))
{
$bSecured = ($_SERVER['HTTP_X_FORWARDED_PROTOCOL'] === 'https');
}
elseif (isset($_SERVER['HTTPS']) && !empty($_SERVER['HTTPS']))
elseif ((!empty($_SERVER['HTTPS'])) && (strtolower($_SERVER['HTTPS']) != 'off'))
{
$bSecured = (strcasecmp($_SERVER['HTTPS'], 'off') !== 0);
}
@@ -2550,10 +2644,10 @@ class utils
public static function GetCkeditorPref()
{
$sLanguage = strtolower(trim(UserRights::GetUserLanguage()));
$aDefaultConf = array(
'language'=> $sLanguage,
'contentsLanguage' => $sLanguage,
'contentsLanguage' => $sLanguage,
'extraPlugins' => 'disabler,codesnippet,mentions',
);
@@ -2587,10 +2681,10 @@ HTML;
];
}
}
$aRichTextConfig = json_decode(appUserPreferences::GetPref('richtext_config', '{}'), true);
return array_merge($aDefaultConf, $aRichTextConfig);
}
@@ -2601,4 +2695,5 @@ HTML;
public static function IsWindowsEnvironment(){
return (substr(PHP_OS,0,3) === 'WIN');
}
}

View File

@@ -1365,7 +1365,16 @@ class Config
'source_of_value' => '',
'show_in_conf_sample' => false,
],
];
'trust_proxies' => [
'type' => 'bool',
'description' => 'If true, then proxies custom header (X-Forwarded-*) are taken into account. Use only if the webserver is not publicly accessible (reachable only by the reverse proxy)',
'default' => false,
'value' => false,
'source_of_value' => '',
'show_in_conf_sample' => false,
],
);
public function IsProperty($sPropCode)

View File

@@ -81,6 +81,30 @@ if (!class_exists('AttachmentInstaller'))
return $oConfiguration;
}
/**
* @param string $sTableName
* @param int $iBulkSize
*
* @return array
* @throws \CoreException
* @throws \MySQLException
* @throws \MySQLHasGoneAwayException
*/
public static function GetOrphanAttachmentIds($sTableName, $iBulkSize){
$sSqlQuery = <<<SQL
SELECT id as attachment_id FROM `$sTableName` WHERE (`item_id`='' OR `item_id` IS NULL) LIMIT {$iBulkSize};
SQL;
/** @var \mysqli_result $oQueryResult */
$oQueryResult = CMDBSource::Query($sSqlQuery);
$aIds = [];
while($aRow = $oQueryResult->fetch_array()){
$aIds[] = $aRow['attachment_id'];
}
return $aIds;
}
/**
* Handler called before creating or upgrading the database schema
* @param $oConfiguration Config The new configuration of the application
@@ -99,9 +123,31 @@ if (!class_exists('AttachmentInstaller'))
if ($iCount > 0)
{
SetupLog::Info("Cleanup of orphan attachments that cannot be migrated to the new ObjKey model: $iCount record(s) must be deleted.");
$sRepairQuery = "DELETE FROM `$sTableName` WHERE (`item_id`='' OR `item_id` IS NULL)";
$iRet = CMDBSource::Query($sRepairQuery); // Throws an exception in case of error
SetupLog::Info("Cleanup of orphan attachments successfully completed.");
$iBulkSize = 100;
$iMaxDuration = 30;
$iDeletedCount = 0;
$fStartTime = microtime(true);
$aIds = self::GetOrphanAttachmentIds($sTableName, $iBulkSize);
while (count($aIds) !== 0) {
$sCleanupQuery = sprintf("DELETE FROM `$sTableName` WHERE `id` IN (%s)", implode(",", $aIds));
CMDBSource::Query($sCleanupQuery); // Throws an exception in case of error
$iDeletedCount += count($aIds);
$fElapsed = microtime(true) - $fStartTime;
if ($fElapsed > $iMaxDuration){
SetupLog::Info(sprintf("Cleanup of orphan attachments interrupted after %.3f s. $iDeletedCount records were deleted among $iCount.", $fElapsed));
break;
}
$aIds = self::GetOrphanAttachmentIds($sTableName, $iBulkSize);
}
if (count($aIds) === 0){
SetupLog::Info("Cleanup of orphan attachments successfully completed.");
}
}
else
{
@@ -109,7 +155,7 @@ if (!class_exists('AttachmentInstaller'))
}
}
}
/**
* Handler called after the creation/update of the database schema
* @param $oConfiguration Config The new configuration of the application
@@ -124,6 +170,7 @@ if (!class_exists('AttachmentInstaller'))
// Prerequisite: change null into 0 (workaround to the fact that we cannot use IS NULL in OQL)
SetupLog::Info("Initializing attachment/item_org_id - null to zero");
$sTableName = MetaModel::DBGetTable('Attachment');
$sRepair = "UPDATE `$sTableName` SET `item_org_id` = 0 WHERE `item_org_id` IS NULL";
CMDBSource::Query($sRepair);
@@ -133,7 +180,13 @@ if (!class_exists('AttachmentInstaller'))
$iUpdated = 0;
while ($oAttachment = $oSet->Fetch())
{
if (empty($oAttachment->Get('item_class'))) {
//do not treat orphan attachment
continue;
}
$oContainer = MetaModel::GetObject($oAttachment->Get('item_class'), $oAttachment->Get('item_id'), false /* must be found */, true /* allow all data */);
if ($oContainer)
{
$oAttachment->SetItem($oContainer, true /*updateonchange*/);

View File

@@ -623,7 +623,7 @@ class ApplicationInstaller
$oMFCompiler = new MFCompiler($oFactory, $sEnvironment);
$oMFCompiler->Compile($sTargetPath, null, $bUseSymbolicLinks);
//$aCompilerLog = $oMFCompiler->GetLog();
//SetupPage::log_info(implode("\n", $aCompilerLog));
//SetupLog::Info(implode("\n", $aCompilerLog));
SetupLog::Info("Data model successfully compiled to '$sTargetPath'.");
$sCacheDir = APPROOT.'/data/cache-'.$sEnvironment.'/';
@@ -727,10 +727,15 @@ class ApplicationInstaller
SetupLog::Info("There are $iOrphanCount useless records in {$sDBPrefix}priv_change (".sprintf('%.2f', ((100.0*$iOrphanCount)/$iTotalCount))."%)");
if ($iOrphanCount > 0)
{
SetupLog::Info("Removing the orphan records...");
$sCleanup = "DELETE FROM `{$sDBPrefix}priv_change` USING `{$sDBPrefix}priv_change` LEFT JOIN `{$sDBPrefix}priv_changeop` ON `{$sDBPrefix}priv_change`.id = `{$sDBPrefix}priv_changeop`.changeid WHERE `{$sDBPrefix}priv_changeop`.id IS NULL;";
CMDBSource::Query($sCleanup);
SetupLog::Info("Cleanup completed successfully.");
if ($iOrphanCount > 100000)
{
SetupLog::Info("There are too much useless records ($iOrphanCount) in {$sDBPrefix}priv_change. Cleanup cannot be done during setup.");
} else {
SetupLog::Info("Removing the orphan records...");
$sCleanup = "DELETE FROM `{$sDBPrefix}priv_change` USING `{$sDBPrefix}priv_change` LEFT JOIN `{$sDBPrefix}priv_changeop` ON `{$sDBPrefix}priv_change`.id = `{$sDBPrefix}priv_changeop`.changeid WHERE `{$sDBPrefix}priv_changeop`.id IS NULL;";
CMDBSource::Query($sCleanup);
SetupLog::Info("Cleanup completed successfully.");
}
}
else
{

View File

@@ -987,14 +987,14 @@ class WizStepMiscParams extends WizardStep
$oPage->add('<fieldset>');
$oPage->add('<legend>Application URL</legend>');
$oPage->add('<table>');
$oPage->add('<tr><td>URL: </td><td><input id="application_url" name="application_url" type="text" size="35" maxlength="1024" value="'.htmlentities($sApplicationURL, ENT_QUOTES, 'UTF-8').'"><span id="v_application_url"/></td><tr>');
$oPage->add('<tr><td colspan="2">Change the value above if the end-users will be accessing the application by another path due to a specific configuration of the web server.</td><tr>');
$oPage->add('<tr><td>URL: </td><td><input id="application_url" name="application_url" type="text" size="35" maxlength="1024" value="'.htmlentities($sApplicationURL, ENT_QUOTES, 'UTF-8').'" style="width: 100%;box-sizing: border-box;"><span id="v_application_url"/></td><tr>');
$oPage->add('<tr><td colspan="2"><div class="message message-warning">Change the value above if the end-users will be accessing the application by another path due to a specific configuration of the web server.</div></td><tr>');
$oPage->add('</table>');
$oPage->add('</fieldset>');
$oPage->add('<fieldset>');
$oPage->add('<legend>Path to Graphviz\' dot application</legend>');
$oPage->add('<table style="width: 100%;">');
$oPage->add('<tr><td>Path: </td><td><input id="graphviz_path" name="graphviz_path" type="text" size="35" maxlength="1024" value="'.htmlentities($sGraphvizPath, ENT_QUOTES, 'UTF-8').'"><span id="v_graphviz_path"/></td><tr>');
$oPage->add('<tr><td>Path: </td><td><input id="graphviz_path" name="graphviz_path" type="text" size="35" maxlength="1024" value="'.htmlentities($sGraphvizPath, ENT_QUOTES, 'UTF-8').'" style="width: 100%;box-sizing: border-box;"><span id="v_graphviz_path"/></td><tr>');
$oPage->add('<tr><td colspan="2"><a href="http://www.graphviz.org" target="_blank">Graphviz</a> is required to display the impact analysis graph (i.e. impacts / depends on).</td><tr>');
$oPage->add('<tr><td colspan="2"><span id="graphviz_status"></span></td><tr>');
$oPage->add('</table>');
@@ -1126,21 +1126,21 @@ class WizStepUpgradeMiscParams extends WizardStep
public function Display(WebPage $oPage)
{
$sApplicationURL = $this->oWizard->GetParameter('application_url', utils::GetDefaultUrlAppRoot(true));
$sApplicationURL = $this->oWizard->GetParameter('application_url', utils::GetAbsoluteUrlAppRoot(true)); //Preserve existing configuration.
$sDefaultGraphvizPath = (strtolower(substr(PHP_OS, 0, 3)) === 'win') ? 'C:\\Program Files\\Graphviz\\bin\\dot.exe' : '/usr/bin/dot';
$sGraphvizPath = $this->oWizard->GetParameter('graphviz_path', $sDefaultGraphvizPath);
$oPage->add('<h2>Additional parameters</h2>');
$oPage->add('<fieldset>');
$oPage->add('<legend>Application URL</legend>');
$oPage->add('<table>');
$oPage->add('<tr><td>URL: </td><td><input id="application_url" name="application_url" type="text" size="35" maxlength="1024" value="'.htmlentities($sApplicationURL, ENT_QUOTES, 'UTF-8').'"><span id="v_application_url"/></td><tr>');
$oPage->add('<tr><td colspan="2">Change the value above if the end-users will be accessing the application by another path due to a specific configuration of the web server.</td><tr>');
$oPage->add('<tr><td>URL: </td><td><input id="application_url" name="application_url" type="text" size="35" maxlength="1024" value="'.htmlentities($sApplicationURL, ENT_QUOTES, 'UTF-8').'" style="width: 100%;box-sizing: border-box;"><span id="v_application_url"/></td><tr>');
$oPage->add('<tr><td colspan="2"><div class="message message-warning">Change the value above if the end-users will be accessing the application by another path due to a specific configuration of the web server.</div></td><tr>');
$oPage->add('</table>');
$oPage->add('</fieldset>');
$oPage->add('<fieldset>');
$oPage->add('<legend>Path to Graphviz\' dot application</legend>');
$oPage->add('<table style="width: 100%;">');
$oPage->add('<tr><td>Path: </td><td><input id="graphviz_path" name="graphviz_path" type="text" size="35" maxlength="1024" value="'.htmlentities($sGraphvizPath, ENT_QUOTES, 'UTF-8').'"><span id="v_graphviz_path"/></td><tr>');
$oPage->add('<tr><td>Path: </td><td><input id="graphviz_path" name="graphviz_path" type="text" size="35" maxlength="1024" value="'.htmlentities($sGraphvizPath, ENT_QUOTES, 'UTF-8').'" style="width: 100%;box-sizing: border-box;"><span id="v_graphviz_path"/></td><tr>');
$oPage->add('<tr><td colspan="2"><a href="http://www.graphviz.org" target="_blank">Graphviz</a> is required to display the impact analysis graph (i.e. impacts / depends on).</td><tr>');
$oPage->add('<tr><td colspan="2"><span id="graphviz_status"></span></td><tr>');
$oPage->add('</table>');

View File

@@ -168,4 +168,151 @@ class UtilsTest extends \Combodo\iTop\Test\UnitTest\ItopTestCase
);
}
/**
* @dataProvider GetDefaultUrlAppRootProvider
*/
public function testGetDefaultUrlAppRoot($bForceTrustProxy, $bConfTrustProxy, $aServerVars, $sExpectedAppRootUrl)
{
$_SERVER = $aServerVars;
utils::GetConfig()->Set('trust_proxies', $bConfTrustProxy);
$sAppRootUrl = utils::GetDefaultUrlAppRoot($bForceTrustProxy);
$this->assertEquals($sExpectedAppRootUrl, $sAppRootUrl);
}
public function GetDefaultUrlAppRootProvider()
{
$this->setUp();
$baseServerVar = [
'REMOTE_ADDR' => '127.0.0.1', //is not set, disable IsProxyTrusted
'SERVER_NAME' => 'example.com',
'HTTP_X_FORWARDED_HOST' => null,
'SERVER_PORT' => '80',
'HTTP_X_FORWARDED_PORT' => null,
'REQUEST_URI' => '/index.php?baz=1',
'SCRIPT_NAME' => '/index.php',
'SCRIPT_FILENAME' => APPROOT.'index.php',
'QUERY_STRING' => 'baz=1',
'HTTP_X_FORWARDED_PROTO' => null,
'HTTP_X_FORWARDED_PROTOCOL' => null,
'HTTPS' => null,
];
return [
'no proxy, http' => [
'bForceTrustProxy' => false,
'bConfTrustProxy' => false,
'aServerVars' => array_merge($baseServerVar, []),
'sExpectedAppRootUrl' => 'http://example.com/',
],
'no proxy, subPath, http' => [
'bForceTrustProxy' => false,
'bConfTrustProxy' => false,
'aServerVars' => array_merge($baseServerVar, [
'REQUEST_URI' => '/foo/index.php?baz=1',
]),
'sExpectedAppRootUrl' => 'http://example.com/foo/',
],
'IIS lack REQUEST_URI' => [
'bForceTrustProxy' => false,
'bConfTrustProxy' => false,
'aServerVars' => array_merge($baseServerVar, [
'REQUEST_URI' => null,
'SCRIPT_NAME' => '/foo/index.php',
]),
'sExpectedAppRootUrl' => 'http://example.com/foo/',
],
'no proxy, https' => [
'bForceTrustProxy' => false,
'bConfTrustProxy' => false,
'aServerVars' => array_merge($baseServerVar, [
'SERVER_PORT' => '443',
'HTTPS' => 'on',
]),
'sExpectedAppRootUrl' => 'https://example.com/',
],
'no proxy, https on 4443' => [
'bForceTrustProxy' => false,
'bConfTrustProxy' => false,
'aServerVars' => array_merge($baseServerVar, [
'SERVER_PORT' => '4443',
'HTTPS' => 'on',
]),
'sExpectedAppRootUrl' => 'https://example.com:4443/',
],
'with proxy, not enabled' => [
'bForceTrustProxy' => false,
'bConfTrustProxy' => false,
'aServerVars' => array_merge($baseServerVar, [
'HTTP_X_FORWARDED_HOST' => 'proxy.com',
'HTTP_X_FORWARDED_PORT' => '4443',
'HTTP_X_FORWARDED_PROTO' => 'https',
]),
'sExpectedAppRootUrl' => 'http://example.com/',
],
'with proxy, enabled' => [
'bForceTrustProxy' => false,
'bConfTrustProxy' => true,
'aServerVars' => array_merge($baseServerVar, [
'HTTP_X_FORWARDED_HOST' => 'proxy.com',
'HTTP_X_FORWARDED_PORT' => '4443',
'HTTP_X_FORWARDED_PROTO' => 'https',
]),
'sExpectedAppRootUrl' => 'https://proxy.com:4443/',
],
'with proxy, enabled - alt' => [
'bForceTrustProxy' => false,
'bConfTrustProxy' => true,
'aServerVars' => array_merge($baseServerVar, [
'HTTP_X_FORWARDED_HOST' => 'proxy.com',
'HTTP_X_FORWARDED_PORT' => '4443',
'HTTP_X_FORWARDED_PROTOCOL' => 'https',
]),
'sExpectedAppRootUrl' => 'https://proxy.com:4443/',
],
'with proxy, disabled, forced' => [
'bForceTrustProxy' => true,
'bConfTrustProxy' => false,
'aServerVars' => array_merge($baseServerVar, [
'HTTP_X_FORWARDED_HOST' => 'proxy.com',
'HTTP_X_FORWARDED_PORT' => '4443',
'HTTP_X_FORWARDED_PROTO' => 'https',
]),
'sExpectedAppRootUrl' => 'https://proxy.com:4443/',
],
'with proxy, enabled, forced' => [
'bForceTrustProxy' => true,
'bConfTrustProxy' => true,
'aServerVars' => array_merge($baseServerVar, [
'HTTP_X_FORWARDED_HOST' => 'proxy.com',
'HTTP_X_FORWARDED_PORT' => '4443',
'HTTP_X_FORWARDED_PROTO' => 'https',
]),
'sExpectedAppRootUrl' => 'https://proxy.com:4443/',
],
'with proxy, disabled, forced, no remote addr' => [
'bForceTrustProxy' => true,
'bConfTrustProxy' => false,
'aServerVars' => array_merge($baseServerVar, [
'REMOTE_ADDR' => null,
'HTTP_X_FORWARDED_HOST' => 'proxy.com',
'HTTP_X_FORWARDED_PORT' => '4443',
'HTTP_X_FORWARDED_PROTO' => 'https',
]),
'sExpectedAppRootUrl' => 'https://proxy.com:4443/',
],
'with proxy, enabled, no remote addr' => [
'bForceTrustProxy' => false,
'bConfTrustProxy' => true,
'aServerVars' => array_merge($baseServerVar, [
'REMOTE_ADDR' => null,
'HTTP_X_FORWARDED_HOST' => 'proxy.com',
'HTTP_X_FORWARDED_PORT' => '4443',
'HTTP_X_FORWARDED_PROTO' => 'https',
]),
'sExpectedAppRootUrl' => 'http://example.com/',
],
];
}
}