mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-22 23:02:42 +01:00
Detect which PHP SAPI the CLI binary uses during setup
Summary: - PHP uses a SAPI ("server API") to determine how it interacts with the caller (e.g., how to read the environment, how to read flags, what code to execute). - There are several different SAPIs: cli, cgi, cgi-fcgi, apache, etc. - Each SAPI has different behavior -- for instance, the "cgi" SAPI emits some CGI headers unless told not to, so a script like 'echo "x"' actually echoes some headers and then 'x' as an HTTP body. - In some setups, "php" may be php-cgi. - If you run php-cgi as "php scriptname.php" and your ENV has an existing CGI request in it, it runs that CGI request instead of the script. This causes an infinite loop. - Add checks to verify that "php" is the "cli" SAPI binary, not some other SAPI. - In particular, cPanel uses suphp and is affected by this configuration issue. See this thread: https://lists.marsching.com/pipermail/suphp/2008-September/002036.html Test Plan: - On a cPanel + suphp machine, ran setup and was stopped for having the "cgi-fcgi" SAPI instead of throw into an infinite loop. - Applied the suggested remedy, setup now runs fine. Reviewers: btrahan, jungejason Reviewed By: btrahan CC: aran, btrahan, epriestley Differential Revision: https://secure.phabricator.com/D1390
This commit is contained in:
parent
cf61f0e32d
commit
b71e1c15ef
1 changed files with 48 additions and 4 deletions
|
@ -147,19 +147,63 @@ class PhabricatorSetup {
|
|||
}
|
||||
}
|
||||
|
||||
list($err, $stdout, $stderr) = exec_manual(
|
||||
'/usr/bin/env php -r %s',
|
||||
'exit;');
|
||||
list($err, $stdout, $stderr) = exec_manual('which php');
|
||||
if ($err) {
|
||||
self::writeFailure();
|
||||
self::write("Unable to execute 'php' on the command line from the web ".
|
||||
self::write("Unable to locate 'php' on the command line from the web ".
|
||||
"server. Verify that 'php' is in the webserver's PATH.\n".
|
||||
" err: {$err}\n".
|
||||
"stdout: {$stdout}\n".
|
||||
"stderr: {$stderr}\n");
|
||||
return;
|
||||
} else {
|
||||
self::write(" okay PHP binary found on the command line.\n");
|
||||
$php_bin = trim($stdout);
|
||||
}
|
||||
|
||||
// NOTE: In cPanel + suphp installs, 'php' may be the PHP CGI SAPI, not the
|
||||
// PHP CLI SAPI. proc_open() will pass the environment to the child process,
|
||||
// which will re-execute the webpage (causing an infinite number of
|
||||
// processes to spawn). To test that the 'php' binary is safe to execute,
|
||||
// we call php_sapi_name() using "env -i" to wipe the environment so it
|
||||
// doesn't execute another reuqest if it's the wrong binary. We can't use
|
||||
// "-r" because php-cgi doesn't support that flag.
|
||||
|
||||
$tmp_file = new TempFile('sapi.php');
|
||||
Filesystem::writeFile($tmp_file, '<?php echo php_sapi_name();');
|
||||
|
||||
list($err, $stdout, $stderr) = exec_manual(
|
||||
'/usr/bin/env -i %s -f %s',
|
||||
$php_bin,
|
||||
$tmp_file);
|
||||
if ($err) {
|
||||
self::writeFailure();
|
||||
self::write("Unable to execute 'php' on the command line from the web ".
|
||||
"server.\n".
|
||||
" err: {$err}\n".
|
||||
"stdout: {$stdout}\n".
|
||||
"stderr: {$stderr}\n");
|
||||
return;
|
||||
} else {
|
||||
self::write(" okay PHP is available from the command line.\n");
|
||||
|
||||
$sapi = trim($stdout);
|
||||
if ($sapi != 'cli') {
|
||||
self::writeFailure();
|
||||
self::write(
|
||||
"The 'php' binary on this system uses the '{$sapi}' SAPI, but the ".
|
||||
"'cli' SAPI is expected. Replace 'php' with the php-cli SAPI ".
|
||||
"binary, or edit your webserver configuration so the first 'php' ".
|
||||
"in PATH is the 'cli' SAPI.\n\n".
|
||||
"If you're running cPanel with suphp, the easiest way to fix this ".
|
||||
"is to add '/usr/local/bin' before '/usr/bin' for 'env_path' in ".
|
||||
"suconf.php:\n\n".
|
||||
' env_path="/bin:/usr/local/bin:/usr/bin"'.
|
||||
"\n\n");
|
||||
return;
|
||||
} else {
|
||||
self::write(" okay 'php' is CLI SAPI.\n");
|
||||
}
|
||||
}
|
||||
|
||||
$root = dirname(phutil_get_library_root('phabricator'));
|
||||
|
|
Loading…
Reference in a new issue