Some research for T12521 bug


#1

Observed Behavior:
I got some situation as in initially description of T12521 (https://secure.phabricator.com/T12521) bug:
hg response
"abort: HTTP Error 500: Error 1: ** unknown exception encountered, please report by visiting"
and similar trace listing.

After some digging to this problem I found next things:

  1. Phabricator’s exceptions rise because server can’t find hg’s commands in HTTP header.
  2. Mercurial, when working with Phabricator send this command in GET request in form 'cmd=batch&cmds=heads…'
    and that cause Phabricator to rise exceptions because (1)
  3. Mercurial, when working with standalone Mercurial server, generate commands, that expect Phabricator, in HTTP
    header in form “HTTP_X_HGARG_”
  4. Responses on ‘capabilities’ command between Phabricator and standalone server differ with small part:
    Phabricator answer:
    lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN
    Standalone:
    lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN httpheader=1024 largefiles=serve

Param, that break all is httpheader=1024
If it forcibly added to Phabricator answer on capability req, than all start work as a charm.

It tested with versions 3.8.4, 4.3 and 4.3.1 of Mercurial client.


#2

For resolving this issue I add this:

diff --git a/src/applications/diffusion/controller/DiffusionServeController.php b/src/applications/diffusion/controller/DiffusionS
erveController.php
index 5a5c446a2..859e5c119 100644
--- a/src/applications/diffusion/controller/DiffusionServeController.php
+++ b/src/applications/diffusion/controller/DiffusionServeController.php
@@ -807,6 +807,9 @@ final class DiffusionServeController extends DiffusionController {
       list($length, $body) = explode("\n", $stdout, 2);
       if ($cmd == 'capabilities') {
         $body = DiffusionMercurialWireProtocol::filterBundle2Capability($body);
+        if (strpos($body, 'httpheader') == false) {
+            $body = $body." httpheader=1024";
+        }
       }
     }