I have the following server running gevent
on top of flask
:
import gevent.monkey
gevent.monkey.patch_all()
import flask
import gevent.wsgi
app = flask.Flask(__name__)
@app.route("/")
def hello():
return "Hello World!"
gevent.wsgi.WSGIServer(('127.0.0.1', 5000), app, keyfile='my.key', certfile='my.cer').serve_forever()
It runs fine when calling https://127.0.0.1:5000
but crashes with http://127.0.0.1:5000
. The reason is that the HTTP call is not handled correctly in a HTTPS context:
Traceback (most recent call last):
File "C:\Users\aaa\AppData\Local\Programs\Python\Python35-32\lib\site-packages\gevent\greenlet.py", line 536, in run
result = self._run(*self.args, **self.kwargs)
File "C:\Users\aaa\AppData\Local\Programs\Python\Python35-32\lib\site-packages\gevent\baseserver.py", line 26, in _handle_and_close_when_done
return handle(*args_tuple)
File "C:\Users\aaa\AppData\Local\Programs\Python\Python35-32\lib\site-packages\gevent\server.py", line 173, in wrap_socket_and_handle
ssl_socket = self.wrap_socket(client_socket, **self.ssl_args)
File "C:\Users\aaa\AppData\Local\Programs\Python\Python35-32\lib\site-packages\gevent\_ssl3.py", line 646, in wrap_socket
ciphers=ciphers)
File "C:\Users\aaa\AppData\Local\Programs\Python\Python35-32\lib\site-packages\gevent\_ssl3.py", line 229, in __init__
raise x
File "C:\Users\aaa\AppData\Local\Programs\Python\Python35-32\lib\site-packages\gevent\_ssl3.py", line 225, in __init__
self.do_handshake()
File "C:\Users\aaa\AppData\Local\Programs\Python\Python35-32\lib\site-packages\gevent\_ssl3.py", line 549, in do_handshake
self._sslobj.do_handshake()
ssl.SSLError: [SSL: HTTP_REQUEST] http request (_ssl.c:645)
Mon Sep 4 16:19:01 2017 <Greenlet at 0x4631c60: _handle_and_close_when_done(<bound method StreamServer.wrap_socket_and_handle , <bound method StreamServer.do_close of <WSGIServer, (<gevent._socket3.socket [closed] object, fd=-1, )> failed with SSLError
What is the correct way to catch exceptions thrown in such a loop ( .serve_forever()
)?
I tried the naïve
try:
gevent.wsgi.WSGIServer(('127.0.0.1', 5000), app, keyfile='my.key', certfile='my.cer').serve_forever()
except Exception as e:
print("got exception {e}".format(e=e))
but it is not caught (my hand waving impression is that the try
/ except
pair is not in place yet (and will never be) when the serve_forever()
loop is running)
You may spawn a greenlet and attach exception handler to it:
g = gevent.spawn(WSGIServer(...).serve_forever)
def exception_callback(g):
"""Process gevent exception"""
try:
g.get()
except Exception as exc:
pass
g.link_exception(exception_callback)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.