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.
--- 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