Changeset View
Changeset View
Standalone View
Standalone View
support/PhabricatorStartup.php
| Show All 33 Lines | |||||
| * @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 $debugTimeLimit; | ||||
| private static $globals = array(); | private static $accessLog; | ||||
| 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. | ||||
| private static $maximumRate = 0; | private static $maximumRate = 0; | ||||
| Show All 16 Lines | /* -( Accessing Request Information )-------------------------------------- */ | ||||
| public static function getMicrosecondsSinceStart() { | public static function getMicrosecondsSinceStart() { | ||||
| return (int)(1000000 * (microtime(true) - self::getStartTime())); | return (int)(1000000 * (microtime(true) - self::getStartTime())); | ||||
| } | } | ||||
| /** | /** | ||||
| * @task info | * @task info | ||||
| */ | */ | ||||
| public static function setGlobal($key, $value) { | public static function setAccessLog($access_log) { | ||||
| self::validateGlobal($key); | self::$accessLog = $access_log; | ||||
| self::$globals[$key] = $value; | |||||
| } | } | ||||
| /** | /** | ||||
| * @task info | * @task info | ||||
| */ | */ | ||||
| public static function getGlobal($key, $default = null) { | |||||
| self::validateGlobal($key); | |||||
| if (!array_key_exists($key, self::$globals)) { | |||||
| return $default; | |||||
| } | |||||
| return self::$globals[$key]; | |||||
| } | |||||
| /** | |||||
| * @task info | |||||
| */ | |||||
| public static function getRawInput() { | public static function getRawInput() { | ||||
| return self::$rawInput; | return self::$rawInput; | ||||
| } | } | ||||
| /* -( Startup Hooks )------------------------------------------------------ */ | /* -( Startup Hooks )------------------------------------------------------ */ | ||||
| /** | /** | ||||
| * @task hook | * @task hook | ||||
| */ | */ | ||||
| public static function didStartup() { | public static function didStartup() { | ||||
| self::$startTime = microtime(true); | self::$startTime = microtime(true); | ||||
| self::$globals = array(); | self::$accessLog = null; | ||||
| static $registered; | static $registered; | ||||
| if (!$registered) { | if (!$registered) { | ||||
| // NOTE: This protects us against multiple calls to didStartup() in the | // NOTE: This protects us against multiple calls to didStartup() in the | ||||
| // same request, but also against repeated requests to the same | // same request, but also against repeated requests to the same | ||||
| // interpreter state, which we may implement in the future. | // interpreter state, which we may implement in the future. | ||||
| register_shutdown_function(array(__CLASS__, 'didShutdown')); | register_shutdown_function(array(__CLASS__, 'didShutdown')); | ||||
| $registered = true; | $registered = true; | ||||
| ▲ Show 20 Lines • Show All 223 Lines • ▼ Show 20 Lines | /* -( In Case of Apocalypse )---------------------------------------------- */ | ||||
| * @task apocalypse | * @task apocalypse | ||||
| */ | */ | ||||
| public static function didFatal($message, $log_message = null) { | public static function didFatal($message, $log_message = null) { | ||||
| if ($log_message === null) { | if ($log_message === null) { | ||||
| $log_message = $message; | $log_message = $message; | ||||
| } | } | ||||
| self::endOutputCapture(); | self::endOutputCapture(); | ||||
| $access_log = self::getGlobal('log.access'); | $access_log = self::$accessLog; | ||||
| if ($access_log) { | if ($access_log) { | ||||
| // We may end up here before the access log is initialized, e.g. from | // We may end up here before the access log is initialized, e.g. from | ||||
| // verifyPHP(). | // verifyPHP(). | ||||
| $access_log->setData( | $access_log->setData( | ||||
| array( | array( | ||||
| 'c' => 500, | 'c' => 500, | ||||
| )); | )); | ||||
| $access_log->write(); | $access_log->write(); | ||||
| Show All 36 Lines | public static function getOldMemoryLimit() { | ||||
| return self::$oldMemoryLimit; | return self::$oldMemoryLimit; | ||||
| } | } | ||||
| /** | /** | ||||
| * @task validation | * @task validation | ||||
| */ | */ | ||||
| private static function normalizeInput() { | private static function normalizeInput() { | ||||
| // Replace superglobals with unfiltered versions, disrespect php.ini (we | // Replace superglobals with unfiltered versions, disrespect php.ini (we | ||||
| // filter ourselves) | // filter ourselves). | ||||
| $filter = array(INPUT_GET, INPUT_POST, | |||||
| INPUT_SERVER, INPUT_ENV, INPUT_COOKIE, | // NOTE: We don't filter INPUT_SERVER because we don't want to overwrite | ||||
| // changes made in "preamble.php". | |||||
| $filter = array( | |||||
| INPUT_GET, | |||||
| INPUT_POST, | |||||
| INPUT_ENV, | |||||
| INPUT_COOKIE, | |||||
| ); | ); | ||||
| foreach ($filter as $type) { | foreach ($filter as $type) { | ||||
| $filtered = filter_input_array($type, FILTER_UNSAFE_RAW); | $filtered = filter_input_array($type, FILTER_UNSAFE_RAW); | ||||
| if (!is_array($filtered)) { | if (!is_array($filtered)) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| switch ($type) { | switch ($type) { | ||||
| case INPUT_SERVER: | |||||
| $_SERVER = array_merge($_SERVER, $filtered); | |||||
| break; | |||||
| case INPUT_GET: | case INPUT_GET: | ||||
| $_GET = array_merge($_GET, $filtered); | $_GET = array_merge($_GET, $filtered); | ||||
| break; | break; | ||||
| case INPUT_COOKIE: | case INPUT_COOKIE: | ||||
| $_COOKIE = array_merge($_COOKIE, $filtered); | $_COOKIE = array_merge($_COOKIE, $filtered); | ||||
| break; | break; | ||||
| case INPUT_POST: | case INPUT_POST: | ||||
| $_POST = array_merge($_POST, $filtered); | $_POST = array_merge($_POST, $filtered); | ||||
| ▲ Show 20 Lines • Show All 121 Lines • ▼ Show 20 Lines | if (!strlen($_REQUEST['__path__'])) { | ||||
| "Request parameter '__path__' is set, but empty. Your rewrite rules ". | "Request parameter '__path__' is set, but empty. Your rewrite rules ". | ||||
| "are not configured correctly. The '__path__' should always ". | "are not configured correctly. The '__path__' should always ". | ||||
| "begin with a '/'."); | "begin with a '/'."); | ||||
| } | } | ||||
| } | } | ||||
| /** | /** | ||||
| * @task validation | |||||
| */ | |||||
| private static function validateGlobal($key) { | |||||
| static $globals = array( | |||||
| 'log.access' => true, | |||||
| 'csrf.salt' => true, | |||||
| ); | |||||
| if (empty($globals[$key])) { | |||||
| throw new Exception("Access to unknown startup global '{$key}'!"); | |||||
| } | |||||
| } | |||||
| /** | |||||
| * Detect if this request has had its POST data stripped by exceeding the | * Detect if this request has had its POST data stripped by exceeding the | ||||
| * 'post_max_size' PHP configuration limit. | * 'post_max_size' PHP configuration limit. | ||||
| * | * | ||||
| * PHP has a setting called 'post_max_size'. If a POST request arrives with | * PHP has a setting called 'post_max_size'. If a POST request arrives with | ||||
| * a body larger than the limit, PHP doesn't generate $_POST but processes | * a body larger than the limit, PHP doesn't generate $_POST but processes | ||||
| * the request anyway, and provides no formal way to detect that this | * the request anyway, and provides no formal way to detect that this | ||||
| * happened. | * happened. | ||||
| * | * | ||||
| ▲ Show 20 Lines • Show All 308 Lines • Show Last 20 Lines | |||||