# HG changeset patch # User Matt Mackall # Date 1234827443 21600 # Node ID a45206455d85d41fbd674bd35e634d552de2b5bf # Parent 9892c4d94fb76df173251df15f54930472ca1b72 keepalive: borrow code from newer httplib to patch ValueError (issue1088) diff -r 9892c4d94fb7 -r a45206455d85 mercurial/keepalive.py --- a/mercurial/keepalive.py Mon Feb 16 17:37:23 2009 -0600 +++ b/mercurial/keepalive.py Mon Feb 16 17:37:23 2009 -0600 @@ -389,6 +389,63 @@ self._rbuf = '' return s + # stolen from Python SVN #68532 to fix issue1088 + def _read_chunked(self, amt): + chunk_left = self.chunk_left + value = '' + + # XXX This accumulates chunks by repeated string concatenation, + # which is not efficient as the number or size of chunks gets big. + while True: + if chunk_left is None: + line = self.fp.readline() + i = line.find(';') + if i >= 0: + line = line[:i] # strip chunk-extensions + try: + chunk_left = int(line, 16) + except ValueError: + # close the connection as protocol synchronisation is + # probably lost + self.close() + raise IncompleteRead(value) + if chunk_left == 0: + break + if amt is None: + value += self._safe_read(chunk_left) + elif amt < chunk_left: + value += self._safe_read(amt) + self.chunk_left = chunk_left - amt + return value + elif amt == chunk_left: + value += self._safe_read(amt) + self._safe_read(2) # toss the CRLF at the end of the chunk + self.chunk_left = None + return value + else: + value += self._safe_read(chunk_left) + amt -= chunk_left + + # we read the whole chunk, get another + self._safe_read(2) # toss the CRLF at the end of the chunk + chunk_left = None + + # read and discard trailer up to the CRLF terminator + ### note: we shouldn't have any trailers! + while True: + line = self.fp.readline() + if not line: + # a vanishingly small number of sites EOF without + # sending the trailer + break + if line == '\r\n': + break + + # we read everything; close the "file" + self.close() + + return value + def readline(self, limit=-1): data = "" i = self._rbuf.find('\n')