diff --git a/mercurial/sshpeer.py b/mercurial/sshpeer.py --- a/mercurial/sshpeer.py +++ b/mercurial/sshpeer.py @@ -466,25 +466,40 @@ return self._sendrequest(cmd, args, framed=True).read() def _callpush(self, cmd, fp, **args): + # The server responds with an empty frame if the client should + # continue submitting the payload. r = self._call(cmd, **args) if r: return '', r + + # The payload consists of frames with content followed by an empty + # frame. for d in iter(lambda: fp.read(4096), ''): self._writeframed(d) self._writeframed("", flush=True) + + # In case of success, there is an empty frame and a frame containing + # the integer result (as a string). + # In case of error, there is a non-empty frame containing the error. r = self._readframed() if r: return '', r return self._readframed(), '' def _calltwowaystream(self, cmd, fp, **args): + # The server responds with an empty frame if the client should + # continue submitting the payload. r = self._call(cmd, **args) if r: # XXX needs to be made better raise error.Abort(_('unexpected remote reply: %s') % r) + + # The payload consists of frames with content followed by an empty + # frame. for d in iter(lambda: fp.read(4096), ''): self._writeframed(d) self._writeframed("", flush=True) + return self._pipei def _getamount(self): diff --git a/mercurial/wireprotoserver.py b/mercurial/wireprotoserver.py --- a/mercurial/wireprotoserver.py +++ b/mercurial/wireprotoserver.py @@ -347,12 +347,16 @@ return [data[k] for k in keys] 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 + # interprets it as an error. + _sshv1respondbytes(self._fout, b'') + # The file is in the form: # # \n # ... # 0\n - _sshv1respondbytes(self._fout, b'') count = int(self._fin.readline()) while count: fpout.write(self._fin.read(count))