Fixed bug exposed by redbo's unit test, tweaked test itself a bit based on experimentation.

This commit is contained in:
Ryan Williams
2010-02-11 00:09:54 -08:00
parent 1235f062f3
commit d0040bf5c6
2 changed files with 32 additions and 13 deletions

View File

@@ -471,7 +471,14 @@ class Server(BaseHTTPServer.HTTPServer):
def log_message(self, message):
self.log.write(message + '\n')
ACCEPT_SOCK = set((errno.EPIPE, errno.EBADF))
try:
import ssl
ACCEPT_EXCEPTIONS = (socket.error, ssl.SSLError)
ACCEPT_ERRNO = set((errno.EPIPE, errno.EBADF,
ssl.SSL_ERROR_EOF, ssl.SSL_ERROR_SSL))
except ImportError:
ACCEPT_EXCEPTIONS = (socket.error,)
ACCEPT_ERRNO = set((errno.EPIPE, errno.EBADF))
def server(sock, site,
log=None,
@@ -536,19 +543,18 @@ def server(sock, site,
serv.log.write("(%s) wsgi starting up on %s://%s%s/\n" % (os.getpid(), scheme, host, port))
while True:
try:
client_socket = sock.accept()
try:
client_socket = sock.accept()
except socket.error, e:
if get_errno(e) not in ACCEPT_SOCK:
raise
try:
pool.spawn_n(serv.process_request, client_socket)
pool.spawn_n(serv.process_request, client_socket)
except AttributeError:
warnings.warn("wsgi's pool should be an instance of " \
"eventlet.greenpool.GreenPool, is %s. Please convert your"\
" call site to use GreenPool instead" % type(pool),
DeprecationWarning, stacklevel=2)
pool.execute_async(serv.process_request, client_socket)
except ACCEPT_EXCEPTIONS, e:
if get_errno(e) not in ACCEPT_ERRNO:
raise
except (KeyboardInterrupt, SystemExit):
serv.log.write("wsgi exiting\n")
break

View File

@@ -741,19 +741,32 @@ class TestHttpd(LimitedTestCase):
try:
wsgi.server(sock=sock, site=hello_world, log=self.logfile)
errored[0] = 'SSL handshake error caused wsgi.server to exit.'
except greenthread.greenlet.GreenletExit:
pass
except Exception, e:
errored[0] = 'SSL handshake error raised exception %s.' % e
srv_sock = api.ssl_listener(('localhost', 0), certificate_file, private_key_file)
port = srv_sock.getsockname()[1]
for data in ('', 'GET /non-ssl-request HTTP/1.0\r\n\r\n'):
g = eventlet.spawn(server, srv_sock)
sock = api.connect_tcp(('localhost', port))
srv_sock = api.ssl_listener(('localhost', 0), certificate_file, private_key_file)
port = srv_sock.getsockname()[1]
g = eventlet.spawn_n(server, srv_sock)
client = api.connect_tcp(('localhost', port))
if data: # send non-ssl request
sock.sendall(data)
client.sendall(data)
else: # close sock prematurely
sock.close()
client.close()
api.sleep(0) # let context switch back to server
self.assert_(not errored[0], errored[0])
# make another request to ensure the server's still alive
try:
from eventlet.green import ssl
client = ssl.wrap_socket(api.connect_tcp(('localhost', port)))
client.write('GET / HTTP/1.0\r\nHost: localhost\r\n\r\n')
result = client.read()
self.assert_(result.startswith('HTTP'), result)
self.assert_(result.endswith('hello world'))
except ImportError:
pass # TODO: should test with OpenSSL
greenthread.kill(g)
if __name__ == '__main__':
main()