Changeset View
Changeset View
Standalone View
Standalone View
support/PhabricatorStartup.php
| Show All 32 Lines | |||||
| * @task hook Startup Hooks | * @task hook Startup Hooks | ||||
| * @task apocalypse In Case Of Apocalypse | * @task apocalypse In Case Of Apocalypse | ||||
| * @task validation Validation | * @task validation Validation | ||||
| * @task ratelimit Rate Limiting | * @task ratelimit Rate Limiting | ||||
| */ | */ | ||||
| final class PhabricatorStartup { | final class PhabricatorStartup { | ||||
| private static $startTime; | private static $startTime; | ||||
| private static $debugTimeLimit; | |||||
| private static $globals = array(); | private static $globals = array(); | ||||
| private static $capturingOutput; | private static $capturingOutput; | ||||
| private static $rawInput; | private static $rawInput; | ||||
| private static $oldMemoryLimit; | private static $oldMemoryLimit; | ||||
| // TODO: For now, disable rate limiting entirely by default. We need to | // TODO: For now, disable rate limiting entirely by default. We need to | ||||
| // iterate on it a bit for Conduit, some of the specific score levels, and | // iterate on it a bit for Conduit, some of the specific score levels, and | ||||
| // to deal with NAT'd offices. | // to deal with NAT'd offices. | ||||
| ▲ Show 20 Lines • Show All 172 Lines • ▼ Show 20 Lines | public static function endOutputCapture() { | ||||
| if (!self::$capturingOutput) { | if (!self::$capturingOutput) { | ||||
| return null; | return null; | ||||
| } | } | ||||
| self::$capturingOutput = false; | self::$capturingOutput = false; | ||||
| return ob_get_clean(); | return ob_get_clean(); | ||||
| } | } | ||||
| /* -( Debug Time Limit )--------------------------------------------------- */ | |||||
| /** | |||||
| * Set a time limit (in seconds) for the current script. After time expires, | |||||
| * the script fatals. | |||||
| * | |||||
| * This works like `max_execution_time`, but prints out a useful stack trace | |||||
| * when the time limit expires. This is primarily intended to make it easier | |||||
| * to debug pages which hang by allowing extraction of a stack trace: set a | |||||
| * short debug limit, then use the trace to figure out what's happening. | |||||
| * | |||||
| * The limit is implemented with a tick function, so enabling it implies | |||||
| * some accounting overhead. | |||||
| * | |||||
| * @param int Time limit in seconds. | |||||
| * @return void | |||||
| */ | |||||
| public static function setDebugTimeLimit($limit) { | |||||
| self::$debugTimeLimit = $limit; | |||||
| static $initialized; | |||||
| if (!$initialized) { | |||||
| declare(ticks=1); | |||||
| register_tick_function(array('PhabricatorStartup', 'onDebugTick')); | |||||
| } | |||||
| } | |||||
| /** | |||||
| * Callback tick function used by @{method:setDebugTimeLimit}. | |||||
| * | |||||
| * Fatals with a useful stack trace after the time limit expires. | |||||
| * | |||||
| * @return void | |||||
| */ | |||||
| public static function onDebugTick() { | |||||
| $limit = self::$debugTimeLimit; | |||||
| if (!$limit) { | |||||
| return; | |||||
| } | |||||
| $elapsed = (microtime(true) - self::getStartTime()); | |||||
| if ($elapsed > $limit) { | |||||
| $frames = array(); | |||||
| foreach (debug_backtrace() as $frame) { | |||||
| $file = isset($frame['file']) ? $frame['file'] : '-'; | |||||
| $file = basename($file); | |||||
| $line = isset($frame['line']) ? $frame['line'] : '-'; | |||||
| $class = isset($frame['class']) ? $frame['class'].'->' : null; | |||||
| $func = isset($frame['function']) ? $frame['function'].'()' : '?'; | |||||
| $frames[] = "{$file}:{$line} {$class}{$func}"; | |||||
| } | |||||
| self::didFatal( | |||||
| "Request aborted by debug time limit after {$limit} seconds.\n\n". | |||||
| "STACK TRACE\n". | |||||
| implode("\n", $frames)); | |||||
| } | |||||
| } | |||||
| /* -( In Case of Apocalypse )---------------------------------------------- */ | /* -( In Case of Apocalypse )---------------------------------------------- */ | ||||
| /** | /** | ||||
| * Fatal the request completely in response to an exception, sending a plain | * Fatal the request completely in response to an exception, sending a plain | ||||
| * text message to the client. Calls @{method:didFatal} internally. | * text message to the client. Calls @{method:didFatal} internally. | ||||
| * | * | ||||
| * @param string Brief description of the exception context, like | * @param string Brief description of the exception context, like | ||||
| ▲ Show 20 Lines • Show All 73 Lines • ▼ Show 20 Lines | /* -( Validation )--------------------------------------------------------- */ | ||||
| * @task validation | * @task validation | ||||
| */ | */ | ||||
| private static function setupPHP() { | private static function setupPHP() { | ||||
| error_reporting(E_ALL | E_STRICT); | error_reporting(E_ALL | E_STRICT); | ||||
| self::$oldMemoryLimit = ini_get('memory_limit'); | self::$oldMemoryLimit = ini_get('memory_limit'); | ||||
| ini_set('memory_limit', -1); | ini_set('memory_limit', -1); | ||||
| // If we have libxml, disable the incredibly dangerous entity loader. | // If we have libxml, disable the incredibly dangerous entity loader. | ||||
| if (function_exists('libxml_disable_entity_loader')) { | if (function_exists('libxml_disable_entity_loader')) { | ||||
joshuaspence: Great success! | |||||
Not Done Inline Actionsepriestley: awwyiss | |||||
| libxml_disable_entity_loader(true); | libxml_disable_entity_loader(true); | ||||
| } | } | ||||
| } | } | ||||
| /** | /** | ||||
| * @task validation | * @task validation | ||||
| */ | */ | ||||
| ▲ Show 20 Lines • Show All 464 Lines • Show Last 20 Lines | |||||
Great success!