diff --git a/django/core/handlers/wsgi.py b/django/core/handlers/wsgi.py index 4e82bc36d7..537154c0cb 100644 --- a/django/core/handlers/wsgi.py +++ b/django/core/handlers/wsgi.py @@ -96,9 +96,10 @@ class LimitedStream(object): return result def readline(self, size=None): - while '\n' not in self.buffer or \ - (size is not None and len(self.buffer) < size): + while '\n' not in self.buffer and \ + (size is None or len(self.buffer) < size): if size: + # since size is not None here, len(self.buffer) < size chunk = self._read_limited(size - len(self.buffer)) else: chunk = self._read_limited() diff --git a/tests/regressiontests/requests/tests.py b/tests/regressiontests/requests/tests.py index b1d80fe30e..a80ee9d571 100644 --- a/tests/regressiontests/requests/tests.py +++ b/tests/regressiontests/requests/tests.py @@ -102,15 +102,21 @@ class RequestsTests(unittest.TestCase): # Read all of a limited stream stream = LimitedStream(StringIO('test'), 2) self.assertEqual(stream.read(), 'te') + # Reading again returns nothing. + self.assertEqual(stream.read(), '') # Read a number of characters greater than the stream has to offer stream = LimitedStream(StringIO('test'), 2) self.assertEqual(stream.read(5), 'te') + # Reading again returns nothing. + self.assertEqual(stream.readline(5), '') # Read sequentially from a stream stream = LimitedStream(StringIO('12345678'), 8) self.assertEqual(stream.read(5), '12345') self.assertEqual(stream.read(5), '678') + # Reading again returns nothing. + self.assertEqual(stream.readline(5), '') # Read lines from a stream stream = LimitedStream(StringIO('1234\n5678\nabcd\nefgh\nijkl'), 24) @@ -129,6 +135,26 @@ class RequestsTests(unittest.TestCase): # Read everything else. self.assertEqual(stream.readline(), 'ijkl') + # Regression for #15018 + # If a stream contains a newline, but the provided length + # is less than the number of provided characters, the newline + # doesn't reset the available character count + stream = LimitedStream(StringIO('1234\nabcdef'), 9) + self.assertEqual(stream.readline(10), '1234\n') + self.assertEqual(stream.readline(3), 'abc') + # Now expire the available characters + self.assertEqual(stream.readline(3), 'd') + # Reading again returns nothing. + self.assertEqual(stream.readline(2), '') + + # Same test, but with read, not readline. + stream = LimitedStream(StringIO('1234\nabcdef'), 9) + self.assertEqual(stream.read(6), '1234\na') + self.assertEqual(stream.read(2), 'bc') + self.assertEqual(stream.read(2), 'd') + self.assertEqual(stream.read(2), '') + self.assertEqual(stream.read(), '') + def test_stream(self): request = WSGIRequest({'REQUEST_METHOD': 'POST', 'wsgi.input': StringIO('name=value')}) self.assertEqual(request.read(), 'name=value')