diff options
author | Jeremy Hylton <jeremy@alum.mit.edu> | 2002-09-03 20:49:06 (GMT) |
---|---|---|
committer | Jeremy Hylton <jeremy@alum.mit.edu> | 2002-09-03 20:49:06 (GMT) |
commit | d4c472c3e21c0823c2c1bdf115e262846e2ba843 (patch) | |
tree | c7ddc5c732b2b4f2f71dbca87703b8aa908c4bda /Lib/httplib.py | |
parent | 066a8df3a4cdd47ce4d8a48a1e35509924ea7984 (diff) | |
download | cpython-d4c472c3e21c0823c2c1bdf115e262846e2ba843.zip cpython-d4c472c3e21c0823c2c1bdf115e262846e2ba843.tar.gz cpython-d4c472c3e21c0823c2c1bdf115e262846e2ba843.tar.bz2 |
Move code for reading chunked responses in helper function,
along with some small changes (e.g. use of +=).
Diffstat (limited to 'Lib/httplib.py')
-rw-r--r-- | Lib/httplib.py | 97 |
1 files changed, 52 insertions, 45 deletions
diff --git a/Lib/httplib.py b/Lib/httplib.py index b9dc6e9..e6dc898 100644 --- a/Lib/httplib.py +++ b/Lib/httplib.py @@ -370,50 +370,9 @@ class HTTPResponse: return '' if self.chunked: - assert self.chunked != _UNKNOWN - chunk_left = self.chunk_left - value = '' - while 1: - if chunk_left is None: - line = self.fp.readline() - i = line.find(';') - if i >= 0: - line = line[:i] # strip chunk-extensions - chunk_left = int(line, 16) - if chunk_left == 0: - break - if amt is None: - value = value + self._safe_read(chunk_left) - elif amt < chunk_left: - value = value + self._safe_read(amt) - self.chunk_left = chunk_left - amt - return value - elif amt == chunk_left: - value = 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 = value + self._safe_read(chunk_left) - amt = 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 1: - line = self.fp.readline() - if line == '\r\n': - break - - # we read everything; close the "file" - self.close() - - return value - - elif amt is None: + return self._read_chunked(amt) + + if amt is None: # unbounded read if self.will_close: s = self.fp.read() @@ -426,7 +385,7 @@ class HTTPResponse: if amt > self.length: # clip the read to the "end of response" amt = self.length - self.length = self.length - amt + self.length -= amt # we do not use _safe_read() here because this may be a .will_close # connection, and the user is reading more bytes than will be provided @@ -435,6 +394,54 @@ class HTTPResponse: return s + def _read_chunked(self, amt): + assert self.chunked != _UNKNOWN + 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 1: + if chunk_left is None: + line = self.fp.readline() + i = line.find(';') + if i >= 0: + line = line[:i] # strip chunk-extensions + chunk_left = int(line, 16) + 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 1: + line = self.fp.readline() + if line == '\r\n': + break + + # we read everything; close the "file" + # XXX Shouldn't the client close the file? + self.close() + + return value + def _safe_read(self, amt): """Read the number of bytes requested, compensating for partial reads. |