Patch from Josh Bell to get wsgi.py to handle ZeroReturnErrors, with unit test.
This commit is contained in:
@@ -31,6 +31,7 @@ from eventlet.green import socket
|
||||
from eventlet.green import BaseHTTPServer
|
||||
from eventlet.pool import Pool
|
||||
|
||||
import greenio
|
||||
|
||||
DEFAULT_MAX_SIMULTANEOUS_REQUESTS = 1024
|
||||
DEFAULT_MAX_HTTP_VERSION = 'HTTP/1.1'
|
||||
@@ -84,7 +85,10 @@ class Input(object):
|
||||
length = self.content_length - self.position
|
||||
if not length:
|
||||
return ''
|
||||
read = reader(length)
|
||||
try:
|
||||
read = reader(length)
|
||||
except greenio.SSL.ZeroReturnError:
|
||||
read = ''
|
||||
self.position += len(read)
|
||||
return read
|
||||
|
||||
@@ -96,25 +100,28 @@ class Input(object):
|
||||
self.wfile_line = None
|
||||
|
||||
response = []
|
||||
if length is None:
|
||||
if self.chunk_length > self.position:
|
||||
response.append(rfile.read(self.chunk_length - self.position))
|
||||
while self.chunk_length != 0:
|
||||
self.chunk_length = int(rfile.readline(), 16)
|
||||
response.append(rfile.read(self.chunk_length))
|
||||
rfile.readline()
|
||||
else:
|
||||
while length > 0 and self.chunk_length != 0:
|
||||
try:
|
||||
if length is None:
|
||||
if self.chunk_length > self.position:
|
||||
response.append(rfile.read(
|
||||
min(self.chunk_length - self.position, length)))
|
||||
length -= len(response[-1])
|
||||
self.position += len(response[-1])
|
||||
if self.chunk_length == self.position:
|
||||
rfile.readline()
|
||||
else:
|
||||
response.append(rfile.read(self.chunk_length - self.position))
|
||||
while self.chunk_length != 0:
|
||||
self.chunk_length = int(rfile.readline(), 16)
|
||||
self.position = 0
|
||||
response.append(rfile.read(self.chunk_length))
|
||||
rfile.readline()
|
||||
else:
|
||||
while length > 0 and self.chunk_length != 0:
|
||||
if self.chunk_length > self.position:
|
||||
response.append(rfile.read(
|
||||
min(self.chunk_length - self.position, length)))
|
||||
length -= len(response[-1])
|
||||
self.position += len(response[-1])
|
||||
if self.chunk_length == self.position:
|
||||
rfile.readline()
|
||||
else:
|
||||
self.chunk_length = int(rfile.readline(), 16)
|
||||
self.position = 0
|
||||
except greenio.SSL.ZeroReturnError:
|
||||
pass
|
||||
return ''.join(response)
|
||||
|
||||
def read(self, length=None):
|
||||
@@ -167,6 +174,8 @@ class HttpProtocol(BaseHTTPServer.BaseHTTPRequestHandler):
|
||||
"HTTP/1.0 414 Request URI Too Long\r\nConnection: close\r\nContent-length: 0\r\n\r\n")
|
||||
self.close_connection = 1
|
||||
return
|
||||
except greenio.SSL.ZeroReturnError:
|
||||
self.raw_requestline = ''
|
||||
except socket.error, e:
|
||||
if e[0] != errno.EBADF:
|
||||
raise
|
||||
|
||||
@@ -393,7 +393,40 @@ class TestHttpd(TestCase):
|
||||
headerlines = fd.readuntil('\r\n\r\n').splitlines()
|
||||
self.assertEquals(1, len([l for l in headerlines
|
||||
if l.lower().startswith('content-length')]))
|
||||
|
||||
|
||||
def test_017_ssl_zeroreturnerror(self):
|
||||
|
||||
def server(sock, site, log=None):
|
||||
try:
|
||||
serv = wsgi.Server(sock, sock.getsockname(), site, log)
|
||||
client_socket = sock.accept()
|
||||
serv.process_request(client_socket)
|
||||
return True
|
||||
except:
|
||||
return False
|
||||
|
||||
def wsgi_app(environ, start_response):
|
||||
start_response('200 OK', {})
|
||||
return [environ['wsgi.input'].read()]
|
||||
|
||||
certificate_file = os.path.join(os.path.dirname(__file__), 'test_server.crt')
|
||||
private_key_file = os.path.join(os.path.dirname(__file__), 'test_server.key')
|
||||
|
||||
port = 4204
|
||||
|
||||
sock = api.ssl_listener(('', port), certificate_file, private_key_file)
|
||||
|
||||
from eventlet import coros
|
||||
server_coro = coros.execute(server, sock, wsgi_app)
|
||||
|
||||
client = api.connect_tcp(('127.0.0.1', port))
|
||||
client = util.wrap_ssl(client)
|
||||
client.write('X') # non-empty payload so that SSL handshake occurs
|
||||
client.shutdown()
|
||||
|
||||
success = server_coro.wait()
|
||||
self.assert_(success)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
Reference in New Issue
Block a user