Fixed #28440 -- Fixed WSGIServer hang on responses without a Content-Length.

Disabled keep-alive to fix the regression in
e6065c7b83.
This commit is contained in:
Tom 2017-07-28 15:10:13 +01:00 committed by Tim Graham
parent 2a4b331348
commit ac756f16c5
2 changed files with 31 additions and 19 deletions

View File

@ -135,13 +135,6 @@ class WSGIRequestHandler(simple_server.WSGIRequestHandler):
return super().get_environ()
def handle(self):
"""Handle multiple requests if necessary."""
self.close_connection = 1
self.handle_one_request()
while not self.close_connection:
self.handle_one_request()
def handle_one_request(self):
"""Copy of WSGIRequestHandler.handle() but with different ServerHandler"""
self.raw_requestline = self.rfile.readline(65537)
if len(self.raw_requestline) > 65536:

View File

@ -4,16 +4,21 @@ Tests for django.core.servers.
import errno
import os
import socket
import sys
from http.client import HTTPConnection
from urllib.error import HTTPError
from urllib.parse import urlencode
from urllib.request import urlopen
from django.test import LiveServerTestCase, override_settings
from django.test.utils import captured_stdout
from .models import Person
try:
from http.client import RemoteDisconnected
except ImportError: # Python 3.4
from http.client import BadStatusLine as RemoteDisconnected
TEST_ROOT = os.path.dirname(__file__)
TEST_SETTINGS = {
'MEDIA_URL': '/media/',
@ -54,17 +59,31 @@ class LiveServerAddress(LiveServerBase):
class LiveServerViews(LiveServerBase):
def test_protocol(self):
"""Launched server serves with HTTP 1.1."""
with captured_stdout() as debug_output:
conn = HTTPConnection(LiveServerViews.server_thread.host, LiveServerViews.server_thread.port)
with self.urlopen('/example_view/') as f:
self.assertEqual(f.version, 11)
@override_settings(MIDDLEWARE=[])
def test_closes_connection_without_content_length(self):
"""
The server doesn't support keep-alive because Python's http.server
module that it uses hangs if a Content-Length header isn't set (for
example, if CommonMiddleware isn't enabled or if the response is a
StreamingHttpResponse) (#28440 / https://bugs.python.org/issue31076).
"""
conn = HTTPConnection(LiveServerViews.server_thread.host, LiveServerViews.server_thread.port, timeout=1)
try:
conn.request('GET', '/example_view/', headers={'Connection': 'keep-alive'})
response = conn.getresponse().read()
conn.request('GET', '/example_view/', headers={'Connection': 'close'})
with self.assertRaises(RemoteDisconnected, msg='Server did not close the connection'):
try:
conn.set_debuglevel(1)
conn.request('GET', '/example_view/', headers={"Connection": "keep-alive"})
conn.getresponse().read()
conn.request('GET', '/example_view/', headers={"Connection": "close"})
conn.getresponse()
except ConnectionAbortedError:
if sys.platform == 'win32':
self.skipTest('Ignore nondeterministic failure on Windows.')
finally:
conn.close()
self.assertEqual(debug_output.getvalue().count("reply: 'HTTP/1.1 200 OK"), 2)
self.assertEqual(response, b'example view')
def test_404(self):
with self.assertRaises(HTTPError) as err: