tests: wsgi: close socket on error in the middle of chunked response
http://rhodesmill.org/brandon/2013/chunked-wsgi/
This commit is contained in:
@@ -43,12 +43,35 @@ def chunked_app(env, start_response):
|
||||
yield "chunked"
|
||||
|
||||
|
||||
def chunked_fail_app(environ, start_response):
|
||||
"""http://rhodesmill.org/brandon/2013/chunked-wsgi/
|
||||
"""
|
||||
headers = [('Content-Type', 'text/plain')]
|
||||
start_response('200 OK', headers)
|
||||
|
||||
# We start streaming data just fine.
|
||||
yield "The dwarves of yore made mighty spells,"
|
||||
yield "While hammers fell like ringing bells"
|
||||
|
||||
# Then the back-end fails!
|
||||
try:
|
||||
1 / 0
|
||||
except Exception:
|
||||
start_response('500 Error', headers, sys.exc_info())
|
||||
return
|
||||
|
||||
# So rest of the response data is not available.
|
||||
yield "In places deep, where dark things sleep,"
|
||||
yield "In hollow halls beneath the fells."
|
||||
|
||||
|
||||
def big_chunks(env, start_response):
|
||||
start_response('200 OK', [('Content-type', 'text/plain')])
|
||||
line = 'a' * 8192
|
||||
for x in range(10):
|
||||
yield line
|
||||
|
||||
|
||||
def use_write(env, start_response):
|
||||
if env['PATH_INFO'] == '/a':
|
||||
write = start_response('200 OK', [('Content-type', 'text/plain'),
|
||||
@@ -59,6 +82,7 @@ def use_write(env, start_response):
|
||||
write('abcde')
|
||||
return []
|
||||
|
||||
|
||||
def chunked_post(env, start_response):
|
||||
start_response('200 OK', [('Content-type', 'text/plain')])
|
||||
if env['PATH_INFO'] == '/a':
|
||||
@@ -68,10 +92,12 @@ def chunked_post(env, start_response):
|
||||
elif env['PATH_INFO'] == '/c':
|
||||
return [x for x in iter(lambda: env['wsgi.input'].read(1), '')]
|
||||
|
||||
|
||||
def already_handled(env, start_response):
|
||||
start_response('200 OK', [('Content-type', 'text/plain')])
|
||||
return wsgi.ALREADY_HANDLED
|
||||
|
||||
|
||||
class Site(object):
|
||||
def __init__(self):
|
||||
self.application = hello_world
|
||||
@@ -79,6 +105,7 @@ class Site(object):
|
||||
def __call__(self, env, start_response):
|
||||
return self.application(env, start_response)
|
||||
|
||||
|
||||
class IterableApp(object):
|
||||
|
||||
def __init__(self, send_start_response=False, return_val=wsgi.ALREADY_HANDLED):
|
||||
@@ -92,6 +119,7 @@ class IterableApp(object):
|
||||
start_response('200 OK', [('Content-type', 'text/plain')])
|
||||
return self.return_val
|
||||
|
||||
|
||||
class IterableSite(Site):
|
||||
def __call__(self, env, start_response):
|
||||
it = self.application(env, start_response)
|
||||
@@ -99,7 +127,6 @@ class IterableSite(Site):
|
||||
yield i
|
||||
|
||||
|
||||
|
||||
CONTENT_LENGTH = 'content-length'
|
||||
|
||||
|
||||
@@ -111,6 +138,7 @@ Content-length: 11
|
||||
hello world
|
||||
"""
|
||||
|
||||
|
||||
class ConnectionClosed(Exception):
|
||||
pass
|
||||
|
||||
@@ -758,6 +786,25 @@ class TestHttpd(_TestBase):
|
||||
self.assertNotEqual(headers.get('transfer-encoding'), 'chunked')
|
||||
self.assertEquals(body, "thisischunked")
|
||||
|
||||
def test_error_in_chunked_closes_connection(self):
|
||||
# From http://rhodesmill.org/brandon/2013/chunked-wsgi/
|
||||
greenthread.kill(self.killer)
|
||||
eventlet.sleep(0)
|
||||
self.spawn_server(minimum_chunk_size=1)
|
||||
|
||||
self.site.application = chunked_fail_app
|
||||
sock = eventlet.connect(('localhost', self.port))
|
||||
|
||||
sock.sendall('GET / HTTP/1.1\r\nHost: localhost\r\n\r\n')
|
||||
|
||||
response_line, headers, body = read_http(sock)
|
||||
self.assertEqual(response_line, 'HTTP/1.1 200 OK\r\n')
|
||||
self.assertEqual(headers.get('transfer-encoding'), 'chunked')
|
||||
self.assertEqual(body, '27\r\nThe dwarves of yore made mighty spells,\r\n25\r\nWhile hammers fell like ringing bells\r\n')
|
||||
|
||||
# verify that socket is closed by server
|
||||
self.assertEqual(sock.recv(1), '')
|
||||
|
||||
def test_026_http_10_nokeepalive(self):
|
||||
# verify that if an http/1.0 client sends connection: keep-alive
|
||||
# and the server doesn't accept keep-alives, we close the connection
|
||||
|
Reference in New Issue
Block a user