Page MenuHomePhabricator

D14241.diff
No OneTemporary

D14241.diff

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
@@ -618,6 +618,7 @@
'DiffusionMercurialServeSSHWorkflow' => 'applications/diffusion/ssh/DiffusionMercurialServeSSHWorkflow.php',
'DiffusionMercurialWireClientSSHProtocolChannel' => 'applications/diffusion/ssh/DiffusionMercurialWireClientSSHProtocolChannel.php',
'DiffusionMercurialWireProtocol' => 'applications/diffusion/protocol/DiffusionMercurialWireProtocol.php',
+ 'DiffusionMercurialWireProtocolTests' => 'applications/diffusion/protocol/__tests__/DiffusionMercurialWireProtocolTests.php',
'DiffusionMercurialWireSSHTestCase' => 'applications/diffusion/ssh/__tests__/DiffusionMercurialWireSSHTestCase.php',
'DiffusionMergedCommitsQueryConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionMergedCommitsQueryConduitAPIMethod.php',
'DiffusionMirrorDeleteController' => 'applications/diffusion/controller/DiffusionMirrorDeleteController.php',
@@ -4341,6 +4342,7 @@
'DiffusionMercurialServeSSHWorkflow' => 'DiffusionMercurialSSHWorkflow',
'DiffusionMercurialWireClientSSHProtocolChannel' => 'PhutilProtocolChannel',
'DiffusionMercurialWireProtocol' => 'Phobject',
+ 'DiffusionMercurialWireProtocolTests' => 'PhabricatorTestCase',
'DiffusionMercurialWireSSHTestCase' => 'PhabricatorTestCase',
'DiffusionMergedCommitsQueryConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod',
'DiffusionMirrorDeleteController' => 'DiffusionController',
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,12 +536,14 @@
$body = strlen($stderr)."\n".$stderr;
} else {
list($length, $body) = explode("\n", $stdout, 2);
+ if ($cmd == 'capabilities') {
+ $body = DiffusionMercurialWireProtocol::filterBundle2Capability($body);
+ }
}
return id(new DiffusionMercurialResponse())->setContent($body);
}
-
private function getMercurialArguments() {
// Mercurial sends arguments in HTTP headers. "Why?", you might wonder,
// "Why would you do this?".
diff --git a/src/applications/diffusion/protocol/DiffusionMercurialWireProtocol.php b/src/applications/diffusion/protocol/DiffusionMercurialWireProtocol.php
--- a/src/applications/diffusion/protocol/DiffusionMercurialWireProtocol.php
+++ b/src/applications/diffusion/protocol/DiffusionMercurialWireProtocol.php
@@ -99,4 +99,34 @@
return true;
}
+ /** If the server version is running 3.4+ it will respond
+ * with 'bundle2' capability 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 static function filterBundle2Capability($capabilities) {
+ $parts = explode(' ', $capabilities);
+ foreach ($parts as $key => $part) {
+ if (preg_match('/^bundle2=/', $part)) {
+ unset($parts[$key]);
+ break;
+ }
+ }
+ return implode(' ', $parts);
+ }
+
}
diff --git a/src/applications/diffusion/protocol/__tests__/DiffusionMercurialWireProtocolTests.php b/src/applications/diffusion/protocol/__tests__/DiffusionMercurialWireProtocolTests.php
new file mode 100644
--- /dev/null
+++ b/src/applications/diffusion/protocol/__tests__/DiffusionMercurialWireProtocolTests.php
@@ -0,0 +1,48 @@
+<?php
+
+final class DiffusionMercurialWireProtocolTests extends PhabricatorTestCase {
+
+ public function testFilteringBundle2Capability() {
+ // this was the result of running 'capabilities' over
+ // `hg serve --stdio` on my systems with Mercurial 3.5.1, 2.6.2
+
+ $capabilities_with_bundle2_hg_351 =
+ 'lookup changegroupsubset branchmap pushkey '.
+ 'known getbundle unbundlehash batch stream '.
+ 'bundle2=HG20%0Achangegroup%3D01%2C02%0Adigests%3Dmd5%2Csha1%2Csha512'.
+ '%0Aerror%3Dabort%2Cunsupportedcontent%2Cpushraced%2Cpushkey%0A'.
+ 'hgtagsfnodes%0Alistkeys%0Apushkey%0Aremote-changegroup%3Dhttp%2Chttps '.
+ 'unbundle=HG10GZ,HG10BZ,HG10UN httpheader=1024';
+
+ $capabilities_without_bundle2_hg_351 =
+ 'lookup changegroupsubset branchmap pushkey '.
+ 'known getbundle unbundlehash batch stream '.
+ 'unbundle=HG10GZ,HG10BZ,HG10UN httpheader=1024';
+
+ $capabilities_hg_262 =
+ 'lookup changegroupsubset branchmap pushkey '.
+ 'known getbundle unbundlehash batch stream '.
+ 'unbundle=HG10GZ,HG10BZ,HG10UN httpheader=1024 largefiles=serve';
+
+ $cases = array(
+ array(
+ 'name' => pht('Filter bundle2 from Mercurial 3.5.1'),
+ 'input' => $capabilities_with_bundle2_hg_351,
+ 'expect' => $capabilities_without_bundle2_hg_351,
+ ),
+
+ array(
+ 'name' => pht('Filter bundle does not affect Mercurial 2.6.2'),
+ 'input' => $capabilities_hg_262,
+ 'expect' => $capabilities_hg_262,
+ ),
+ );
+
+ foreach ($cases as $case) {
+ $actual = DiffusionMercurialWireProtocol::filterBundle2Capability(
+ $case['input']);
+ $this->assertEqual($case['expect'], $actual, $case['name']);
+ }
+ }
+
+}
diff --git a/src/applications/diffusion/ssh/DiffusionMercurialServeSSHWorkflow.php b/src/applications/diffusion/ssh/DiffusionMercurialServeSSHWorkflow.php
--- a/src/applications/diffusion/ssh/DiffusionMercurialServeSSHWorkflow.php
+++ b/src/applications/diffusion/ssh/DiffusionMercurialServeSSHWorkflow.php
@@ -107,8 +107,14 @@
$this->didSeeWrite = true;
}
+ $raw_message = $message['raw'];
+ if ($command == 'capabilities') {
+ $raw_message = DiffusionMercurialWireProtocol::filterBundle2Capability(
+ $raw_message);
+ }
+
// If we're good, return the raw message data.
- return $message['raw'];
+ return $raw_message;
}
}

File Metadata

Mime Type
text/plain
Expires
Sun, Nov 3, 10:01 AM (2 w, 2 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6715654
Default Alt Text
D14241.diff (6 KB)

Event Timeline