wireproto: avoid exposing pushkey abort for server without evolution stable
authorPierre-Yves David <pierre-yves.david@octobus.net>
Tue, 07 Nov 2017 12:10:22 +0100
branchstable
changeset 3172 aed2cac9edc3
parent 3171 dbd340eafcb0
child 3173 3afe20410b55
wireproto: avoid exposing pushkey abort for server without evolution Client with evolution enabled will query the 'obsolete' pushley namespace if no other way to request obsmarkers have been found. They will do this unconditionally as long as no other obsolescence related capabilities have been advertised by the server. The call is "harmless" since the namespace will be empty if obsmarkers exchange is disabled. However, since we forbid the use of pushkey for obsmarkers this lead to unexpected crash report for up to date client talking to a server with the evolve extensions but exchange disabled. We fix the issue by serving the expected empty namespace in this case. We keep forbidding the query if obsmarker exchange is enabled since new client should have picked another more effective was to fetch the data first. We also add some tests for this logic.
hgext3rd/evolve/obsexchange.py
tests/test-wireproto.t
--- a/hgext3rd/evolve/obsexchange.py	Thu Nov 02 19:22:32 2017 +0100
+++ b/hgext3rd/evolve/obsexchange.py	Tue Nov 07 12:10:22 2017 +0100
@@ -201,6 +201,12 @@
     """prevent exchange through pushkey"""
     raise error.Abort(abortmsg, hint=hint)
 
+def forbidlistkey(repo=None, key=None, old=None, new=None):
+    """prevent exchange through pushkey"""
+    if obsolete.isenabled(repo, obsolete.exchangeopt):
+        raise error.Abort(abortmsg, hint=hint)
+    return {}
+
 @eh.uisetup
 def setuppushkeyforbidding(ui):
-    pushkey._namespaces['obsolete'] = (forbidpushkey, forbidpushkey)
+    pushkey._namespaces['obsolete'] = (forbidpushkey, forbidlistkey)
--- a/tests/test-wireproto.t	Thu Nov 02 19:22:32 2017 +0100
+++ b/tests/test-wireproto.t	Tue Nov 07 12:10:22 2017 +0100
@@ -187,13 +187,29 @@
   (controled by 'experimental.evolution.obsdiscovery' configuration)
   obsmarker-exchange: 258 bytes received
 
+  $ cd ..
+
 And disable it server side too:
 
-  $ hg serve -R ../server -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log  --config experimental.evolution.obsdiscovery=no
+  $ hg serve -R server -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log  --config experimental.evolution.obsdiscovery=no
   $ cat hg.pid >> $DAEMON_PIDS
 
   $ curl -s http://localhost:$HGPORT/?cmd=capabilities
   _evoext_getbundle_obscommon batch branchmap bundle2=HG20%0Achangegroup%3D01%2C02%0Adigests%3Dmd5%2Csha1%2Csha512%0Aerror%3Dabort%2Cunsupportedcontent%2Cpushraced%2Cpushkey%0Ahgtagsfnodes%0Alistkeys%0Aobsmarkers%3DV0%2CV1%0Aphases%3Dheads%0Apushkey%0Aremote-changegroup%3Dhttp%2Chttps changegroupsubset compression=zstd,zlib getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (no-eol)
-  $ $RUNTESTDIR/killdaemons.py $DAEMON_PIDS
+
+Check we cannot use pushkey for marker exchange anymore
 
-  $ cd ..
+  $ hg debugpushkey http://localhost:$HGPORT/ obsolete
+  abort: HTTP Error 500: Internal Server Error
+  [255]
+  $ hg debugpushkey ssh://user@dummy/server obsolete
+  remote: abort: won't exchange obsmarkers through pushkey
+  remote: (upgrade your client or server to use the bundle2 protocol)
+  abort: unexpected response: empty string
+  [255]
+
+But we do let it goes fine on repository with exchange disabled:
+
+  $ $RUNTESTDIR/killdaemons.py $DAEMON_PIDS
+  $ hg serve -R server -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log  --config experimental.evolution='!'
+  $ hg debugpushkey http://localhost:$HGPORT/ obsolete