diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -711,6 +711,7 @@ 'DiffusionSSHWorkflow' => 'applications/diffusion/ssh/DiffusionSSHWorkflow.php', 'DiffusionSearchQueryConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionSearchQueryConduitAPIMethod.php', 'DiffusionServeController' => 'applications/diffusion/controller/DiffusionServeController.php', + 'DiffusionServeControllerTests' => 'applications/diffusion/controller/__tests__/DiffusionServeControllerTests.php', 'DiffusionSetPasswordSettingsPanel' => 'applications/diffusion/panel/DiffusionSetPasswordSettingsPanel.php', 'DiffusionSetupException' => 'applications/diffusion/exception/DiffusionSetupException.php', 'DiffusionSubversionSSHWorkflow' => 'applications/diffusion/ssh/DiffusionSubversionSSHWorkflow.php', @@ -4434,6 +4435,7 @@ 'DiffusionSSHWorkflow' => 'PhabricatorSSHWorkflow', 'DiffusionSearchQueryConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod', 'DiffusionServeController' => 'DiffusionController', + 'DiffusionServeControllerTests' => 'PhabricatorTestCase', 'DiffusionSetPasswordSettingsPanel' => 'PhabricatorSettingsPanel', 'DiffusionSetupException' => 'Exception', 'DiffusionSubversionSSHWorkflow' => 'DiffusionSSHWorkflow', diff --git a/src/applications/diffusion/controller/DiffusionServeController.php b/src/applications/diffusion/controller/DiffusionServeController.php --- a/src/applications/diffusion/controller/DiffusionServeController.php +++ b/src/applications/diffusion/controller/DiffusionServeController.php @@ -536,11 +536,52 @@ $body = strlen($stderr)."\n".$stderr; } else { list($length, $body) = explode("\n", $stdout, 2); + if ($cmd == 'capabilities') { + $body = $this->removeMercurialBundle2Capability($body); + } } return id(new DiffusionMercurialResponse())->setContent($body); } + /** If the server version is running 3.4+ it will respond + * with 'bundle2' capabilit in the format of "bundle2=(url-encoding)". + * Until we maange to properly package up bundles to send back we + * disallow the client from knowing we speak bundle2 by removing it + * from the capabilities listing. + * + * The format of the capabilties string is: "a space separated list + * of strings representing what commands the server supports" + * @link https://www.mercurial-scm.org/wiki/CommandServer#Protocol + * + * @param string $capabilities - The string of capabilities to + * strip the bundle2 capability from. This is expected to be + * the space-separated list of strings resulting from the + * querying the 'capabilties' command. + * + * @return string The resulting space-separated list of capabilities + * which no longer contains the 'bundle2' capability. This is meant + * to replace the original $body to send back to client. + */ + public function removeMercurialBundle2Capability($capabilities) { + $bundle2_arg = 'bundle2='; + $bundle2_arg_len = strlen($bundle2_arg); + $capabilities_arr = explode(' ', $capabilities); + $arrindex = -1; + $found_bundle2 = false; + foreach ($capabilities_arr as $capability) { + $arrindex++; + if (substr($capability, 0, $bundle2_arg_len) == $bundle2_arg) { + $found_bundle2 = true; + break; + } + } + if ($found_bundle2 && $arrindex > -1) { + unset($capabilities_arr[$arrindex]); + } + $capabilities_without_bundle2 = implode(' ', $capabilities_arr); + return $capabilities_without_bundle2; + } private function getMercurialArguments() { // Mercurial sends arguments in HTTP headers. "Why?", you might wonder, diff --git a/src/applications/diffusion/controller/__tests__/DiffusionServeControllerTests.php b/src/applications/diffusion/controller/__tests__/DiffusionServeControllerTests.php new file mode 100644 --- /dev/null +++ b/src/applications/diffusion/controller/__tests__/DiffusionServeControllerTests.php @@ -0,0 +1,28 @@ +removeMercurialBundle2Capability($test_case); + $this->assertEqual($expected, $actual, + 'Removal of bundle2 capabilty removes from list'); + + $test_case = self::$hgCapabilities_262; + $expected = self::$hgCapabilities_262; + $actual = $controller->removeMercurialBundle2Capability($test_case); + $this->assertEqual($expected, $actual, 'Removing does not modify legacy capabilities'); + } +}