1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-09 16:32:39 +01:00

Fix reading of the request path when running the PHP builtin webserver

Summary:
Ref T13575. Since PHP builtin webserver support was added, the pathway for parsing request parameters became more complex. We now rebuild "$_REQUEST" later, and this rebuild will destroy any mutations made to it here, so the assignment to "__path__" is lost.

Instead of "validating" the request path, make this method "read" the request path and store it explicitly, so it will survive any later request mutations.

Test Plan:
  - Submitted any POST form while running Phabricator under the builtin PHP webserver. Old behavior was an error when accessing "__path__"; new behavior is a working application.
  - Loaded normal pages, etc.

Maniphest Tasks: T13575

Differential Revision: https://secure.phabricator.com/D21506
This commit is contained in:
epriestley 2021-01-11 10:29:58 -08:00
parent b2ab18f8f3
commit 18f049a282
2 changed files with 47 additions and 8 deletions

View file

@ -176,7 +176,7 @@ final class AphrontApplicationConfiguration
} }
$host = AphrontRequest::getHTTPHeader('Host'); $host = AphrontRequest::getHTTPHeader('Host');
$path = $_REQUEST['__path__']; $path = PhabricatorStartup::getRequestPath();
$application = new self(); $application = new self();
@ -759,7 +759,7 @@ final class AphrontApplicationConfiguration
} }
private static function newSelfCheckResponse() { private static function newSelfCheckResponse() {
$path = idx($_REQUEST, '__path__', ''); $path = PhabricatorStartup::getRequestPath();
$query = idx($_SERVER, 'QUERY_STRING', ''); $query = idx($_SERVER, 'QUERY_STRING', '');
$pairs = id(new PhutilQueryStringParser()) $pairs = id(new PhutilQueryStringParser())

View file

@ -35,6 +35,7 @@
* @task validation Validation * @task validation Validation
* @task ratelimit Rate Limiting * @task ratelimit Rate Limiting
* @task phases Startup Phase Timers * @task phases Startup Phase Timers
* @task request-path Request Path
*/ */
final class PhabricatorStartup { final class PhabricatorStartup {
@ -47,6 +48,7 @@ final class PhabricatorStartup {
private static $phases; private static $phases;
private static $limits = array(); private static $limits = array();
private static $requestPath;
/* -( Accessing Request Information )-------------------------------------- */ /* -( Accessing Request Information )-------------------------------------- */
@ -119,6 +121,7 @@ final class PhabricatorStartup {
self::$phases = array(); self::$phases = array();
self::$accessLog = null; self::$accessLog = null;
self::$requestPath = null;
static $registered; static $registered;
if (!$registered) { if (!$registered) {
@ -140,7 +143,7 @@ final class PhabricatorStartup {
self::normalizeInput(); self::normalizeInput();
self::verifyRewriteRules(); self::readRequestPath();
self::beginOutputCapture(); self::beginOutputCapture();
} }
@ -552,17 +555,29 @@ final class PhabricatorStartup {
/** /**
* @task validation * @task request-path
*/ */
private static function verifyRewriteRules() { private static function readRequestPath() {
// See T13575. The request path may be provided in:
//
// - the "$_GET" parameter "__path__" (normal for Apache and nginx); or
// - the "$_SERVER" parameter "REQUEST_URI" (normal for the PHP builtin
// webserver).
//
// Locate it wherever it is, and store it for later use. Note that writing
// to "$_REQUEST" here won't always work, because later code may rebuild
// "$_REQUEST" from other sources.
if (isset($_REQUEST['__path__']) && strlen($_REQUEST['__path__'])) { if (isset($_REQUEST['__path__']) && strlen($_REQUEST['__path__'])) {
self::setRequestPath($_REQUEST['__path__']);
return; return;
} }
// Compatibility with PHP 5.4+ built-in web server.
if (php_sapi_name() == 'cli-server') { if (php_sapi_name() == 'cli-server') {
// Compatibility with PHP 5.4+ built-in web server. $path = parse_url($_SERVER['REQUEST_URI']);
$url = parse_url($_SERVER['REQUEST_URI']); self::setRequestPath($path['path']);
$_REQUEST['__path__'] = $url['path'];
return; return;
} }
@ -580,6 +595,30 @@ final class PhabricatorStartup {
} }
} }
/**
* @task request-path
*/
public static function getRequestPath() {
$path = self::$requestPath;
if ($path === null) {
self::didFatal(
'Request attempted to access request path, but no request path is '.
'available for this request. You may be calling web request code '.
'from a non-request context, or your webserver may not be passing '.
'a request path to Phabricator in a format that it understands.');
}
return $path;
}
/**
* @task request-path
*/
public static function setRequestPath($path) {
self::$requestPath = $path;
}
/* -( Rate Limiting )------------------------------------------------------ */ /* -( Rate Limiting )------------------------------------------------------ */