diff -r a4f02a17420d -r afcfdf53e4b5 mercurial/wireprotoserver.py --- a/mercurial/wireprotoserver.py Thu Apr 05 17:51:10 2018 +0200 +++ b/mercurial/wireprotoserver.py Sat Mar 24 17:57:22 2018 +0100 @@ -67,6 +67,7 @@ self._req = req self._ui = ui self._checkperm = checkperm + self._protocaps = None @property def name(self): @@ -99,6 +100,12 @@ args.update(urlreq.parseqs(argvalue, keep_blank_values=True)) return args + def getprotocaps(self): + if self._protocaps is None: + value = decodevaluefromheaders(self._req, r'X-HgProto') + self._protocaps = set(value.split(' ')) + return self._protocaps + def forwardpayload(self, fp): # Existing clients *always* send Content-Length. length = int(self._req.headers[b'Content-Length']) @@ -599,6 +606,10 @@ return [data[k] for k in args.split()] + def getprotocaps(self): + # Protocol capabilities are currently not implemented for HTTP V2. + return set() + def forwardpayload(self, fp): raise NotImplementedError @@ -615,28 +626,21 @@ def checkperm(self, perm): raise NotImplementedError -def _httpresponsetype(ui, req, prefer_uncompressed): +def _httpresponsetype(ui, proto, prefer_uncompressed): """Determine the appropriate response type and compression settings. Returns a tuple of (mediatype, compengine, engineopts). """ # Determine the response media type and compression engine based # on the request parameters. - protocaps = decodevaluefromheaders(req, 'X-HgProto').split(' ') - if '0.2' in protocaps: + if '0.2' in proto.getprotocaps(): # All clients are expected to support uncompressed data. if prefer_uncompressed: return HGTYPE2, util._noopengine(), {} - # Default as defined by wire protocol spec. - compformats = ['zlib', 'none'] - for cap in protocaps: - if cap.startswith('comp='): - compformats = cap[5:].split(',') - break - # Now find an agreed upon compression format. + compformats = wireproto.clientcompressionsupport(proto) for engine in wireproto.supportedcompengines(ui, util.SERVERROLE): if engine.wireprotosupport().name in compformats: opts = {} @@ -705,7 +709,7 @@ # This code for compression should not be streamres specific. It # is here because we only compress streamres at the moment. mediatype, engine, engineopts = _httpresponsetype( - repo.ui, req, rsp.prefer_uncompressed) + repo.ui, proto, rsp.prefer_uncompressed) gen = engine.compressstream(gen, engineopts) if mediatype == HGTYPE2: @@ -749,6 +753,7 @@ self._ui = ui self._fin = fin self._fout = fout + self._protocaps = set() @property def name(self): @@ -775,6 +780,9 @@ data[arg] = val return [data[k] for k in keys] + def getprotocaps(self): + return self._protocaps + def forwardpayload(self, fpout): # We initially send an empty response. This tells the client it is # OK to start sending data. If a client sees any other response, it @@ -800,6 +808,8 @@ return 'remote:ssh:' + client def addcapabilities(self, repo, caps): + if self.name == wireprototypes.SSHV1: + caps.append(b'protocaps') caps.append(b'batch') return caps