From b71e1c15ef93e856630bb3eefbef0e71dbf2c925 Mon Sep 17 00:00:00 2001 From: epriestley Date: Fri, 13 Jan 2012 11:29:52 -0800 Subject: [PATCH] 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 --- src/infrastructure/setup/PhabricatorSetup.php | 52 +++++++++++++++++-- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/src/infrastructure/setup/PhabricatorSetup.php b/src/infrastructure/setup/PhabricatorSetup.php index 6398b2fa8e..e24a18a98c 100644 --- a/src/infrastructure/setup/PhabricatorSetup.php +++ b/src/infrastructure/setup/PhabricatorSetup.php @@ -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, '