Page MenuHomePhabricator

PHP built-in webserver fails on POST
Closed, ResolvedPublic



When running in the PHP's devloper webserver on php 7.4.3, the first POST (create admin user) fails with "undefined index __path__".

From what I understand of the flow:

  1. PhabricatorStartup::rebuildRequest() happens, where we re-write $_REQUEST.
  2. At some point later, PhabricatorStartup::verifyRewriteRules() updates $_REQUEST with the __path__. (there's still no phlog at this point).
  3. At some point after that, in AphrontApplicationConfiguration::runHTTPRequest() (line 179), $_REQUEST doesn't have __path__ value.

If I take the special case from verifyRewriteRules() and dump it at the end of rebuildRequest(), everything is happy at (3) and the request continues.

In D20903, @Firehed describes a different solution, to set _$GET at the end of verifyRewriteRules(), and he claims that fixed this for him, but that was a while ago.

Also when reports of this showed up, I still had php 5.5, and appears that it worked for me then with that config.

Event Timeline

I wonder if maintaining support for the builtin webserver is worthwhile -- I never use it, and I feel like I only see it referenced when users report bugs like this in the vein of "PHP builtin webserver has been completely broken for 13 years", which suggests it's probably not seeing very much use in the wild, either.

A possible argument in support of the builtin webserver is that Apache was very difficult to get working with PHP extensions about a year and a half ago (T13232). I'm not sure if this is still true or not.

Maybe a half-step in this direction would be to fix whatever the root issue is here, but also move the documentation somewhere deep into the "Advanced Developer Stuff" part of the documentation.

In the Discourse thread, the first user appears to be running on Windows, so I suspect their efforts will fail whether the webserver works or not:

D:\OutilsPHP\php\php-7.3.10-nts-Win32-VC15-x64\php.exe -S -t ...

The second user isn't on Windows, so their use case may be less ill-fated, but I'm still not sure if there's a good reason to choose the builtin server over Apache.

Both reference PHPStorm, so maybe there's some shared root cause like "PHPStorm's XYZ integration is easy with the builtin webserver and hard/nonexistent with Apache".

Yeah, it might make sense to drop it; I use it because it's easier to setup then Apache and the error log is right in my console, but setting up a real server isn't that much of a bother, except for Apple changing the rugs on you every other day (Soon with both x86 and ARM versions!)

For what it's worth, the only reason I was trying to figure out stuff with the built-in server was because at the time trying to get Phabricator running in Docker correctly was... not nearly as easy as I would have liked. Quickly skimming online suggests that's improved in the interim.

epriestley triaged this task as Normal priority.

I switched to an M1 Mac Mini on Big Sur, which has motivated me somewhat to try to get this working since I suspect doing another install through Homebrew on M1 silicon will be more adventure than I have stomach for.

Guess I should probably add M1 to the remarkup blocklist now.

I think this is now resolved. I'm not completely thrilled about maintaining PHP builtin webserver support because I think use is very limited, but since I'm currently using it I expect to support it at least until I summon the nerve to deal with Homebrew.

I added M1, etc., to the ignored list in D21507.

It's possible the new readRequestPath() mechanism could be cleaner (e.g., ignore __path__ entirely and just read REQUEST_URI in more/all cases) but any changes in that vein need configuration/documentation changes so I don't plan to pursue them for now.

I added M1, etc., to the ignored list in D21507.

...and updated the config on secure, which customizes this list slightly.

I'm not completely thrilled about maintaining PHP builtin webserver support...

A major issue here is that the webserver has a single execution thread and can only handle one request at a time. This makes the self-request setup check hang until it hits a timeout and get skipped, and effectively breaks all clustering behavior (which relies on making Conduit requests to the server).

You can work around this (so far, at least) by running two copies of the webserver on different ports (for example, web on 80 and repo-web on 8000) and registering the second server in Almanac. But this is increasingly ridiculous, and only even worth considering because of the mess with Apache, PHP, code signing, Homebrew, and M1 on Big Sur, etc.