diff options
| author | Matthew Wood <woodm1979@gmail.com> | 2013-03-18 16:06:24 -0600 |
|---|---|---|
| committer | Simon Charette <charette.s@gmail.com> | 2013-03-20 18:46:26 -0400 |
| commit | a7960bcb3575fd9fcd5180986ddcdba1caa46dd5 (patch) | |
| tree | 8cbe5a463ed41e919ab44afc925bf1cb18995272 /tests/builtin_server | |
| parent | 80e68ee2ffb44d90c66b48e2db18ec4e16c025b4 (diff) | |
Fixed #18972 -- Refactored bundled wsgi server's chunking algorithm.
Thanks to amosonn at yahoo.com for the report, @doda for the initial patch and
@datagrok for the revamped logic and test case.
Diffstat (limited to 'tests/builtin_server')
| -rw-r--r-- | tests/builtin_server/tests.py | 63 |
1 files changed, 55 insertions, 8 deletions
diff --git a/tests/builtin_server/tests.py b/tests/builtin_server/tests.py index 041bb3c319..662466a110 100644 --- a/tests/builtin_server/tests.py +++ b/tests/builtin_server/tests.py @@ -2,22 +2,18 @@ from __future__ import unicode_literals from io import BytesIO -from django.core.servers.basehttp import ServerHandler +from django.core.servers.basehttp import ServerHandler, MAX_SOCKET_CHUNK_SIZE from django.utils.unittest import TestCase -# -# Tests for #9659: wsgi.file_wrapper in the builtin server. -# We need to mock a couple of handlers and keep track of what -# gets called when using a couple kinds of WSGI apps. -# class DummyHandler(object): - def log_request(*args, **kwargs): + def log_request(self, *args, **kwargs): pass + class FileWrapperHandler(ServerHandler): def __init__(self, *args, **kwargs): - ServerHandler.__init__(self, *args, **kwargs) + super(FileWrapperHandler, self).__init__(*args, **kwargs) self.request_handler = DummyHandler() self._used_sendfile = False @@ -25,17 +21,24 @@ class FileWrapperHandler(ServerHandler): self._used_sendfile = True return True + def wsgi_app(environ, start_response): start_response(str('200 OK'), [(str('Content-Type'), str('text/plain'))]) return [b'Hello World!'] + def wsgi_app_file_wrapper(environ, start_response): start_response(str('200 OK'), [(str('Content-Type'), str('text/plain'))]) return environ['wsgi.file_wrapper'](BytesIO(b'foo')) + class WSGIFileWrapperTests(TestCase): """ Test that the wsgi.file_wrapper works for the builting server. + + Tests for #9659: wsgi.file_wrapper in the builtin server. + We need to mock a couple of handlers and keep track of what + gets called when using a couple kinds of WSGI apps. """ def test_file_wrapper_uses_sendfile(self): @@ -53,3 +56,47 @@ class WSGIFileWrapperTests(TestCase): self.assertFalse(handler._used_sendfile) self.assertEqual(handler.stdout.getvalue().splitlines()[-1], b'Hello World!') self.assertEqual(handler.stderr.getvalue(), b'') + + +class WriteChunkCounterHandler(ServerHandler): + """ + Server handler that counts the number of chunks written after headers were + sent. Used to make sure large response body chunking works properly. + """ + + def __init__(self, *args, **kwargs): + super(WriteChunkCounterHandler, self).__init__(*args, **kwargs) + self.request_handler = DummyHandler() + self.headers_written = False + self.write_chunk_counter = 0 + + def send_headers(self): + super(WriteChunkCounterHandler, self).send_headers() + self.headers_written = True + + def _write(self, data): + if self.headers_written: + self.write_chunk_counter += 1 + self.stdout.write(data) + + +def send_big_data_app(environ, start_response): + start_response(str('200 OK'), [(str('Content-Type'), str('text/plain'))]) + # Return a blob of data that is 1.5 times the maximum chunk size. + return [b'x' * (MAX_SOCKET_CHUNK_SIZE + MAX_SOCKET_CHUNK_SIZE // 2)] + + +class ServerHandlerChunksProperly(TestCase): + """ + Test that the ServerHandler chunks data properly. + + Tests for #18972: The logic that performs the math to break data into + 32MB (MAX_SOCKET_CHUNK_SIZE) chunks was flawed, BUT it didn't actually + cause any problems. + """ + + def test_chunked_data(self): + env = {'SERVER_PROTOCOL': 'HTTP/1.0'} + handler = WriteChunkCounterHandler(None, BytesIO(), BytesIO(), env) + handler.run(send_big_data_app) + self.assertEqual(handler.write_chunk_counter, 2) |
