diff options
author | atsuo ishimoto <atsuoishimoto@gmail.com> | 2019-07-07 00:43:59 +0900 |
---|---|---|
committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2019-07-10 13:22:17 +0200 |
commit | a9c6ab03560424ed7dff24849c8ddaa3e1eae62e (patch) | |
tree | c1f53269e1b7edcfb568efc20275e9cdc82a40fb /tests/servers | |
parent | 00d4e6f8b587dcea147c51ece253dc54c461a11d (diff) | |
download | django-a9c6ab03560424ed7dff24849c8ddaa3e1eae62e.tar.gz |
Fixed #30619 -- Made runserver --nothreading use single threaded WSGIServer.
Browsers often use multiple connections with Connection: keep-alive.
If --nothreading is specified, the WSGI server cannot accept new
connections until the old connection is closed, causing hangs.
Force Connection: close when --nothreading option is used.
Diffstat (limited to 'tests/servers')
-rw-r--r-- | tests/servers/tests.py | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/tests/servers/tests.py b/tests/servers/tests.py index 1f111fb5ae..243b5a4200 100644 --- a/tests/servers/tests.py +++ b/tests/servers/tests.py @@ -9,7 +9,9 @@ from urllib.error import HTTPError from urllib.parse import urlencode from urllib.request import urlopen +from django.core.servers.basehttp import WSGIServer from django.test import LiveServerTestCase, override_settings +from django.test.testcases import LiveServerThread, QuietWSGIRequestHandler from .models import Person @@ -50,6 +52,15 @@ class LiveServerAddress(LiveServerBase): self.assertEqual(self.live_server_url_test[0], self.live_server_url) +class LiveServerSingleThread(LiveServerThread): + def _create_server(self): + return WSGIServer((self.host, self.port), QuietWSGIRequestHandler, allow_reuse_address=False) + + +class SingleThreadLiveServerTestCase(LiveServerTestCase): + server_thread_class = LiveServerSingleThread + + class LiveServerViews(LiveServerBase): def test_protocol(self): """Launched server serves with HTTP 1.1.""" @@ -162,6 +173,32 @@ class LiveServerViews(LiveServerBase): self.assertIn(b"QUERY_STRING: 'q=%D1%82%D0%B5%D1%81%D1%82'", f.read()) +@override_settings(ROOT_URLCONF='servers.urls') +class SingleTreadLiveServerViews(SingleThreadLiveServerTestCase): + available_apps = ['servers'] + + def test_closes_connection_with_content_length(self): + """ + Contrast to + LiveServerViews.test_keep_alive_on_connection_with_content_length(). + Persistent connections require threading server. + """ + conn = HTTPConnection( + SingleTreadLiveServerViews.server_thread.host, + SingleTreadLiveServerViews.server_thread.port, + timeout=1, + ) + try: + conn.request('GET', '/example_view/', headers={'Connection': 'keep-alive'}) + response = conn.getresponse() + self.assertTrue(response.will_close) + self.assertEqual(response.read(), b'example view') + self.assertEqual(response.status, 200) + self.assertEqual(response.getheader('Connection'), 'close') + finally: + conn.close() + + class LiveServerDatabase(LiveServerBase): def test_fixtures_loaded(self): |