mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-22 06:42:42 +01:00
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
This commit is contained in:
parent
ed58f6c5f4
commit
9e6d59829c
6 changed files with 245 additions and 256 deletions
|
@ -1,5 +1,6 @@
|
|||
<?php
|
||||
|
||||
function init_phabricator_script() {
|
||||
error_reporting(E_ALL | E_STRICT);
|
||||
ini_set('display_errors', 1);
|
||||
|
||||
|
@ -14,59 +15,10 @@ if (!@constant('__LIBPHUTIL__')) {
|
|||
exit(1);
|
||||
}
|
||||
|
||||
phutil_load_library('arcanist/src');
|
||||
phutil_load_library(dirname(__FILE__).'/../src/');
|
||||
|
||||
// NOTE: This is dangerous in general, but we know we're in a script context and
|
||||
// are not vulnerable to CSRF.
|
||||
AphrontWriteGuard::allowDangerousUnguardedWrites(true);
|
||||
|
||||
require_once dirname(dirname(__FILE__)).'/conf/__init_conf__.php';
|
||||
|
||||
$env = isset($_SERVER['PHABRICATOR_ENV'])
|
||||
? $_SERVER['PHABRICATOR_ENV']
|
||||
: getenv('PHABRICATOR_ENV');
|
||||
if (!$env) {
|
||||
echo phutil_console_wrap(
|
||||
phutil_console_format(
|
||||
"**ERROR**: PHABRICATOR_ENV Not Set\n\n".
|
||||
"Define the __PHABRICATOR_ENV__ environment variable before running ".
|
||||
"this script. You can do it on the command line like this:\n\n".
|
||||
" $ PHABRICATOR_ENV=__custom/myconfig__ %s ...\n\n".
|
||||
"Replace __custom/myconfig__ with the path to your configuration file. ".
|
||||
"For more information, see the 'Configuration Guide' in the ".
|
||||
"Phabricator documentation.\n\n",
|
||||
$argv[0]));
|
||||
exit(1);
|
||||
PhabricatorEnv::initializeScriptEnvironment();
|
||||
}
|
||||
|
||||
$conf = phabricator_read_config_file($env);
|
||||
$conf['phabricator.env'] = $env;
|
||||
|
||||
PhabricatorEnv::setEnvConfig($conf);
|
||||
|
||||
phutil_load_library('arcanist/src');
|
||||
|
||||
foreach (PhabricatorEnv::getEnvConfig('load-libraries') as $library) {
|
||||
phutil_load_library($library);
|
||||
}
|
||||
|
||||
PhutilErrorHandler::initialize();
|
||||
PhabricatorEventEngine::initialize();
|
||||
|
||||
$tz = PhabricatorEnv::getEnvConfig('phabricator.timezone');
|
||||
if ($tz) {
|
||||
date_default_timezone_set($tz);
|
||||
}
|
||||
|
||||
$translation = PhabricatorEnv::newObjectFromConfig('translation.provider');
|
||||
PhutilTranslator::getInstance()
|
||||
->setLanguage($translation->getLanguage())
|
||||
->addTranslations($translation->getTranslations());
|
||||
|
||||
// Append any paths to $PATH if we need to.
|
||||
$paths = PhabricatorEnv::getEnvConfig('environment.append-paths');
|
||||
if (!empty($paths)) {
|
||||
$current_env_path = getenv('PATH');
|
||||
$new_env_paths = implode(PATH_SEPARATOR, $paths);
|
||||
putenv('PATH='.$current_env_path.PATH_SEPARATOR.$new_env_paths);
|
||||
}
|
||||
init_phabricator_script();
|
||||
|
|
|
@ -1080,7 +1080,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorRepositorySymbol' => 'applications/repository/storage/PhabricatorRepositorySymbol.php',
|
||||
'PhabricatorRepositoryTestCase' => 'applications/repository/storage/__tests__/PhabricatorRepositoryTestCase.php',
|
||||
'PhabricatorRepositoryType' => 'applications/repository/constants/PhabricatorRepositoryType.php',
|
||||
'PhabricatorRequestOverseer' => 'infrastructure/PhabricatorRequestOverseer.php',
|
||||
'PhabricatorS3FileStorageEngine' => 'applications/files/engine/PhabricatorS3FileStorageEngine.php',
|
||||
'PhabricatorSQLPatchList' => 'infrastructure/storage/patch/PhabricatorSQLPatchList.php',
|
||||
'PhabricatorSSHWorkflow' => 'infrastructure/ssh/PhabricatorSSHWorkflow.php',
|
||||
|
|
|
@ -53,6 +53,102 @@ final class PhabricatorEnv {
|
|||
private static $env;
|
||||
private static $stack = array();
|
||||
|
||||
/**
|
||||
* @phutil-external-symbol class PhabricatorStartup
|
||||
*/
|
||||
public static function initializeWebEnvironment() {
|
||||
$env = self::getSelectedEnvironmentName();
|
||||
if (!$env) {
|
||||
PhabricatorStartup::didFatal(
|
||||
"The 'PHABRICATOR_ENV' environmental variable is not defined. Modify ".
|
||||
"your httpd.conf to include 'SetEnv PHABRICATOR_ENV <env>', where ".
|
||||
"'<env>' is one of 'development', 'production', or a custom ".
|
||||
"environment.");
|
||||
}
|
||||
|
||||
self::initializeCommonEnvironment();
|
||||
}
|
||||
|
||||
public static function initializeScriptEnvironment() {
|
||||
$env = self::getSelectedEnvironmentName();
|
||||
if (!$env) {
|
||||
echo phutil_console_wrap(
|
||||
phutil_console_format(
|
||||
"**ERROR**: PHABRICATOR_ENV Not Set\n\n".
|
||||
"Define the __PHABRICATOR_ENV__ environment variable before ".
|
||||
"running this script. You can do it on the command line like ".
|
||||
"this:\n\n".
|
||||
" $ PHABRICATOR_ENV=__custom/myconfig__ %s ...\n\n".
|
||||
"Replace __custom/myconfig__ with the path to your configuration ".
|
||||
"file. For more information, see the 'Configuration Guide' in the ".
|
||||
"Phabricator documentation.\n\n",
|
||||
$GLOBALS['argv'][0]));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
self::initializeCommonEnvironment();
|
||||
|
||||
// NOTE: This is dangerous in general, but we know we're in a script context
|
||||
// and are not vulnerable to CSRF.
|
||||
AphrontWriteGuard::allowDangerousUnguardedWrites(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @phutil-external-symbol function phabricator_read_config_file
|
||||
*/
|
||||
private static function initializeCommonEnvironment() {
|
||||
$env = self::getSelectedEnvironmentName();
|
||||
|
||||
$root = dirname(phutil_get_library_root('phabricator'));
|
||||
require_once $root.'/conf/__init_conf__.php';
|
||||
$conf = phabricator_read_config_file($env);
|
||||
$conf['phabricator.env'] = $env;
|
||||
|
||||
PhabricatorEnv::setEnvConfig($conf);
|
||||
|
||||
PhutilErrorHandler::initialize();
|
||||
|
||||
$tz = PhabricatorEnv::getEnvConfig('phabricator.timezone');
|
||||
if ($tz) {
|
||||
date_default_timezone_set($tz);
|
||||
}
|
||||
|
||||
// Append any paths to $PATH if we need to.
|
||||
$paths = PhabricatorEnv::getEnvConfig('environment.append-paths');
|
||||
if (!empty($paths)) {
|
||||
$current_env_path = getenv('PATH');
|
||||
$new_env_paths = implode(PATH_SEPARATOR, $paths);
|
||||
putenv('PATH='.$current_env_path.PATH_SEPARATOR.$new_env_paths);
|
||||
}
|
||||
|
||||
foreach (PhabricatorEnv::getEnvConfig('load-libraries') as $library) {
|
||||
phutil_load_library($library);
|
||||
}
|
||||
|
||||
PhabricatorEventEngine::initialize();
|
||||
|
||||
$translation = PhabricatorEnv::newObjectFromConfig('translation.provider');
|
||||
PhutilTranslator::getInstance()
|
||||
->setLanguage($translation->getLanguage())
|
||||
->addTranslations($translation->getTranslations());
|
||||
}
|
||||
|
||||
public static function getSelectedEnvironmentName() {
|
||||
$env_var = 'PHABRICATOR_ENV';
|
||||
|
||||
$env = idx($_SERVER, $env_var);
|
||||
|
||||
if (!$env) {
|
||||
$env = getenv($env_var);
|
||||
}
|
||||
|
||||
if (!$env) {
|
||||
$env = idx($_ENV, $env_var);
|
||||
}
|
||||
|
||||
return $env;
|
||||
}
|
||||
|
||||
|
||||
/* -( Reading Configuration )---------------------------------------------- */
|
||||
|
||||
|
|
|
@ -1,98 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorRequestOverseer {
|
||||
|
||||
public function didStartup() {
|
||||
$this->detectPostMaxSizeTriggered();
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect if this request has had its POST data stripped by exceeding the
|
||||
* 'post_max_size' PHP configuration limit.
|
||||
*
|
||||
* 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
|
||||
* the request anyway, and provides no formal way to detect that this
|
||||
* happened.
|
||||
*
|
||||
* We can still read the entire body out of `php://input`. However according
|
||||
* to the documentation the stream isn't available for "multipart/form-data"
|
||||
* (on nginx + php-fpm it appears that it is available, though, at least) so
|
||||
* any attempt to generate $_POST would be fragile.
|
||||
*
|
||||
* @phutil-external-symbol class PhabricatorStartup
|
||||
*/
|
||||
private function detectPostMaxSizeTriggered() {
|
||||
// If this wasn't a POST, we're fine.
|
||||
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||
return;
|
||||
}
|
||||
|
||||
// If there's POST data, clearly we're in good shape.
|
||||
if ($_POST) {
|
||||
return;
|
||||
}
|
||||
|
||||
// For HTML5 drag-and-drop file uploads, Safari submits the data as
|
||||
// "application/x-www-form-urlencoded". For most files this generates
|
||||
// something in POST because most files decode to some nonempty (albeit
|
||||
// meaningless) value. However, some files (particularly small images)
|
||||
// don't decode to anything. If we know this is a drag-and-drop upload,
|
||||
// we can skip this check.
|
||||
if (isset($_REQUEST['__upload__'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
// PHP generates $_POST only for two content types. This routing happens
|
||||
// in `main/php_content_types.c` in PHP. Normally, all forms use one of
|
||||
// these content types, but some requests may not -- for example, Firefox
|
||||
// submits files sent over HTML5 XMLHTTPRequest APIs with the Content-Type
|
||||
// of the file itself. If we don't have a recognized content type, we
|
||||
// don't need $_POST.
|
||||
//
|
||||
// NOTE: We use strncmp() because the actual content type may be something
|
||||
// like "multipart/form-data; boundary=...".
|
||||
//
|
||||
// NOTE: Chrome sometimes omits this header, see some discussion in T1762
|
||||
// and http://code.google.com/p/chromium/issues/detail?id=6800
|
||||
$content_type = idx($_SERVER, 'CONTENT_TYPE', '');
|
||||
|
||||
$parsed_types = array(
|
||||
'application/x-www-form-urlencoded',
|
||||
'multipart/form-data',
|
||||
);
|
||||
|
||||
$is_parsed_type = false;
|
||||
foreach ($parsed_types as $parsed_type) {
|
||||
if (strncmp($content_type, $parsed_type, strlen($parsed_type)) === 0) {
|
||||
$is_parsed_type = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$is_parsed_type) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for 'Content-Length'. If there's no data, we don't expect $_POST
|
||||
// to exist.
|
||||
$length = (int)$_SERVER['CONTENT_LENGTH'];
|
||||
if (!$length) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Time to fatal: we know this was a POST with data that should have been
|
||||
// populated into $_POST, but it wasn't.
|
||||
|
||||
$config = ini_get('post_max_size');
|
||||
PhabricatorStartup::didFatal(
|
||||
"As received by the server, this request had a nonzero content length ".
|
||||
"but no POST data.\n\n".
|
||||
"Normally, this indicates that it exceeds the 'post_max_size' setting ".
|
||||
"in the PHP configuration on the server. Increase the 'post_max_size' ".
|
||||
"setting or reduce the size of the request.\n\n".
|
||||
"Request size according to 'Content-Length' was '{$length}', ".
|
||||
"'post_max_size' is set to '{$config}'.");
|
||||
}
|
||||
|
||||
}
|
|
@ -63,11 +63,6 @@ final class PhabricatorStartup {
|
|||
self::$startTime = microtime(true);
|
||||
self::$globals = array();
|
||||
|
||||
self::setupPHP();
|
||||
self::verifyPHP();
|
||||
|
||||
self::verifyRewriteRules();
|
||||
|
||||
static $registered;
|
||||
if (!$registered) {
|
||||
// NOTE: This protects us against multiple calls to didStartup() in the
|
||||
|
@ -76,6 +71,13 @@ final class PhabricatorStartup {
|
|||
register_shutdown_function(array(__CLASS__, 'didShutdown'));
|
||||
$registered = true;
|
||||
}
|
||||
|
||||
self::setupPHP();
|
||||
self::verifyPHP();
|
||||
|
||||
self::verifyRewriteRules();
|
||||
|
||||
self::detectPostMaxSizeTriggered();
|
||||
}
|
||||
|
||||
|
||||
|
@ -118,6 +120,35 @@ final class PhabricatorStartup {
|
|||
self::didFatal($msg);
|
||||
}
|
||||
|
||||
public static function loadCoreLibraries() {
|
||||
$phabricator_root = dirname(dirname(__FILE__));
|
||||
$libraries_root = dirname($phabricator_root);
|
||||
|
||||
$root = null;
|
||||
if (!empty($_SERVER['PHUTIL_LIBRARY_ROOT'])) {
|
||||
$root = $_SERVER['PHUTIL_LIBRARY_ROOT'];
|
||||
}
|
||||
|
||||
ini_set(
|
||||
'include_path',
|
||||
$libraries_root.PATH_SEPARATOR.ini_get('include_path'));
|
||||
|
||||
@include_once $root.'libphutil/src/__phutil_library_init__.php';
|
||||
if (!@constant('__LIBPHUTIL__')) {
|
||||
self::didFatal(
|
||||
"Unable to load libphutil. Put libphutil/ next to phabricator/, or ".
|
||||
"update your PHP 'include_path' to include the parent directory of ".
|
||||
"libphutil/.");
|
||||
}
|
||||
|
||||
phutil_load_library('arcanist/src');
|
||||
|
||||
// Load Phabricator itself using the absolute path, so we never end up doing
|
||||
// anything surprising (loading index.php and libraries from different
|
||||
// directories).
|
||||
phutil_load_library($phabricator_root.'/src');
|
||||
}
|
||||
|
||||
|
||||
/* -( In Case of Apocalypse )---------------------------------------------- */
|
||||
|
||||
|
@ -219,4 +250,96 @@ final class PhabricatorStartup {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Detect if this request has had its POST data stripped by exceeding the
|
||||
* 'post_max_size' PHP configuration limit.
|
||||
*
|
||||
* 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
|
||||
* the request anyway, and provides no formal way to detect that this
|
||||
* happened.
|
||||
*
|
||||
* We can still read the entire body out of `php://input`. However according
|
||||
* to the documentation the stream isn't available for "multipart/form-data"
|
||||
* (on nginx + php-fpm it appears that it is available, though, at least) so
|
||||
* any attempt to generate $_POST would be fragile.
|
||||
*
|
||||
* @task validation
|
||||
*/
|
||||
private static function detectPostMaxSizeTriggered() {
|
||||
// If this wasn't a POST, we're fine.
|
||||
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
|
||||
return;
|
||||
}
|
||||
|
||||
// If there's POST data, clearly we're in good shape.
|
||||
if ($_POST) {
|
||||
return;
|
||||
}
|
||||
|
||||
// For HTML5 drag-and-drop file uploads, Safari submits the data as
|
||||
// "application/x-www-form-urlencoded". For most files this generates
|
||||
// something in POST because most files decode to some nonempty (albeit
|
||||
// meaningless) value. However, some files (particularly small images)
|
||||
// don't decode to anything. If we know this is a drag-and-drop upload,
|
||||
// we can skip this check.
|
||||
if (isset($_REQUEST['__upload__'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
// PHP generates $_POST only for two content types. This routing happens
|
||||
// in `main/php_content_types.c` in PHP. Normally, all forms use one of
|
||||
// these content types, but some requests may not -- for example, Firefox
|
||||
// submits files sent over HTML5 XMLHTTPRequest APIs with the Content-Type
|
||||
// of the file itself. If we don't have a recognized content type, we
|
||||
// don't need $_POST.
|
||||
//
|
||||
// NOTE: We use strncmp() because the actual content type may be something
|
||||
// like "multipart/form-data; boundary=...".
|
||||
//
|
||||
// NOTE: Chrome sometimes omits this header, see some discussion in T1762
|
||||
// and http://code.google.com/p/chromium/issues/detail?id=6800
|
||||
$content_type = isset($_SERVER['CONTENT_TYPE'])
|
||||
? $_SERVER['CONTENT_TYPE']
|
||||
: '';
|
||||
|
||||
$parsed_types = array(
|
||||
'application/x-www-form-urlencoded',
|
||||
'multipart/form-data',
|
||||
);
|
||||
|
||||
$is_parsed_type = false;
|
||||
foreach ($parsed_types as $parsed_type) {
|
||||
if (strncmp($content_type, $parsed_type, strlen($parsed_type)) === 0) {
|
||||
$is_parsed_type = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$is_parsed_type) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for 'Content-Length'. If there's no data, we don't expect $_POST
|
||||
// to exist.
|
||||
$length = (int)$_SERVER['CONTENT_LENGTH'];
|
||||
if (!$length) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Time to fatal: we know this was a POST with data that should have been
|
||||
// populated into $_POST, but it wasn't.
|
||||
|
||||
$config = ini_get('post_max_size');
|
||||
PhabricatorStartup::didFatal(
|
||||
"As received by the server, this request had a nonzero content length ".
|
||||
"but no POST data.\n\n".
|
||||
"Normally, this indicates that it exceeds the 'post_max_size' setting ".
|
||||
"in the PHP configuration on the server. Increase the 'post_max_size' ".
|
||||
"setting or reduce the size of the request.\n\n".
|
||||
"Request size according to 'Content-Length' was '{$length}', ".
|
||||
"'post_max_size' is set to '{$config}'.");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,50 +3,10 @@
|
|||
require_once dirname(dirname(__FILE__)).'/support/PhabricatorStartup.php';
|
||||
PhabricatorStartup::didStartup();
|
||||
|
||||
$access_log = null;
|
||||
|
||||
$env = getenv('PHABRICATOR_ENV'); // Apache
|
||||
if (!$env) {
|
||||
if (isset($_ENV['PHABRICATOR_ENV'])) {
|
||||
$env = $_ENV['PHABRICATOR_ENV'];
|
||||
}
|
||||
}
|
||||
|
||||
if (!$env) {
|
||||
PhabricatorStartup::didFatal(
|
||||
"The 'PHABRICATOR_ENV' environmental variable is not defined. Modify ".
|
||||
"your httpd.conf to include 'SetEnv PHABRICATOR_ENV <env>', where '<env>' ".
|
||||
"is one of 'development', 'production', or a custom environment.");
|
||||
}
|
||||
|
||||
|
||||
require_once dirname(dirname(__FILE__)).'/conf/__init_conf__.php';
|
||||
|
||||
try {
|
||||
setup_aphront_basics();
|
||||
PhabricatorStartup::loadCoreLibraries();
|
||||
|
||||
$overseer = new PhabricatorRequestOverseer();
|
||||
$overseer->didStartup();
|
||||
|
||||
$conf = phabricator_read_config_file($env);
|
||||
$conf['phabricator.env'] = $env;
|
||||
|
||||
PhabricatorEnv::setEnvConfig($conf);
|
||||
|
||||
// This needs to be done before we create the log, because
|
||||
// PhabricatorAccessLog::getLog() calls date()
|
||||
$tz = PhabricatorEnv::getEnvConfig('phabricator.timezone');
|
||||
if ($tz) {
|
||||
date_default_timezone_set($tz);
|
||||
}
|
||||
|
||||
// Append any paths to $PATH if we need to.
|
||||
$paths = PhabricatorEnv::getEnvConfig('environment.append-paths');
|
||||
if (!empty($paths)) {
|
||||
$current_env_path = getenv('PATH');
|
||||
$new_env_paths = implode(':', $paths);
|
||||
putenv('PATH='.$current_env_path.':'.$new_env_paths);
|
||||
}
|
||||
PhabricatorEnv::initializeWebEnvironment();
|
||||
|
||||
// This is the earliest we can get away with this, we need env config first.
|
||||
PhabricatorAccessLog::init();
|
||||
|
@ -63,15 +23,9 @@ try {
|
|||
|
||||
DarkConsoleXHProfPluginAPI::hookProfiler();
|
||||
|
||||
PhutilErrorHandler::initialize();
|
||||
|
||||
PhutilErrorHandler::setErrorListener(
|
||||
array('DarkConsoleErrorLogPluginAPI', 'handleErrors'));
|
||||
|
||||
foreach (PhabricatorEnv::getEnvConfig('load-libraries') as $library) {
|
||||
phutil_load_library($library);
|
||||
}
|
||||
|
||||
if (PhabricatorEnv::getEnvConfig('phabricator.setup')) {
|
||||
try {
|
||||
PhabricatorSetup::runSetup();
|
||||
|
@ -84,11 +38,6 @@ try {
|
|||
|
||||
phabricator_detect_bad_base_uri();
|
||||
|
||||
$translation = PhabricatorEnv::newObjectFromConfig('translation.provider');
|
||||
PhutilTranslator::getInstance()
|
||||
->setLanguage($translation->getLanguage())
|
||||
->addTranslations($translation->getTranslations());
|
||||
|
||||
$host = $_SERVER['HTTP_HOST'];
|
||||
$path = $_REQUEST['__path__'];
|
||||
|
||||
|
@ -216,38 +165,6 @@ try {
|
|||
PhabricatorStartup::didFatal("[Exception] ".$ex->getMessage());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @group aphront
|
||||
*/
|
||||
function setup_aphront_basics() {
|
||||
$aphront_root = dirname(dirname(__FILE__));
|
||||
$libraries_root = dirname($aphront_root);
|
||||
|
||||
$root = null;
|
||||
if (!empty($_SERVER['PHUTIL_LIBRARY_ROOT'])) {
|
||||
$root = $_SERVER['PHUTIL_LIBRARY_ROOT'];
|
||||
}
|
||||
|
||||
ini_set(
|
||||
'include_path',
|
||||
$libraries_root.PATH_SEPARATOR.ini_get('include_path'));
|
||||
@include_once $root.'libphutil/src/__phutil_library_init__.php';
|
||||
if (!@constant('__LIBPHUTIL__')) {
|
||||
echo "ERROR: Unable to load libphutil. Put libphutil/ next to ".
|
||||
"phabricator/, or update your PHP 'include_path' to include ".
|
||||
"the parent directory of libphutil/.\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Load Phabricator itself using the absolute path, so we never end up doing
|
||||
// anything surprising (loading index.php and libraries from different
|
||||
// directories).
|
||||
phutil_load_library($aphront_root.'/src');
|
||||
phutil_load_library('arcanist/src');
|
||||
|
||||
}
|
||||
|
||||
function phabricator_detect_bad_base_uri() {
|
||||
$conf = PhabricatorEnv::getEnvConfig('phabricator.base-uri');
|
||||
$uri = new PhutilURI($conf);
|
||||
|
|
Loading…
Reference in a new issue