Patch from Josh Bell to get wsgi.py to handle ZeroReturnErrors, with unit test.

This commit is contained in:
Ryan Williams
2009-09-25 23:53:15 -07:00
parent 77ceed8b16
commit 757a48f7b7
2 changed files with 61 additions and 19 deletions

View File

@@ -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

View File

@@ -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()