From 869e133d6b164c740cbe224235058424ae9ad11e Mon Sep 17 00:00:00 2001 From: dalazx Date: Tue, 11 Oct 2016 20:07:24 +0300 Subject: [PATCH] Fixed StreamReader._read_nowait (#1297) * Fixed StreamReader._read_nowait * Added an entry to CHANGES --- CHANGES.rst | 3 ++- aiohttp/streams.py | 20 +++++++++++++++----- tests/test_streams.py | 22 ++++++++++++++++++++++ 3 files changed, 39 insertions(+), 6 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 9610131e0ff..064b972fa85 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,7 +4,8 @@ CHANGES 1.0.5 (XXXX-XX-XX) ------------------ -- +- Fix StreamReader._read_nowait to return all available + data up to the requested amount - diff --git a/aiohttp/streams.py b/aiohttp/streams.py index c47cfb86912..fbe8d67efa8 100644 --- a/aiohttp/streams.py +++ b/aiohttp/streams.py @@ -242,7 +242,7 @@ def readline(self): offset = self._buffer_offset ichar = self._buffer[0].find(b'\n', offset) + 1 # Read from current offset to found b'\n' or to the end. - data = self._read_nowait(ichar - offset if ichar else -1) + data = self._read_nowait_chunk(ichar - offset if ichar else -1) line.append(data) line_size += len(data) if ichar: @@ -340,10 +340,7 @@ def read_nowait(self, n=-1): return self._read_nowait(n) - def _read_nowait(self, n): - if not self._buffer: - return EOF_MARKER - + def _read_nowait_chunk(self, n): first_buffer = self._buffer[0] offset = self._buffer_offset if n != -1 and len(first_buffer) - offset > n: @@ -361,6 +358,19 @@ def _read_nowait(self, n): self._buffer_size -= len(data) return data + def _read_nowait(self, n): + chunks = [] + + while self._buffer: + chunk = self._read_nowait_chunk(n) + chunks.append(chunk) + if n != -1: + n -= len(chunk) + if n == 0: + break + + return b''.join(chunks) if chunks else EOF_MARKER + class EmptyStreamReader(AsyncStreamReaderMixin): diff --git a/tests/test_streams.py b/tests/test_streams.py index dbee463cf6f..0be2c104430 100644 --- a/tests/test_streams.py +++ b/tests/test_streams.py @@ -124,6 +124,28 @@ def test_read_line_breaks(self): data = self.loop.run_until_complete(stream.read(5)) self.assertEqual(b'line2', data) + def test_read_all(self): + # Read all avaliable buffered bytes + stream = self._make_one() + stream.feed_data(b'line1') + stream.feed_data(b'line2') + stream.feed_eof() + + data = self.loop.run_until_complete(stream.read()) + self.assertEqual(b'line1line2', data) + + def test_read_up_to(self): + # Read available buffered bytes up to requested amount + stream = self._make_one() + stream.feed_data(b'line1') + stream.feed_data(b'line2') + + data = self.loop.run_until_complete(stream.read(8)) + self.assertEqual(b'line1lin', data) + + data = self.loop.run_until_complete(stream.read(8)) + self.assertEqual(b'e2', data) + def test_read_eof(self): # Read bytes, stop at eof. stream = self._make_one()