Kaynağa Gözat

- Try to protect as much as possible from fatal errors occuring during the data load:
1) Make sure we have enough memory to perform the task
2) In case of fatal error in the Ajax call, catch it, display it to the end-user and stop the installation.
See Trac #84 for more information.

git-svn-id: http://svn.code.sf.net/p/itop/code/trunk@298 a333f486-631f-4898-b8df-5754b55c2be0

dflaven 15 yıl önce
ebeveyn
işleme
149be75793
3 değiştirilmiş dosya ile 51 ekleme ve 6 silme
  1. 48 5
      setup/ajax.dataloader.php
  2. 1 0
      setup/index.php
  3. 2 1
      setup/setup.js

+ 48 - 5
setup/ajax.dataloader.php

@@ -5,11 +5,51 @@
  * 'file' string Name of the file to load
  * 'session_status' string 'start', 'continue' or 'end'
  * 'percent' integer 0..100 the percentage of completion once the file has been loaded 
- */ 
+ */ 
+define('SAFE_MINIMUM_MEMORY', 32*1024*1024);
 require_once('../application/utils.inc.php');
+require_once('./setuppage.class.inc.php');
+
+$iMemoryLimit = utils::ConvertToBytes(ini_get('memory_limit'));
+if ($iMemoryLimit < SAFE_MINIMUM_MEMORY)
+{
+	if (ini_set('memory_limit', SAFE_MINIMUM_MEMORY) === FALSE)
+	{
+		SetupWebPage::error("memory_limit is too small: $iMemoryLimit and can not be increased by the script itself.");		
+	}
+	else
+	{
+		SetupWebPage::log("memory_limit increased from $iMemoryLimit to ".SAFE_MINIMUM_MEMORY.".");		
+	}
+}
+
+function FatalErrorCatcher($sOutput)
+{ 
+	if ( preg_match('|<phpfatalerror>.*</phpfatalerror>|s', $sOutput, &$aMatches) )
+	{
+		header("HTTP/1.0 500 Internal server error.");
+		foreach ($aMatches as $sMatch)
+		{
+			$errors .= strip_tags($sMatch)."\n";
+		}
+		$sOutput = "$errors\n";
+		// Logging to a file does not work if the whole memory is exhausted...		
+		//SetupWebPage::error("Fatal error - in $__FILE__ , $errors");
+	}
+	return $sOutput;
+}
+	
+//Define some bogus, invalid HTML tags that no sane
+//person would ever put in an actual document and tell
+//PHP to delimit fatal error warnings with them.
+ini_set('error_prepend_string', '<phpfatalerror>');
+ini_set('error_append_string', '</phpfatalerror>');
+
+// Starts the capture of the ouput, and sets a filter to capture the fatal errors.
+ob_start('FatalErrorCatcher'); // Start capturing the output, and pass it through the fatal error catcher
+
 require_once('../core/config.class.inc.php');
 require_once('../core/cmdbsource.class.inc.php');
-require_once('./setuppage.class.inc.php');
 require_once('./xmldataloader.class.inc.php');
 
 define('TMP_CONFIG_FILE', '../tmp-config-itop.php');
@@ -18,8 +58,7 @@ define('TMP_CONFIG_FILE', '../tmp-config-itop.php');
 // Never cache this page
 header("Cache-Control: no-cache, must-revalidate");  // HTTP/1.1
 header("Expires: Fri, 17 Jul 1970 05:00:00 GMT");    // Date in the past
-
-
+
 /**
  * Main program
  */
@@ -62,6 +101,10 @@ catch(Exception $e)
 	echo "<p>An error happened while loading the data</p>\n";
 	echo '<p>'.$e."</p>\n";
 	SetupWebPage::log("Error - An error happened while loading the data. ".$e);
+}
+
+if (function_exists('memory_get_peak_usage'))
+{
+	SetupWebPage::log("Info - loading file '$sFileName', peak memory usage. ".memory_get_peak_usage());
 }
-
 ?>

+ 1 - 0
setup/index.php

@@ -544,6 +544,7 @@ function DisplayStep4(SetupWebPage $oP, Config $oConfig, $sAdminUser, $sAdminPwd
 	$oP->add("<input type=\"hidden\" name=\"auth_pwd\" value=\"$sAdminPwd\">\n"); // To be compatible with login page
 	$oP->add("<input type=\"hidden\" name=\"operation\" value=\"$sNextOperation\">\n");
 	$oP->add("</form>\n");
+	$oP->add("<div id=\"log\" style=\"color:#F00;\"></div>\n");
 	$oP->add_linked_script('./jquery.progression.js');
 
 	PopulateDataFilesList($oP);

+ 2 - 1
setup/setup.js

@@ -103,7 +103,8 @@ function DoLoadDataAsynchronous()
 
 	$('#setup').block({message: '<p>Loading data...<br/><div id=\"progress\">0%</div></p>'});
 	$('#progress').progression( {Current:0, Maximum: 100, aBackgroundImg: 'orange-progress.gif', aTextColor: '#000000'} );
-	LoadNextDataFile('', '');
+	$('#log').ajaxError(function(e, xhr, settings, exception) {	alert('Fatal error detected: '+ xhr.responseText); $('#log').append(xhr.responseText); $('#setup').unblock(); } );
+   LoadNextDataFile('', '');
 	return false; // Stop here for now
 }