hypercorn
hypercorn copied to clipboard
SSL: APPLICATION_DATA_AFTER_CLOSE_NOTIFY
Apparently the SSL: APPLICATION_DATA_AFTER_CLOSE_NOTIFY still exists with hypercorn 0.17.3 and python 3.11.5 (as well as 3.12.7).
Closing a running hypercorn instance with ctr-c or any other SIGTERM will (most of the time) result in "ssl.SSLError: [SSL: APPLICATION_DATA_AFTER_CLOSE_NOTIFY] application data after close notify (_ssl.c:2706)".
In my particular case i ran
hypercorn run_service:quart_app -w 3 --graceful-timeout 10 -b 0.0.0.0:44444 --certfile ../dev/ssl/cert.pem --keyfile ../dev/ssl/key.pem --keyfile-password test
and got
File ".venv/lib/python3.11/site-packages/hypercorn/asyncio/run.py", line 110, in _server_callback
await TCPServer(app, loop, config, context, lifespan_state, reader, writer)
File ".venv/lib/python3.11/site-packages/hypercorn/asyncio/tcp_server.py", line 76, in run
await self._close()
File ".venv/lib/python3.11/site-packages/hypercorn/asyncio/tcp_server.py", line 119, in _close
await self.writer.wait_closed()
File "/usr/local/anaconda3/lib/python3.11/asyncio/streams.py", line 350, in wait_closed
await self._protocol._get_close_waiter(self)
File "/usr/local/anaconda3/lib/python3.11/asyncio/sslproto.py", line 644, in _do_shutdown
self._sslobj.unwrap()
File "/usr/local/anaconda3/lib/python3.11/ssl.py", line 983, in unwrap
return self._sslobj.shutdown()
^^^^^^^^^^^^^^^^^^^^^^^
ssl.SSLError: [SSL: APPLICATION_DATA_AFTER_CLOSE_NOTIFY] application data after close notify (_ssl.c:2706)
Not sure if it is related to this old issue.
If i missed something in the server configuration to avoid this error please let me know.
Python 3.12.3 Hypercorn 0.17.3 Quart 0.19.6
click to show terminal output
(venv) znote@Froeya:~/Projects/HIMS$ python3 run.py
* Serving Quart app 'app.app'
* Debug mode: True
* Please use an ASGI server (e.g. Hypercorn) directly in production
* Running on https://0.0.0.0:5000 (CTRL + C to quit)
[2024-10-22 23:52:46 +0200] [168718] [INFO] Running on https://0.0.0.0:5000 (CTRL + C to quit)
[2024-10-22 23:52:51 +0200] [168718] [INFO] 127.0.0.1:34254 GET /qr/ 2 200 285 3582
Unhandled exception in client_connected_cb
handle_traceback: Handle created at (most recent call last):
File "/home/znote/Projects/HIMS/run.py", line 4, in <module>
app.run(host='0.0.0.0', port=5000, debug=True, certfile='ssl_keys/app.crt', keyfile='ssl_keys/app.key')
File "/home/znote/Projects/HIMS/venv/lib/python3.12/site-packages/quart/app.py", line 852, in run
loop.run_until_complete(asyncio.gather(*tasks))
File "/usr/lib/python3.12/asyncio/base_events.py", line 674, in run_until_complete
self.run_forever()
File "/usr/lib/python3.12/asyncio/base_events.py", line 641, in run_forever
self._run_once()
File "/usr/lib/python3.12/asyncio/base_events.py", line 1979, in _run_once
handle._run()
File "/usr/lib/python3.12/asyncio/events.py", line 88, in _run
self._context.run(self._callback, *self._args)
transport: <asyncio.sslproto._SSLProtocolTransport object at 0x79f5cd59b950>
Traceback (most recent call last):
File "/home/znote/Projects/HIMS/venv/lib/python3.12/site-packages/hypercorn/asyncio/run.py", line 110, in _server_callback
await TCPServer(app, loop, config, context, lifespan_state, reader, writer)
File "/home/znote/Projects/HIMS/venv/lib/python3.12/site-packages/hypercorn/asyncio/tcp_server.py", line 76, in run
await self._close()
File "/home/znote/Projects/HIMS/venv/lib/python3.12/site-packages/hypercorn/asyncio/tcp_server.py", line 119, in _close
await self.writer.wait_closed()
File "/usr/lib/python3.12/asyncio/streams.py", line 364, in wait_closed
await self._protocol._get_close_waiter(self)
File "/usr/lib/python3.12/asyncio/sslproto.py", line 648, in _do_shutdown
self._sslobj.unwrap()
File "/usr/lib/python3.12/ssl.py", line 921, in unwrap
return self._sslobj.shutdown()
^^^^^^^^^^^^^^^^^^^^^^^
ssl.SSLError: [SSL: APPLICATION_DATA_AFTER_CLOSE_NOTIFY] application data after close notify (_ssl.c:2685)
[2024-10-22 23:53:26 +0200] [168718] [INFO] 127.0.0.1:42346 GET /qr/scan 2 200 667 3092
[2024-10-22 23:53:26 +0200] [168718] [INFO] 127.0.0.1:42346 GET /static/html5-qrcode.min.js 2 200 375364 40740
[2024-10-22 23:53:28 +0200] [168718] [INFO] 127.0.0.1:42346 GET / 2 200 116 3335
Unhandled exception in client_connected_cb
handle_traceback: Handle created at (most recent call last):
File "/home/znote/Projects/HIMS/run.py", line 4, in <module>
app.run(host='0.0.0.0', port=5000, debug=True, certfile='ssl_keys/app.crt', keyfile='ssl_keys/app.key')
File "/home/znote/Projects/HIMS/venv/lib/python3.12/site-packages/quart/app.py", line 852, in run
loop.run_until_complete(asyncio.gather(*tasks))
File "/usr/lib/python3.12/asyncio/base_events.py", line 674, in run_until_complete
self.run_forever()
File "/usr/lib/python3.12/asyncio/base_events.py", line 641, in run_forever
self._run_once()
File "/usr/lib/python3.12/asyncio/base_events.py", line 1979, in _run_once
handle._run()
File "/usr/lib/python3.12/asyncio/events.py", line 88, in _run
self._context.run(self._callback, *self._args)
transport: <asyncio.sslproto._SSLProtocolTransport object at 0x79f5ccb01010>
Traceback (most recent call last):
File "/home/znote/Projects/HIMS/venv/lib/python3.12/site-packages/hypercorn/asyncio/run.py", line 110, in _server_callback
await TCPServer(app, loop, config, context, lifespan_state, reader, writer)
File "/home/znote/Projects/HIMS/venv/lib/python3.12/site-packages/hypercorn/asyncio/tcp_server.py", line 76, in run
await self._close()
File "/home/znote/Projects/HIMS/venv/lib/python3.12/site-packages/hypercorn/asyncio/tcp_server.py", line 119, in _close
await self.writer.wait_closed()
File "/usr/lib/python3.12/asyncio/streams.py", line 364, in wait_closed
await self._protocol._get_close_waiter(self)
File "/usr/lib/python3.12/asyncio/sslproto.py", line 648, in _do_shutdown
self._sslobj.unwrap()
File "/usr/lib/python3.12/ssl.py", line 921, in unwrap
return self._sslobj.shutdown()
^^^^^^^^^^^^^^^^^^^^^^^
ssl.SSLError: [SSL: APPLICATION_DATA_AFTER_CLOSE_NOTIFY] application data after close notify (_ssl.c:2685)
[2024-10-22 23:53:34 +0200] [168718] [INFO] 127.0.0.1:41024 GET /qr/ 2 200 285 2281
[2024-10-22 23:53:36 +0200] [168718] [INFO] 127.0.0.1:41024 GET /qr/scan 2 200 667 3352
[2024-10-22 23:53:39 +0200] [168718] [INFO] 127.0.0.1:41024 GET / 2 200 116 3398
Unhandled exception in client_connected_cb
handle_traceback: Handle created at (most recent call last):
File "/home/znote/Projects/HIMS/run.py", line 4, in <module>
app.run(host='0.0.0.0', port=5000, debug=True, certfile='ssl_keys/app.crt', keyfile='ssl_keys/app.key')
File "/home/znote/Projects/HIMS/venv/lib/python3.12/site-packages/quart/app.py", line 852, in run
loop.run_until_complete(asyncio.gather(*tasks))
File "/usr/lib/python3.12/asyncio/base_events.py", line 674, in run_until_complete
self.run_forever()
File "/usr/lib/python3.12/asyncio/base_events.py", line 641, in run_forever
self._run_once()
File "/usr/lib/python3.12/asyncio/base_events.py", line 1979, in _run_once
handle._run()
File "/usr/lib/python3.12/asyncio/events.py", line 88, in _run
self._context.run(self._callback, *self._args)
transport: <asyncio.sslproto._SSLProtocolTransport object at 0x79f5ccb07110>
Traceback (most recent call last):
File "/home/znote/Projects/HIMS/venv/lib/python3.12/site-packages/hypercorn/asyncio/run.py", line 110, in _server_callback
await TCPServer(app, loop, config, context, lifespan_state, reader, writer)
File "/home/znote/Projects/HIMS/venv/lib/python3.12/site-packages/hypercorn/asyncio/tcp_server.py", line 76, in run
await self._close()
File "/home/znote/Projects/HIMS/venv/lib/python3.12/site-packages/hypercorn/asyncio/tcp_server.py", line 119, in _close
await self.writer.wait_closed()
File "/usr/lib/python3.12/asyncio/streams.py", line 364, in wait_closed
await self._protocol._get_close_waiter(self)
File "/usr/lib/python3.12/asyncio/sslproto.py", line 648, in _do_shutdown
self._sslobj.unwrap()
File "/usr/lib/python3.12/ssl.py", line 921, in unwrap
return self._sslobj.shutdown()
^^^^^^^^^^^^^^^^^^^^^^^
ssl.SSLError: [SSL: APPLICATION_DATA_AFTER_CLOSE_NOTIFY] application data after close notify (_ssl.c:2685)
I had to generate a self signed certificate without a PEM password just so it wouldn't hang up on me. Although these errors happen, the requests seemingly load and work fine.
For me (using quart dev mode) this would happen with a coin-toss probability at the end of a request, and if my cert isn't password protected would reinitialize by next request continue working. (at a first glance, haven't properly tested this out)
I'm still not convinced that this isn't a bug made by me, new with async code so might have forgotten to await something. Perhaps I should use @app.teardown_appcontext and let ssl close gracefully somehow.
As @cjavad mentioned above, I get the same error exactly 5 seconds after the request, using a basic Quart example on Windows 11, Py 3.13.0.
Minimal repo here: https://github.com/cjavad/python-hypercorn-issue-125981-repo
Is there a way to work around this to not make this so painful while testing websites from the browser?