Page MenuHomePhabricator

D16500.id39710.diff
No OneTemporary

D16500.id39710.diff

diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -2998,6 +2998,7 @@
'PhabricatorPHPASTApplication' => 'applications/phpast/application/PhabricatorPHPASTApplication.php',
'PhabricatorPHPConfigSetupCheck' => 'applications/config/check/PhabricatorPHPConfigSetupCheck.php',
'PhabricatorPHPMailerConfigOptions' => 'applications/config/option/PhabricatorPHPMailerConfigOptions.php',
+ 'PhabricatorPHPPreflightSetupCheck' => 'applications/config/check/PhabricatorPHPPreflightSetupCheck.php',
'PhabricatorPackagesApplication' => 'applications/packages/application/PhabricatorPackagesApplication.php',
'PhabricatorPackagesController' => 'applications/packages/controller/PhabricatorPackagesController.php',
'PhabricatorPackagesCreatePublisherCapability' => 'applications/packages/capability/PhabricatorPackagesCreatePublisherCapability.php',
@@ -7855,6 +7856,7 @@
'PhabricatorPHPASTApplication' => 'PhabricatorApplication',
'PhabricatorPHPConfigSetupCheck' => 'PhabricatorSetupCheck',
'PhabricatorPHPMailerConfigOptions' => 'PhabricatorApplicationConfigOptions',
+ 'PhabricatorPHPPreflightSetupCheck' => 'PhabricatorSetupCheck',
'PhabricatorPackagesApplication' => 'PhabricatorApplication',
'PhabricatorPackagesController' => 'PhabricatorController',
'PhabricatorPackagesCreatePublisherCapability' => 'PhabricatorPolicyCapability',
diff --git a/src/aphront/configuration/AphrontApplicationConfiguration.php b/src/aphront/configuration/AphrontApplicationConfiguration.php
--- a/src/aphront/configuration/AphrontApplicationConfiguration.php
+++ b/src/aphront/configuration/AphrontApplicationConfiguration.php
@@ -69,6 +69,15 @@
// request object first.
$write_guard = new AphrontWriteGuard('id');
+ PhabricatorStartup::beginStartupPhase('preflight');
+
+ $response = PhabricatorSetupCheck::willPreflightRequest();
+ if ($response) {
+ PhabricatorStartup::endOutputCapture();
+ $sink->writeResponse($response);
+ return;
+ }
+
PhabricatorStartup::beginStartupPhase('env.init');
PhabricatorEnv::initializeWebEnvironment();
diff --git a/src/applications/config/check/PhabricatorExtensionsSetupCheck.php b/src/applications/config/check/PhabricatorExtensionsSetupCheck.php
--- a/src/applications/config/check/PhabricatorExtensionsSetupCheck.php
+++ b/src/applications/config/check/PhabricatorExtensionsSetupCheck.php
@@ -12,7 +12,6 @@
protected function executeChecks() {
// TODO: Make 'mbstring' and 'iconv' soft requirements.
- // TODO: Make 'curl' a soft requirement.
$required = array(
'hash',
@@ -22,9 +21,8 @@
'iconv',
'ctype',
- // There is a chance we might not need this, but some configurations (like
- // OAuth or Amazon SES) will require it. Just mark it 'required' since
- // it's widely available and relatively core.
+ // There is a tiny chance we might not need this, but a significant
+ // number of applications require it and it's widely available.
'curl',
);
diff --git a/src/applications/config/check/PhabricatorPHPConfigSetupCheck.php b/src/applications/config/check/PhabricatorPHPConfigSetupCheck.php
--- a/src/applications/config/check/PhabricatorPHPConfigSetupCheck.php
+++ b/src/applications/config/check/PhabricatorPHPConfigSetupCheck.php
@@ -1,202 +1,17 @@
<?php
+/**
+ * Noncritical PHP configuration checks.
+ *
+ * For critical checks, see @{class:PhabricatorPHPPreflightSetupCheck}.
+ */
final class PhabricatorPHPConfigSetupCheck extends PhabricatorSetupCheck {
public function getDefaultGroup() {
return self::GROUP_PHP;
}
- public function isPreflightCheck() {
- return true;
- }
-
protected function executeChecks() {
- if (version_compare(phpversion(), 7, '>=')) {
- $message = pht(
- 'This version of Phabricator does not support PHP 7. You '.
- 'are running PHP %s.',
- phpversion());
-
- $this->newIssue('php.version7')
- ->setIsFatal(true)
- ->setName(pht('PHP 7 Not Supported'))
- ->setMessage($message)
- ->addLink(
- 'https://phurl.io/u/php7',
- pht('Phabricator PHP 7 Compatibility Information'));
-
- return;
- }
-
- $safe_mode = ini_get('safe_mode');
- if ($safe_mode) {
- $message = pht(
- "You have '%s' enabled in your PHP configuration, but Phabricator ".
- "will not run in safe mode. Safe mode has been deprecated in PHP 5.3 ".
- "and removed in PHP 5.4.\n\nDisable safe mode to continue.",
- 'safe_mode');
-
- $this->newIssue('php.safe_mode')
- ->setIsFatal(true)
- ->setName(pht('Disable PHP %s', 'safe_mode'))
- ->setMessage($message)
- ->addPHPConfig('safe_mode');
- return;
- }
-
- // Check for `disable_functions` or `disable_classes`. Although it's
- // possible to disable a bunch of functions (say, `array_change_key_case()`)
- // and classes and still have Phabricator work fine, it's unreasonably
- // difficult for us to be sure we'll even survive setup if these options
- // are enabled. Phabricator needs access to the most dangerous functions,
- // so there is no reasonable configuration value here which actually
- // provides a benefit while guaranteeing Phabricator will run properly.
-
- $disable_options = array('disable_functions', 'disable_classes');
- foreach ($disable_options as $disable_option) {
- $disable_value = ini_get($disable_option);
- if ($disable_value) {
-
- // By default Debian installs the pcntl extension but disables all of
- // its functions using configuration. Whitelist disabling these
- // functions so that Debian PHP works out of the box (we do not need to
- // call these functions from the web UI). This is pretty ridiculous but
- // it's not the users' fault and they haven't done anything crazy to
- // get here, so don't make them pay for Debian's unusual choices.
- // See: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=605571
- $fatal = true;
- if ($disable_option == 'disable_functions') {
- $functions = preg_split('/[, ]+/', $disable_value);
- $functions = array_filter($functions);
- foreach ($functions as $k => $function) {
- if (preg_match('/^pcntl_/', $function)) {
- unset($functions[$k]);
- }
- }
- if (!$functions) {
- $fatal = false;
- }
- }
-
- if ($fatal) {
- $message = pht(
- "You have '%s' enabled in your PHP configuration.\n\n".
- "This option is not compatible with Phabricator. Remove ".
- "'%s' from your configuration to continue.",
- $disable_option,
- $disable_option);
-
- $this->newIssue('php.'.$disable_option)
- ->setIsFatal(true)
- ->setName(pht('Remove PHP %s', $disable_option))
- ->setMessage($message)
- ->addPHPConfig($disable_option);
- }
- }
- }
-
- $overload_option = 'mbstring.func_overload';
- $func_overload = ini_get($overload_option);
- if ($func_overload) {
- $message = pht(
- "You have '%s' enabled in your PHP configuration.\n\n".
- "This option is not compatible with Phabricator. Disable ".
- "'%s' in your PHP configuration to continue.",
- $overload_option,
- $overload_option);
-
- $this->newIssue('php'.$overload_option)
- ->setIsFatal(true)
- ->setName(pht('Disable PHP %s', $overload_option))
- ->setMessage($message)
- ->addPHPConfig($overload_option);
- }
-
- $open_basedir = ini_get('open_basedir');
- if ($open_basedir) {
-
- // 'open_basedir' restricts which files we're allowed to access with
- // file operations. This might be okay -- we don't need to write to
- // arbitrary places in the filesystem -- but we need to access certain
- // resources. This setting is unlikely to be providing any real measure
- // of security so warn even if things look OK.
-
- $failures = array();
-
- try {
- $open_libphutil = class_exists('Future');
- } catch (Exception $ex) {
- $failures[] = $ex->getMessage();
- }
-
- try {
- $open_arcanist = class_exists('ArcanistDiffParser');
- } catch (Exception $ex) {
- $failures[] = $ex->getMessage();
- }
-
- $open_urandom = false;
- try {
- Filesystem::readRandomBytes(1);
- $open_urandom = true;
- } catch (FilesystemException $ex) {
- $failures[] = $ex->getMessage();
- }
-
- try {
- $tmp = new TempFile();
- file_put_contents($tmp, '.');
- $open_tmp = @fopen((string)$tmp, 'r');
- if (!$open_tmp) {
- $failures[] = pht(
- "Unable to read temporary file '%s'.",
- (string)$tmp);
- }
- } catch (Exception $ex) {
- $message = $ex->getMessage();
- $dir = sys_get_temp_dir();
- $failures[] = pht(
- "Unable to open temp files from '%s': %s",
- $dir,
- $message);
- }
-
- $issue = $this->newIssue('php.open_basedir')
- ->setName(pht('Disable PHP %s', 'open_basedir'))
- ->addPHPConfig('open_basedir');
-
- if ($failures) {
- $message = pht(
- "Your server is configured with '%s', which prevents Phabricator ".
- "from opening files it requires access to.\n\n".
- "Disable this setting to continue.\n\nFailures:\n\n%s",
- 'open_basedir',
- implode("\n\n", $failures));
-
- $issue
- ->setIsFatal(true)
- ->setMessage($message);
-
- return;
- } else {
- $summary = pht(
- "You have '%s' configured in your PHP settings, which ".
- "may cause some features to fail.",
- 'open_basedir');
-
- $message = pht(
- "You have '%s' configured in your PHP settings. Although this ".
- "setting appears permissive enough that Phabricator will work ".
- "properly, you may still run into problems because of it.\n\n".
- "Consider disabling '%s'.",
- 'open_basedir',
- 'open_basedir');
-
- $issue
- ->setSummary($summary)
- ->setMessage($message);
- }
- }
if (empty($_SERVER['REMOTE_ADDR'])) {
$doc_href = PhabricatorEnv::getDocLink('Configuring a Preamble Script');
@@ -245,5 +60,7 @@
->setMessage($message)
->addPHPConfig('always_populate_raw_post_data');
}
+
}
+
}
diff --git a/src/applications/config/check/PhabricatorPHPConfigSetupCheck.php b/src/applications/config/check/PhabricatorPHPPreflightSetupCheck.php
copy from src/applications/config/check/PhabricatorPHPConfigSetupCheck.php
copy to src/applications/config/check/PhabricatorPHPPreflightSetupCheck.php
--- a/src/applications/config/check/PhabricatorPHPConfigSetupCheck.php
+++ b/src/applications/config/check/PhabricatorPHPPreflightSetupCheck.php
@@ -1,6 +1,6 @@
<?php
-final class PhabricatorPHPConfigSetupCheck extends PhabricatorSetupCheck {
+final class PhabricatorPHPPreflightSetupCheck extends PhabricatorSetupCheck {
public function getDefaultGroup() {
return self::GROUP_PHP;
@@ -197,53 +197,5 @@
->setMessage($message);
}
}
-
- if (empty($_SERVER['REMOTE_ADDR'])) {
- $doc_href = PhabricatorEnv::getDocLink('Configuring a Preamble Script');
-
- $summary = pht(
- 'You likely need to fix your preamble script so '.
- 'REMOTE_ADDR is no longer empty.');
-
- $message = pht(
- 'No REMOTE_ADDR is available, so Phabricator cannot determine the '.
- 'origin address for requests. This will prevent Phabricator from '.
- 'performing important security checks. This most often means you '.
- 'have a mistake in your preamble script. Consult the documentation '.
- '(%s) and double-check that the script is written correctly.',
- phutil_tag(
- 'a',
- array(
- 'href' => $doc_href,
- 'target' => '_blank',
- ),
- pht('Configuring a Preamble Script')));
-
- $this->newIssue('php.remote_addr')
- ->setName(pht('No REMOTE_ADDR available'))
- ->setSummary($summary)
- ->setMessage($message);
- }
-
- $raw_post_data = (int)ini_get('always_populate_raw_post_data');
- if ($raw_post_data != -1) {
- $summary = pht(
- 'PHP setting "%s" should be set to "-1" to avoid deprecation '.
- 'warnings.',
- 'always_populate_raw_post_data');
-
- $message = pht(
- 'The "%s" key is set to some value other than "-1" in your PHP '.
- 'configuration. This can cause PHP to raise deprecation warnings '.
- 'during process startup. Set this option to "-1" to prevent these '.
- 'warnings from appearing.',
- 'always_populate_raw_post_data');
-
- $this->newIssue('php.always_populate_raw_post_data')
- ->setName(pht('Disable PHP %s', 'always_populate_raw_post_data'))
- ->setSummary($summary)
- ->setMessage($message)
- ->addPHPConfig('always_populate_raw_post_data');
- }
}
}
diff --git a/src/applications/config/check/PhabricatorSetupCheck.php b/src/applications/config/check/PhabricatorSetupCheck.php
--- a/src/applications/config/check/PhabricatorSetupCheck.php
+++ b/src/applications/config/check/PhabricatorSetupCheck.php
@@ -129,16 +129,39 @@
));
}
+ final public static function willPreflightRequest() {
+ $checks = self::loadAllChecks();
+
+ foreach ($checks as $check) {
+ if (!$check->isPreflightCheck()) {
+ continue;
+ }
+
+ $check->runSetupChecks();
+
+ foreach ($check->getIssues() as $key => $issue) {
+ return self::newIssueResponse($issue);
+ }
+ }
+
+ return null;
+ }
+
+ private static function newIssueResponse(PhabricatorSetupIssue $issue) {
+ $view = id(new PhabricatorSetupIssueView())
+ ->setIssue($issue);
+
+ return id(new PhabricatorConfigResponse())
+ ->setView($view);
+ }
+
final public static function willProcessRequest() {
$issue_keys = self::getOpenSetupIssueKeys();
if ($issue_keys === null) {
- $issues = self::runAllChecks();
+ $issues = self::runNormalChecks();
foreach ($issues as $issue) {
if ($issue->getIsFatal()) {
- $view = id(new PhabricatorSetupIssueView())
- ->setIssue($issue);
- return id(new PhabricatorConfigResponse())
- ->setView($view);
+ return self::newIssueResponse($issue);
}
}
$issue_keys = self::getUnignoredIssueKeys($issues);
@@ -176,9 +199,15 @@
->execute();
}
- final public static function runAllChecks() {
+ final public static function runNormalChecks() {
$checks = self::loadAllChecks();
+ foreach ($checks as $key => $check) {
+ if ($check->isPreflightCheck()) {
+ unset($checks[$key]);
+ }
+ }
+
$issues = array();
foreach ($checks as $check) {
$check->runSetupChecks();
diff --git a/src/applications/config/controller/PhabricatorConfigIssueListController.php b/src/applications/config/controller/PhabricatorConfigIssueListController.php
--- a/src/applications/config/controller/PhabricatorConfigIssueListController.php
+++ b/src/applications/config/controller/PhabricatorConfigIssueListController.php
@@ -9,7 +9,7 @@
$nav = $this->buildSideNavView();
$nav->selectFilter('issue/');
- $issues = PhabricatorSetupCheck::runAllChecks();
+ $issues = PhabricatorSetupCheck::runNormalChecks();
PhabricatorSetupCheck::setOpenSetupIssueKeys(
PhabricatorSetupCheck::getUnignoredIssueKeys($issues),
$update_database = true);
diff --git a/src/applications/config/controller/PhabricatorConfigIssuePanelController.php b/src/applications/config/controller/PhabricatorConfigIssuePanelController.php
--- a/src/applications/config/controller/PhabricatorConfigIssuePanelController.php
+++ b/src/applications/config/controller/PhabricatorConfigIssuePanelController.php
@@ -6,7 +6,7 @@
public function handleRequest(AphrontRequest $request) {
$viewer = $request->getViewer();
$open_items = PhabricatorSetupCheck::getOpenSetupIssueKeys();
- $issues = PhabricatorSetupCheck::runAllChecks();
+ $issues = PhabricatorSetupCheck::runNormalChecks();
PhabricatorSetupCheck::setOpenSetupIssueKeys(
PhabricatorSetupCheck::getUnignoredIssueKeys($issues),
$update_database = true);
diff --git a/src/applications/config/controller/PhabricatorConfigIssueViewController.php b/src/applications/config/controller/PhabricatorConfigIssueViewController.php
--- a/src/applications/config/controller/PhabricatorConfigIssueViewController.php
+++ b/src/applications/config/controller/PhabricatorConfigIssueViewController.php
@@ -7,7 +7,7 @@
$viewer = $request->getViewer();
$issue_key = $request->getURIData('key');
- $issues = PhabricatorSetupCheck::runAllChecks();
+ $issues = PhabricatorSetupCheck::runNormalChecks();
PhabricatorSetupCheck::setOpenSetupIssueKeys(
PhabricatorSetupCheck::getUnignoredIssueKeys($issues),
$update_database = true);
diff --git a/src/infrastructure/env/PhabricatorEnv.php b/src/infrastructure/env/PhabricatorEnv.php
--- a/src/infrastructure/env/PhabricatorEnv.php
+++ b/src/infrastructure/env/PhabricatorEnv.php
@@ -315,6 +315,14 @@
return self::$cache[$key];
}
+ if (!self::$sourceStack) {
+ throw new Exception(
+ pht(
+ 'Trying to read configuration "%s" before configuration has been '.
+ 'initialized.',
+ $key));
+ }
+
$result = self::$sourceStack->getKeys(array($key));
if (array_key_exists($key, $result)) {
self::$cache[$key] = $result[$key];
@@ -327,7 +335,6 @@
}
}
-
/**
* Get the current configuration setting for a given key. If the key
* does not exist, return a default value instead of throwing. This is

File Metadata

Mime Type
text/plain
Expires
Wed, Mar 19, 5:57 PM (2 w, 5 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7705819
Default Alt Text
D16500.id39710.diff (17 KB)

Event Timeline