@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Consolidate environmental initialization

Summary:
We have a bunch of code duplication now between __init_script__.php and webroot/index.php. Consoldiate these methods and move them into PhabricatorEnv.

Merge PhabricatorRequestOverseer into PhabricatorStartup.

Test Plan: Loaded page, ran script. Wiped PHABRICATOR_ENV; loaded page, ran script; got errors.

Reviewers: btrahan, vrana

Reviewed By: btrahan

CC: aran

Maniphest Tasks: T2223

Differential Revision: https://secure.phabricator.com/D4283

+243 -254
+17 -65
scripts/__init_script__.php
··· 1 1 <?php 2 2 3 - error_reporting(E_ALL | E_STRICT); 4 - ini_set('display_errors', 1); 5 - 6 - $include_path = ini_get('include_path'); 7 - ini_set( 8 - 'include_path', 9 - $include_path.PATH_SEPARATOR.dirname(__FILE__).'/../../'); 10 - @include_once 'libphutil/scripts/__init_script__.php'; 11 - if (!@constant('__LIBPHUTIL__')) { 12 - echo "ERROR: Unable to load libphutil. Update your PHP 'include_path' to ". 13 - "include the parent directory of libphutil/.\n"; 14 - exit(1); 15 - } 16 - 17 - phutil_load_library(dirname(__FILE__).'/../src/'); 18 - 19 - // NOTE: This is dangerous in general, but we know we're in a script context and 20 - // are not vulnerable to CSRF. 21 - AphrontWriteGuard::allowDangerousUnguardedWrites(true); 22 - 23 - require_once dirname(dirname(__FILE__)).'/conf/__init_conf__.php'; 24 - 25 - $env = isset($_SERVER['PHABRICATOR_ENV']) 26 - ? $_SERVER['PHABRICATOR_ENV'] 27 - : getenv('PHABRICATOR_ENV'); 28 - if (!$env) { 29 - echo phutil_console_wrap( 30 - phutil_console_format( 31 - "**ERROR**: PHABRICATOR_ENV Not Set\n\n". 32 - "Define the __PHABRICATOR_ENV__ environment variable before running ". 33 - "this script. You can do it on the command line like this:\n\n". 34 - " $ PHABRICATOR_ENV=__custom/myconfig__ %s ...\n\n". 35 - "Replace __custom/myconfig__ with the path to your configuration file. ". 36 - "For more information, see the 'Configuration Guide' in the ". 37 - "Phabricator documentation.\n\n", 38 - $argv[0])); 39 - exit(1); 40 - } 41 - 42 - $conf = phabricator_read_config_file($env); 43 - $conf['phabricator.env'] = $env; 3 + function init_phabricator_script() { 4 + error_reporting(E_ALL | E_STRICT); 5 + ini_set('display_errors', 1); 44 6 45 - PhabricatorEnv::setEnvConfig($conf); 7 + $include_path = ini_get('include_path'); 8 + ini_set( 9 + 'include_path', 10 + $include_path.PATH_SEPARATOR.dirname(__FILE__).'/../../'); 11 + @include_once 'libphutil/scripts/__init_script__.php'; 12 + if (!@constant('__LIBPHUTIL__')) { 13 + echo "ERROR: Unable to load libphutil. Update your PHP 'include_path' to ". 14 + "include the parent directory of libphutil/.\n"; 15 + exit(1); 16 + } 46 17 47 - phutil_load_library('arcanist/src'); 18 + phutil_load_library('arcanist/src'); 19 + phutil_load_library(dirname(__FILE__).'/../src/'); 48 20 49 - foreach (PhabricatorEnv::getEnvConfig('load-libraries') as $library) { 50 - phutil_load_library($library); 21 + PhabricatorEnv::initializeScriptEnvironment(); 51 22 } 52 23 53 - PhutilErrorHandler::initialize(); 54 - PhabricatorEventEngine::initialize(); 55 - 56 - $tz = PhabricatorEnv::getEnvConfig('phabricator.timezone'); 57 - if ($tz) { 58 - date_default_timezone_set($tz); 59 - } 60 - 61 - $translation = PhabricatorEnv::newObjectFromConfig('translation.provider'); 62 - PhutilTranslator::getInstance() 63 - ->setLanguage($translation->getLanguage()) 64 - ->addTranslations($translation->getTranslations()); 65 - 66 - // Append any paths to $PATH if we need to. 67 - $paths = PhabricatorEnv::getEnvConfig('environment.append-paths'); 68 - if (!empty($paths)) { 69 - $current_env_path = getenv('PATH'); 70 - $new_env_paths = implode(PATH_SEPARATOR, $paths); 71 - putenv('PATH='.$current_env_path.PATH_SEPARATOR.$new_env_paths); 72 - } 24 + init_phabricator_script();
-1
src/__phutil_library_map__.php
··· 1080 1080 'PhabricatorRepositorySymbol' => 'applications/repository/storage/PhabricatorRepositorySymbol.php', 1081 1081 'PhabricatorRepositoryTestCase' => 'applications/repository/storage/__tests__/PhabricatorRepositoryTestCase.php', 1082 1082 'PhabricatorRepositoryType' => 'applications/repository/constants/PhabricatorRepositoryType.php', 1083 - 'PhabricatorRequestOverseer' => 'infrastructure/PhabricatorRequestOverseer.php', 1084 1083 'PhabricatorS3FileStorageEngine' => 'applications/files/engine/PhabricatorS3FileStorageEngine.php', 1085 1084 'PhabricatorSQLPatchList' => 'infrastructure/storage/patch/PhabricatorSQLPatchList.php', 1086 1085 'PhabricatorSSHWorkflow' => 'infrastructure/ssh/PhabricatorSSHWorkflow.php',
+96
src/infrastructure/PhabricatorEnv.php
··· 53 53 private static $env; 54 54 private static $stack = array(); 55 55 56 + /** 57 + * @phutil-external-symbol class PhabricatorStartup 58 + */ 59 + public static function initializeWebEnvironment() { 60 + $env = self::getSelectedEnvironmentName(); 61 + if (!$env) { 62 + PhabricatorStartup::didFatal( 63 + "The 'PHABRICATOR_ENV' environmental variable is not defined. Modify ". 64 + "your httpd.conf to include 'SetEnv PHABRICATOR_ENV <env>', where ". 65 + "'<env>' is one of 'development', 'production', or a custom ". 66 + "environment."); 67 + } 68 + 69 + self::initializeCommonEnvironment(); 70 + } 71 + 72 + public static function initializeScriptEnvironment() { 73 + $env = self::getSelectedEnvironmentName(); 74 + if (!$env) { 75 + echo phutil_console_wrap( 76 + phutil_console_format( 77 + "**ERROR**: PHABRICATOR_ENV Not Set\n\n". 78 + "Define the __PHABRICATOR_ENV__ environment variable before ". 79 + "running this script. You can do it on the command line like ". 80 + "this:\n\n". 81 + " $ PHABRICATOR_ENV=__custom/myconfig__ %s ...\n\n". 82 + "Replace __custom/myconfig__ with the path to your configuration ". 83 + "file. For more information, see the 'Configuration Guide' in the ". 84 + "Phabricator documentation.\n\n", 85 + $GLOBALS['argv'][0])); 86 + exit(1); 87 + } 88 + 89 + self::initializeCommonEnvironment(); 90 + 91 + // NOTE: This is dangerous in general, but we know we're in a script context 92 + // and are not vulnerable to CSRF. 93 + AphrontWriteGuard::allowDangerousUnguardedWrites(true); 94 + } 95 + 96 + /** 97 + * @phutil-external-symbol function phabricator_read_config_file 98 + */ 99 + private static function initializeCommonEnvironment() { 100 + $env = self::getSelectedEnvironmentName(); 101 + 102 + $root = dirname(phutil_get_library_root('phabricator')); 103 + require_once $root.'/conf/__init_conf__.php'; 104 + $conf = phabricator_read_config_file($env); 105 + $conf['phabricator.env'] = $env; 106 + 107 + PhabricatorEnv::setEnvConfig($conf); 108 + 109 + PhutilErrorHandler::initialize(); 110 + 111 + $tz = PhabricatorEnv::getEnvConfig('phabricator.timezone'); 112 + if ($tz) { 113 + date_default_timezone_set($tz); 114 + } 115 + 116 + // Append any paths to $PATH if we need to. 117 + $paths = PhabricatorEnv::getEnvConfig('environment.append-paths'); 118 + if (!empty($paths)) { 119 + $current_env_path = getenv('PATH'); 120 + $new_env_paths = implode(PATH_SEPARATOR, $paths); 121 + putenv('PATH='.$current_env_path.PATH_SEPARATOR.$new_env_paths); 122 + } 123 + 124 + foreach (PhabricatorEnv::getEnvConfig('load-libraries') as $library) { 125 + phutil_load_library($library); 126 + } 127 + 128 + PhabricatorEventEngine::initialize(); 129 + 130 + $translation = PhabricatorEnv::newObjectFromConfig('translation.provider'); 131 + PhutilTranslator::getInstance() 132 + ->setLanguage($translation->getLanguage()) 133 + ->addTranslations($translation->getTranslations()); 134 + } 135 + 136 + public static function getSelectedEnvironmentName() { 137 + $env_var = 'PHABRICATOR_ENV'; 138 + 139 + $env = idx($_SERVER, $env_var); 140 + 141 + if (!$env) { 142 + $env = getenv($env_var); 143 + } 144 + 145 + if (!$env) { 146 + $env = idx($_ENV, $env_var); 147 + } 148 + 149 + return $env; 150 + } 151 + 56 152 57 153 /* -( Reading Configuration )---------------------------------------------- */ 58 154
-98
src/infrastructure/PhabricatorRequestOverseer.php
··· 1 - <?php 2 - 3 - final class PhabricatorRequestOverseer { 4 - 5 - public function didStartup() { 6 - $this->detectPostMaxSizeTriggered(); 7 - } 8 - 9 - /** 10 - * Detect if this request has had its POST data stripped by exceeding the 11 - * 'post_max_size' PHP configuration limit. 12 - * 13 - * PHP has a setting called 'post_max_size'. If a POST request arrives with 14 - * a body larger than the limit, PHP doesn't generate $_POST but processes 15 - * the request anyway, and provides no formal way to detect that this 16 - * happened. 17 - * 18 - * We can still read the entire body out of `php://input`. However according 19 - * to the documentation the stream isn't available for "multipart/form-data" 20 - * (on nginx + php-fpm it appears that it is available, though, at least) so 21 - * any attempt to generate $_POST would be fragile. 22 - * 23 - * @phutil-external-symbol class PhabricatorStartup 24 - */ 25 - private function detectPostMaxSizeTriggered() { 26 - // If this wasn't a POST, we're fine. 27 - if ($_SERVER['REQUEST_METHOD'] != 'POST') { 28 - return; 29 - } 30 - 31 - // If there's POST data, clearly we're in good shape. 32 - if ($_POST) { 33 - return; 34 - } 35 - 36 - // For HTML5 drag-and-drop file uploads, Safari submits the data as 37 - // "application/x-www-form-urlencoded". For most files this generates 38 - // something in POST because most files decode to some nonempty (albeit 39 - // meaningless) value. However, some files (particularly small images) 40 - // don't decode to anything. If we know this is a drag-and-drop upload, 41 - // we can skip this check. 42 - if (isset($_REQUEST['__upload__'])) { 43 - return; 44 - } 45 - 46 - // PHP generates $_POST only for two content types. This routing happens 47 - // in `main/php_content_types.c` in PHP. Normally, all forms use one of 48 - // these content types, but some requests may not -- for example, Firefox 49 - // submits files sent over HTML5 XMLHTTPRequest APIs with the Content-Type 50 - // of the file itself. If we don't have a recognized content type, we 51 - // don't need $_POST. 52 - // 53 - // NOTE: We use strncmp() because the actual content type may be something 54 - // like "multipart/form-data; boundary=...". 55 - // 56 - // NOTE: Chrome sometimes omits this header, see some discussion in T1762 57 - // and http://code.google.com/p/chromium/issues/detail?id=6800 58 - $content_type = idx($_SERVER, 'CONTENT_TYPE', ''); 59 - 60 - $parsed_types = array( 61 - 'application/x-www-form-urlencoded', 62 - 'multipart/form-data', 63 - ); 64 - 65 - $is_parsed_type = false; 66 - foreach ($parsed_types as $parsed_type) { 67 - if (strncmp($content_type, $parsed_type, strlen($parsed_type)) === 0) { 68 - $is_parsed_type = true; 69 - break; 70 - } 71 - } 72 - 73 - if (!$is_parsed_type) { 74 - return; 75 - } 76 - 77 - // Check for 'Content-Length'. If there's no data, we don't expect $_POST 78 - // to exist. 79 - $length = (int)$_SERVER['CONTENT_LENGTH']; 80 - if (!$length) { 81 - return; 82 - } 83 - 84 - // Time to fatal: we know this was a POST with data that should have been 85 - // populated into $_POST, but it wasn't. 86 - 87 - $config = ini_get('post_max_size'); 88 - PhabricatorStartup::didFatal( 89 - "As received by the server, this request had a nonzero content length ". 90 - "but no POST data.\n\n". 91 - "Normally, this indicates that it exceeds the 'post_max_size' setting ". 92 - "in the PHP configuration on the server. Increase the 'post_max_size' ". 93 - "setting or reduce the size of the request.\n\n". 94 - "Request size according to 'Content-Length' was '{$length}', ". 95 - "'post_max_size' is set to '{$config}'."); 96 - } 97 - 98 - }
+128 -5
support/PhabricatorStartup.php
··· 63 63 self::$startTime = microtime(true); 64 64 self::$globals = array(); 65 65 66 - self::setupPHP(); 67 - self::verifyPHP(); 68 - 69 - self::verifyRewriteRules(); 70 - 71 66 static $registered; 72 67 if (!$registered) { 73 68 // NOTE: This protects us against multiple calls to didStartup() in the ··· 76 71 register_shutdown_function(array(__CLASS__, 'didShutdown')); 77 72 $registered = true; 78 73 } 74 + 75 + self::setupPHP(); 76 + self::verifyPHP(); 77 + 78 + self::verifyRewriteRules(); 79 + 80 + self::detectPostMaxSizeTriggered(); 79 81 } 80 82 81 83 ··· 118 120 self::didFatal($msg); 119 121 } 120 122 123 + public static function loadCoreLibraries() { 124 + $phabricator_root = dirname(dirname(__FILE__)); 125 + $libraries_root = dirname($phabricator_root); 126 + 127 + $root = null; 128 + if (!empty($_SERVER['PHUTIL_LIBRARY_ROOT'])) { 129 + $root = $_SERVER['PHUTIL_LIBRARY_ROOT']; 130 + } 131 + 132 + ini_set( 133 + 'include_path', 134 + $libraries_root.PATH_SEPARATOR.ini_get('include_path')); 135 + 136 + @include_once $root.'libphutil/src/__phutil_library_init__.php'; 137 + if (!@constant('__LIBPHUTIL__')) { 138 + self::didFatal( 139 + "Unable to load libphutil. Put libphutil/ next to phabricator/, or ". 140 + "update your PHP 'include_path' to include the parent directory of ". 141 + "libphutil/."); 142 + } 143 + 144 + phutil_load_library('arcanist/src'); 145 + 146 + // Load Phabricator itself using the absolute path, so we never end up doing 147 + // anything surprising (loading index.php and libraries from different 148 + // directories). 149 + phutil_load_library($phabricator_root.'/src'); 150 + } 151 + 121 152 122 153 /* -( In Case of Apocalypse )---------------------------------------------- */ 123 154 ··· 217 248 if (empty($globals[$key])) { 218 249 throw new Exception("Access to unknown startup global '{$key}'!"); 219 250 } 251 + } 252 + 253 + 254 + /** 255 + * Detect if this request has had its POST data stripped by exceeding the 256 + * 'post_max_size' PHP configuration limit. 257 + * 258 + * PHP has a setting called 'post_max_size'. If a POST request arrives with 259 + * a body larger than the limit, PHP doesn't generate $_POST but processes 260 + * the request anyway, and provides no formal way to detect that this 261 + * happened. 262 + * 263 + * We can still read the entire body out of `php://input`. However according 264 + * to the documentation the stream isn't available for "multipart/form-data" 265 + * (on nginx + php-fpm it appears that it is available, though, at least) so 266 + * any attempt to generate $_POST would be fragile. 267 + * 268 + * @task validation 269 + */ 270 + private static function detectPostMaxSizeTriggered() { 271 + // If this wasn't a POST, we're fine. 272 + if ($_SERVER['REQUEST_METHOD'] != 'POST') { 273 + return; 274 + } 275 + 276 + // If there's POST data, clearly we're in good shape. 277 + if ($_POST) { 278 + return; 279 + } 280 + 281 + // For HTML5 drag-and-drop file uploads, Safari submits the data as 282 + // "application/x-www-form-urlencoded". For most files this generates 283 + // something in POST because most files decode to some nonempty (albeit 284 + // meaningless) value. However, some files (particularly small images) 285 + // don't decode to anything. If we know this is a drag-and-drop upload, 286 + // we can skip this check. 287 + if (isset($_REQUEST['__upload__'])) { 288 + return; 289 + } 290 + 291 + // PHP generates $_POST only for two content types. This routing happens 292 + // in `main/php_content_types.c` in PHP. Normally, all forms use one of 293 + // these content types, but some requests may not -- for example, Firefox 294 + // submits files sent over HTML5 XMLHTTPRequest APIs with the Content-Type 295 + // of the file itself. If we don't have a recognized content type, we 296 + // don't need $_POST. 297 + // 298 + // NOTE: We use strncmp() because the actual content type may be something 299 + // like "multipart/form-data; boundary=...". 300 + // 301 + // NOTE: Chrome sometimes omits this header, see some discussion in T1762 302 + // and http://code.google.com/p/chromium/issues/detail?id=6800 303 + $content_type = isset($_SERVER['CONTENT_TYPE']) 304 + ? $_SERVER['CONTENT_TYPE'] 305 + : ''; 306 + 307 + $parsed_types = array( 308 + 'application/x-www-form-urlencoded', 309 + 'multipart/form-data', 310 + ); 311 + 312 + $is_parsed_type = false; 313 + foreach ($parsed_types as $parsed_type) { 314 + if (strncmp($content_type, $parsed_type, strlen($parsed_type)) === 0) { 315 + $is_parsed_type = true; 316 + break; 317 + } 318 + } 319 + 320 + if (!$is_parsed_type) { 321 + return; 322 + } 323 + 324 + // Check for 'Content-Length'. If there's no data, we don't expect $_POST 325 + // to exist. 326 + $length = (int)$_SERVER['CONTENT_LENGTH']; 327 + if (!$length) { 328 + return; 329 + } 330 + 331 + // Time to fatal: we know this was a POST with data that should have been 332 + // populated into $_POST, but it wasn't. 333 + 334 + $config = ini_get('post_max_size'); 335 + PhabricatorStartup::didFatal( 336 + "As received by the server, this request had a nonzero content length ". 337 + "but no POST data.\n\n". 338 + "Normally, this indicates that it exceeds the 'post_max_size' setting ". 339 + "in the PHP configuration on the server. Increase the 'post_max_size' ". 340 + "setting or reduce the size of the request.\n\n". 341 + "Request size according to 'Content-Length' was '{$length}', ". 342 + "'post_max_size' is set to '{$config}'."); 220 343 } 221 344 222 345 }
+2 -85
webroot/index.php
··· 3 3 require_once dirname(dirname(__FILE__)).'/support/PhabricatorStartup.php'; 4 4 PhabricatorStartup::didStartup(); 5 5 6 - $access_log = null; 7 - 8 - $env = getenv('PHABRICATOR_ENV'); // Apache 9 - if (!$env) { 10 - if (isset($_ENV['PHABRICATOR_ENV'])) { 11 - $env = $_ENV['PHABRICATOR_ENV']; 12 - } 13 - } 14 - 15 - if (!$env) { 16 - PhabricatorStartup::didFatal( 17 - "The 'PHABRICATOR_ENV' environmental variable is not defined. Modify ". 18 - "your httpd.conf to include 'SetEnv PHABRICATOR_ENV <env>', where '<env>' ". 19 - "is one of 'development', 'production', or a custom environment."); 20 - } 21 - 22 - 23 - require_once dirname(dirname(__FILE__)).'/conf/__init_conf__.php'; 24 - 25 6 try { 26 - setup_aphront_basics(); 27 - 28 - $overseer = new PhabricatorRequestOverseer(); 29 - $overseer->didStartup(); 7 + PhabricatorStartup::loadCoreLibraries(); 30 8 31 - $conf = phabricator_read_config_file($env); 32 - $conf['phabricator.env'] = $env; 33 - 34 - PhabricatorEnv::setEnvConfig($conf); 35 - 36 - // This needs to be done before we create the log, because 37 - // PhabricatorAccessLog::getLog() calls date() 38 - $tz = PhabricatorEnv::getEnvConfig('phabricator.timezone'); 39 - if ($tz) { 40 - date_default_timezone_set($tz); 41 - } 42 - 43 - // Append any paths to $PATH if we need to. 44 - $paths = PhabricatorEnv::getEnvConfig('environment.append-paths'); 45 - if (!empty($paths)) { 46 - $current_env_path = getenv('PATH'); 47 - $new_env_paths = implode(':', $paths); 48 - putenv('PATH='.$current_env_path.':'.$new_env_paths); 49 - } 9 + PhabricatorEnv::initializeWebEnvironment(); 50 10 51 11 // This is the earliest we can get away with this, we need env config first. 52 12 PhabricatorAccessLog::init(); ··· 63 23 64 24 DarkConsoleXHProfPluginAPI::hookProfiler(); 65 25 66 - PhutilErrorHandler::initialize(); 67 - 68 26 PhutilErrorHandler::setErrorListener( 69 27 array('DarkConsoleErrorLogPluginAPI', 'handleErrors')); 70 28 71 - foreach (PhabricatorEnv::getEnvConfig('load-libraries') as $library) { 72 - phutil_load_library($library); 73 - } 74 - 75 29 if (PhabricatorEnv::getEnvConfig('phabricator.setup')) { 76 30 try { 77 31 PhabricatorSetup::runSetup(); ··· 83 37 } 84 38 85 39 phabricator_detect_bad_base_uri(); 86 - 87 - $translation = PhabricatorEnv::newObjectFromConfig('translation.provider'); 88 - PhutilTranslator::getInstance() 89 - ->setLanguage($translation->getLanguage()) 90 - ->addTranslations($translation->getTranslations()); 91 40 92 41 $host = $_SERVER['HTTP_HOST']; 93 42 $path = $_REQUEST['__path__']; ··· 214 163 215 164 } catch (Exception $ex) { 216 165 PhabricatorStartup::didFatal("[Exception] ".$ex->getMessage()); 217 - } 218 - 219 - 220 - /** 221 - * @group aphront 222 - */ 223 - function setup_aphront_basics() { 224 - $aphront_root = dirname(dirname(__FILE__)); 225 - $libraries_root = dirname($aphront_root); 226 - 227 - $root = null; 228 - if (!empty($_SERVER['PHUTIL_LIBRARY_ROOT'])) { 229 - $root = $_SERVER['PHUTIL_LIBRARY_ROOT']; 230 - } 231 - 232 - ini_set( 233 - 'include_path', 234 - $libraries_root.PATH_SEPARATOR.ini_get('include_path')); 235 - @include_once $root.'libphutil/src/__phutil_library_init__.php'; 236 - if (!@constant('__LIBPHUTIL__')) { 237 - echo "ERROR: Unable to load libphutil. Put libphutil/ next to ". 238 - "phabricator/, or update your PHP 'include_path' to include ". 239 - "the parent directory of libphutil/.\n"; 240 - exit(1); 241 - } 242 - 243 - // Load Phabricator itself using the absolute path, so we never end up doing 244 - // anything surprising (loading index.php and libraries from different 245 - // directories). 246 - phutil_load_library($aphront_root.'/src'); 247 - phutil_load_library('arcanist/src'); 248 - 249 166 } 250 167 251 168 function phabricator_detect_bad_base_uri() {